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. Go-内存To Be

    做一个快乐的互联网搬运工- 逃逸分析 逃逸分析的概念 在编译程序优化理论中,逃逸分析是一种确定指针动态范围的方法——分析在程序的哪些地方可以访问到指针. 它涉及到指针分析和形状分析. 当一个变量(或对 ...

  2. Using Tensorflow SavedModel Format to Save and Do Predictions

    We are now trying to deploy our Deep Learning model onto Google Cloud. It is required to use Google ...

  3. 【linux】 mail/mutt 发送邮件

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

  4. 编程语言 - 脚本编程 - JavaScript/Jquery/Ajax/XML/JSON/ActionScript3

    事件处理onmouseover <!DOCTYPE html> <html> <head> <meta charset="utf-8"&g ...

  5. 使EasyUI的window、panel、dialog 不被拖出页面

    function easyuiPanelOnMove(left, top) {  var l = left;  var t = top;  if (l < 1) {    l = 1;  }  ...

  6. 爬虫(六)——存储库(一)MongoDB存储库

    目录 存储库--MongoDB 一.安装MongoDB 4.0 1.安装 2.修改数据库文件和日志保存位置设置(可不改) 3.账户管理.远程服务 三.MongoDB数据库操作 1.对库操作 2.对集合 ...

  7. docker实现分布式项目部署

    docker的安装及基本命令这里就略过了,可以看我的这篇笔记https://www.cnblogs.com/pyweb/p/11351878.html. 这次需要在docker上部署两个项目,整体的流 ...

  8. vue构造器注册UI组件

    import ConfirmComponent from '../../components/confirm/index' import { mergeOptions } from '../plugi ...

  9. mybatis输出映射总结

    使用resultType作为输出映射 只有查询出来的列名和pojo中的属性名一致时,才会映射成功, 如果不一致,可以使用resultMap最为输出类型 不管是输出单个对象还是列表(list中包括poj ...

  10. 61-python基础-python3-格式化浮点数方法-%e、%f、%g

    1-%e是用科学记数法计数: %f是按指定精确格式化浮点数(默认保留6位): %g是根据数值的大小采用e或%f. 2-%f可以按长度和精度格式化浮点数,如%a.bf,a表示浮点数的长度,b表示浮点数小 ...