根据深度图重建物体位置

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

[c-sharp]  view plain copy
  1. // 深度pass的顶点shader代码:  
  2. output.vPositionCS = mul(input.vPositionOS, g_matWorldViewProj);  
  3. output.vDepthCS.xy = output.vPositionCS.zw;   
  4.   
  5. // 深度pass的像素 shader 代码 (输出 z/w):  
  6. return input.vDepthCS.x / input.vDepthCS.y;  
   

 

另一个延时渲染shader

 

[c-sharp]  view plain copy
  1. // 功能:把深度值转换成视图空间的顶点位置  
  2. // vTexCoord 是一个全屏四边形的纹理坐标,x=0是屏幕的左边, y=0是屏幕的上边;  
  3. float3 VSPositionFromDepth(float2 vTexCoord)  
  4. {  
  5.     // 获取这个像素的深度值  
  6.     float z = tex2D(DepthSampler, vTexCoord);  
  7.   
  8.     // 根据视口的位置获取x/w和y/w  
  9.     float x = vTexCoord.x * 2 - 1;  
  10.     float y = (1 - vTexCoord.y) * 2 - 1;  
  11.   
  12.     float4 vProjectedPos = float4(x, y, z, 1.0f);  
  13.   
  14.     // 乘以投影矩阵的逆矩阵  
  15.     float4 vPositionVS = mul(vProjectedPos, g_matInvProjection);    
  16.   
  17.     // 除以w来获取顶点的位置  
  18.     return vPositionVS.xyz / vPositionVS.w;  
  19. }  
  

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

渲染线性深度

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

延时shader来重建顶点位置

 

[c-sharp]  view plain copy
  1. //渲染一个全屏的四边形,顶点shader如下:  
  2. void QuadVS (     in float3 in_vPositionOS           : POSITION,  
  3.               in float3 in_vTexCoordAndCornerIndex       : TEXCOORD0,  
  4.               out float4 out_vPositionCS              : POSITION,  
  5.               out float2 out_vTexCoord        : TEXCOORD0,  
  6.               out float3 out_vFrustumCornerVS         : TEXCOORD1      )  
  7. {  
  8.       // 偏移半个像素的位置  
  9.        out_vPositionCS.x = in_vPositionOS.x - (1.0f/g_vOcclusionTextureSize.x);  
  10.        out_vPositionCS.y = in_vPositionOS.y + (1.0f/g_vOcclusionTextureSize.y);  
  11.        out_vPositionCS.z = in_vPositionOS.z;  
  12.        out_vPositionCS.w = 1.0f;  
  13.   
  14.      // 传递纹理坐标 和 视锥体顶叫位置。 这些顶点位置是经过插值的,以便像素shader能够通过射线来查询顶点的位置  
  15.        out_vTexCoord = in_vTexCoordAndCornerIndex.xy;  
  16.        out_vFrustumCornerVS = g_vFrustumCornersVS[in_vTexCoordAndCornerIndex.z];  
  17. }  
  18.   
  19. // 像素shader:用于重建viewSpace下的位置  
  20. float3 VSPositionFromDepth(float2 vTexCoord, float3 vFrustumRayVS)  
  21. {  
  22.        float fPixelDepth = tex2D(DepthSampler, vTexCoord).r;  
  23.        return fPixelDepth * vFrustumRayVS;  
  24. }  
  

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值