Unity3D Shader Stencil模版测试学习
官方文档地址:
https://docs.unity3d.com/Manual/SL-Stencil.html
参考博客:
http://blog.csdn.net/onafioo/article/details/53943264
http://blog.csdn.net/u013833399/article/details/47340447
(因表述的内容都大致一样,一些内容直接引用自原作者)
1.简介
在Unity中一个像素会有多个缓存信息,模版缓存(其实Stencil不应该被翻译成模版,但网上都这么写)是其中之一。
模板缓冲区可以为屏幕上的每个像素点保存一个无符号整数值,
通过一些比较来改变当前像素区域模版缓冲的值,从而改变深度关系,似乎UGUI的Mask也是通过其实现的
延迟光照中Stencil有一些限制,具体看unity的文档,这里只介绍正向光照中的使用
Stencil所在的渲染管线中的顺序位置:

Stencil的所有参数如下
Stencil
{
Ref //Reference Value
ReadMask
WriteMask
Comp Always //Comparison Function
Pass Replace
Fail Keep
ZFail Replace
}
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
2.实践
下面结合案例,说一下Stencil的使用

现在有一个球和面片,通过Stencil模版测试把stencil值一致的物体渲染为蓝色
为了更直观使用了两个shader,面片是shader1,球是shader2
球肯定是优先渲染,并且设置好stencil的值,面片后渲染,并且判断stencil的值
文件结构:

MaskTest2是球的shader
Shader "Unlit/MaskTest2"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Tags{ "RenderType" = "Opaque" "Queue" = "Geometry" } Stencil
{
Ref
Comp Always
Pass Replace
} 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
{
return fixed4(,,,);
}
ENDCG
}
}
}
MaskTest2
Stencil里,比较条件设置为总通过,通过操作设置为替换Ref值
这样球部分的像素Stencil值就是1
Stencil
{
Ref
Comp Always
Pass Replace
}
MaskTest1是面片的Shader
Shader "Unlit/MaskTest1"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Tags{ "RenderType" = "Opaque" "Queue" = "Geometry+1" } Stencil
{
Ref
Comp equal
} 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
{
return fixed4(,,,);
}
ENDCG
}
}
}
Stencil里,比较条件是和Ref值一致时,才会执行渲染
否则跳出
Stencil
{
Ref
Comp equal
}
蓝色是片段shader里写好的
fixed4 frag (v2f i) : SV_Target
{
return fixed4(,,,);
}
这样就可以达到上述效果。
测试工程文件下载:http://files.cnblogs.com/files/hont/StencilMaskTest.zip
Unity3D Shader Stencil模版测试学习的更多相关文章
- 【淡墨Unity3D Shader计划】四 热带雨林的文章: 排除、深度测试、Alpha测试和基本雾编译
本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://hpw123.net/a/C__/kongzhitaichengxu/2014/1222/163.html 作者:毛星云 ...
- unity3d shader 学习
[浅墨Unity3D Shader编程] 着色器参考 [Unity Shaders]
- 【译】Unity3D Shader 新手教程(1/6)
本文为翻译,附上原文链接. 转载请注明出处--polobymulberry-博客园. 刚开始接触Unity3D Shader编程时,你会发现有关shader的文档相当散,这也造成初学者对Unity3D ...
- 【浅墨Unity3D Shader编程】之一 夏威夷篇:游戏场景的创建 & 第一个Shader的书写
本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/40723789 作者:毛星云(浅墨) ...
- Unity3d Shader
Unity3d Shader 预览Surface Shader主要用来实现光照相关处理,可能更简洁. Vertex and Fragment Shader 如果不与光照交互, 则可以用这个shader ...
- 【Aladdin Unity3D Shader编程】之一 基本入门
OpenGL.DirectX以及GLSL.HLSL.CG OpenGL和DirectX是图像应用编程接口,用于渲染二维或者三维图形. GLSL着色语言是用来在OpenGL中着色编程的语言,有点在于跨平 ...
- OpenGL和D3D11中的深度模版测试
在OpenGL和D3D11的管线中,像素shader之后的操作就是深度模版测试,深度模版测试是以sample为单位进行的,就是一个像素上可以有多个采样点,每个采样点都有深度信息.深度模版测试对 ...
- Unity3D Shader 入门之简单案例的实现(通过法线实现颜色变化)
在没有接触Unity3D Shader 之前,总感觉shader特别神奇,因为听说是对渲染流水线进行编程,就是对GPU进行编程.听着特别高大上.这不,最近刚刚接触Shader,学了几个小案例,然后本 ...
- Unity Shader之模板测试
Unity Shader之模板测试 一沙一世界,一花一天堂 一.Stencil testing 渲染管线 当片段着色器处理完一个片段之后,模板测试(Stencil Test)会开始执行,和深度 ...
随机推荐
- java算法 蓝桥杯 高精度加法
问题描述 在C/C++语言中,整型所能表示的范围一般为-231到231(大约21亿),即使long long型,一般也只能表示到-263到263.要想计算更加规模的数,就要用软件来扩展了,比如用数组或 ...
- Unity随手记
过年11天假期,带娃带了7天,吃吃喝喝.也看了点书,<射雕英雄传>(书)看了一半,还有就是在看<unity官方案例精讲>这本. 随手记一些自觉有价值或者有意思的点. 1. 对脚 ...
- [Bullet3]常见物体和初始化
官方文档:http://bulletphysics.org 开源代码:https://github.com/bulletphysics/bullet3/releases API文档:http://bu ...
- C++编程练习(5)----“实现简单的循环队列的顺序存储结构“
队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表. 队列是一种先进先出(First In First Out)的线性表,简称FIFO.允许插入的一端称为队尾,允许删除的一端 ...
- Linq 集合操作
Linq 集合操作 演示代码 两个对象一个是Person,一个Address, AddressId是外键, public class Person { public string ID { get; ...
- Weex系列二、显示图片
上次我们创建了一个简单的Weex的demo. 一.常用的类 WXSDKEngine:SDK开放的绝大多数接口都在此有声明. WXLog: 用来打印日志. WXDebugTool: weex提供的对外调 ...
- Javascript—①你好,世界!
新手Perfect教程之Javascript教程①-你好,世界! 前言:不知道Javascript是什么东东的自行度娘或google一下 Javascript在html<head>和< ...
- sizeof和strlen的区别和联系总结
link:http://blog.csdn.net/ghevinn/article/details/9974967 strlen所作的仅仅是一个计数器的工作,它从内存的某个位置(可以是字符串开头 ...
- js移动端向左滑动出现删除按钮
最近在做移动端项目时,需要实现一个列表页面的每一项item向左滑动时出现相应的删除按钮,本来想着直接使用zepto的touch.js插件,因为之前实现相同的功能时用过这个插件,当时还挺好用的,直接使用 ...
- BZOJ 4085:[Sdoi2015]quality(round 2 音质检测)(数据结构)
居然在考场上把这道题打出来了觉得自己也是有点吊啊(虽然后面就没时间做其他题了囧而且还被卡常数了...) 题解自己写了一份TEX的就直接放上来吧.... 好啦,在谈点什么别的 什么?你在bz上TLE了? ...