Unity Shader教程(三)深度测试(depth test)

发表于2018-05-27
评论0 1.18w浏览
上篇文章和大家介绍了在片段程序处理之前除了裁剪,还有一个比较重要的概念就是深度测试。深度测试的作用其实是对裁剪的弥补,裁剪讨论的范围是局部坐标的模型本身的优化,而深度测试是在世界空间的对渲染的优化,想象一下,在世界空间中有很多出现在视野中,但是有互相遮挡的情况,其实我们是不需要去处理他的着色的。而要完成这个过程就必须用到两个术语(缺一不可):深度缓存(zwrite) + 颜色缓存(ztest)

zwrite 分类

zwrite on / off : 开启深度缓冲/关闭深度缓冲(其实就是记录Z值,把最小的Z存放在缓冲中),一般情况不透明的物体都会使用zwrite on 而 半透明的物体都会使用 zwrite off 这样半透明的物体就直接比较ztest了

ztest 分类

less / greater / lequal /gequal / equal / notequal /always(其实就是拿着当前的像素来对深度缓冲中的z值进行比较的条件)

那么他们的情况就有如下几种:
1. 当ZWrite为On时,ZTest通过时,该像素的深度才能成功写入深度缓存,同时因为ZTest通过了,该像素的颜色值也会写入颜色缓存。
2. 当ZWrite为On时,ZTest不通过时,该像素的深度不能成功写入深度缓存,同时因为ZTest不通过,该像素的颜色值不会写入颜色缓存。
3. 当ZWrite为Off时,ZTest通过时,该像素的深度不能成功写入深度缓存,同时因为ZTest通过了,该像素的颜色值会写入颜色缓存。
4. 当ZWrite为Off时,ZTest不通过时,该像素的深度不能成功写入深度缓存,同时因为ZTest不通过,该像素的颜色值不会写入颜色缓存。

总结:zwrite只是处理深度值,ztest才是决定采用谁的颜色值,zwrite只是为ztest服务的。默认情况下unity采用的是zwrite为on,ztest为lqeual 也就是越靠近相机的显示优先级越高。

例子一:两个不透明的物体我需要后面的物体不被挡住。比如游戏里面的轮廓显示主角(要实现这种情况其实有很多方式,具体可以自己尝试)


代码:
Shader "Custom/Depth Test" {
    Properties {
        //定义一个贴图
        _MainTex ("Base (RGB)", 2D) = "white" {} 
    }
    SubShader 
    {       
      Pass
        {
            zwrite on //打开深度缓存
            ztest greater  //打开深度测试,颜色通过
        }
        Pass
        {
            SetTexture [_MainTex] 
            {
                Combine texture * primary  //正面赋予贴图
            }
        }
    } 
    FallBa

渲染队列

前面我们说的zwrite 和 ztest 可以理解为在同一个队列里面进行的,我们知道在Tag 里面可以设置queue这个参数来表明物体所在的队列。也许你看到的不透明不同越靠近相机,半透明物体远离相机,但是由于他们的queue不同也就是基础深度不同,所以他们渲染的渲染顺序也是不同的。

例子二:使用渲染队列决定z值


cube的代码:
Shader "Custom/Depth Transparent" {
    SubShader 
    {       
        Tags { "Queue"="Transparent-1000"} //这里可以自己试着修改,比如修改为-999的时候你会发现角色被挡住了
         pass{
         }
    } 
    FallBack "Diffuse"
}

这里列举下unity 内部的渲染队列: Background = 1000, Geometry = 2000, AlphaTest = 2450,Transparent = 3000, Overlay = 4000 所以知道为什么上面的 -1000 和 -999 的区别了吧 (越大的值越后渲染)
来自:https://blog.csdn.net/pdw_jsp/article/details/54314381

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引