美文网首页
UnityShader:深度测试&深度写入

UnityShader:深度测试&深度写入

作者: 忆中异 | 来源:发表于2024-04-17 16:21 被阅读0次

    对于两个不透明的物体A和B,它们处于同一个渲染队列中。假如它们一前一后地摆放着,当先渲染A再渲染B,那么B显示在前面;当先渲染B再渲染A,那么A显示在前面。因此,单靠渲染队列还是无法很好解决物体间的遮挡关系,这时就需要利用深度这个东西了。

    深度

    • 指该像素距离摄像机的距离。离摄像机越远,深度越大。

    深度缓冲 & 颜色缓冲

    • 深度缓冲中存储着每个像素对应的深度值。
    • 颜色缓冲中存储着每个像素对应的颜色值。

    深度测试

    • 将像素的深度与深度缓冲的深度进行比较。如果通过了深度测试,就有机会去改写深度缓冲的对应值;否则该像素会被舍弃。
      语法如下:
      ZTest Less | Greater | LEqual | GEqual | Equal | NotEqual | Always
      默认值为LEqual,小于等于。即表示如果像素的深度小于等于深度缓冲的深度,则通过了深度测试。
      那么他们的情况就有如下几种:
    1. 当ZWrite为On时,ZTest通过时,该像素的深度才能成功写入深度缓存,同时因为ZTest通过了,该像素的颜色值也会写入颜色缓存。
    2. 当ZWrite为On时,ZTest不通过时,该像素的深度不能成功写入深度缓存,同时因为ZTest不通过,该像素的颜色值不会写入颜色缓存。
    3. 当ZWrite为Off时,ZTest通过时,该像素的深度不能成功写入深度缓存,同时因为ZTest通过了,该像素的颜色值会写入颜色缓存。
    4. 当ZWrite为Off时,ZTest不通过时,该像素的深度不能成功写入深度缓存,同时因为ZTest不通过,该像素的颜色值不会写入颜色缓存。
    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才是决定采用谁的颜色值,zwrite只是为ztest服务的。默认情况下unity采用的是zwrite为on,ztest为lqeual 也就是越靠近相机的显示优先级越高。

    深度写入

    • 是否要将像素的深度写入到深度缓冲中。前提是通过了深度测试。
      语法如下:
      ZWrite On / Off: 开启深度缓冲/关闭深度缓冲(其实就是记录Z值,把最小的Z存放在缓冲中),一般情况不透明的物体都会使用zwrite on 而 半透明的物体都会使用 zwrite off 这样半透明的物体就直接比较ztest了。
      默认值为On,即写入深度缓冲。

    渲染队列

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

    总结

    a.根据这两个默认值,可以知道,离摄像机近的会遮挡住离摄像机远的,因此也就解决了最开始说的两个物体的遮挡问题:假如A在前B在后,当先渲染A再渲染B,在渲染B时B不能通过深度测试从而被舍弃;当先渲染B再渲染A,在渲染A时A通过深度测试从而覆盖了B。因此对于不透明物体间的遮挡,通过这两个默认值就可以得到很好的处理。
    b.当深度测试不通过时,该像素会被舍弃,深度缓冲和颜色缓冲无变化;否则,该像素的颜色值会覆盖掉颜色缓冲的颜色值,然后根据深度写入来决定是否覆盖掉深度缓冲中的深度值。


    image.png

    相关文章

      网友评论

          本文标题:UnityShader:深度测试&深度写入

          本文链接:https://www.haomeiwen.com/subject/qjtexjtx.html