unity shader中的模板测试

模板测试想象成「剪纸模板」

小时候玩过剪纸吗?比如拿一张镂空的纸板盖在画布上,只有镂空的部分能涂颜色,其他区域被挡住。模板测试就是这个原理——它决定哪些像素能"露出来"被绘制,哪些要被"盖住"。


核心工具:模板缓冲区(Stencil Buffer)

  1. 这是一个隐藏的"草稿纸",每个像素对应一个数字(比如0、1、2…)
  2. 你可以在 Shader 中写规则:“只有草稿纸上写着某个数字的地方,才允许画像素”
  3. 这个数字可以被修改,实现动态遮罩效果

模板测试的关键参数(就像设置规则)

在 Shader 中你会看到类似这样的代码:

Stencil {
    Ref 1          // 参考值:我要用数字1当标准
    Comp Equal     // 比较规则:只画草稿纸上也是1的地方
    Pass Keep      // 如果通过测试:保持草稿纸原来的数字不变
    Fail Replace   // 如果没通过:把草稿纸改成参考值1
}

实际应用场景(超直观)

  1. UI圆形头像遮罩

    • 先画一个圆形区域,把模板缓冲区对应位置写成1
    • 再画头像图片,只允许模板值为1的地方显示,其他区域被裁切
  2. 角色被遮挡时显示轮廓

    • 正常绘制角色,模板值写1
    • 当角色被墙挡住时,检测模板值非1的区域画红色轮廓
  3. 镜子效果

    • 先画镜子区域,模板值写1
    • 再在镜像位置绘制角色,但只显示在模板值为1的区域

常见坑点提醒

  • 忘记清空模板缓冲区:可能导致上一帧的数据影响当前帧(就像没擦黑板)
  • 多物体混合使用:不同物体用不同的模板值时,要规划好数字分配(比如A用1-10,B用11-20)
  • 渲染顺序很重要:先画模板区域,再画被遮罩的内容(就像先放镂空纸板再喷漆)

一句话总结

模板测试 = 数字化的动态遮罩,通过给像素"贴标签"(数字),控制哪里能画哪里不能画,是制作高级特效的必备技能!

### 如何在 Unity测试 Shader 模板 #### 使用 `Stencil` 关键字配置模板测试 为了启用并自定义模板测试,在着色器中需加入特定的 `Stencil` 代码块。此部分允许开发者指定一系列参数来控制哪些像素应当被绘制以及如何更新模板缓冲区中的数据[^3]。 ```cg Shader "Custom/StencilTest" { Properties { _MainTex ("Texture", 2D) = "white" {} } SubShader { Tags { "RenderType"="Opaque" } Pass { Stencil { Ref [_RefVal] ReadMask [_ReadMaskVal] WriteMask [_WriteMaskVal] Comp Always // Comparison function Pass Replace // Action on pass Fail Keep // Action on fail ZFail Keep // Depth buffer fail action } CGPROGRAM #pragma vertex vert #pragma fragment frag sampler2D _MainTex; struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 pos : SV_POSITION; }; v2f vert (appdata v) { v2f o; o.pos = UnityObjectToClipPos(v.vertex); o.uv = v.uv; return o; } fixed4 frag (v2f i) : SV_Target { fixed4 col = tex2D(_MainTex, i.uv); return col; } ENDCG } } } ``` 这段代码展示了怎样创建一个带有基本纹理映射功能的同时也启用了模板测试的着色器。其中,`Comp`, `Pass`, `Fail`, 和 `ZFail` 定义了当执行模板测试时不同情况下的行为;而 `Ref`, `ReadMask`, 及 `WriteMask` 则用于设置参考值及其掩码操作[^5]。 #### 配置材质属性以调整模板测试逻辑 除了编写合适的着色器外,还需要通过脚本或Inspector面板动态修改这些属性以便灵活地改变模板测试的行为模式: - `_RefVal`: 设置参考数值。 - `_ReadMaskVal`: 设定读取遮罩位。 - `_WriteMaskVal`: 控制写入遮罩位。 这使得可以在运行期间轻松切换不同的模板测试条件而不必重新编译着色器程序[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值