Raymarching学习中自定义隐式曲面在Shadertoy无法正常显示求助
核心问题原因
返回值不是合法有向距离场(SDF)
你当前sdRound返回的是隐式曲面的多项式函数值,并非Raymarching要求的有向距离。Matlab的fimplicit3仅需定位f(x,y,z)=0的等值面,对函数输出的单位无要求,但Raymarching的步进逻辑依赖返回值作为实际空间距离单位,直接用多项式值会导致步进长度完全错误,要么提前终止要么直接穿透曲面,最终渲染异常。缺少梯度归一化修正
如果要使用自定义隐式函数做Raymarching,需要将隐式函数值除以其梯度的模长,转换为近似有向距离,修正后的代码参考:
// 原始隐式曲面函数 float map(vec3 p) { float lengthXYZ = dot(p,p); return lengthXYZ * lengthXYZ + 2.0 * p.y * lengthXYZ + 2.0 * (p.x*p.x + p.z*p.z); } // 修正后的近似SDF float sdRound(vec3 p) { float f = map(p); // 计算函数梯度 vec2 e = vec2(0.001, 0.0); vec3 grad = vec3( map(p + e.xyy) - map(p - e.xyy), map(p + e.yxy) - map(p - e.yxy), map(p + e.yyx) - map(p - e.yyx) ) / (2.0 * e.x); // 归一化得到近似有向距离 return f / length(grad); }
- 可选适配方案
如果不做梯度归一化,也可以调整步进逻辑适配隐函数:步进时判断abs(map(p)) < 自定义阈值(阈值根据模型尺寸调整,参考范围0.01~0.1),同时调小步进系数,比如每次步进距离取0.1 * abs(map(p))避免穿透,但这种方案的渲染效率和精度都低于使用修正后的SDF。
内容的提问来源于stack exchange,提问作者Joy900
相关产品推荐
相关产品推荐

