转载自:http://www.myexception.cn/mobile/1902628.html

[UnityShader]渲染队列、ZWrite和ZTest

参考链接:http://blog.csdn.net/zhuyingqingfen/article/details/18979547

http://blog.csdn.net/lysc_forever/article/details/13614449

(1)什么是深度?

深度其实就是该像素点在3d世界中距离摄象机的距离,深度值(Z值)越大,则离摄像机越远。

(2)什么是深度缓存?

深度缓存中存储着每个像素点(绘制在屏幕上的)的深度值!如果启用了深度缓冲区,在绘制每个像素之前,OpenGL会把它的深度值和已经存储在这个像素的深度值进行比较。新像素深度值<原先像素深度值,则新像素值会取代原先的;反之,新像素值被遮挡,其颜色值和深度将被丢弃,最终屏幕显示的就是深度缓存中深度对应的像素点的颜色!(深度主要起的是比较的作用)

(3)什么是深度测试?

在深度测试中,默认情况是将要绘制的新像素的z值与深度缓冲区中对应位置的z值进行比较,如果比深度缓存中的值小,那么用新像素的颜色值更新深度缓存中对应像素的颜色值。

(4)为什么需要深度?

在不使用深度测试的时候,如果我们先绘制一个距离较近的物体,再绘制距离较远的物体,则距离远的物体因为后绘制,会把距离近的物体覆盖掉,这样的效果并不是我们所希望的。而有了深度缓冲以后,绘制物体的顺序就不那么重要了,都能按照远近(Z值)正常显示,这很关键。(越后绘制的东西,距离相机就越近)

那么,在unity中,如果知道了渲染队列,ZWrite,ZTest,如何确定哪个物体先显示呢?

首先,unity先将渲染队列中较前的进行渲染,然后再执行ZWrite,ZTest

ZWrite可以取的值为:On/Off,默认值为On,代表是否要将像素的深度写入深度缓存中

ZTest可以取的值为:Greater/GEqual/Less/LEqual/Equal/NotEqual/Always/Never/Off,默认值为LEqual,代表如何将像素的颜色写入深度缓存中,例如当取默认值的情况下,如果将要绘制的新像素的z值小于等于深度缓存中的值,则将用新像素的颜色值更新深度缓存中对应像素的颜色值。需要注意的是,当ZTest取值为Off时,表示的是关闭深度测试,等价于取值为Always,而不是Never!Always指的是直接将当前像素颜色(不是深度)写进颜色缓冲区中;而Never指的是不要将当前像素颜色写进颜色缓冲区中,相当于消失。

因为ZWrite默认值为On,ZTest默认值为LEqual,所以这很好地解释了为什么在unity中,距离相机近的东西会阻挡住距离相机远的东西。如果我们先绘制一个距离较近的物体,再绘制距离较远的物体,则距离远的物体因为后绘制,会把距离近的物体覆盖掉,这时我们可以通过修改ZWrite和ZTest来改变物体的遮挡关系!

测试环境(蓝色方块距离相机较近,注意这个不是Game视图):

测试的Shader代码(两个方块的shader代码起始都是一样的,测试时修改的是测试区里的代码):

Shader "Custom/ZTest" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
/////////////////////////////////////////测试区
Tags{ "Queue" = "Geometry" }
//ZWrite Off
//ZTest Off
/////////////////////////////////////////测试区
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"
}

渲染顺序:先蓝色方块再白色方块(以下简称蓝,白)

注意ZWrite默认值为On,ZTest默认值为LEqual,没有渲染物体时,深度缓存中的深度可以理解为无限大

1.

/////////////////////////////////////////蓝色方块测试区
Tags{ "Queue" = "Geometry+200" }
ZWrite Off
//ZTest Off
/////////////////////////////////////////蓝色方块测试区
/////////////////////////////////////////白色方块测试区
Tags{ "Queue" = "Geometry+300" }
//ZWrite Off
//ZTest Off
/////////////////////////////////////////白色方块测试区

结果:白在前面

分析:蓝没有将像素写进深度缓存中,颜色缓冲区中存放了蓝的颜色值;而白将像素写进深度缓存中,深度缓存被替换了,深度缓存中深度对应的颜色也被舍弃了,所以显示白

2.

/////////////////////////////////////////蓝色方块测试区
Tags{ "Queue" = "Geometry+200" }
//ZWrite Off
//ZTest Off
/////////////////////////////////////////蓝色方块测试区
/////////////////////////////////////////白色方块测试区
Tags{ "Queue" = "Geometry+300" }
//ZWrite Off
//ZTest Off
/////////////////////////////////////////白色方块测试区

结果:蓝在前面

分析:蓝将像素写进深度缓存中;而白将像素写进深度缓存时,因为像素深度大于蓝的,被遮挡的像素被舍弃,所以显示蓝

3.

/////////////////////////////////////////蓝色方块测试区
Tags{ "Queue" = "Geometry+200" }
ZWrite Off
ZTest Off
/////////////////////////////////////////蓝色方块测试区
/////////////////////////////////////////白色方块测试区
Tags{ "Queue" = "Geometry+300" }
//ZWrite Off
//ZTest Off
/////////////////////////////////////////白色方块测试区

结果:白在前面

分析:与1类似

4.

/////////////////////////////////////////蓝色方块测试区
Tags{ "Queue" = "Geometry+200" }
//ZWrite Off
//ZTest Off
/////////////////////////////////////////蓝色方块测试区
/////////////////////////////////////////白色方块测试区
Tags{ "Queue" = "Geometry+300" }
//ZWrite Off
ZTest Off
/////////////////////////////////////////白色方块测试区

结果:白在前面

分析:蓝将像素写进了深度缓存中;白没有成功将像素写进了深度缓存中,但因为ZTest Off,白将颜色缓存中的蓝的像素颜色值替换了。也就是深度缓存中是蓝像素的深度,颜色缓冲中是白像素的颜色

5.

/////////////////////////////////////////蓝色方块测试区
Tags{ "Queue" = "Geometry+200" }
//ZWrite Off
//ZTest Off
/////////////////////////////////////////蓝色方块测试区
/////////////////////////////////////////白色方块测试区
Tags{ "Queue" = "Geometry+300" }
ZWrite Off
ZTest Off
/////////////////////////////////////////白色方块测试区

结果:白在前面

分析:与4类似

6.

/////////////////////////////////////////蓝色方块测试区
Tags{ "Queue" = "Geometry+200" }
//ZWrite Off
ZTest Off
/////////////////////////////////////////蓝色方块测试区
/////////////////////////////////////////白色方块测试区
Tags{ "Queue" = "Geometry+300" }
//ZWrite Off
ZTest Off
/////////////////////////////////////////白色方块测试区

结果:白在前面

分析:与5类似

7.

/////////////////////////////////////////蓝色方块测试区
Tags{ "Queue" = "Geometry+200" }
ZWrite Off
//ZTest Off
/////////////////////////////////////////蓝色方块测试区
/////////////////////////////////////////白色方块测试区
Tags{ "Queue" = "Geometry+300" }
ZWrite Off
//ZTest Off
/////////////////////////////////////////白色方块测试区

结果:白在前面

分析:白、蓝都没有将像素写入深度缓存中,所以深度缓存中的深度值为无穷大,最后因为白中ZTest默认值的原因,所以显示白

8.

/////////////////////////////////////////蓝色方块测试区
Tags{ "Queue" = "Geometry+200" }
ZWrite Off
ZTest Off
/////////////////////////////////////////蓝色方块测试区
/////////////////////////////////////////白色方块测试区
Tags{ "Queue" = "Geometry+300" }
ZWrite Off
ZTest Off
/////////////////////////////////////////白色方块测试区

结果:白在前面

分析:与7类似

[UnityShader]点染队列、ZWrite和ZTest的更多相关文章

  1. unity, imageEffect的最后一步blit所用的shader,应该关闭zwrite和ztest

    给项目组做了个imageEffect特效,结果导致ngui不显示(ugui则不存在此问题),看ngui的一些shader,其中ztest是开着的,而且ui相机的Clear Flags用的是Don't ...

  2. 3、shader深度测试(Cull、ZWrite 、ZTest )

    剔除和深度测试是渲染法线中的一个流程 Cull:默认情况下,Unity中给的所有Shader都是单面的,它都把反面的渲染给关闭掉了,如果你在开发的过程中需要使用到双面,只要把cull关闭(off)即可 ...

  3. UnityShader之遮挡透明

    好久没写博客了,最近在学shader,不得不说,shader真的非常美妙,我沉迷其中无法自拔= = 之前做过一个遮挡透明的功能,当物体遮挡住主角时,该物体会变成半透明显示出主角.这次同样是遮挡透明的功 ...

  4. UnityShader快速上手指南(三)

    简介 这一篇还是一些基本的shader操作:裁剪.透明和法向量的应用 (纠结了很久写不写这些,因为代码很简单,主要是些概念上的东西) 先来看下大概的效果图:(从左到右依次是裁剪,透明,加了法向量的透明 ...

  5. UnityShader实现物体被遮挡描边

    之前在网上看到物体遮挡描边的功能,自己也拿来实现了一番.算作第一篇博客的开篇. 先贴出几张效果图,也是个人思路和方案的改进路线吧. ////////////////////////////////// ...

  6. [UnityShader效果]01.Mask

    参考链接: https://blog.csdn.net/akof1314/article/details/50428200 1.Mask.shader // Unity built-in shader ...

  7. [UnityShader基础]08.UI-Default.shader

    参考链接: https://zhuanlan.zhihu.com/p/32561155 https://blog.csdn.net/WuShangLZ/article/details/80401441 ...

  8. Fill-rate, Canvases and input 【译】

    翻译自https://unity3d.com/cn/learn/tutorials/topics/best-practices/fill-rate-canvases-and-input?playlis ...

  9. Unity渲染

    我们先大概了解一下对渲染的优先级有影响的几个因素 1.Camera.Depth 不同相机的深度,在渲染顺序的优先度里面是最高的,Depth越大,渲染的图像越靠前 2.Render.SortingOrd ...

随机推荐

  1. tomcat使用不同的jdk版本 liunx 装两个jdk

    原作者文章 https://blog.csdn.net/qq_34626097/article/details/83385219 看了原作者学会的!上面链接 因为公司的服务器里面是jdk1.7和tom ...

  2. javascript的最重要的特性之一:闭包的解决方案

    初始代码: for (var j = 0; j < lnglats.length; j++) { AMap.event.addListener(markers[j], 'mouseover', ...

  3. Codeforces Round #339 (Div. 2) A

    Description Programmer Rostislav got seriously interested in the Link/Cut Tree data structure, which ...

  4. 06-图2 Saving James Bond - Easy Version (25 分)

    This time let us consider the situation in the movie "Live and Let Die" in which James Bon ...

  5. Why Nexiq 125032 USB Link Truck diagnostic tool is so helpful ?

    As for as I am concerned , Heavy Duty Diagnostic Nexiq 125032 USB is a helpful tool , which has exce ...

  6. acm刷题序列

    POJ推荐50题 著名的北邮acm训练队推荐50题 https://blog.csdn.net/bat67/article/details/71735012 都是poj上的题 1000:会教会你如何使 ...

  7. linux下pid命令

    ps aux | grep tomcat|  awk '{if(NR==1)print $2}' Linux:批量修改分隔符(awk.BEGIN.FS.OFS.print.tr命令) 批量修改文件的分 ...

  8. oracle merge into函数中插入clob字段

    当使用Merge into 函数向ORACLE数据库中插入或更新数据时,报错“ORA-01461: 仅可以为插入 LONG 列的 LONG 值赋值”,使用如下方法可以把String转换为clob. 需 ...

  9. 文献综述一:基于UML技术的商品管理系统设计与实现

    一.基本信息 标题:基于UML技术的商品管理系统设计与实现 时间:2018 出版源:福建电脑 文件分类:uml技术的研究 二.研究背景 使用 UML 技术对商品管理系统进行了分析与研究,使用户对商品信 ...

  10. 用navigator.geolocation.getCurrentPosition在IOS10以上的系统无法定位

    昨天老板告诉我代码有Bug(定位失败),于是各种测试最终发现IOS10以上版本手机不能成功(穷,买不起iphone,测试不完全),先贴失败代码: var city =""; nav ...