You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 16:35:21