官方文档地址:

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模版测试学习的更多相关文章

  1. 【淡墨Unity3D Shader计划】四 热带雨林的文章: 排除、深度测试、Alpha测试和基本雾编译

    本系列文章由@浅墨_毛星云 出品,转载请注明出处.   文章链接:http://hpw123.net/a/C__/kongzhitaichengxu/2014/1222/163.html 作者:毛星云 ...

  2. unity3d shader 学习

    [浅墨Unity3D Shader编程] 着色器参考 [Unity Shaders]

  3. 【译】Unity3D Shader 新手教程(1/6)

    本文为翻译,附上原文链接. 转载请注明出处--polobymulberry-博客园. 刚开始接触Unity3D Shader编程时,你会发现有关shader的文档相当散,这也造成初学者对Unity3D ...

  4. 【浅墨Unity3D Shader编程】之一 夏威夷篇:游戏场景的创建 & 第一个Shader的书写

    本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/40723789 作者:毛星云(浅墨)  ...

  5. Unity3d Shader

    Unity3d Shader 预览Surface Shader主要用来实现光照相关处理,可能更简洁. Vertex and Fragment Shader 如果不与光照交互, 则可以用这个shader ...

  6. 【Aladdin Unity3D Shader编程】之一 基本入门

    OpenGL.DirectX以及GLSL.HLSL.CG OpenGL和DirectX是图像应用编程接口,用于渲染二维或者三维图形. GLSL着色语言是用来在OpenGL中着色编程的语言,有点在于跨平 ...

  7. OpenGL和D3D11中的深度模版测试

        在OpenGL和D3D11的管线中,像素shader之后的操作就是深度模版测试,深度模版测试是以sample为单位进行的,就是一个像素上可以有多个采样点,每个采样点都有深度信息.深度模版测试对 ...

  8. Unity3D Shader 入门之简单案例的实现(通过法线实现颜色变化)

    在没有接触Unity3D  Shader 之前,总感觉shader特别神奇,因为听说是对渲染流水线进行编程,就是对GPU进行编程.听着特别高大上.这不,最近刚刚接触Shader,学了几个小案例,然后本 ...

  9. Unity Shader之模板测试

    Unity Shader之模板测试 一沙一世界,一花一天堂 一.Stencil testing 渲染管线     当片段着色器处理完一个片段之后,模板测试(Stencil Test)会开始执行,和深度 ...

随机推荐

  1. jdbcTemplate获取mysql的blob

    java使用jdbcTemplate操作mysql数据库,遇到blob字段,正常读取出来是blob的地址,而不是blob的内容. 下面采用2中方式读取blob的内容: 1.以二进制数组形式读取blob ...

  2. 使用AOP的方式监测方法执行耗时

    在一些对系统中,往往可能需要对一些核心业务做相应的监测.如:记录调用参数,返回值,方法执行耗时等等.如果直接在方法的前后加入代码,如下: public int F(int a, string s) { ...

  3. GreenOpenPaint的实现(一)基本框架

    Win7下的MSPaint是Ribbon的典型运行.这种SDI程序对于图像处理来说是很适合的.利用春节时间,基于之前的积累,我实现GreenOpenPaint,主要就是模拟MSPaint的界面,实现出 ...

  4. 小学生之Hibernate插入数据修改数据使用数据库默认值的实现

    最近在写一个案例,定时任务对数据库进行更新操作,废话不多说,上代码: @Component("taskJob") public class TaskJob extends Hibe ...

  5. CentOS7 ssh无密码登录

    准备工作:给各个主机取个名字,如master(主节点),slave01(从节点01),slave02(从节点02) 1.修改主机名: hostname master hostname slave01 ...

  6. Wireshark网络抓包(三)——网络协议

    一.ARP协议 ARP(Address Resolution Protocol)地址解析协议,将IP地址解析成MAC地址. IP地址在OSI模型第三层,MAC地址在OSI第二层,彼此不直接通信: 在通 ...

  7. 使用cordova开发app

    前言 公司之前用的app就是一个套壳挂个链接就能用的app,后来需要添加微信分享方便传播,没办法只好做成混合式的app了, 因为之前做.net用vs可以创建cordova项目也试着玩过,就决定用cor ...

  8. sass 基础——回顾

    1.webstorm 自动编译SASS 下载安装包 http://rubyinstaller.org/downloads/ 然后点击安装,路径为默认路径就行, 勾选以下两项 add Ruby exec ...

  9. weex官方demo weex-hackernews代码解读(下)

    weex 是阿里出品的一个类似RN的框架,可以使用前端技术来开发移动应用,实现一份代码支持H5,IOS和Android.而weex-hacknews则是weex官方出品的,首个使用 Weex 和 Vu ...

  10. BZOJ 1096: [ZJOI2007]仓库建设(动态规划+斜率优化)

    第一次写斜率优化,发现其实也没啥难的,没打过就随便找了一份代码借(chao)鉴(xi)下,不要介意= = 题解实在是懒得写了,贴代码吧= = CODE: #include<cstdio># ...