官方文档地址:

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. HDU5914

    Triangle Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Su ...

  2. HDU3410(单调队列)

    Passing the Message Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  3. 转:C# Process.Start()方法详解

    http://blog.csdn.net/czw2010/article/details/7896264 System.Diagnostics.Process.Start(); 能做什么呢?它主要有以 ...

  4. 02月刊(上) | 微信小程序

    * { margin: 0; padding: 0 } .con { width: 802px; margin: 0 auto; text-align: center; position: inher ...

  5. jQuery --checkbox全选和取消全选简洁高效的解决办法

    最近在公司做了一个小项目,其中有一个全选和取消全选的这么一个模块,搞了半天找不到一种最佳的解决方案!后来通过各种努力找到了一种简洁高效的解决办法,这里想和大家分享一下.有问题的话,还望各路大神指导一二 ...

  6. python报错UnicodeDecodeError: 'ascii' codec can't decode byte 0xe8 in position 0 解决方案

    环境:mac+python 2.7 场景描述:在使用python修改excel内容修改表格内容为中文保存时报以下错误 此时已经设置了utf-8了 但保存时仍然报错错 此时将python中的中文使用un ...

  7. JavaScript中国象棋程序(8) - 进一步优化

    在这最后一节,我们的主要工作是使用开局库.对根节点的搜索分离出来.以及引入PVS(Principal Variation Search,)主要变例搜索. 8.1.开局库 这一节我们引入book.js文 ...

  8. java集合框架04——LinkedList和源码分析

    上一章学习了ArrayList,并分析了其源码,这一章我们将对LinkedList的具体实现进行详细的学习.依然遵循上一章的步骤,先对LinkedList有个整体的认识,然后学习它的源码,深入剖析Li ...

  9. android学习12——重载SurfaceView一些方法的执行顺序

    先看代码 public class SurfaceViewActivity extends Activity { @Override public void onCreate(Bundle saved ...

  10. Android 调用jepg库进行图片压缩,保持图片不失真

    1. 浅谈为什么Android和iOS图片质量差距那么大? 首先来说,作为一个安卓狗,机器当然用的是安卓的手机.现在的安卓手机大多数都会以高清拍照,动不动就几千万柔光相机来吸引各种买家.买来后,拍照发 ...