模板测试(Stencil)

作者:追风剑情 发布于:2018-12-27 16:02 分类:Shader

ShaderLab 命令:模板

示例: 利用Sphere在Cube身上挖个洞


  1. Shader "Custom/StencilTest"
  2. {
  3. Properties
  4. {
  5. _MainTex ("Texture", 2D) = "white" {}
  6.  
  7. //利用模板可实现像素级遮罩(决定哪些像素要丢弃)
  8. //Stencil功能在延迟渲染路径中有一定的限制
  9.  
  10. //Ref值
  11. _Stencil ("Stencil Ref", Float) = 0
  12. //比较值
  13. _StencilComp ("Stencil Comparison", Float) = 8
  14. //处理方式
  15. _StencilOp ("Stencil Operation", Float) = 0
  16. //0-255
  17. _StencilWriteMask ("Stencil Write Mask", Float) = 255
  18. //0-255
  19. _StencilReadMask ("Stencil Read Mask", Float) = 255
  20.  
  21. //_ColorMask ABGR(1-2-4-8)
  22. //0表示不写入颜色通道到颜色缓冲区
  23. _ColorMask ("Color Mask", Float) = 15
  24. [Enum(UnityEngine.Rendering.CompareFunction)] _ZTest("ZTest", Float) = 4
  25. }
  26. SubShader
  27. {
  28. Tags { "RenderType"="Opaque" }
  29. LOD 100
  30.  
  31. Stencil
  32. {
  33. //三个测试阶段顺序:
  34. //顶点着色器->片元着色器->AlphaTest->StencilTest->DepthTest
  35.  
  36. //该值用来比较
  37. Ref [_Stencil]
  38. //用Ref值与模板缓冲区中的值进行比较(即,模板测试),默认为: always
  39. Comp [_StencilComp]
  40. //当模板测试、深度测试都通过时要做什么处理。默认: keep.
  41. Pass [_StencilOp]
  42. //模板测试未通过时要做什么处理。 默认: keep.
  43. //Fail stencilOperation
  44. //模板测试通过,但深度测试未通过时要做什么处理。默认: keep.
  45. //ZFail stencilOperation
  46.  
  47. //也可以显示指定是对Cull Front还是对Cull Back进行判断
  48. //CompFront, PassFront, FailFront, ZFailFront
  49. //CompBack, PassBack, FailBack, ZFailBack
  50.  
  51. /**
  52. 比较函数(Comparison Function):
  53. Greater: 只渲染Ref值比缓冲区中值大的像素
  54. GEqual: 只渲染Ref值比缓冲区中值大的或等于的像素
  55. Less: 只渲染Ref值比缓冲区中值小的像素
  56. LEqual: 只渲染Ref值比缓冲区中值小的或等于的像素
  57. Equal: 只渲染Ref值与缓冲区中值相等的像素
  58. NotEqual:只渲染Ref值与缓冲区中值不相等的像素
  59. Always: 让stencil测试总是通过
  60. Never: 让stencil测试总是失败
  61. */
  62.  
  63. /**
  64. 模板操作(Stencil Operation):
  65. Keep: 保持缓冲区内容
  66. Zero: 写入0到缓冲区
  67. Replace: 写入Ref值到缓冲区
  68. IncrSat: 增加缓冲区的值,如果缓冲区的值已经达到255,则保持255
  69. DecrSat: 减少缓冲区的值,如果缓冲区的值已经为0,则保持0
  70. Invert: 反转所有位
  71. IncrWrap: 增加缓冲区的值,如果缓冲区的值已经达到255,则变为0
  72. DecrWrap: 减少缓冲区的值,如果缓冲区的值已经为0,则变为255
  73. */
  74.  
  75. /**
  76. ReadMask: 默认值为255
  77. if(referenceValue&readMask comparisonFunction stencilBufferValue&readMask) {
  78. 通过模板测试
  79. }
  80. */
  81.  
  82. /**
  83. WriteMask: 默认值为255
  84. 缓冲区的值=referenceValue&writeMask
  85. */
  86.  
  87. ReadMask [_StencilReadMask]
  88. WriteMask [_StencilWriteMask]
  89. }
  90.  
  91. //Cull Off
  92. //Lighting Off
  93. //ZWrite Off
  94. //Blend SrcAlpha OneMinusSrcAlpha
  95. ZTest [_ZTest]
  96. //向颜色缓冲区写入颜色通道值(0: 不写入)
  97. //ColorMask RGBA
  98. ColorMask [_ColorMask]
  99.  
  100. Pass
  101. {
  102. CGPROGRAM
  103. #pragma vertex vert
  104. #pragma fragment frag
  105. // make fog work
  106. #pragma multi_compile_fog
  107. #include "UnityCG.cginc"
  108.  
  109. struct appdata
  110. {
  111. float4 vertex : POSITION;
  112. float2 uv : TEXCOORD0;
  113. };
  114.  
  115. struct v2f
  116. {
  117. float2 uv : TEXCOORD0;
  118. UNITY_FOG_COORDS(1)
  119. float4 vertex : SV_POSITION;
  120. };
  121.  
  122. sampler2D _MainTex;
  123. float4 _MainTex_ST;
  124. v2f vert (appdata v)
  125. {
  126. v2f o;
  127. o.vertex = UnityObjectToClipPos(v.vertex);
  128. o.uv = TRANSFORM_TEX(v.uv, _MainTex);
  129. UNITY_TRANSFER_FOG(o,o.vertex);
  130. return o;
  131. }
  132. fixed4 frag (v2f i) : SV_Target
  133. {
  134. // sample the texture
  135. fixed4 col = tex2D(_MainTex, i.uv);
  136. // apply fog
  137. UNITY_APPLY_FOG(i.fogCoord, col);
  138. return col;
  139. }
  140. ENDCG
  141. }
  142. }
  143. }


效果

1111.png22222.png

444.png333.png

Stencil功能在延迟渲染路径中有一定的限制

1111.png


标签: Shader

Powered by emlog  蜀ICP备18021003号-1   sitemap

川公网安备 51019002001593号