案例 22.3角度淡出:开启 Decal Shader Graph 的 Angle Fade进阶
目标:贴花在与投影方向接近平行的表面上自动淡出,消除拉伸。
Decal Projector 有 startAngleFade / endAngleFade 两个参数(0–180°,默认都是 180,即不淡出)。但只设置它们没有效果——还需要贴花材质的 Shader Graph 在 Graph Settings 里勾选 ,它会为 Shader 生成 DECAL_ANGLE_FADE 关键字和对应的计算。URP 包自带的 Decal.shadergraph 没有勾选这一项。
.shadergraph 文件本质上是 JSON,Graph Settings 存在 UniversalDecalSubTarget 对象的 m_DecalData 字段里。本章把包里的 Decal.shadergraph 复制一份到 Ch22/DecalAngleFade.shadergraph,只改了两处:"angleFade": true,以及把 Shader 路径 m_Path 改为 Cookbook/Ch22。在编辑器里则只需打开 Graph、在 Graph Inspector 里勾选 Angle Fade。
淡出的计算在 C# 端预先打包好,摘自 URP 14 Runtime/Decal/Entities/DecalEntityManager.cs 的注释与代码:
// In the shader to remap from cosine -1 to 1 to new range 0..1 (with 0 - 0 degree and 1 - 180 degree) // we do 1.0 - (dot() * 0.5 + 0.5) => 0.5 * (1 - dot()) // we actually square that to get smoother result => x = (0.5 - 0.5 * dot())^2 // Do a remap in the shader. 1.0 - saturate((x - start) / (end - start)) // After simplification => saturate(a + b * dot() * (dot() - 2.0)) float angleStart = startAngleFade / 180.0f; float angleEnd = endAngleFade / 180.0f; var range = Mathf.Max(0.0001f, angleEnd - angleStart); cachedChunk.angleFades[arrayIndex] = new Vector2(1.0f - (0.25f - angleStart) / range, -0.25f / range);
也就是说,它没有在 Shader 里算反余弦求角度,而是把“夹角 0–180°”近似映射成 ,再把重映射的系数在 CPU 上算好,Shader 里只剩一次乘加。这是一个很典型的“把非线性重映射的常量部分搬到 CPU”的优化。
