先看一下官方的流程:
![](https://img-my.csdn.net/uploads/201602/25/1456399794_8254.png-thumb.jpg)
渲染队列和ZTest判断
本篇主要说明 Queue、RenderType、ZWrite、ZTest、ColorMask的作用。
SubShader内部可以有标签(Tags)的定义。Tag指定了这个SubShader的渲染顺序(时机),以及其他的一些设置。
RenderType标签:
RenderType
tag categorizes shaders into several predefined groups, e.g. is is an opaque shader, or an alpha-tested shader etc。This is used by Shader Replacement and insome cases used to produce camera’s depth texture.
RenderType
将Shader分成预定义的组。Unity可以运行时替换符合RenderType的所有shader。
Unity内置的RenderType包括:
- “Opaque” 不透明物体
- “Transparent”绝大部分的透明物体、包括粒子特效都使用这个
- “BackGround”天空盒
- “Overlay” GUI、镜头光晕使用这个
- 用户也可以定义任意自己的RenderType字符串。参加http://docs.unity3d.com/Manual/SL-ShaderReplacement.html
Queue标签(Rendering Order):
目前Unity中有5个默认的Queue值,他们是:
- BackGround 最早被渲染。this render queue is rendered before any others. You’d typically use this for things that really need to be in the background.这个是注定要被覆盖的。
Geometry
(default) - this is used for most objects. Opaque geometry uses this queue.基本上不透明的几何体都在这个顺序里被渲染。- AlphaTest - alpha tested geometry uses this queue. It’s a separate queue from
Geometry
one since it’s more efficient to render alpha-tested objects after all solid ones are drawn. AlphaTest的几何体用这个顺序。这个顺序不同于上一个顺序,因为在所有的不透明几何体渲染完之后再渲染alpha-tested几何体会更有效率。(ooo 不理解翻译一下) - Transparent 这个顺序用来渲染透明物体。用back-to-front order。. Anything alpha-blended (i.e. shaders that don’t write to depth buffer) should go here (glass, particle effects)。所有有关透明混合的物体都应该在这里渲染,比如不往深度缓冲区中写的数据,例如 玻璃、粒子特效等。
-
- Overlay this render queue is meant for overlay effects. Anything rendered last should go here (e.g. lens flares).
ZWrite:
表明一个物体的像素是否写入深度缓存中。(
Default is On
)If you’re drawng solid objects, leave this on. If you’re drawing semitransparent effects, switch to ZWrite Off.官方文档告诉我们,如果我们需要绘制不透明的物体,总是将ZWrite设置为On,绘制半透明的物体,设置Off。
ZTest:
ZTest Less | Greater | LEqual | GEqual | Equal | NotEqual | Always
How should depth testing be performed. Default is LEqual (draw objects in from or at the distance as existing objects; hide objects behind them).确定了深度测试的方式,默认的是LEqual。由远及近的方式绘制物体,由近处的物体遮住远处的。
由于有ZWrite和ZTest,下面说明下深度缓存和颜色缓存的概念:
深度缓存:
- 什么是深度:深度就是该像素点在3D世界中与摄像机的距离。离摄像机越远,深度值(Z值)越大
- 深度缓存:depth buffer又称 Z缓冲区。深度缓冲区中记录着每个像素点的深度,在绘制每个像素之前,如果启用了深度缓冲,系统会把它的深度值和已经存储在缓冲里的这个像素的深度值进行比较。如果新像素深度值小于原先像素深度值,则新像素值会取代原先的;反之,新像素值被遮挡,它的颜色值和深度将被丢弃。
- 深度缓冲区的目的:深度缓冲的目的在于正确地生成通常的深度感知效果:较近的物体遮挡较远的物体。
颜色缓冲区:
- 概念:颜色缓冲区就是帧缓冲区,需要渲染的场景的每一个像素都要写入到该缓冲区,然后由他在渲染到屏幕上显示。
下面继续某些Tag
ColorMask:
Set color channel writing mask. Writing
ColorMask 0
turns off rendering to all color channels. Default mode is writing to all channels (RGBA), but for some special effects
you might want to leave certain channels unmodified, or disable color writes completely.设置颜色写入的遮罩。当设置ColorMask 0的时候关闭所有的颜色通道。默认值是开启所有的通道(RGBA)。这个可以配合上面的深度缓存的概念做一些特殊的效果。
一个虚假的切割的例子。
最终的效果
实现方式:
首先是2面墙的的深度处理
Shader "Custom/Queue1" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
}
SubShader {
Tags { "RenderType"="Opaque" "Queue"="Geometry+1"}
LOD 200
CGPROGRAM
#pragma surface surf Lambert
sampler2D _MainTex;
struct Input {
float2 uv_MainTex;
};
void surf (Input IN, inout SurfaceOutput o) {
half4 c = tex2D (_MainTex, IN.uv_MainTex);
o.Albedo = c.rgb;
o.Alpha = c.a;
}
ENDCG
}
}
第一个墙的深度是Geometry+1 第二面墙深度Geometry+3
下面是产生透帖效果的骷髅shader
Shader "Custom/QueueMask" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
}
SubShader {
Tags { "RenderType"="Opaque" "Queue"="Geometry+2"}
LOD 200
ColorMask 0
CGPROGRAM
#pragma surface surf Lambert
sampler2D _MainTex;
struct Input {
float2 uv_MainTex;
};
void surf (Input IN, inout SurfaceOutput o) {
half4 c = tex2D (_MainTex, IN.uv_MainTex);
o.Albedo = c.rgb;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}
可知这个骷髅深度是
Geometry+2