Unity Shader之模板测试
Unity Shader之模板测试
一沙一世界,一花一天堂
一、Stencil testing
当片段着色器处理完一个片段之后,模板测试(Stencil Test)会开始执行,和深度测试一样,它也可能会丢弃片段。接下来,被保留的片段会进入深度测试,它可能会丢弃更多的片段。模板测试是根据又一个缓冲来进行的,它叫做模板缓冲(Stencil Buffer),我们可以在渲染的时候更新它来获得一些很有意思的效果。
一个模板缓冲中,(通常)每个模板值(Stencil Value)是8位的。所以每个像素/片段一共能有256种不同的模板值。我们可以将这些模板值设置为我们想要的值,然后当某一个片段有某一个模板值的时候,我们就可以选择丢弃或是保留这个片段了。
二、模板函数
2.1 调用函数
- Stencil
- {
- Ref 1//Reference Value ReadMask 255 WriteMask 255 Comp Always //Comparison Function Pass Replace
- Fail Keep
- ZFail Replace
- }
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 描边
- Shader "ShaderCookbook/stencil_outline" {
- Properties {
- _MainTex("Texture", 2D) = "white" {}
- _OutLineWidth("Width", float) = 0.01
- _OutLineColor("Color", color) = (1, 1, 1, 1)
- }
- SubShader {
- Tags {
- "RenderType" = "Opaque"
- }
- LOD 100
- Stencil {
- Ref 0 Comp Equal Pass IncrSat
- }
- Pass {
- CGPROGRAM
- #pragma vertex vert
- #pragma fragment frag
- #include "UnityCG.cginc"
- struct appdata {
- float4 vertex: POSITION;
- float2 uv: TEXCOORD0;
- };
- struct v2f {
- float2 uv: TEXCOORD0;
- float4 vertex: SV_POSITION;
- };
- sampler2D _MainTex;
- float4 _MainTex_ST;
- v2f vert(appdata v) {
- v2f o;
- o.vertex = UnityObjectToClipPos(v.vertex);
- o.uv = TRANSFORM_TEX(v.uv, _MainTex);
- return o;
- }
- fixed4 frag(v2f i) : SV_Target {
- // sample the texture
- fixed4 col = tex2D(_MainTex, i.uv);
- return col;
- }
- ENDCG
- }
- Pass {
- CGPROGRAM
- #pragma vertex vert
- #pragma fragment frag
- struct appdata {
- float4 vertex: POSITION;
- float4 normal: NORMAL;
- };
- struct v2f {
- float4 vertex: SV_POSITION;
- };
- fixed4 _OutLineColor;
- float _OutLineWidth;
- v2f vert(appdata v) {
- v2f o;
- v.vertex = v.vertex + normalize(v.normal) * _OutLineWidth;
- o.vertex = UnityObjectToClipPos(v.vertex);
- return o;
- }
- fixed4 frag(v2f i) : SV_Target {
- // sample the texture
- fixed4 col = _OutLineColor;
- return col;
- }
- ENDCG
- }
- }
- }
3.2 百宝箱
遮罩层:
- Shader "ShaderCookbook/StencilEnumMask"
- {
- Properties
- {
- _MainTex ("Texture", 2D) = "white" {}
- [ForceInt]
- _StencilRef("StencilRef",float) = 0
- [Enum(UnityEngine.Rendering.CompareFunction)]
- _StencilComp("StencilComp",int) =0
- [Enum(UnityEngine.Rendering.StencilOp)]
- _StencilOp("StencilOp",int)=0
- [ForceInt]
- _StencilReadMask("ReadMask",int)=255
- [ForceInt]
- _StencilWriteMask("WriteMask",int)=255
- [MaterialToggle]
- _ZWrite("zWrite",float)=0
- }
- SubShader
- {
- Tags { "RenderType"="StencilMaskOpaque"
- "Queue" = "Geometry-100"
- "IgnoreProjector" = "True" }
- LOD 100
- Pass
- {
- ColorMask 0
- ZWrite [_ZWrite]
- Stencil{
- Ref [_StencilRef]
- Comp[_StencilComp]
- Pass[_StencilOp]
- ReadMask[_StencilReadMask]
- WriteMask[_StencilWriteMask]
- }
- CGPROGRAM
- #pragma vertex vert
- #pragma fragment frag
- // make fog work
- #pragma multi_compile_fog
- #include "UnityCG.cginc"
- struct appdata
- {
- float4 vertex : POSITION;
- float2 uv : TEXCOORD0;
- };
- struct v2f
- {
- float2 uv : TEXCOORD0;
- UNITY_FOG_COORDS(1)
- float4 vertex : SV_POSITION;
- };
- sampler2D _MainTex;
- float4 _MainTex_ST;
- v2f vert (appdata v)
- {
- v2f o;
- o.vertex = UnityObjectToClipPos(v.vertex);
- o.uv = TRANSFORM_TEX(v.uv, _MainTex);
- UNITY_TRANSFER_FOG(o,o.vertex);
- return o;
- }
- fixed4 frag (v2f i) : SV_Target
- {
- // sample the texture
- fixed4 col = tex2D(_MainTex, i.uv);
- // apply fog
- UNITY_APPLY_FOG(i.fogCoord, col);
- return col;
- }
- ENDCG
- }
- }
- }
显示层:
- Shader "ShaderCookbook/StencilEnum"
- {
- Properties
- {
- _MainTex ("Texture", 2D) = "white" {}
- [ForceInt]
- _StencilRef("StencilRef",float) = 0
- [Enum(UnityEngine.Rendering.CompareFunction)]
- _StencilComp("StencilComp",int) =0
- [Enum(UnityEngine.Rendering.StencilOp)]
- _StencilOp("StencilOp",int)=0
- [ForceInt]
- _StencilReadMask("ReadMask",int)=255
- [ForceInt]
- _StencilWriteMask("WriteMask",int)=255
- }
- SubShader
- {
- Tags { "RenderType"="opaque" }
- LOD 100
- Pass
- {
- Stencil{
- Ref [_StencilRef]
- Comp[_StencilComp]
- Pass[_StencilOp]
- ReadMask[_StencilReadMask]
- WriteMask[_StencilWriteMask]
- }
- CGPROGRAM
- #pragma vertex vert
- #pragma fragment frag
- // make fog work
- #pragma multi_compile_fog
- #include "UnityCG.cginc"
- struct appdata
- {
- float4 vertex : POSITION;
- float2 uv : TEXCOORD0;
- };
- struct v2f
- {
- float2 uv : TEXCOORD0;
- UNITY_FOG_COORDS(1)
- float4 vertex : SV_POSITION;
- };
- sampler2D _MainTex;
- float4 _MainTex_ST;
- v2f vert (appdata v)
- {
- v2f o;
- o.vertex = UnityObjectToClipPos(v.vertex);
- o.uv = TRANSFORM_TEX(v.uv, _MainTex);
- UNITY_TRANSFER_FOG(o,o.vertex);
- return o;
- }
- fixed4 frag (v2f i) : SV_Target
- {
- // sample the texture
- fixed4 col = tex2D(_MainTex, i.uv);
- // apply fog
- UNITY_APPLY_FOG(i.fogCoord, col);
- return col;
- }
- ENDCG
- }
- }
- }
Ad
这里推荐一款可视化shader编程工具,对美术同学非常友好,就像建模工具中的材质编辑器一样
Unity Shader之模板测试的更多相关文章
- Shader 模板缓冲和模板测试
http://blog.sina.com.cn/s/blog_6e159df70102xa67.html 模板缓冲的概念 Unity官方的Shader文档根本没有提到这个玩意,这个概念也是看到了UGU ...
- Unity Shader 知识点总结(一)
在学习了一段时间的Unity Shader后,打算写一些知识总结,便于今后的查找.如有错误,希望大家指出更改. 本文参照的unity入门精要一书,做一个知识归纳,如有兴趣可以看看其开源的部分,是一本比 ...
- Unity Shader入门精要读书笔记(一)序章
本系列的博文是笔者读<Unity Shader入门精要>的读书笔记,这本书的章节框架是: 第一章:着手准备. 第二章:GPU流水线. 第三章:Shader基本语法. 第四章:Shader数 ...
- Unity Shader实现描边效果
http://gad.qq.com/article/detail/28346 描边效果是游戏里面非常常用的一种效果,一般是为了凸显游戏中的某个对象,会给对象增加一个描边效果.本篇文章和大家介绍下利用S ...
- 【转】《Unity Shader入门精要》冯乐乐著 书中彩图
为方便个人手机学习时候查阅,从网上转来这些彩图. 如属过当行为,联系本人删除. 勘错表 http://candycat1992.github.io/unity_shaders_book/unity_s ...
- Unity Shader入门精要学习笔记 - 第9章 更复杂的光照
转载自 冯乐乐的<Unity Shader入门精要> Unity 的渲染路径 在Unity里,渲染路径决定了光照是如何应该到Unity Shader 中的.因此,如果要和光源打交道,我们需 ...
- Unity Shader入门精要学习笔记 - 第2章 渲染流水线
来源作者:candycat http://blog.csdn.net/candycat1992/article/ 2.1 综述 渲染流水线的最终目的在于生成或者说是渲染一张二维纹理,即我们在电脑屏 ...
- unity shader之预备知识
1.渲染流水线 任务:从一个三维场景出发,生成(或者渲染)一张二维图像.即:计算机需要从一系列的定点出数据,纹理等信息出发,把这些信息最终转换程一张人眼可以看到的图像.而这个工作通常是由CPU和GPU ...
- Unity Shader学习笔记-1
本篇文章是对Unity Shader入门精要的学习笔记,插图大部分来自冯乐乐女神的github 如果有什么说的不正确的请批评指正 目录 渲染流水线 流程图 Shader作用 屏幕映射 三角形遍历 两大 ...
随机推荐
- 字符串模式匹配算法系列(二):KMP算法
算法背景: KMP算法是由Donald Knuth和Vaughan Pratt于1970年共同提出的,而James H.Morris也几乎同时间独立提出了这个算法.因此人们将其称作“克努特-莫里斯-普 ...
- Entity Framework 中遇到的一些小问题
一.在多表关联中,一个表中有另一个表的model累,在Include方法里提示lambda表达式不是委托类型,这时候需要using System.Data.Entity; 二.插入数据时,主键并非自增 ...
- [Python3 练习] 010 找出藏在字符串中的“密码”
题目:找出藏在字符串中的"密码" (1) 描述 1) 题源 1 Python Challenge, level 3 2) 题源 2 小甲鱼老师的 Python 课程,第 20 讲课 ...
- python开发之路-day01
1.Python前世今生 python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程序,作为A ...
- [Interview] Bubble sort using singly-linked list
Question : Bubble sort using singly-linked list 群暉面試題 Idea : 在linked list 交換node與node時, 我們會想用換*next ...
- CF208E Blood Cousins
Blood Cousins 题目描述 小C喜欢研究族谱,这一天小C拿到了一整张族谱. 小C先要定义一下k-祖先. x的1-祖先指的是x的父亲 x的k-祖先指的是x的(k-1)-祖先的父亲 小C接下来要 ...
- shell简单的菜单功能
- smbumount - 为普通用户卸载smb文件系统
总览 smbumount 装载点 描述 普通用户使用这个程序可以卸载smb文件系统.它在工作时会suid到root身份,并且向普通linux用户提供了对资源更多的控制能力.在suid方面,它拥有足够的 ...
- Collection集合家族
集合家族 数组:存储相同类型的多个元素 对象:存储不同类型的多个元素 集合:存储多个不同类型的对象 List List继承自Collection接口,是有序可重复的集合. 它的实现类有:ArrayLi ...
- Java1.7与1.8新特性
Java 1.7: switch中可以使用字符串 List<String> list = new ArrayList<>(),即泛型实例化类型自动推断 try块可以不用fina ...