Raymarching深度计算异常求助:深度测试出现错误判定
光线步进器深度测试异常问题排查
我编写了一个简单的光线步进器(目标是实现高质量体积火焰),但遇到了如下问题:当距离物体足够近时深度测试正常,稍微向后移动一点,盒子就会突然被判定为比武士刀更近。我的渲染设置为渲染全屏四边形,随后执行如下片段着色器代码:
void main() { //aabb of box in world space vec4 bmin = model * vec4(-1.f.xxx, 1.f); vec4 bmax = model * vec4(1.f.xxx, 1.f); Ray r; RayHitInfo info; // vpos is fullscreen rect with coords in NDC [-1, 1] vec4 rd = inverse(projection) * vec4(vpos, -1., 1.); rd /= rd.w; rd = inverse(view) * rd; r.d = normalize(rd.xyz - cam_pos); r.o = cam_pos; ray_box(r, bmin.xyz, bmax.xyz, info); //Tavian Barnes //branchless ray/bb intersection alg. if(!info.hit) {discard;} vec3 a = r.o + info.tmin*r.d; //box enter ray pos vec3 b = r.o + info.tmax*r.d; //box exit ray pos vec4 depth = a.xyzz; depth.w=1.; depth = projection * view * depth; depth/=depth.w; gl_FragDepth = depth.z; FRAG_COL = vec4(.9.xxx, .8); return; }
问题原因
核心错误出在射线方向的计算逻辑:
- 你通过逆投影、逆视图变换得到的
rd,已经是世界空间下从相机原点出发、指向当前像素对应世界空间点的方向向量。但你错误地用rd.xyz - cam_pos来计算射线方向,这相当于计算了相机位置到那个世界空间点的向量,完全违背了射线的定义(射线起点是cam_pos,方向应该是从起点指向外部的向量)。 - 错误的射线方向会导致
ray_box函数计算出的交点参数info.tmin和info.tmax完全失真,进而使得你基于进入点a计算的深度值混乱,出现距离变化时深度测试突然反转的问题。
修复方案
修正射线方向的计算代码:
// 替换原错误的射线方向计算 r.d = normalize(rd.xyz);
额外建议:
- 检查
ray_box函数的实现,确保它能正确处理射线起点在盒子内部的场景(此时info.tmin应为0,info.tmax为射线离开盒子的距离)。 - 深度值的计算逻辑可以保留,但要确保射线交点的正确性,这样才能保证
gl_FragDepth的取值符合实际的深度缓冲区规则。
内容的提问来源于stack exchange,提问作者Breeze
相关产品推荐
相关产品推荐

