- 用于精确控制像素丢弃的逐片元操作,通过模板缓冲区(8位整数/像素)实现复杂遮罩效果。
- 支持8种比较函数和6种缓冲操作
- 当前模版操作,只能在Shader文件中书写操作,ShaderGraph中无法直接使用模版指令。
【从UnityURP开始探索游戏渲染】专栏-直达
核心配置预览
- Stencil {
- Ref 2 // 必要模版数值
- ReadMask 255
- WriteMask 255
- Comp Greater // 必要比较操作符
- Pass Replace // 必要通过后的操作
- Fail Keep
- ZFail DecrSat
- }
复制代码 1. 核心配置命令
- Ref:设置参考值(0-255整数),用于与模板缓冲区比较
- ReadMask:读取掩码(0-255),按位与操作后比较(默认255)
- WriteMask:写入掩码(0-255),控制可修改的缓冲区位(默认255)
2. 比较函数命令
Comp支持以下枚举值:
- Always/Never:始终通过/拒绝
- Less/Greater:小于/大于时通过
- Equal/NotEqual:等于/不等于时通过
- LessEqual/GreaterEqual:小于等于/大于等于时通过
3. 操作命令
Pass/Fail/ZFail支持的操作:
- Keep:保持原值
- Zero:置零
- Replace:用Ref值替换
- IncrSat/DecrSat:饱和增减(0/255边界)
- IncrWrap/DecrWrap:循环增减
- Invert:按位取反
模板测试具体过程
- 缓冲区初始化
- 清除模板缓冲:GL.Clear(ClearBufferMask.StencilBufferBit)
- 设置初始值:GL.StencilMask(0xFF)(默认全255)
- 测试阶段-逐片元
- plaintext
- if (片元模板值 [比较函数] 参考值) {
- 执行通过操作(如保留像素)
- } else {
- 执行失败操作(如丢弃像素)
- }
复制代码 - 缓冲更新
比较函数(StencilFunc)
函数含义OpenGL常量Never永远不通过GL_NEVERAlways永远通过GL_ALWAYSLess模板值 < 参考值GL_LESSLEqual模板值 ≤ 参考值GL_LEQUALGreater模板值 > 参考值GL_GREATERGEqual模板值 ≥ 参考值GL_GEQUALEqual模板值 == 参考值GL_EQUALNotEqual模板值 != 参考值GL_NOTEQUAL缓冲操作(StencilOp)
操作组合含义Keep保持当前模板值不变(默认)Zero将模板值设为0Replace用参考值替换模板值Incr/IncrWrap模板值+1(超过255时,前者截断后者循环)Decr/DecrWrap模板值-1(低于0时,前者截断后者循环)Invert按位取反(~操作)示例1
- Shader "Custom/StencilMask" {
- SubShader {
- Tags { "Queue"="Geometry-1" } // 优先渲染
- ColorMask 0 // 不写入颜色
- ZWrite Off
- Stencil {
- Ref 1
- Comp Always
- Pass Replace // 将模板值设为1
- }
- Pass {} // 空Pass仅用于写入模板
- }
- }
复制代码
- 物体模版测试shader,该Shader仅在模板值为1的区域内渲染物体。
- Shader "Custom/StencilObject" {
- SubShader {
- Stencil {
- Ref 1
- Comp Equal // 仅渲染模板值=1的区域
- Pass Keep
- }
- Pass {
- // 正常着色代码...
- }
- }
- }
复制代码 示例2 外轮廓描边
【从UnityURP开始探索游戏渲染】专栏-直达
(欢迎点赞留言探讨,更多人加入进来能更加完善这个探索的过程,
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |