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作用 屏幕映射 三角形遍历 两大 ...
随机推荐
- Phone-java标准类
//project-module-package //.代表包的目录层次 package cn.learn.day01.demo01; /* 1.类是一组相关属性(成员变量)与行为(方法)的集合,对象 ...
- JavaScript LinkedList
function LinkedList() { var Node = function(element) { this.element = element; this.next = null } va ...
- Struts2+Ajax实现数据交互
1.导入jar包 struts核心包: json需要的包: 2.配置web.xml <filter> <filter-name>struts2</filter-name& ...
- [原]Threads vs Processes in Linux 分析
Linux中thread (light-weighted process) 跟process在實作上幾乎一樣. 最大的差異來自於,thread 會分享 virtual memory address s ...
- 怕忘记了CSS中position的absolute和relative用法
CSS2.0中的定位确实有时会把人弄糊涂,所以今天给它记下来,同时供以后查阅.下面写的内容有一部分借鉴了w3cschool和divcss5这两个官方网站,在此处特别的说明一下 CSS2.0中posit ...
- C# Winform 窗体界面”假死”后台线程阻塞 解决办法–BeginInvoke
原文:C# Winform 窗体界面"假死"后台线程阻塞 解决办法–BeginInvoke 这个方法可以用在任何后台任务耗时较长,造成界面“假死”界面控件不更新的情况. 比如要要执 ...
- Java的GC机制及算法
GC的阶段 对每个对象而言,垃圾回收分为两个阶段:finalization和reclamation. finalization: 指运行这个对象的finalize的方法. reclamation: ...
- Vue组件-组件组合
组件设计初衷就是要配合使用的,最常见的就是形成父子组件的关系:组件 A 在它的模板中使用了组件 B. <html> <head> <title>Vue组件 A 在它 ...
- React Native框架如何白盒测试-HIPPY接口测试架构篇
本文转载自腾讯TMQ团队 ,侵权删. 1.开天辟地 Hippy是什么呢?简单点,能用JavaScript来写Android和iOS应用的框架, 类似业界的React Native. 好吧,我们还是严谨 ...
- spring 整合rabbitMQ
<!-- 配置邮件消息队列监听 --> <bean id="maillistener" class="cn.xdf.wlyy.listener.Mail ...