世界位置的线性深度
Linear Depth to World Position
我有以下片段和顶点着色器。
HLSL代码
`
// 顶点着色器
//-------------------------------------------- ----------------------------------
void mainVP(
float4 position : POSITION,
out float4 outPos : POSITION,
out float2 outDepth : TEXCOORD0,
uniform float4x4 worldViewProj,
uniform float4 texelOffsets,
uniform float4 depthRange) //Passed as float4(minDepth, maxDepth,depthRange,1 / depthRange)
{
outPos = mul(worldViewProj, position);
outPos.xy += texelOffsets.zw * outPos.w;
outDepth.x = (outPos.z - depthRange.x)*depthRange.w;//value [0..1]
outDepth.y = outPos.w;
}
// Fragment shader
void mainFP( float2 depth: TEXCOORD0, out float4 result : COLOR) {
float finalDepth = depth.x;
result = float4(finalDepth, finalDepth, finalDepth, 1);
}
`
此着色器生成深度图。
然后必须使用此深度图来重建深度值的世界位置。我搜索了其他 post,但其中 none 似乎使用我正在使用的相同公式存储深度。唯一类似的post是下面的
因此,我很难使用深度图中的 x 和 y 坐标以及相应的深度来重建点。
我需要一些帮助来构建着色器以获得特定纹理坐标深度的世界视图位置。
你似乎没有在标准化你的深度。试试这个。在你的 VS 中,执行:
outDepth.xy = outPos.zw;
而在你的 PS 中渲染深度,你可以这样做:
float finalDepth = depth.x / depth.y;
这是一个函数,可以从深度纹理中提取特定像素的 view-space 位置。我假设您正在渲染屏幕对齐四边形并在像素着色器中执行 position-extraction。
// Function for converting depth to view-space position
// in deferred pixel shader pass. vTexCoord is a texture
// coordinate for a full-screen quad, such that x=0 is the
// left of the screen, and y=0 is the top of the screen.
float3 VSPositionFromDepth(float2 vTexCoord)
{
// Get the depth value for this pixel
float z = tex2D(DepthSampler, vTexCoord);
// Get x/w and y/w from the viewport position
float x = vTexCoord.x * 2 - 1;
float y = (1 - vTexCoord.y) * 2 - 1;
float4 vProjectedPos = float4(x, y, z, 1.0f);
// Transform by the inverse projection matrix
float4 vPositionVS = mul(vProjectedPos, g_matInvProjection);
// Divide by w to get the view-space position
return vPositionVS.xyz / vPositionVS.w;
}
更高级的方法减少了涉及的计算数量,但涉及使用 view frustum and a special way of rendering the screen-aligned quad, see here。
我有以下片段和顶点着色器。
HLSL代码 ` // 顶点着色器 //-------------------------------------------- ----------------------------------
void mainVP(
float4 position : POSITION,
out float4 outPos : POSITION,
out float2 outDepth : TEXCOORD0,
uniform float4x4 worldViewProj,
uniform float4 texelOffsets,
uniform float4 depthRange) //Passed as float4(minDepth, maxDepth,depthRange,1 / depthRange)
{
outPos = mul(worldViewProj, position);
outPos.xy += texelOffsets.zw * outPos.w;
outDepth.x = (outPos.z - depthRange.x)*depthRange.w;//value [0..1]
outDepth.y = outPos.w;
}
// Fragment shader
void mainFP( float2 depth: TEXCOORD0, out float4 result : COLOR) {
float finalDepth = depth.x;
result = float4(finalDepth, finalDepth, finalDepth, 1);
}
`
此着色器生成深度图。
然后必须使用此深度图来重建深度值的世界位置。我搜索了其他 post,但其中 none 似乎使用我正在使用的相同公式存储深度。唯一类似的post是下面的
因此,我很难使用深度图中的 x 和 y 坐标以及相应的深度来重建点。
我需要一些帮助来构建着色器以获得特定纹理坐标深度的世界视图位置。
你似乎没有在标准化你的深度。试试这个。在你的 VS 中,执行:
outDepth.xy = outPos.zw;
而在你的 PS 中渲染深度,你可以这样做:
float finalDepth = depth.x / depth.y;
这是一个函数,可以从深度纹理中提取特定像素的 view-space 位置。我假设您正在渲染屏幕对齐四边形并在像素着色器中执行 position-extraction。
// Function for converting depth to view-space position
// in deferred pixel shader pass. vTexCoord is a texture
// coordinate for a full-screen quad, such that x=0 is the
// left of the screen, and y=0 is the top of the screen.
float3 VSPositionFromDepth(float2 vTexCoord)
{
// Get the depth value for this pixel
float z = tex2D(DepthSampler, vTexCoord);
// Get x/w and y/w from the viewport position
float x = vTexCoord.x * 2 - 1;
float y = (1 - vTexCoord.y) * 2 - 1;
float4 vProjectedPos = float4(x, y, z, 1.0f);
// Transform by the inverse projection matrix
float4 vPositionVS = mul(vProjectedPos, g_matInvProjection);
// Divide by w to get the view-space position
return vPositionVS.xyz / vPositionVS.w;
}
更高级的方法减少了涉及的计算数量,但涉及使用 view frustum and a special way of rendering the screen-aligned quad, see here。