Shader学习笔记(三)

UnityShader 初级篇(三)

Unity中的透明效果

学习Unity shader的第三天,继续了解一下shader的透明效果。

Unity Shader 的渲染顺序

Unity为了解决渲染顺序问题提供了渲染队列(render queue)这一解决方案,可用SubShader的Queue标签来决定模型归于哪个渲染队列。首先看一下Unity中的几种内置的渲染队列,按照渲染顺序,从先到后进行排序,队列数越小的,越先渲染,队列数越大的,越后渲染。

Background(1000) | 最早被渲染的物体的队列。
Geometry(2000) | 不透明物体的渲染队列。大多数物体都应该使用该队列进行渲染,也是Unity Shader中默认的渲染队列
AlphaTest(2450) | 有透明通道,需要进行Alpha Test的物体的队列,比在Geomerty中更有效。
Transparent(3000) | 半透物体的渲染队列。一般是不写深度的物体,Alpha Blend等的在该队列渲染。
Overlay (4000) | 最后被渲染的物体的队列,一般是覆盖效果,比如镜头光晕,屏幕贴片之类的。

透明度测试

通常,会在片元着色器中使用clip函数来进行透明度测试,clip是CG中的一个函数

  1. 在Properties语义块中声明一个范围在[0,1]之间的属性_Cutoff:
    在这里插入图片描述
    _Cutoff参数用于决定调用clip进行透明度测试时使用的判断条件。它的范围是[0,1],这是因为纹理像素的透明度就在此范围内
  2. 在SubShader语义块中定义了一个Pass语义块
    在这里插入图片描述
    RenderType标签可让Unity把该Shader归入到提前定义的组(这里指TransparentCount组)中,以指明该Shader是一个使用了透明度测试的Shader
  3. 与Properties建立联系,由于_Cutoff的范围在[0,1],因此可使用fixed精度来存储它。
    在这里插入图片描述
  4. 顶点着色器
    在这里插入图片描述
  5. 最重要的透明度测试在片元着色器:
    在这里插入图片描述

最终效果

在这里插入图片描述

透明度混合

**透明度混合:**这种方法可得到真正的半透明效果。它会使用当前片元的透明度作为混合因子,与已经存储在颜色缓冲中的颜色值进行混合,得到新的颜色,但是透明度混合需要关闭深度写入,这使得要非常小心物体的渲染顺序
为了进行混合,需要使用Unity提供的混合命令——Blend。Blend命令的语义可参考【Unity ShaderLab】Blend混合命令

通常,透明度混合使用的是以下的混合命令
在这里插入图片描述

  1. 修改Properties语义块及对应属性变量:
    在这里插入图片描述在这里插入图片描述
  2. 修改SubShader使用的标签:
    在这里插入图片描述
  3. 设置Pass
    在这里插入图片描述
  4. 修改片元着色器
    在这里插入图片描述

最终效果

在这里插入图片描述
但是当模型本身有复杂的遮挡关系或是包含了复杂的非凸网格时,就会有各种各样因为排序错误而产生的错误的透明效果,如图
在这里插入图片描述
这是由于关闭了深度写入造成的,因为这样无法对模型进行像素级别的深度排序,一种解决方法是分割网格,从而可得到一个“质量优等”的网格。但很多情况下这往往不切实际,这时,可让模型像半透明物体一样进行淡入淡出。

开启深度写入的半透明效果

  1. 只需要在原来使用的Pass前面再增加一个新的Pass即可:
    在这里插入图片描述
    引入了新的渲染命令——ColorMask。它的语义如下:
    ColorMask RGB | A | 0 | 其他任何R、G、B、A的组合
    当ColorMask 设为0时,意味着该Pass不写入任何颜色通道,即不会输出任何颜色。这正是所需的——该Pass只需写入深度缓存即可。

最终效果

在这里插入图片描述

ShaderLab的混合命令

先看下混合是如何实现的,当片元着色器产生一个颜色时,可选择与颜色缓存中的颜色进行混合
混合就和两个操作数有关:源颜色(source color)目标颜色(destination color)
源颜色,用S表示,指由片元着色器产生的颜色值;目标颜色,用D表示,从颜色缓冲中读取到的颜色值。对其进行混合后得到的输出颜色,用O表示,它会重新写入到颜色缓冲中。需注意谈及混合中的源颜色、目标颜色和输出颜色时,都包含了RGBA四个通道的值,而并非仅仅是RGB通道
想使用混合,必须先开启它。当使用Blend(Blend Off)命令时,除了设置混合状态外也开启了混合。例如在OpenGL中,需使用glEnable(GL_BLEND)来开启混合,但在Unity中,它已经在背后做了这些工作。
源颜色S和目标颜色D,想要得到输出颜色O就必须使用等式计算,这种等式称为混合等式(blend equation)。当进行混合时,需要两个混合等式:一个用于混合RGB通道,一个用于混合A通道。当设置混合状态时,实际上设置的就是混合等式中的操作因子。在默认情况下,混合等式使用的操作都是加操作,只需再设置一下混合因子即可。由于需两个因子(分别用于混合RGB通道和A通道),每个等式有两个因子(一个用于和源颜色相乘,一个用于和目标颜色相乘),因此一共需要4个因子。
这里可参考 ShaderLab中设置混合因子的命令

双面渲染的透明效果

默认情况下渲染引擎剔除了物体背面(相对于摄像机的方向)的渲染图元,而只渲染了物体的正面。
在Unity中,Cull指令的语法如下:
Cull Back | Front | Off
若设置为Back,那么背对着摄像机的渲染图元就不会被渲染,这也是默认情况下的剔除状态;如果设置为Front,那么那些朝向摄像机的渲染图元就不会被渲染;如果设置为Off,就会关闭剔除功能,那么所有的渲染图元都会被渲染,当由于这时需要渲染的图元数目会成倍增加,因此除非是用于特殊效果,例如这里的双面渲染的透明效果,通常情况是不会关闭剔除功能的。

透明度测试的双面渲染

  1. 参考上面的AlphaTest加入Cull指令关闭剔除即可
    在这里插入图片描述

最终效果

在这里插入图片描述

透明度混合的双面渲染

  1. 复制Pass的代码,得到另一个Pass
  2. 在两个Pass中分别使用Cull指令剔除不同朝向的渲染图元:
    在这里插入图片描述在这里插入图片描述

最终效果

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_42050609/article/details/124861992