TA百人计划学习笔记 3.1.2深度测试

  • 资料

  • Z test(depth test) 深度测试

    • 引入
    • 是什么

      • 从渲染管线理解

        • 深度测试同样位于逐片元操作过程中,在模板测试之后,透明度混合之前。
      • 从逻辑上理解

        • 和模板测试差不多,都是通过一个比较来判断一系列操作
          • 如果ZWrite On,且当前深度值和深度缓冲区的值作比较,如果通过就写入深度,不通过就忽略深度
          • 当前深度值和深度缓冲区中的值做比较,如果通过就写入颜色缓冲区,不通过就不写入颜色缓冲区
      • 从书面概念上理解
        • 就是针对当前屏幕上(更准确的说是FrameBuffer)对应的像素点,将对象自身的深度值与当前深度缓冲区的深度值做比较,如果通过了,这个对象在该像素点才会将颜色写入颜色缓冲区
      • 从发展上看
          • 控制渲染顺序

            • 画家算法:

              • 这里是指油画的画法,也就是画一幅油画,是从远处开始画,然后近处的东西一点点叠加在上面
              • 存在的问题:例如一列物体,最前面的物体最大,站在正前面看只能看到最前面的物体,这样一来后边的就不用画了,不然就是性能浪费(OverDraw)。
            • Z-Buffer算法:
              • 通过深度缓冲区来控制渲染顺序
          • 控制Z-Buffer对深度的存储

            • 例如:什么时候更新深度缓冲区、什么时候使用深度缓冲区
            • 两个典型的功能:

              • Z Test
              • Z Write
          • 控制不同类型物体的渲染顺序

            • 透明物体
            • 不透明物体
            • 渲染队列
          • 减少OverDraw

            • Early-Z
            • Z-cull(优化手段)
            • Z-check(确认正确遮挡关系)
    • 原理和方法

      • Z-Buffer(深度缓冲区)

        • 和颜色缓冲区一样,在每个片段中存储了信息,并且通常和颜色缓冲有着一样的宽度和高度
          • 颜色缓冲区:
            • 就是最终在显示屏硬件上显示颜色的GPU显存区域了,这个缓冲区储存了每帧更新后的最终颜色值,图形流水线经过一系列测试,包括片段丢弃、颜色混合等,最终生成的像素颜色值就储存在这里,然后提交给显示硬件显示。
        • 深度缓冲是由窗口系统自动创建的,它会以16、24、32位float形式存储深度值。
          • //大部分系统中深度值是24位的
        • Z-Buffer中存储的是当前的深度信息,对于每个像素存储一个深度值。
          • 我们可以通过Z-Write 、Z-Test来调用Z-Buffer,来达到想要的渲染效果
      • Z Writer(深度写入)

        • 深度写入包括两种状态

          • ZWrite On
            • 当我们开启深度写入,物体被渲染时针对物体在屏幕(FrameBuffer)上每个像素的深度都写入到深度缓冲区。
          • ZWrite Off
            • 关闭深度写入状态,物体的深度就不会写入深度缓冲区。
        • 只有ZTest和ZWrite都可行的情况下才写入深度缓冲区
            • 除了ZWrite的是否写入深度缓冲区,更重要的是:是否通过深度测试,也就是Z-Test
            • 如果Z-Test都没通过,也就不会写入深度了。
            • 综上,ZWrite有On、Off两种情况;ZTest有通过、不通过两种情况,两者结合的四种情况如下:
      • Z-Test的比较函数
          • 默认情况下:

            • Z Write:On
            • Z Test:LEqual
            • 深度缓冲一开始为无穷大
      • Unity的渲染队列

        • Unity内置的几种渲染队列:
            • 按照渲染顺序从先到后排序,队列数越小,越先渲染;反之同理。
            • BUT

              • Unity中透明物体的渲染顺序:从后往前(类似画家算法,会造成OverDraw)
              • Unity中不透明物体的渲染顺序:从前往后
                • 也就是说深度小的先渲染,其次再渲染深度大的
        • Unity中设置渲染队列:

          • 语法:Tags { "Queue" = "渲染队列名"}
            • 默认是Geometry
          • 可以在shader的Inspector面板中查看渲染队列相关属性
      • 简述Early-Z技术

        • early

          • adv. 提前;提早;在早期;在初期
          • adj. 早期的;初期的;早先的;早到的
          • 三角形遍历之后、片元着色器(像素着色器)之前。
          • 传统的渲染管线中,ZTest是在Blending阶段,这时进行深度测试的话,所以对象的像素着色器都会计算一遍,没有性能提升,只是为了得到正确的效果,造成了大量的无用计算。(深度测试失败的片元是经过片元着色器计算的片元,也就是说:到在ZTest不通过而被抛弃,前边的计算就是无用功了)
          • Z-Cull是为了筛选片元达到性能优化的目的
          • Z-check是为了保证正确的遮挡关系。
      • 深度值

        • 模型在渲染管线中的几次空间变换
            • 最后通过一些投影映射变换到屏幕空间
    • 效果

      • 案例一

        • 三个正方体遮挡关系
        • shader

          • code
        • 在frame debug中查看渲染顺序
      • 案例二 X-Ray效果

          • 实现思路:
            • shader的多pass

              • pass0
                • X-Ray效果使用ZTest :Greater,关闭深度写入
              • pass1
                • 默认的渲染:LEqual、ZWrite On
        • shader

          • code

              • Cull back 是剔除背面,为了优化
              • Blend SrcAlpha One :由于有一个透明的效果,除了上边的,还需要一步Blend,来做透明度混合
      • 拓展
  • 参考资料

    • 《shader入门精要》
    • 《Unity ShaderLab 开发实战详解》
相关推荐
报错小能手19 分钟前
C++笔记(面向对象)RTTI操作符
开发语言·c++·笔记
CodeLongBear34 分钟前
计算机网络学习笔记 | 传输层核心知识点总结(DAY03,匠心制作)
笔记·学习·计算机网络
晓北斗NorSnow43 分钟前
机器学习核心算法与学习资源解析
学习·算法·机器学习
wdfk_prog1 小时前
[Linux]学习笔记系列 -- [kernel][time]tick
linux·笔记·学习
凯歌的博客2 小时前
python虚拟环境应用
linux·开发语言·python
峰顶听歌的鲸鱼2 小时前
9.OpenStack管理(三)
运维·笔记·分布式·openstack·学习方法
我命由我123453 小时前
Photoshop - Photoshop 工具栏(22)单行选框工具
学习·ui·职场和发展·求职招聘·职场发展·学习方法·photoshop
我在人间贩卖青春3 小时前
Linux基础
linux
立志成为大牛的小牛3 小时前
数据结构——三十七、关键路径(王道408)
数据结构·笔记·程序人生·考研·算法
大聪明-PLUS3 小时前
从 C 到 C++20 协程编写方法的演变。第一部分:函数 + 宏 = 协程
linux·嵌入式·arm·smarc