专栏首页逍遥剑客的游戏开发Reconstructing Position From Depth

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 条评论
登录 后参与评论

相关文章

  • VR中对带有约束的物理对象的交互

    逍遥剑客
  • LowPloy风格的模型导入

    逍遥剑客
  • 从Native到Web(四), NaCl学习笔记: 物理引擎

    逍遥剑客
  • 如何在Ubuntu 16.04上为用户目录设置vsftpd

    FTP是文件传输协议的缩写,是一种曾经广泛用于在客户端和服务器之间移动文件的网络协议。它已被更快,更安全,更方便的文件传输方式所取代。许多休闲网民希望直接用ht...

    GeekZ
  • 【SAP ABAP系列】一个完整的SAP的Abap例子(idoc,edi文件的相互转换)

    matinal
  • 一个完整的SAP的Abap例子(idoc,edi文件的相互转换)

    matinal
  • BlackOasis APT 和利用 0day 漏洞的新目标攻击

    原文地址:https://securelist.com/blackoasis-apt-and-new-targeted-attacks-leveraging-z...

    Seebug漏洞平台
  • 编译libjson_7.6.1

    编译libjson_7.6.1可能会遇到如下的问题: makefile:180: Extraneous text after `else' directive...

    一见
  • JS方法 - 字符串处理函数封装汇总 (更新中...)

    可返回字符串固定位置的字符的Unicode编码,这个返回值是0-65535之间的整数,如果值<=255时为英文,反之为中文。

    xing.org1^
  • java字符串对象的存储机制

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/gdutxiaoxu/article/details/...

    用户2965908

扫码关注云+社区

领取腾讯云代金券