Unity Shader之模板测试

摘要:
UnityShader的模板测试一个沙子,一个世界,一朵花,一个天堂。一个模具测试渲染管道当段着色器处理一个段时,模板测试将开始执行。与深度测试一样,它也可以丢弃该段。在模板缓冲区中,(通常)每个模板值为8位。Ref参考值与当前像素缓存上的值进行比较。
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 百宝箱

 

Unity Shader之模板测试第3张
渲染管线

 

遮罩层:

  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编程工具,对美术同学非常友好,就像建模工具中的材质编辑器一样

免责声明:文章转载自《Unity Shader之模板测试》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇ROS学习之启动文件WPF绑定属性下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

依赖注入之unity(winform方式)

依赖注入之unity(winform方式) 要讲unity就必须先了解DI和IOC及DIP,如下链接提供DI和IOC的基础:https://www.cnblogs.com/zlp520/p/12015973.html 一.什么是unity? unity是实现依赖注入的IOC容器,通过unity可以降低代码的耦合度。 二.下载并添加引用: Microsoft...

Unity3D中抖屏(抖动相机)效果的简单实现

这里是一个简单的摄像机抖动方法,记录下来便于查阅。 public class CameraShake : MonoBehaviour { // 抖动目标的transform(若未添加引用,怎默认为当前物体的transform) public Transform camTransform; //持续抖动的时长 public...

Unity打开VisualStudio一直显示hold on的解决办法(自醒)

我的VS版本:Visual Studio Community2022     我的Unity版本:unity2020.3.24     我的Visual版本:vs2022 我一开始在unity hub下载自带的2019版本,可气的是他直接装我C盘上了,我就给卸载了。又去官网上下载了最新版本,在unity里面配置好了启动器 问题:我Visual单独点击可以...

AssetPostprocessor.OnPreprocessModel

今天对工程中的模型做一些统一设置, 然后发现一个问题, 就是修改了设置点Apply之后, 又会被改回默认设置. 最后搜了一下, 处理方案是使用assetImport的userData进行判断. 参考文章: <Manage Default Asset Import Settings in Unity> http://www.cliffordroc...

Unity进阶之ET网络游戏开发框架 02-ET的客户端启动流程分析

版权申明: 本文原创首发于以下网站: 博客园『优梦创客』的空间:https://www.cnblogs.com/raymondking123 优梦创客的官方博客:https://91make.top 优梦创客的游戏讲堂:https://91make.ke.qq.com 『优梦创客』的微信公众号:umaketop 您可以自由转载,但必须加入完整的版权声明...

Unity中AndroidManifest增加权限,打开应用时不弹出权限申请

一 屏蔽第一次打开apk时权限弹窗: 在Activity下添加<meta-data android:name="unityplayer.SkipPermissionsDialog" android:value="true" />。 二 在需要权限的位置再请求权限: unity端: usingUnityEngine; #if UNITY_AN...