zoukankan      html  css  js  c++  java
  • Unity Shader之模板测试

    Unity Shader之模板测试

    一沙一世界,一花一天堂

    一、Stencil testing

     

    渲染管线
    渲染管线

        当片段着色器处理完一个片段之后,模板测试(Stencil Test)会开始执行,和深度测试一样,它也可能会丢弃片段。接下来,被保留的片段会进入深度测试,它可能会丢弃更多的片段。模板测试是根据又一个缓冲来进行的,它叫做模板缓冲(Stencil Buffer),我们可以在渲染的时候更新它来获得一些很有意思的效果。
        一个模板缓冲中,(通常)每个模板值(Stencil Value)是8位的。所以每个像素/片段一共能有256种不同的模板值。我们可以将这些模板值设置为我们想要的值,然后当某一个片段有某一个模板值的时候,我们就可以选择丢弃或是保留这个片段了。

     

    二、模板函数

    2.1 调用函数

    1. Stencil 
    2. { 
    3. Ref 1//Reference Value ReadMask 255 WriteMask 255 Comp Always //Comparison Function Pass Replace 
    4. Fail Keep 
    5. ZFail Replace 
    6. } 

    2.2 参数说明

    Ref :就是参考值,当参数允许赋值时,会把参考值赋给当前像素
    ReadMask: 对当前参考值和已有值进行mask操作,默认值255,一般不用
    WriteMask: 写入Mask操作,默认值255,一般不用

    Comp: 比较方法。是拿Ref参考值和当前像素缓存上的值进行比较。默认值always,即一直通过。
    -- Greater - 大于

    • GEqual - 大于等于
    • Less - 小于
    • LEqual - 小于等于
    • Equal - 等于
    • NotEqual - 不等于
    • Always - 永远通过
    • Never - 永远通不过

    Pass: 当模版测试和深度测试都通过时,进行处理

    Fail :当模版测试和深度测试都失败时,进行处理

    ZFail: 当模版测试通过而深度测试失败时,进行处理

    pass,Fail,ZFail都属于Stencil操作,他们参数统一如下:

    • Keep 保持(即不把参考值赋上去,直接不管)
    • Zero 归零
    • Replace 替换(拿参考值替代原有值)
    • IncrSat 值增加1,但不溢出,如果到255,就不再加
    • DecrSat 值减少1,但不溢出,值到0就不再减
    • Invert 反转所有位,如果1就会变成254
    • IncrWrap 值增加1,会溢出,所以255变成0
    • DecrWrap 值减少1,会溢出,所以0变成255

    三、案例

    3.1 描边

     

    渲染管线
    渲染管线

     

    1. Shader "ShaderCookbook/stencil_outline" { 
    2. Properties { 
    3. _MainTex("Texture", 2D) = "white" {} 
    4. _OutLineWidth("Width", float) = 0.01  
    5. _OutLineColor("Color", color) = (1, 1, 1, 1
    6. SubShader { 
    7. Tags { 
    8. "RenderType" = "Opaque" 
    9. LOD 100 
    10.  
    11. Stencil { 
    12. Ref 0 Comp Equal Pass IncrSat 
    13.  
    14. Pass { 
    15. CGPROGRAM 
    16. #pragma vertex vert 
    17. #pragma fragment frag 
    18. #include "UnityCG.cginc" 
    19.  
    20. struct appdata { 
    21. float4 vertex: POSITION; 
    22. float2 uv: TEXCOORD0; 
    23. }; 
    24.  
    25. struct v2f { 
    26. float2 uv: TEXCOORD0; 
    27. float4 vertex: SV_POSITION; 
    28. }; 
    29.  
    30. sampler2D _MainTex; 
    31. float4 _MainTex_ST; 
    32. v2f vert(appdata v) { 
    33. v2f o; 
    34. o.vertex = UnityObjectToClipPos(v.vertex); 
    35. o.uv = TRANSFORM_TEX(v.uv, _MainTex); 
    36. return o; 
    37. fixed4 frag(v2f i) : SV_Target { 
    38. // sample the texture 
    39. fixed4 col = tex2D(_MainTex, i.uv); 
    40. return col; 
    41. ENDCG 
    42.  
    43. Pass { 
    44. CGPROGRAM 
    45. #pragma vertex vert 
    46. #pragma fragment frag 
    47.  
    48. struct appdata { 
    49. float4 vertex: POSITION; 
    50. float4 normal: NORMAL; 
    51. }; 
    52.  
    53. struct v2f { 
    54. float4 vertex: SV_POSITION; 
    55. }; 
    56.  
    57. fixed4 _OutLineColor; 
    58. float _OutLineWidth; 
    59. v2f vert(appdata v) { 
    60. v2f o; 
    61. v.vertex = v.vertex + normalize(v.normal) * _OutLineWidth; 
    62. o.vertex = UnityObjectToClipPos(v.vertex); 
    63. return o; 
    64. fixed4 frag(v2f i) : SV_Target { 
    65. // sample the texture 
    66. fixed4 col = _OutLineColor; 
    67. return col; 
    68. ENDCG 

    3.2 百宝箱

     


    渲染管线

     

    遮罩层:

    1. Shader "ShaderCookbook/StencilEnumMask" 
    2. Properties 
    3. _MainTex ("Texture", 2D) = "white" {} 
    4. [ForceInt] 
    5. _StencilRef("StencilRef",float) = 0 
    6. [Enum(UnityEngine.Rendering.CompareFunction)] 
    7. _StencilComp("StencilComp",int) =0 
    8. [Enum(UnityEngine.Rendering.StencilOp)] 
    9. _StencilOp("StencilOp",int)=0 
    10.  
    11. [ForceInt] 
    12. _StencilReadMask("ReadMask",int)=255 
    13. [ForceInt] 
    14. _StencilWriteMask("WriteMask",int)=255 
    15. [MaterialToggle] 
    16. _ZWrite("zWrite",float)=0 
    17. SubShader 
    18. Tags { "RenderType"="StencilMaskOpaque" 
    19. "Queue" = "Geometry-100
    20. "IgnoreProjector" = "True" } 
    21. LOD 100 
    22.  
    23.  
    24. Pass 
    25. ColorMask 0 
    26. ZWrite [_ZWrite] 
    27.  
    28. Stencil{ 
    29. Ref [_StencilRef] 
    30. Comp[_StencilComp] 
    31. Pass[_StencilOp] 
    32. ReadMask[_StencilReadMask] 
    33. WriteMask[_StencilWriteMask] 
    34.  
    35. CGPROGRAM 
    36. #pragma vertex vert 
    37. #pragma fragment frag 
    38. // make fog work 
    39. #pragma multi_compile_fog 
    40. #include "UnityCG.cginc" 
    41.  
    42.  
    43. struct appdata 
    44. float4 vertex : POSITION; 
    45. float2 uv : TEXCOORD0; 
    46. }; 
    47.  
    48. struct v2f 
    49. float2 uv : TEXCOORD0; 
    50. UNITY_FOG_COORDS(1
    51. float4 vertex : SV_POSITION; 
    52. }; 
    53.  
    54. sampler2D _MainTex; 
    55. float4 _MainTex_ST; 
    56. v2f vert (appdata v) 
    57. v2f o; 
    58. o.vertex = UnityObjectToClipPos(v.vertex); 
    59. o.uv = TRANSFORM_TEX(v.uv, _MainTex); 
    60. UNITY_TRANSFER_FOG(o,o.vertex); 
    61. return o; 
    62. fixed4 frag (v2f i) : SV_Target 
    63. // sample the texture 
    64. fixed4 col = tex2D(_MainTex, i.uv); 
    65. // apply fog 
    66. UNITY_APPLY_FOG(i.fogCoord, col); 
    67. return col; 
    68. ENDCG 

    显示层:

    1.  
    2.  
    3. Shader "ShaderCookbook/StencilEnum" 
    4. Properties 
    5. _MainTex ("Texture", 2D) = "white" {} 
    6. [ForceInt] 
    7. _StencilRef("StencilRef",float) = 0 
    8. [Enum(UnityEngine.Rendering.CompareFunction)] 
    9. _StencilComp("StencilComp",int) =0 
    10. [Enum(UnityEngine.Rendering.StencilOp)] 
    11. _StencilOp("StencilOp",int)=0 
    12.  
    13. [ForceInt] 
    14. _StencilReadMask("ReadMask",int)=255 
    15. [ForceInt] 
    16. _StencilWriteMask("WriteMask",int)=255 
    17. SubShader 
    18. Tags { "RenderType"="opaque" } 
    19. LOD 100 
    20.  
    21.  
    22. Pass 
    23.  
    24. Stencil{ 
    25. Ref [_StencilRef] 
    26. Comp[_StencilComp] 
    27. Pass[_StencilOp] 
    28. ReadMask[_StencilReadMask] 
    29. WriteMask[_StencilWriteMask] 
    30.  
    31. CGPROGRAM 
    32. #pragma vertex vert 
    33. #pragma fragment frag 
    34. // make fog work 
    35. #pragma multi_compile_fog 
    36. #include "UnityCG.cginc" 
    37.  
    38.  
    39. struct appdata 
    40. float4 vertex : POSITION; 
    41. float2 uv : TEXCOORD0; 
    42. }; 
    43.  
    44. struct v2f 
    45. float2 uv : TEXCOORD0; 
    46. UNITY_FOG_COORDS(1
    47. float4 vertex : SV_POSITION; 
    48. }; 
    49.  
    50. sampler2D _MainTex; 
    51. float4 _MainTex_ST; 
    52. v2f vert (appdata v) 
    53. v2f o; 
    54. o.vertex = UnityObjectToClipPos(v.vertex); 
    55. o.uv = TRANSFORM_TEX(v.uv, _MainTex); 
    56. UNITY_TRANSFER_FOG(o,o.vertex); 
    57. return o; 
    58. fixed4 frag (v2f i) : SV_Target 
    59. // sample the texture 
    60. fixed4 col = tex2D(_MainTex, i.uv); 
    61. // apply fog 
    62. UNITY_APPLY_FOG(i.fogCoord, col); 
    63. return col; 
    64. ENDCG 

    Ad

    这里推荐一款可视化shader编程工具,对美术同学非常友好,就像建模工具中的材质编辑器一样

  • 相关阅读:
    ZYB建围墙
    换根DP
    原码,反码,补码的计算
    字符串游戏-博弈论-trie
    【十连赛day8】神炎皇
    生成序列
    【USACO 2006 February Silver】产奶安排Stall Reservations-贪心
    tar 压缩解压命令
    java 注解
    回溯算法解决全排列问题
  • 原文地址:https://www.cnblogs.com/Firepad-magic/p/10816430.html
Copyright © 2011-2022 走看看