UntiyShader基础学习笔记(六)
本章节学习目标:
- 学习案例制作《镜花水月》案例
- 熟悉Unity ASE工具的使用
- 熟悉UnityShaderLab代码的使用
- 熟悉模版测试和深度测试内容和应用
环境配置:
- UnityTA学习计划
- UnityShaderASE节点全解
- 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 Mask
Write 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实现效果
- 设置模版测试
```hlsl Pass { Stencil { Ref 1 Comp alays Pass replace } }
```
- 设置颜色效果
```hlsl Pass { ColorMask 0 //ColorMask R;ColorMask RG;ColorMask RGB;ColorMask RGBA }
```
- 关闭深度写入
```hlsl Pass { ZWrite Off }
```