Early-Z与discard:渲染优化的互补双剑

Early-Z和片元着色器的discard是互补关系而非对立。Early-Z在着色前通过深度 测试丢弃被遮挡像素,节省计算资源;而discard则在着色阶段根据材质细节(如贴图alpha通道)丢弃特定像素,实现孔洞等效果。Early-Z无法处理材质本身的透明度需求,discard则能精准控制局部显示。二者协同工作:Early-Z解决全局遮挡,discard处理细节裁剪。某些视觉效果(如植被遮罩)必须依赖discard实现,这是Early-Z无法替代的。

这个问题非常棒,很多人初学渲染时会有这样的困惑。

简要结论:Early-Z 和片元着色器里的 discard 并不是对立关系,而是解决不同问题的组合,且二者的配合有时会影响性能和视觉效果,并且discard依然有其不可替代的实际用途。下面用通俗和技术化的方式,详细解释 :


一、两者是什么,各自解决什么问题?

Early-Z 的目的:
在片元着色器运行之前,用深度缓冲判断一个像素是否“可见”——
不可见者提前丢弃,无需执行片元着色器,节省算力和带宽。

discard (丢弃指令)的目的:
在片元着色器里,判断当前像素是否应该被绘制——
比如植被的遮罩、窗格、有洞的物体,通过贴图的 alpha 通道,决定像素要不要留下。
这通常和美术需求/物体结构有关,和“前后遮挡”不是一个层面。


二、为什么 Early-Z 不能替代 discard?

1. Early-Z 只能帮助丢弃“被遮住”的像素(被别的物体挡住的)

它只根据已有的深度判断一个片元是不是在最前面。

它不知道这个片元本身是不是“本体的一部分”——比如:

树叶的空洞、铁丝网的间隙、破布的破洞…这些都需要discard根据贴图alpha来决定!

Early-Z根本不理解美术想让透明贴图 某区域空出来 的需求。

2. discard 是“根据材质内容”或“美术/贴图”来决定,这不是Early-Z关心的

比如一张图片里,只有α通道大于0.5的地方才是树叶,其余都是空的,Early-Z无能为力,但discard能把空区域丢掉。

没有discard的话,所有片元不管alpha多少,都会算颜色、写入带宽、甚至被混合!

3. 有些视觉需求必须用 discard,Early-Z根本帮不上忙

你不想这块空间有叶子,就得让片元着色器自己说:“丢掉!”

Early-Z只关心“挡住了没”,不关心“本身该不该画”


三、二者如何协作?

Early-Z 帮你“提前丢弃被挡住的整块区域”

discard 帮你“细致地丢弃某些本体内不需要的局部像素”

结合 PreZ Pass,Early-Z 能更高效地减少因为 discard 导致的多余片元着色器执行次数(前面案例已详细分析)


四、生活比喻

Early-Z :只让站在队伍最前面的客人进门,其他的提前拦住(门口看深度)

discard:来了个客人,虽然站得很前,但他穿的是舞会的“半透明服”,美术说他的袖子和裙摆不能进场,这时门卫会根据衣服花纹决定哪些部分要“丢弃”掉

所以,只靠门口筛人,不一定能满足“衣服花纹”这种细致筛查,必须两个协同工作!


五、技术总结

Early-Z 负责空前的剔除(遮挡);discard 负责精准的本体裁剪(遮罩、洞)——一个负责全局,另一个负责细节,两者不是替代关系,而是互补关系。某些材质效果没有discard就做不到!

以下用实际游戏开发、美术需求常见的3~5个场景,举例说明在什么情况下discard特别适合,也就是“非用不可”,而且用Early-Z或其它方案都搞不定:

1. 植被、树叶等Alpha遮罩物体

场景举例
做一片树林,树叶是用一张有alpha通道的贴图叠加上去。贴图里不透明部分是叶子,透明部分实际上没有叶子(只是图片里的空白)。

为什么用discard?
不用discard,整个矩形区域都会被渲染成叶子,包括空白。
用了discard,在片元着色器里判断alpha值,并对透明(<阈值)的地方discard,这样形状就只剩叶子,空白区域透过去了。

效果
正确还原枝叶缝隙、边缘的锯齿也能“隐去”,不然就会是一堆方块伪装的树叶。

2. 铁丝网、格栅、破布、破木板

场景举例
很多需要做栅栏、破布帘、破门板的场所,通常美术只用一个平面Mesh加上一张Alpha遮罩图。

为什么用discard?
贴图中alpha为0的地方是洞,alpha为1的地方是铁丝/木板。
用discard剔除掉洞的部分,不然你的铁丝网两边就会是透明方块(非常丑)。

效果
网络游戏/射击游戏甚至靠这个来做“可穿透的射击区域”。

3. 血迹、水渍、污渍贴花、弹孔

场景举例
在地面、墙壁、物体表面贴“血渍、水渍、弹孔”,贴图的非矩形。这些通常用Decal或者贴片技术,也常常有不规则Alpha通道。

为什么用discard?
美术只需要不规则形状的血迹,矩形区域要被裁切掉。
discard能在shader里把透明的地方裁掉,不然地板上一堆方形血渍很出戏。

效果
贴花效果真实、光滑,没有矩形残影。

4. 复杂UI、特效:火焰尾巴、云雾、精灵粒子

场景举例
很多粒子特效其实用的都是一个个小方片Plane,但贴图是火焰、烟雾、光 斑。

为什么用discard?

火焰和烟雾不像方形,有很多非规则边缘。
discard能让只有“亮”的片元显示出来,背景的(alpha低的)就丢弃了。

效果
火焰边缘柔美、烟雾朦胧,没有难看的方形框框。

5. 游戏角色带洞装备:破洞牛仔裤、战损盔甲

场景举例
有时角色装备有撕裂、镂空的细节,比如透明纱裙、破洞牛仔裤。

为什么用discard?
贴图控制实际显示的区域和不可见部分。
用discard抠除不需要的片元,不然服装就没有洞洞了!

效果
真实还原服装的特殊剪裁或者破坏细节。


总结一句话

用discard就是让你能用一个简单的网格(面片)通过复杂的贴图,在像素级裁剪出各种真实、细腻、不规则的视觉效果,否则没法高效实现美术想表现的大量特殊造型!

Early-Z是判断遮不遮住,**discard则是实现“本物体自带的不规则镂空/透明/遮罩”**的最有效方式。


版权声明:本文为CSDN博主「你一身傲骨怎能输」的原创文章,
遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_33060405/article/details/150940523

最新文章