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

Unity光线步进计算着色器SDF有向距离场法向量计算失效问题

问题原因

你编写的法向量计算函数存在笔误,每个分量的差分计算中减数与被减数完全相同,导致所有分量的计算结果均为0,最终输出全黑颜色。

原normal函数的三个分量计算逻辑均为sdf_box(偏移点) - sdf_box(同一个偏移点),两个相等的值相减结果为0,三个分量全0经过normalize处理后仍然是零向量,映射为RGB颜色就是纯黑。

修正后的代码

使用中心差分法的正确实现如下:

float EPSILON = 0.001f;
float3 normal(float3 p) {
    float2 e = float2(EPSILON, 0);
    return normalize(float3(
        sdf_box(p + e.xyy) - sdf_box(p - e.xyy),
        sdf_box(p + e.yxy) - sdf_box(p - e.yxy),
        sdf_box(p + e.yyx) - sdf_box(p - e.yyx))
    );
}

如果需要降低计算量,也可以使用前向差分实现:

float3 normal(float3 p) {
    const float EPSILON = 0.001f;
    float d = sdf_box(p);
    return normalize(float3(
        sdf_box(p + float3(EPSILON, 0, 0)) - d,
        sdf_box(p + float3(0, EPSILON, 0)) - d,
        sdf_box(p + float3(0, 0, EPSILON)) - d
    ));
}

额外优化建议

你当前的立方体SDF实现可以简化,无需拆分x/y/z分别计算:

float sdf_box (float3 p)
{
    const float3 center = float3(0.0f, 0.0f, 0.0f);
    const float3 size = float3(1.0f, 1.0f, 1.0f);
    float3 q = abs(p - center) - size * 0.5f;
    return length(max(q, 0.0f)) + min(max(q.x, max(q.y, q.z)), 0.0f);
}

内容的提问来源于stack exchange,提问作者Jimmy Diddler

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 20:39:05