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 开发实战详解》
相关推荐
小政同学3 小时前
【NFS故障】共享的文件无法执行
linux·运维·服务器
AI木马人4 小时前
3.【Prompt工程实战】如何设计一个可复用的Prompt系统?(避免每次手写提示词)
linux·服务器·人工智能·深度学习·prompt
lwf0061644 小时前
导数学习日记
学习·算法·机器学习
ch3nyuyu4 小时前
Ubuntu(乌班图)基础指令
linux·运维·网络
qeen874 小时前
【编程日记】现阶段总结
学习
minglie14 小时前
gcc编译器汇总
linux
daanpdf5 小时前
新视野大学英语视听说教程2第四版听力音频原文及答案
笔记
白菜欣6 小时前
Linux —《开发三件套:gcc/g++、gdb、make/Makefile 全解析》
linux·运维
senijusene6 小时前
基于 imx6ull平台按键驱动开发:input子系统+中断子系统+platform总线
linux·驱动开发
-Marks-6 小时前
【C++编程】STL简介 --- (是什么 | 版本发展历程 | 六大组件 | 重要性缺陷以及如何学习)
开发语言·c++·学习·stl·stl版本