Reconstructing Position From Depth

需求: 根据当前像素的Depth计算出其View空间的Position

先说一种惯性思维的方法: 既然知道depth是怎么算出来的, 那么进行逆运算回去不就得到position了?

先说说depth是怎么出来的:

Vertex shader:

output.position = mul(input.postion, matWorldViewProject); output.depth.xy = output.position.zw;

Pixel shader(输出z/w):

return input.depth.x / input.depth.y;

那么, 逆运算回去就很直接了(input.uv是全屏矩形的纹理坐标):

float z = tex2D(DepthSampler, input.uv); // transform to projection space float x = input.uv.x * 2 - 1; float y = (1 - input.uv.y) * 2 - 1; float4 vProjectedPos = float4(x, y, z, 1); // transform to view space  float4 vPosition = mul(vProjectedPos , matInvProject); return (vPosition.xyz / vPosition.w);

那么这样做有什么缺点呢?

l z/w是非线性分布的, 经过RTT后再变换回去会有精度上的损失

l 计算量有点大, 要知道PS里的每个指令都是很宝贵的.

下面说说另一种非常快的算法, 而且也可以解决精度问题. 先看看摄像机视锥体的抽象形式:

从摄像机位置到远裁剪面发射一条射线, 那么, 对于可见的任意一点, 有这么个关系:

vPositionView = vViewRayDir * fLinearDepth;

其中, fLinearDepth代表规格化的Z, 它是线性分布的, 即:

fLinearDepth = vPositionView.z / fFarClipDist;

剩下的, 就是这个屏幕射线vViewRayDir从哪来的问题了.

我们知道, 在View空间, 摄像机位置是(0, 0, 0). 那么, 对于每条射线的方向, 等价于射线与远裁剪面的交点坐标. 即:

vViewRayDir = float3(fFarClipX, fFarClipY, fFarClipDist);

远裁剪面上的4个顶点坐标我们是可以算出来的, 就是Frustum中的四个顶点. 如果我们把这四个顶点坐标写入全屏矩形的顶点坐标中, 然后在VS中输出, 那么在PS中得到的就是已经插值好的射线方向了!

整理一下整个思路:

1. 把vPositionView.z / fFarClipDist输出到RTT, 这里因为是线性分布的, 在精度允许的前提下可以进行压缩

2. 从RTT里得到fLinearDepth, 从VS_OUTPUT出的寄存器里得到已经插值好的vViewRayDir.xy, vViewRayDir.z就是fFarClipDist, Position的重建只需要一句计算就可以得到:

vPositionView = vViewRayDir * fLinearDepth;

Reference(要翻墙): http://mynameismjp.wordpress.com/2009/03/10/reconstructing-position-from-depth/

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏数据魔术师

基础算法 | 关于图论中最小生成树(Minimum Spanning Tree)那些不可告人的秘密

最近双11又快到了 有女朋友的忙着帮女朋友清空购物车 有男朋友的忙着叫男朋友帮清购物车 而小编就比较牛逼了 小编沉迷学习,已经无法自拔。 那么今天小编又给大家带...

5075
来自专栏社区的朋友们

Steering Behaviors 详解

Steering Behaviors 意在使游戏中的AI个体具备真实的运动行为,通过对力的施加与整合,使游戏个体具备类生命体般的运动特征。

8781
来自专栏章鱼的慢慢技术路

Direct3D 11 Tutorial 6:Lighting_Direct3D 11 教程6:灯光

在之前的教程中,世界看起来很无聊,因为所有对象都以相同的方式点亮。 本教程将介绍简单照明的概念及其应用方法。 使用的技术将是朗伯照明。

802
来自专栏PPV课数据科学社区

【大数据问答】SPSS是如何做到发现数据质量问题,例如,如何发现缺失值?

SPSS是如何做到发现数据质量问题,例如,如何发现缺失值? (1)系统缺失值、空白值 每一个变量均有可能出现系统缺失或者空白,当数据量巨大时我们根本无法用眼睛...

4124
来自专栏深度学习自然语言处理

【概率笔记】条件概率这样学才快啦

比如,一个上学期间整天鬼混的学沫,根本就不好好学习,对于他而言,选择题的四个选项ABCD被他选取的概率就为1/4。而对于大学霸来说,题题都会,那么他选取每一个选...

883
来自专栏我和未来有约会

[Silverlight动画]转向行为 - 到达行为

到达行为在很多场合都可以被当作是寻找行为。实际上,它们之间的算法和处理方式都一样。唯一不同的是,在到达模式中,一辆机车在到达目标的某一距离时,会变成一种精确模式...

2066

组和分组卷积

考虑一个正方形。它是对称的吗?它是如何对称的?它有多少对称性?它有什么样的对称性?

30710
来自专栏ACM算法日常

最短路(Floyd算法的动态规划本质)- HDU 2544

Floyd–Warshall(简称Floyd算法)是一种著名的解决任意两点间的最短路径(All Paris Shortest Paths,APS...

2391
来自专栏MixLab科技+设计实验室

【图像处理篇】自动识别手写数字web应用05

往期的4篇已经把Docker+Keras+Flask+JS的全栈+深度学习介绍完整了: 自己动手做一个识别手写数字的web应用01 自己动手做一个识别手写数字的...

4376
来自专栏数据科学与人工智能

【陆勤践行】最流行的4个机器学习数据集

机器学习算法需要作用于数据,而数据的本质则决定了应用的机器学习算法是否合适,而数据的质量也会决定算法表现的好坏程度。所以会研究数据,会分析数据很重要。本文作为学...

21310

扫码关注云+社区

领取腾讯云代金券