Shader 中的渲染顺序

1、深度测试和深度写入

有了深度测试和深度写入发挥作用让我们不需要关心不透明物体的渲染顺序比如一个物体A 挡住了 物体B,即使底层逻辑中 先渲染A,后渲染B,我们也不用担心 B的颜色会把A覆盖,因为在进行深度测试时,远处的B的深度值无法通过深度测试,因为它的深度会比已经写入深度缓冲中A的深度值大,重合处的片元会被丢弃,颜色自然就不会写入,最终重叠处渲染出来的会是A的颜色

之前写的所有Shader都没有刻意的去设置深度测试(默认小于判断)、深度写入(默认开启) 、混合模式(默认不混合) 、 渲染队列(默认几何Geometry队列) 相关内容,是因为对于不透明的物体来说,使用默认设置就能够得到正确的渲染效果,但目前处理透明混合时,需要关闭深度写入

2、透明混合为什么需要关闭深度写入

图形学中模拟出现实世界的半透明效果是通过将多个颜色进行混合计算呈现出来的
举例:
如果前方的A对象不关闭深度写入,那么B被A遮挡的部分会在深度测试时被舍弃(因为A离摄像机更近深度更小),那么我们就无法得到被遮挡部分的颜色,也就无法进行颜色的混合计算,因此我们必须关闭透明物体的深度写入,让其不会导致被遮挡物体无法通过深度测试从而无法进行颜色混合。

3、关闭深度写入带来的问题

关闭深度写入,那么物体的渲染顺序就会变得非常的重要,谁先被渲染,谁后被渲染都会影响最终的呈现效果,举例说明
事例一:两个物体 A为半透明物体 B为不透明物体
两种可能的渲染顺序
第一种:先渲染B,再渲染A,可以得到正确的半透明效果
第二种:先渲染A,再渲染B,只会看到B的颜色

从这个例子我们看出,想要得到正确的半透明混合效果,需要先渲染不透明物体,再渲染透明物体。

事例二:两个物体 A B 都为半透明物体
两种可能的渲染顺序
第一种:先渲染B,再渲染A,得到正确的半透明效果
第二种:先渲染A,再渲染B,得到错误的半透明效果(B在前)

从这个例子我们看出,想要得到正确的半透明混合效果,半透明物体之间也需要正确的渲染顺序才能得到正确结果。

通过这两个事例我们知道,当关闭了深度写入后带来的最大问题是物体的渲染顺序会直接影响最终的渲染效果如果先渲染没有开启深度写入的前面的物体,之后渲染后面的物体就会将前面物体的颜色覆盖或出现错误前后关系表现

4、如何解决渲染顺序带来的问题

为了解决渲染顺序带来的问题,大部分的渲染引擎采取的方式都是先对场景上的物体进行排序,然后再渲染

常规方法为:
1.先渲染所有不透明物体,开启它们的深度测试和深度写入

2.将半透明物体按照离摄像机的远近进行排序,然后从后往前的顺序渲染它们开启深度测试关闭深度写入

这样做的目的是保证靠后的物体颜色能先直接进入颜色缓冲区或混合后进入颜色缓冲区,就不会出现之前两个事例当中由于先渲染前面的物体导致结果出现问题

特殊情况

常规方法:
1.先渲染所有不透明物体开启它们的深度测试和深度写入
2.将半透明物体按照离摄像机的远近进行排序,然后从后往前的顺序渲染它们
开启深度测试关闭深度写入(排序是基于物体的,而不是片元的)

解决方案:

1.忍一忍,接受部分细节的小瑕疵
2.从模型入手:拆分模型
3.使用开启深度写入的半透明效果来模拟半透明(性能消耗较高)

  • 25
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Unity,Tags是一种特殊的关键字,用于在Shader指定一些渲染相关的信息,例如渲染类型、渲染队列、渲染器名称等。Tags通常被用于告诉Unity如何处理Shader,以及如何在场景使用该Shader。 下面是一些常用的Tags及其含义: - RenderType:指定渲染类型,例如Opaque(不透明)、Transparent(半透明)、TransparentCutout(半透明带透明贴图)等。 - Queue:指定渲染队列,用于控制Shader渲染顺序。具有相同队列的Shader将按照其在场景顺序进行渲染。 - DisableBatching:禁用批处理,用于控制是否对多个物体使用相同的Shader进行批处理。如果禁用批处理,则会为每个物体单独进行渲染,可能会影响性能。 - RenderPipeline:指定渲染管线,用于控制Shader在哪个渲染管线使用(例如Built-in或Universal Render Pipeline)。 - ShaderLOD:指定Shader的LOD级别,用于控制Shader在不同距离下的细节程度。较远的物体可以使用较低的LOD级别以提高性能。 Tags通常出现在Shader文件的SubShader,用于告诉Unity如何处理该SubShader。例如,在以下示例,我们使用RenderType标签指定该SubShader渲染类型为Opaque: ```ShaderLab SubShader { Tags { "RenderType"="Opaque" } // ... } ``` 除了在Shader文件使用Tags之外,我们还可以在Unity Editor使用Tags进行场景配置。例如,在设置相机的渲染路径时,我们可以使用Tags来指定渲染管线: ```C# Camera.main.depthTextureMode = DepthTextureMode.Depth; Camera.main.renderingPath = RenderingPath.Forward; Camera.main.actualRenderingPath = RenderingPath.Forward; Camera.main.clearFlags = CameraClearFlags.SolidColor; Camera.main.backgroundColor = Color.black; Camera.main.allowHDR = true; Camera.main.allowMSAA = true; Camera.main.allowDynamicResolution = true; Camera.main.SetReplacementShader(Shader.Find("MyShader"), "RenderType=Opaque"); ``` 使用Tags可以为我们提供更多的灵活性和控制权,使得Shader在不同的场景都能够得到良好的表现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值