概述

在渲染管线中的顶点变换中,介绍了顶点在各个坐标空间的变换。变换到最后,是屏幕坐标空间。在OpenGL中,屏幕空间坐标的Z值即是深度缓冲中的深度值。深度缓冲包含了一个介于0.0和1.0之间的深度值,它将会与观察者视角所看见的场景中所有物体的z值进行比较。本文将介绍深度值的计算,以及从深度值反向计算出相机空间中的顶点的Z值。

深度值计算

在渲染管线中的顶点变换中,计算得到了透视投影矩阵:
Mpersp=[2nr−l0l+rl−r002nt−bb+tb−t000f+nf−n2nfn−f0010]M_{persp} = \begin{bmatrix} \frac{2n}{r-l} & 0 & \frac{l+r}{l-r} & 0 \\ 0 & \frac{2n}{t-b} & \frac{b+t}{b-t} & 0 \\ 0 & 0 & \frac{f+n}{f-n} & \frac{2nf}{n-f} \\ 0 & 0 & 1 & 0 \\ \end{bmatrix} Mpersp​=⎣⎢⎢⎡​r−l2n​000​0t−b2n​00​l−rl+r​b−tb+t​f−nf+n​1​00n−f2nf​0​⎦⎥⎥⎤​
同时,也得到了视口变换矩阵:
Mviewport=[w200w20h20h20012120001]M_{viewport} = \begin{bmatrix} \frac{w}{2} & 0 & 0 & \frac{w}{2} \\ 0 & \frac{h}{2} & 0 & \frac{h}{2} \\ 0 & 0 & \frac{1}{2} & \frac{1}{2} \\ 0 & 0 & 0 & 1 \\ \end{bmatrix} Mviewport​=⎣⎢⎢⎡​2w​000​02h​00​0021​0​2w​2h​21​1​⎦⎥⎥⎤​
首先,根据透视矩阵,计算NDC空间的Z值。这里,相机空间中的坐标经过透视矩阵变换后,还要进行齐次除法,才能得到NDC空间中的坐标。
(xclipyclipzclipwclip)=Mpersp(xeyeyeyezeyeweye)\begin{pmatrix} x_{clip} \\ y_{clip} \\ z_{clip} \\ w_{clip} \\ \end{pmatrix} = M_{persp} \begin{pmatrix} x_{eye} \\ y_{eye} \\ z_{eye} \\ w_{eye} \\ \end{pmatrix} ⎝⎜⎜⎛​xclip​yclip​zclip​wclip​​⎠⎟⎟⎞​=Mpersp​⎝⎜⎜⎛​xeye​yeye​zeye​weye​​⎠⎟⎟⎞​

(xndcyndczndc)=(xclipwclipyclipwclipzclipwclip)\begin{pmatrix} x_{ndc} \\ y_{ndc} \\ z_{ndc} \\ \end{pmatrix} = \begin{pmatrix} \frac{x_{clip}}{w_{clip}} \\ \frac{y_{clip}}{w_{clip}} \\ \frac{z_{clip}}{w_{clip}} \\ \end{pmatrix} ⎝⎛​xndc​yndc​zndc​​⎠⎞​=⎝⎜⎛​wclip​xclip​​wclip​yclip​​wclip​zclip​​​⎠⎟⎞​

由此,可以得出:
KaTeX parse error: No such environment: equation at position 8: \begin{̲e̲q̲u̲a̲t̲i̲o̲n̲}̲ \begin{aligned…
根据上述公式,可以得出:
zeye=2nf(f+n)−zndc(f−n)(2)z_{eye} = \frac{2nf}{(f+n)-z_{ndc}(f-n)} \tag{2} zeye​=(f+n)−zndc​(f−n)2nf​(2)
根据视口变换矩阵,可以得出:
zwin=12zndc+12(3)z_{win} = \frac{1}{2}z_{ndc}+\frac{1}{2} \tag{3} zwin​=21​zndc​+21​(3)

将(1)\left(1\right)(1)带入(3)\left(3\right)(3),可以得到:
zwin=12(zndc+1)=12(f+nf−n+−2nfzeye(f−n)+1)=f−nfzeyef−n=1n−1zeye1n−1f\begin{aligned} z_{win} &= \frac{1}{2}(z_{ndc}+1) \\ &=\frac{1}{2}(\frac{f+n}{f-n}+\frac{-2nf}{z_{eye}(f-n)} + 1) \\ &=\frac{f-\frac{nf}{z_{eye}}}{f-n} \\ &= \frac{\frac{1}{n}-\frac{1}{z_{eye}}}{\frac{1}{n}-\frac{1}{f}} \end{aligned} zwin​​=21​(zndc​+1)=21​(f−nf+n​+zeye​(f−n)−2nf​+1)=f−nf−zeye​nf​​=n1​−f1​n1​−zeye​1​​​

即:
zwin=1n−1zeye1n−1f(4)z_{win} = \frac{\frac{1}{n}-\frac{1}{z_{eye}}}{\frac{1}{n}-\frac{1}{f}} \tag{4} zwin​=n1​−f1​n1​−zeye​1​​(4)

到这一步,即可以求得屏幕空间中的深度。

在Learn OpenGL CN学习过的,可能对深度测试这一节的内容有些印象。它得到的深度值的公式是:
Fdepth=1/z−1/near1/far−1/nearF_{depth} = \frac{1/z - 1/near}{1/far - 1/near} Fdepth​=1/far−1/near1/z−1/near​
跟(4)\left(4\right)(4)式对比,发现有些不一样,这是怎么回事呢?

这里要注意,本文定义的nnn、fff和zeyez_{eye}zeye​是实际的坐标值,是负的。而深度测试文中,定义的nearnearnear、farfarfar代表了近平面和远平面,而zzz代表了近、远平面之间的值,它们都是正的。将n=−nearn=-nearn=−near、f=−farf=-farf=−far、zeye=−zz_{eye}=-zzeye​=−z代入(4)\left(4\right)(4)式,可得:
Fdepth=zwin=1n−1zeye1n−1f=1−near−1−z1−near−1−far=1z−1near1far−1near\begin{aligned} F_{depth} &= z_{win} \\ &= \frac{\frac{1}{n}-\frac{1}{z_{eye}}}{\frac{1}{n}-\frac{1}{f}} \\ &= \frac{\frac{1}{-near}-\frac{1}{-z}}{\frac{1}{-near}-\frac{1}{-far}} \\ &= \frac{\frac{1}{z}-\frac{1}{near}}{\frac{1}{far}-\frac{1}{near}} \end{aligned} Fdepth​​=zwin​=n1​−f1​n1​−zeye​1​​=−near1​−−far1​−near1​−−z1​​=far1​−near1​z1​−near1​​​

深度值的线性可视化

经过上面的推导,我们得出了深度值的计算公式。

现在,反过来,我们知道了屏幕空间中的深度值,怎么求出相机空间中的深度值呢?

首先,根据(3)\left(3\right)(3),可以推导出:
zndc=2zwin−1z_{ndc} = 2z_{win}-1 zndc​=2zwin​−1
对于公式2,得出的是实际坐标的ZZZ值。为了和OpenGL中的定义统一,也将nearnearnear、farfarfar和zzz代入公式(2)\left(2\right)(2),可以得到:
zeye=2(−near)(−far)((−far)+(−near))−zndc((−far)−(−near))=2nearfar−(far+near)−zndc(near−far)(5)\begin{aligned} z_{eye} &= \frac{2(-near)(-far)}{((-far)+(-near))-z_{ndc}((-far)-(-near))} \\ &= \frac{2nearfar}{-(far+near)-z_{ndc}(near-far)} \\ \end{aligned} \tag{5} zeye​​=((−far)+(−near))−zndc​((−far)−(−near))2(−near)(−far)​=−(far+near)−zndc​(near−far)2nearfar​​(5)
在深度测试这一节中,得出的公式是:
floatlinearDepth=(2.0∗near∗far)/(far+near−z∗(far−near));float \quad linearDepth = (2.0 * near * far) / (far + near - z * (far - near)); floatlinearDepth=(2.0∗near∗far)/(far+near−z∗(far−near));
对比发现,跟公式(5)\left(5\right)(5)有些不一样。这是因为,linearDepthlinearDepthlinearDepth求出的是顶点距离相机的距离,是正值。而zeyez_{eye}zeye​是顶点的实际坐标,是负值,将zeyez_{eye}zeye​取反,即可得到linearDepthlinearDepthlinearDepth。
linearDepth=−zeye=2nearfar(far+near)−zndc(far−near)\begin{aligned} linearDepth &= -z_{eye} \\ &= \frac{2nearfar}{(far+near)-z_{ndc}(far-near)} \end{aligned} linearDepth​=−zeye​=(far+near)−zndc​(far−near)2nearfar​​
至此,推导完成。

参考

  • [1] 深度测试
  • [2] 渲染管线中的顶点变换

深度缓冲中的深度值计算及可视化相关推荐

  1. 深度学习中7种最优化算法的可视化与理解

    作者丨小小鱼@知乎 来源丨https://zhuanlan.zhihu.com/p/41799394 本文旨在优化一维函数,实际上模型参数有数百万维以上,差距很大,因此本文最好作为辅助法的理解,而非对 ...

  2. 深度学习中的深度前馈网络简介

     几乎所有的深度学习算法都可以被描述为一个相当简单的配方:特定的数据集.代价函数.优化过程和模型. 在大多数情况下,优化算法可以定义为求解代价函数梯度为零的正规方程.我们可以替换独立于其它组件的大多数 ...

  3. 计算机视觉中的深度深度学习中的深度

    关于深度 Deep learning Depth estimation Deep Depth不一样的 Depth estimation指的是估计图片中每个像素点到相机的距离,或者说每个像素点的深度. ...

  4. 深度学习中的深度信念神经网络

    深度信念神经网络(DBNN)是深度学习的最早应用之一.DBNN就是具有多个层的常规信念神经网络.Neil在1992年提出的信念神经网络不同于常规的FFNN.Hinton(2007)将DBNN描述为&q ...

  5. 深度相机中提取深度信息

    OpenCV-apps opencv函数的应用 cv_bridge 连接ros和cv

  6. 深度学习中的图像增强

    引言 图像增强是我们在深度学习领域中绕不开的一个话题,本文我们将讨论什么是图像增强,并在三个不同的 python 库中实现它,即 Keras.Pytorch 和 augmentation(专门用于图像 ...

  7. 项目管理之项目的挣值计算问题

    本文将通过详细讲解历年的四道挣值计算真题来帮助掌握项目管理中的挣值计算问题. 项目管理专业术语与计算公式汇总 真题一:挣值计算(2010.11) 真题二:进度与挣值计算(2012.05) 真题三:进度 ...

  8. 深度学习算法/模型——深度学习基础(持续更新)

    深度学习基本概念 0. 深度学习的起源和发展 1. 神经网络基础(概念) 1.0 基础 神经元 激活函数 网络结构 1.1 前馈神经网络 全连接神经网络(FCNN) 应用到机器学习 参数学习 反向传播 ...

  9. 【机器学习算法面试题】四.深度神经网络中激活函数有哪些?

    欢迎订阅本专栏:<机器学习算法面试题> 订阅地址:https://blog.csdn.net/m0_38068876/category_11810806.html [机器学习算法面试题]一 ...

最新文章

  1. mybatis配置文件解析
  2. 易观于揚:数据分析是人工智能的基础构件
  3. php 类似微信下拉菜单,微信小程序实现下拉框(附代码)
  4. css选择器权重排序_CSS选择器的权重与优先规则
  5. 数据库里账号的密码,这样存放最安全!
  6. 智能电视直播软件_速度快,节目多,高清网络电视直播
  7. 小米12 mini曝光:骁龙898加持
  8. HTTP和HTTPS的区别及HTTPS加密算法
  9. html dom怎么写,HTML DOM 属性
  10. html取php值,使用PHP从HTML中提取值
  11. 小峰servlet/jsp(2)
  12. python计算圆环的面积_基于Python制作美观动态圆环图、饼图
  13. 查看iOS App的bundleId
  14. Maven cmd 打包命令
  15. 电脑怎么把大量音频合并
  16. 双因素认证令牌_安全令牌:防止双因素令牌认证攻击
  17. Excel如何快速划分等级或成绩评级
  18. 部署k8s时ssh端口不是22导致创建ssh session failed问题
  19. gabor滤波器 opencv 实现
  20. 工具推荐 10款移动界面原型设计工具

热门文章

  1. 最新安徽安全员B考试选择题预测题库
  2. 开关电源基础知识(PWM与PFM)
  3. html页面使用var变量,html元素:var标签的使用方法及作用
  4. 赛扬处理器_两款还未官宣的10代赛扬出现在海外电商平台,赛扬首次拥有4MB三级缓存...
  5. 重磅综述|Nat Rev Gastroenterol Hepatol:人类胃肠道中的产甲烷古菌
  6. 【计算机系统】如何在阿里云ECS服务器上定时执行Python脚本?
  7. 落地零售智能体,百联集团全力打造面向未来的数字化商业体
  8. Cannot construct instance of `com.*` (although at least one Creator exists): cannot deserializ
  9. 【数据库迁移系列】从MySQL到openGauss的数据库对象迁移实践
  10. 第2章第6节:艺术字体的下载和安装和嵌入 [PowerPoint精美幻灯片实战教程]