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. } 

  7. SubShader { 

  8. Tags { 

  9. "RenderType" = "Opaque" 

  10. } 

  11. LOD 100 


  12. Stencil { 

  13. Ref 0 Comp Equal Pass IncrSat 

  14. } 


  15. Pass { 

  16. CGPROGRAM 

  17. #pragma vertex vert 

  18. #pragma fragment frag 

  19. #include "UnityCG.cginc" 


  20. struct appdata { 

  21. float4 vertex: POSITION; 

  22. float2 uv: TEXCOORD0; 

  23. }; 


  24. struct v2f { 

  25. float2 uv: TEXCOORD0; 

  26. float4 vertex: SV_POSITION; 

  27. }; 


  28. sampler2D _MainTex; 

  29. float4 _MainTex_ST; 

  30. v2f vert(appdata v) { 

  31. v2f o; 

  32. o.vertex = UnityObjectToClipPos(v.vertex); 

  33. o.uv = TRANSFORM_TEX(v.uv, _MainTex); 

  34. return o; 

  35. } 

  36. fixed4 frag(v2f i) : SV_Target { 

  37. // sample the texture 

  38. fixed4 col = tex2D(_MainTex, i.uv); 

  39. return col; 

  40. } 

  41. ENDCG 

  42. } 


  43. Pass { 

  44. CGPROGRAM 

  45. #pragma vertex vert 

  46. #pragma fragment frag 


  47. struct appdata { 

  48. float4 vertex: POSITION; 

  49. float4 normal: NORMAL; 

  50. }; 


  51. struct v2f { 

  52. float4 vertex: SV_POSITION; 

  53. }; 


  54. fixed4 _OutLineColor; 

  55. float _OutLineWidth; 

  56. v2f vert(appdata v) { 

  57. v2f o; 

  58. v.vertex = v.vertex + normalize(v.normal) * _OutLineWidth; 

  59. o.vertex = UnityObjectToClipPos(v.vertex); 

  60. return o; 

  61. } 

  62. fixed4 frag(v2f i) : SV_Target { 

  63. // sample the texture 

  64. fixed4 col = _OutLineColor; 

  65. return col; 

  66. } 

  67. ENDCG 

  68. } 

  69. } 

  70. } 

3.2 百宝箱

渲染管线

遮罩层:

  1. Shader "ShaderCookbook/StencilEnumMask" 

  2. { 

  3. Properties 

  4. { 

  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. [ForceInt] 

  13. _StencilReadMask("ReadMask",int)=255 

  14. [ForceInt] 

  15. _StencilWriteMask("WriteMask",int)=255 

  16. [MaterialToggle] 

  17. _ZWrite("zWrite",float)=0 

  18. } 

  19. SubShader 

  20. { 

  21. Tags { "RenderType"="StencilMaskOpaque" 

  22. "Queue" = "Geometry-100" 

  23. "IgnoreProjector" = "True" } 

  24. LOD 100 



  25. Pass 

  26. { 

  27. ColorMask 0 

  28. ZWrite [_ZWrite] 


  29. Stencil{ 

  30. Ref [_StencilRef] 

  31. Comp[_StencilComp] 

  32. Pass[_StencilOp] 

  33. ReadMask[_StencilReadMask] 

  34. WriteMask[_StencilWriteMask] 

  35. } 


  36. CGPROGRAM 

  37. #pragma vertex vert 

  38. #pragma fragment frag 

  39. // make fog work 

  40. #pragma multi_compile_fog 

  41. #include "UnityCG.cginc" 



  42. struct appdata 

  43. { 

  44. float4 vertex : POSITION; 

  45. float2 uv : TEXCOORD0; 

  46. }; 


  47. struct v2f 

  48. { 

  49. float2 uv : TEXCOORD0; 

  50. UNITY_FOG_COORDS(1) 

  51. float4 vertex : SV_POSITION; 

  52. }; 


  53. sampler2D _MainTex; 

  54. float4 _MainTex_ST; 

  55. v2f vert (appdata v) 

  56. { 

  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. } 

  63. fixed4 frag (v2f i) : SV_Target 

  64. { 

  65. // sample the texture 

  66. fixed4 col = tex2D(_MainTex, i.uv); 

  67. // apply fog 

  68. UNITY_APPLY_FOG(i.fogCoord, col); 

  69. return col; 

  70. } 

  71. ENDCG 

  72. } 

  73. } 

  74. } 

显示层:



  1. Shader "ShaderCookbook/StencilEnum" 

  2. { 

  3. Properties 

  4. { 

  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. [ForceInt] 

  13. _StencilReadMask("ReadMask",int)=255 

  14. [ForceInt] 

  15. _StencilWriteMask("WriteMask",int)=255 

  16. } 

  17. SubShader 

  18. { 

  19. Tags { "RenderType"="opaque" } 

  20. LOD 100 



  21. Pass 

  22. { 


  23. Stencil{ 

  24. Ref [_StencilRef] 

  25. Comp[_StencilComp] 

  26. Pass[_StencilOp] 

  27. ReadMask[_StencilReadMask] 

  28. WriteMask[_StencilWriteMask] 

  29. } 


  30. CGPROGRAM 

  31. #pragma vertex vert 

  32. #pragma fragment frag 

  33. // make fog work 

  34. #pragma multi_compile_fog 

  35. #include "UnityCG.cginc" 



  36. struct appdata 

  37. { 

  38. float4 vertex : POSITION; 

  39. float2 uv : TEXCOORD0; 

  40. }; 


  41. struct v2f 

  42. { 

  43. float2 uv : TEXCOORD0; 

  44. UNITY_FOG_COORDS(1) 

  45. float4 vertex : SV_POSITION; 

  46. }; 


  47. sampler2D _MainTex; 

  48. float4 _MainTex_ST; 

  49. v2f vert (appdata v) 

  50. { 

  51. v2f o; 

  52. o.vertex = UnityObjectToClipPos(v.vertex); 

  53. o.uv = TRANSFORM_TEX(v.uv, _MainTex); 

  54. UNITY_TRANSFER_FOG(o,o.vertex); 

  55. return o; 

  56. } 

  57. fixed4 frag (v2f i) : SV_Target 

  58. { 

  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. } 

  65. ENDCG 

  66. } 

  67. } 

  68. } 

Ad

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

Unity Shader之模板测试的更多相关文章

  1. Shader 模板缓冲和模板测试

    http://blog.sina.com.cn/s/blog_6e159df70102xa67.html 模板缓冲的概念 Unity官方的Shader文档根本没有提到这个玩意,这个概念也是看到了UGU ...

  2. Unity Shader 知识点总结(一)

    在学习了一段时间的Unity Shader后,打算写一些知识总结,便于今后的查找.如有错误,希望大家指出更改. 本文参照的unity入门精要一书,做一个知识归纳,如有兴趣可以看看其开源的部分,是一本比 ...

  3. Unity Shader入门精要读书笔记(一)序章

    本系列的博文是笔者读<Unity Shader入门精要>的读书笔记,这本书的章节框架是: 第一章:着手准备. 第二章:GPU流水线. 第三章:Shader基本语法. 第四章:Shader数 ...

  4. Unity Shader实现描边效果

    http://gad.qq.com/article/detail/28346 描边效果是游戏里面非常常用的一种效果,一般是为了凸显游戏中的某个对象,会给对象增加一个描边效果.本篇文章和大家介绍下利用S ...

  5. 【转】《Unity Shader入门精要》冯乐乐著 书中彩图

    为方便个人手机学习时候查阅,从网上转来这些彩图. 如属过当行为,联系本人删除. 勘错表 http://candycat1992.github.io/unity_shaders_book/unity_s ...

  6. Unity Shader入门精要学习笔记 - 第9章 更复杂的光照

    转载自 冯乐乐的<Unity Shader入门精要> Unity 的渲染路径 在Unity里,渲染路径决定了光照是如何应该到Unity Shader 中的.因此,如果要和光源打交道,我们需 ...

  7. Unity Shader入门精要学习笔记 - 第2章 渲染流水线

    来源作者:candycat   http://blog.csdn.net/candycat1992/article/ 2.1 综述 渲染流水线的最终目的在于生成或者说是渲染一张二维纹理,即我们在电脑屏 ...

  8. unity shader之预备知识

    1.渲染流水线 任务:从一个三维场景出发,生成(或者渲染)一张二维图像.即:计算机需要从一系列的定点出数据,纹理等信息出发,把这些信息最终转换程一张人眼可以看到的图像.而这个工作通常是由CPU和GPU ...

  9. Unity Shader学习笔记-1

    本篇文章是对Unity Shader入门精要的学习笔记,插图大部分来自冯乐乐女神的github 如果有什么说的不正确的请批评指正 目录 渲染流水线 流程图 Shader作用 屏幕映射 三角形遍历 两大 ...

随机推荐

  1. Codeforces Round #285 (Div. 2)C. Misha and Forest(拓扑排序)

    传送门 Description Let's define a forest as a non-directed acyclic graph (also without loops and parall ...

  2. workflow-core 简介

    最近想做一个OA相关的网站开发,一直都听说有workflow的东西,之前也断断续续学习过 Workflow Foundation 4.0,还是没有搞明白到底能够用它做什么 但还是觉得workflow在 ...

  3. 跨平台自动构建工具v1.0.2 发布

    XMake是一个跨平台自动构建工具,支持在各种主流平台上构建项目,类似cmake.automake.premake,但是更加的方便易用,工程描述语法更简洁直观,支持平台更多,并且集创建.配置.编译.打 ...

  4. Linux的mysql部署

    1.  先输入代码yum install wget -y才可以做后面的 2.下载并安装MySQL官方的 Yum Repository   代码: wget -i -c http://dev.mysql ...

  5. [BZOJ3622] 已经没有什么好害怕的了(dp+容斥)

    Description: ​ 有两个数组a和b,两两配对,求 \(a_i>b_i\) 的配对比 \(b_i>a_i\) 的配对多 \(k\) 个的方案数 \(k\le n\le 2000\ ...

  6. Vue的入门之安装

    vue.js是前端框架中比较热门的,因为工作关系,也加入了浩浩荡荡的学习大潮中,用笔记记录下点滴,便于后面学习查阅! 1 node.js环境的安装包(npm包管理器) 2 vue-cli 脚手架构建工 ...

  7. 踩坑,vue项目中,main.js引入scss文件时报错

    当我们在src目录下创建.scss文件,并在main.js中引用,运行时会报: ERROR Failed to compile with 1 errors 5:25:07 PMThis relativ ...

  8. eclipse安装weblogic Server服务器

    1.首先打开eclipse,第一次进入欢迎画面点击上方标签X,关闭欢迎标签 2.关闭欢迎标签后,进入eclipse操作界面,在上方的菜单栏,选择windows下拉菜单,选择子菜单Preference ...

  9. GeneXus笔记本—常用函数(下)

    这篇是常用函数的最后一节 当然 我这里聊的还不是全部的,需要各位朋友继续在工作中去深入才行啊 ,毕竟从入门到入土....┌(; ̄◇ ̄)┘ 1:Sleep 这个函数你们应该能猜到 ”To allow m ...

  10. 【记录】mysql查询语句对于为null和为空字符串给出特定值处理

    SELECT if(IFNULL(filedName,"指定字符串")="","指定字符串",filedName) '重命名的字符名' FR ...