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. Stencil { 

  11. Ref 0 Comp Equal Pass IncrSat 




  12. Pass { 

  13. CGPROGRAM 

  14. #pragma vertex vert 

  15. #pragma fragment frag 

  16. #include "UnityCG.cginc" 


  17. struct appdata { 

  18. float4 vertex: POSITION; 

  19. float2 uv: TEXCOORD0; 

  20. }; 


  21. struct v2f { 

  22. float2 uv: TEXCOORD0; 

  23. float4 vertex: SV_POSITION; 

  24. }; 


  25. sampler2D _MainTex; 

  26. float4 _MainTex_ST; 

  27. v2f vert(appdata v) { 

  28. v2f o; 

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

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

  31. return o; 



  32. fixed4 frag(v2f i) : SV_Target { 

  33. // sample the texture 

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

  35. return col; 



  36. ENDCG 




  37. Pass { 

  38. CGPROGRAM 

  39. #pragma vertex vert 

  40. #pragma fragment frag 


  41. struct appdata { 

  42. float4 vertex: POSITION; 

  43. float4 normal: NORMAL; 

  44. }; 


  45. struct v2f { 

  46. float4 vertex: SV_POSITION; 

  47. }; 


  48. fixed4 _OutLineColor; 

  49. float _OutLineWidth; 

  50. v2f vert(appdata v) { 

  51. v2f o; 

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

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

  54. return o; 



  55. fixed4 frag(v2f i) : SV_Target { 

  56. // sample the texture 

  57. fixed4 col = _OutLineColor; 

  58. return col; 



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

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

  12. [ForceInt] 

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

  14. [MaterialToggle] 

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



  16. SubShader 



  17. Tags { "RenderType"="StencilMaskOpaque" 

  18. "Queue" = "Geometry-100" 

  19. "IgnoreProjector" = "True" } 

  20. LOD 100 



  21. Pass 



  22. ColorMask 0 

  23. ZWrite [_ZWrite] 


  24. Stencil{ 

  25. Ref [_StencilRef] 

  26. Comp[_StencilComp] 

  27. Pass[_StencilOp] 

  28. ReadMask[_StencilReadMask] 

  29. WriteMask[_StencilWriteMask] 




  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. float4 vertex : POSITION; 

  38. float2 uv : TEXCOORD0; 

  39. }; 


  40. struct v2f 



  41. float2 uv : TEXCOORD0; 

  42. UNITY_FOG_COORDS(1) 

  43. float4 vertex : SV_POSITION; 

  44. }; 


  45. sampler2D _MainTex; 

  46. float4 _MainTex_ST; 

  47. v2f vert (appdata v) 



  48. v2f o; 

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

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

  51. UNITY_TRANSFER_FOG(o,o.vertex); 

  52. return o; 



  53. fixed4 frag (v2f i) : SV_Target 



  54. // sample the texture 

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

  56. // apply fog 

  57. UNITY_APPLY_FOG(i.fogCoord, col); 

  58. return col; 



  59. ENDCG 







显示层:



  1. Shader "ShaderCookbook/StencilEnum" 



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

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

  12. [ForceInt] 

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



  14. SubShader 



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

  16. LOD 100 



  17. Pass 




  18. Stencil{ 

  19. Ref [_StencilRef] 

  20. Comp[_StencilComp] 

  21. Pass[_StencilOp] 

  22. ReadMask[_StencilReadMask] 

  23. WriteMask[_StencilWriteMask] 




  24. CGPROGRAM 

  25. #pragma vertex vert 

  26. #pragma fragment frag 

  27. // make fog work 

  28. #pragma multi_compile_fog 

  29. #include "UnityCG.cginc" 



  30. struct appdata 



  31. float4 vertex : POSITION; 

  32. float2 uv : TEXCOORD0; 

  33. }; 


  34. struct v2f 



  35. float2 uv : TEXCOORD0; 

  36. UNITY_FOG_COORDS(1) 

  37. float4 vertex : SV_POSITION; 

  38. }; 


  39. sampler2D _MainTex; 

  40. float4 _MainTex_ST; 

  41. v2f vert (appdata v) 



  42. v2f o; 

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

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

  45. UNITY_TRANSFER_FOG(o,o.vertex); 

  46. return o; 



  47. fixed4 frag (v2f i) : SV_Target 



  48. // sample the texture 

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

  50. // apply fog 

  51. UNITY_APPLY_FOG(i.fogCoord, col); 

  52. return col; 



  53. ENDCG 







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. 【MM系列】SAP ABAP 在选择画面显示输出结果

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[ABAP系列]SAP ABAP 在选择画面显示 ...

  2. 【Unity渲染】Camera RenderToCubemap 渲染到立方体纹理

    Unity圣典 传送门:http://www.ceeger.com/Script/Camera/Camera.RenderToCubemap.html Camera.RenderToCubemap 有 ...

  3. 应用安全 - Windows操作系统 - 漏洞 - 汇总

    FTP弱密码 将FTP服务器的密码更改为强密码 vi /etc/vsftpd/vsftpd.conf anonymous_enable=NO #禁止匿名登录 重启ftp服务 Windows匿名用户整改 ...

  4. 20190825 On Java8 第十三章 函数式编程

    第十三章 函数式编程 函数式编程语言操纵代码片段就像操作数据一样容易. 虽然 Java 不是函数式语言,但 Java 8 Lambda 表达式和方法引用 (Method References) 允许你 ...

  5. springboot启动脚本

    #!/bin/sh JAVA_HOME="/ulic1/jdk/jdk1.8.0_201/bin" export JAVA_HOME lsof -i:9010 |awk '{pri ...

  6. 2019 Multi-University Training Contest 1 - 1009 - String - 贪心

    不知道错在哪里. 是要把atop改成stop!两个弄混了.感谢自造样例. #include<bits/stdc++.h> using namespace std; typedef long ...

  7. springcloud费话之Eureka接口调用(feign)

    目录: springcloud费话之Eureka基础 springcloud费话之Eureka集群 springcloud费话之Eureka服务访问(restTemplate) springcloud ...

  8. Redis这篇就够了

    Redis 简介 Redis 优势 Redis 数据类型 string hash list set Zset 小总结 基本命令 发布订阅 简介 实例 发布订阅常用命令 事务 实例 Redis 事务命令 ...

  9. windows10安装docker[含百度网盘docker安装包]

    在win10上安装 docker(比较简单) 安装步骤: 现在 Docker 有专门的 Win10 专业版系统的安装包,需要开启Hyper-V. 1.开启 Hyper-V 程序和功能 启用或关闭Win ...

  10. ES6 的基础教程

    一.介绍 1.历史 ECMAScript和JavaScript ECMA是标准,JS是实现 类似于HTML5是标准,IE10.Chrome.FF都是实现 换句话说,将来也能有其他XXXScript来实 ...