根据深度图重建物体位置

转载请注明处: http://blog.csdn.net/tianhai110

根据深度图重建物体位置

第一种方法 存储 投影后z/w,并结合x/w,y/w, 通过 乘以投影矩阵的逆矩阵 再除以w得到物体的位置;

// 深度pass的顶点shader代码: output.vPositionCS = mul(input.vPositionOS, g_matWorldViewProj); output.vDepthCS.xy = output.vPositionCS.zw; // 深度pass的像素 shader 代码 (输出 z/w): return input.vDepthCS.x / input.vDepthCS.y;    

 

另一个延时渲染shader

 

// 功能:把深度值转换成视图空间的顶点位置 // vTexCoord 是一个全屏四边形的纹理坐标,x=0是屏幕的左边, y=0是屏幕的上边; float3 VSPositionFromDepth(float2 vTexCoord) { // 获取这个像素的深度值 float z = tex2D(DepthSampler, vTexCoord); // 根据视口的位置获取x/w和y/w float x = vTexCoord.x * 2 - 1; float y = (1 - vTexCoord.y) * 2 - 1; float4 vProjectedPos = float4(x, y, z, 1.0f); // 乘以投影矩阵的逆矩阵 float4 vPositionVS = mul(vProjectedPos, g_matInvProjection); // 除以w来获取顶点的位置 return vPositionVS.xyz / vPositionVS.w; }   

第二种方法:存储归一化的视图空间的z来作为我们的深度。 由于视图空间的深度是线性的,这就意味着我们能够获得均匀的分布,而不必投影和逆投影,来还原顶点的位置。 我们只需要通过该深度值,乘以一条指向视锥体远截面的射线,就能够重建顶点的位置。

渲染线性深度

void DepthVS( in float4 in_vPositionOS : POSITION, out float4 out_vPositionCS : POSITION, out float out_fDepthVS : TEXCOORD0 ) { // 计算出顶点在view空间和clip空间的位置 float4x4 matWorldView = mul(g_matWorld, g_matView); float4 vPositionVS = mul(in_vPositionOS, matWorldView); out_vPositionCS = mul(vPositionVS, g_matProj); out_fDepthVS = vPositionVS.z; } float4 DepthPS(in float in_fDepthVS : TEXCOORD0) : COLOR0 { // z值 取反并除以远截面的距离(以便深度值位于[0,1]之间) //(如果是左手坐标系 不要负号) float fDepth = -in_fDepthVS/g_fFarClip; return float4(fDepth, 1.0f, 1.0f, 1.0f); }   

延时shader来重建顶点位置

 

//渲染一个全屏的四边形,顶点shader如下: void QuadVS ( in float3 in_vPositionOS : POSITION, in float3 in_vTexCoordAndCornerIndex : TEXCOORD0, out float4 out_vPositionCS : POSITION, out float2 out_vTexCoord : TEXCOORD0, out float3 out_vFrustumCornerVS : TEXCOORD1 ) { // 偏移半个像素的位置 out_vPositionCS.x = in_vPositionOS.x - (1.0f/g_vOcclusionTextureSize.x); out_vPositionCS.y = in_vPositionOS.y + (1.0f/g_vOcclusionTextureSize.y); out_vPositionCS.z = in_vPositionOS.z; out_vPositionCS.w = 1.0f; // 传递纹理坐标 和 视锥体顶叫位置。 这些顶点位置是经过插值的,以便像素shader能够通过射线来查询顶点的位置 out_vTexCoord = in_vTexCoordAndCornerIndex.xy; out_vFrustumCornerVS = g_vFrustumCornersVS[in_vTexCoordAndCornerIndex.z]; } // 像素shader:用于重建viewSpace下的位置 float3 VSPositionFromDepth(float2 vTexCoord, float3 vFrustumRayVS) { float fPixelDepth = tex2D(DepthSampler, vTexCoord).r; return fPixelDepth * vFrustumRayVS; }   

 g_vFrustumCornersVS 为视锥体远截面上的四个顶点。

你可能感兴趣的:(根据深度图重建物体位置)