这边给unlit(不发光) shader加上stencil功能
Unlit_Stencil.shader,其中stencil相关的用//-----包起来了
Shader "My/Unlit_Stencil" { Properties { _MainTex("Texture", 2D) = "white" {} _Color("Tint", Color) = (1,1,1,1) //----- stencil [Enum(UnityEngine.Rendering.CompareFunction)]_StencilComp("Stencil Comparison", Float) = 8 //CompareFunction.Always _Stencil("Stencil ID", Float) = 0 [Enum(UnityEngine.Rendering.StencilOp)]_StencilOp("Stencil Operation", Float) = 0 //StencilOp.Keep _StencilReadMask("Stencil Read Mask", Float) = 255 _StencilWriteMask("Stencil Write Mask", Float) = 255 //----- } SubShader { Tags { "RenderType" = "Opaque" } LOD 100 Pass { //----- stencil Stencil { Ref[_Stencil] Comp[_StencilComp] Pass[_StencilOp] ReadMask[_StencilReadMask] WriteMask[_StencilWriteMask] } //----- CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float4 color : COLOR; float2 uv : TEXCOORD0; }; struct v2f { float4 vertex : SV_POSITION; fixed4 color : COLOR; float2 uv : TEXCOORD0; float4 worldPosition : TEXCOORD1; }; sampler2D _MainTex; float4 _MainTex_ST; fixed4 _Color; v2f vert(appdata v) { v2f o; o.worldPosition = v.vertex; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = TRANSFORM_TEX(v.uv, _MainTex); //应用贴图的tiling和offset o.color = v.color * _Color; return o; } fixed4 frag(v2f i) : SV_Target { fixed4 c = tex2D(_MainTex, i.uv) * i.color; return c; } ENDCG } } }
创建一个Unlit_Stencil.mat, 把材质的shader设置为Unlit_Stencil,就能在材质检查器(Inspector)上修改材质的stencil参数了
简单的例子
效果:stencil相同的区域显示为蓝色
1) 用上面的shader创建材质Stencil_ID1_Always_Replace.mat
这个材质的效果:所在的区域总是将stencil buffer设置为1
2) 场景中的Cube使用该材质
3) 创建材质Stencil_ID1_Equal_Keep.mat, 确保渲染顺序在上面的材质之后
这个材质的效果:检查stencil buffer是否等于1,等于1的绘制像素(蓝色),否则丢弃像素;
4) 场景中的Capsule使用该材质
5) 运行后就能看到上面的效果
修改共享材质的stencil参数
可以通过MaterialPropertyBlock来修改,这样就不会相互影响
using UnityEngine; using UnityEngine.Rendering; public class ChangeRendererStencil : MonoBehaviour { public int m_stencil; public CompareFunction m_stencilComp = CompareFunction.Always; public StencilOp m_stencilOp = StencilOp.Keep; public int m_stencilWriteMask = 255; public int m_stencilReadMask = 255; private MaterialPropertyBlock m_tempMatProps; void Start() { var renderer = GetComponent<Renderer>(); if (renderer) { if (null == m_tempMatProps) m_tempMatProps = new MaterialPropertyBlock(); renderer.GetPropertyBlock(m_tempMatProps); m_tempMatProps.SetInt("_Stencil", m_stencil); m_tempMatProps.SetInt("_StencilOp", (int)m_stencilOp); m_tempMatProps.SetInt("_StencilComp", (int)m_stencilComp); m_tempMatProps.SetInt("_StencilReadMask", m_stencilWriteMask); m_tempMatProps.SetInt("_StencilWriteMask", m_stencilWriteMask); renderer.SetPropertyBlock(m_tempMatProps); } } }
参考
UnityShader学习笔记- Stencil Buffer - 飞翔的子明 - 博客园 (cnblogs.com)
Unity3D Shader Stencil模版测试学习 - HONT - 博客园 (cnblogs.com)
MaterialPropertyBlock_阿赵3D的博客-CSDN博客_materiapropertyblock
标签:Stencil,简单,public,StencilOp,stencil,使用,tempMatProps,材质 From: https://www.cnblogs.com/sailJs/p/17061209.html