URP 渲染实战 / 第 20 章 地形与植被 / 案例 20.9
案例 20.9距离淡出:缩短与抖动裁剪进阶
目标:草在远处平滑地消失,而不是在某个距离“啪”地断掉。
草地必须有一个绘制距离:几十米外的草叶小于一个像素,画了也只是产生闪烁和过度绘制(Overdraw)。直接截断会在地面上留下一条清晰的边界线,相机一动边界线跟着移动,非常显眼。我们组合两种手段:
- 缩短:顶点着色器里按到相机的距离计算
fade,把整丛草的高度乘以lerp(0.3, 1, fade)。远处的草先变矮,自然地“沉”进地面。 - 抖动裁剪(Dither Clip):片元着色器里用 4×4 Bayer 矩阵给每个像素一个阈值,
clip(fade − 阈值)。fade 为 0.5 时恰好一半像素被丢弃。没有时间抗锯齿时能看到细小的网点(如图 20-17 右的远处),开启 TAA 后网点在帧间累积,看起来就像半透明;它仍然是不透明渲染,不需要排序、也能正常写深度。注意 MSAA 帮不上忙:clip 是按片元执行的,同一像素的多个采样一起被保留或丢弃。
Assets/Cookbook/Ch20/Grass.shader(节选:dither)
// 4×4 Bayer 抖动阈值(0..1):按屏幕像素位置给出不同阈值,用 clip 做“半透明” float Bayer4x4(float2 pixel) { const float m[16] = { 0, 8, 2, 10, 12, 4, 14, 6, 3, 11, 1, 9, 15, 7, 13, 5 }; uint2 p = uint2(pixel) % 4; return (m[p.y * 4 + p.x] + 0.5) / 16.0; }

移动端提示
clip(Alpha Test)在 TBDR 架构的移动 GPU 上会破坏隐藏面剔除(HSR/Early-Z)的效率,大面积使用时代价明显。移动端可以只保留“缩短”,或者把淡出带放在非常远、覆盖像素很少的地方;更彻底的做法是按区块做 LOD:远处区块直接用更稀疏的实例数组。地面贴图的颜色也要与草的平均颜色接近,草消失后才不会露出一块不同色的地面——这也是为什么示范地形的草地层贴图偏深绿。本案例出自《URP 渲染实战》第 20 章「地形与植被」。在章节中阅读上下文 →