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. 【linux】 mail/mutt 发送邮件

    mail: 比较常用,缺点是发送附件要同时安装其他软件: mutt:功能强大,注意发送html需要升级到1.5+版本:   用mail发送邮件: echo "邮件正文" | mai ...

  2. 21.线程,全局解释器锁(GIL)

    import time from threading import Thread from multiprocessing import Process #计数的方式消耗系统资源 def two_hu ...

  3. #C语言l作业04

    这个作业属于哪个课程** C语言程序设计ll 这个作业的要求 (https://edu.cnblogs.com/campus/zswxy/SE2019-4/homework/9776) 我在这个课程的 ...

  4. MyBatis-Spring的sqlSessionTemplate

    转自:http://www.cnblogs.com/yhtboke/p/5611375.html SqlSessionTemplate SqlSessionTemplate是MyBatis-Sprin ...

  5. Python入门之基础day1

    一.引子 1. 什么是编程语言? 编程语言就是人与计算机沟通的介质 2.什么是编程? 编程就是人把自己想命令计算机干的事情通过编程语言翻译出来并写到文件里去 为什么要编程? 编程的目的就是为了让计算机 ...

  6. BZOJ 1683.City skyline 城市地平线

    传送门 从左到右扫一遍,考虑什么时候会和之前形成同一幢房子从而不用统计 显然是当前的高度和之前某个点高度相同,并且它们之间没有更矮的建筑 考虑用一个单调栈维护一个单调上升的房子轮廓,然后对于扫到的每一 ...

  7. CAS无锁策略

    并发编程时,对于共享资源的使用需要确保绝对的安全性.除了利用锁机制之外,还有一种无锁的概念.所谓无锁,就是假定在并发情况下,对于共享资源的访问没有冲突,线程可以一直不停的运行,无需阻塞,如果产生冲突, ...

  8. 云中沙箱学习笔记1-快速部署并使用MySQL数据库

    1.1 背景知识 业务背景 MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于Oracle旗下产品.MySQL 是最流行的关系型数据库管理系统,在 WEB 应用方面MyS ...

  9. systemd:在service文件中给Exec传入多个参数

    原问题是这样的: 答案是这样的: 此外在使用prometheus监控mongodb时需要安装prometheus-mongodb-exporter,过程中也发现这种用法: 看看service单元文件是 ...

  10. bzoj1495 [NOI2006]网络收费 复杂度分析+树上背包

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=1495 题解 通过观察可以发现,对于一个 \(lca\),如果 \(nA \leq nB\),那 ...