
UntiyShader基础学习笔记(六)
本章节学习目标:
-
学习案例制作《镜花水月》案例
-
熟悉Unity ASE工具的使用
-
熟悉UnityShaderLab代码的使用
-
熟悉模版测试和深度测试内容和应用
环境配置:
-
VScode
-
Unity2022·····
-
UnityShader入门精要
一、模版测试和深度测试的技术解析
1、模版测试技术解析
-
基本原理
-
模板缓冲区(Stencil Buffer)
模板缓冲区是一个与帧缓冲区大小相同的额外缓冲区,每个像素对应一个模板值,通常是一个8位无符号整数,取值范围为0到255,默认值为0。这些值可以在渲染过程中被修改,并用于后续的模板测试。 -
模板测试操作
在输出合并阶段,GPU会比较当前像素片段的模板参考值(Stencil Reference Value)与模板缓冲区中相应位置的模板值。比较操作可以是等于、不等于、大于、小于等逻辑运算。根据比较结果,决定当前像素片段是否通过测试并被写入帧缓冲区。 -
模板操作
如果模板测试失败,可以配置GPU执行特定的操作,如保持原值、设置为0、递增或递减模板值等。这些操作允许在渲染过程中动态地修改模板缓冲区的内容。
-
实现步骤
-
初始化模板缓冲区
在开始渲染之前,通常需要清除模板缓冲区,并设置初始的模板值。例如,可以使用glClearStencil
和glClear
函数在OpenGL中清除模板缓冲区。 -
配置模板测试参数
设置模板参考值、定义模板比较函数(如GL_EQUAL
、GL_NOTEQUAL
等)以及指定模板测试失败时的操作(如GL_KEEP
、GL_REPLACE
等)。 -
在着色器中使用模板值
可以在顶点着色器或片段着色器中读取和修改模板值。例如,在片段着色器中可以根据计算结果更新模板值。 -
应用模板测试
在渲染循环中启用模板测试,并提交相应的绘制调用。GPU会根据配置的参数自动执行模板测试。
-
应用场景
-
遮罩效果
通过模板测试可以实现复杂的遮罩区域,只在特定区域内绘制内容。例如,可以先渲染一个遮罩对象,设置其模板值,然后在后续渲染中仅对模板值匹配的区域进行绘制。 -
镜像反射
使用模板测试来标记反射区域的边界,然后只在这些区域内渲染反射图像。 -
轮廓渲染
先渲染物体的内部部分并设置模板值,再渲染外部轮廓并根据模板值进行混合。 -
多视口渲染
在多视口渲染中,模板测试可以用于限制每个视口的渲染区域。
2、深度测试技术解析
二、镜花水月案例
1、UnityASE实现效果
-
模版测试设置
Reference(引用的意思,引用的数值,放在模版测试缓冲区的数值,默认0,范围0-255)
Read MaskWrite Mask
Comparison(模版测试的规则,“Always是总是能够通过模版测试,Never是不能通过”)本次设置为总是通过Always
Pass Front(意思为,模版测试通过之后模版值怎么处理,正面,(还有背面))需要关闭背面剔除可以得到背面设置方法。本次设置为Replace替换成1
Fail Front(模版测试失败了要怎么做的选项)
Zfail Front(模版测试通过之后,但是深度测试没有通过的选项)
-
关闭Color Mask(关闭颜色显示)
-
更改渲染队列参数
-
将深度写入关闭,深度写入关闭后将不再遮挡后面的物体
-
给场景中的物体的Shader进行模版设置
-
ASE修改渲染队列的方法
-
深度测试修改
在Unity等图形渲染引擎中,ZTest Mode通常有以下几种模式:
-
Always:始终通过深度测试,无论深度值如何。
-
Never:始终不通过深度测试。
-
Less:当当前像素的深度值小于深度缓冲区中的值时通过测试。
-
Greater:当当前像素的深度值大于深度缓冲区中的值时通过测试。
-
Equal:当当前像素的深度值等于深度缓冲区中的值时通过测试。
-
LEqual:当当前像素的深度值小于等于深度缓冲区中的值时通过测试(默认模式)。
-
GEqual:当当前像素的深度值大于等于深度缓冲区中的值时通过测试。
-
NotEqual:当当前像素的深度值不等于深度缓冲区中的值时通过测试。
-
2、UnityShaderCode实现效果
-
设置模版测试
Pass { Stencil { Ref 1 Comp alays Pass replace } }
-
设置颜色效果
Pass { ColorMask 0 //ColorMask R;ColorMask RG;ColorMask RGB;ColorMask RGBA }
-
关闭深度写入
Pass { ZWrite Off }
- 感谢您的赞赏