从此网站:http://www.catalinzima.com/?page_id=14
我一直对如何计算深度图感到困惑。
顶点着色器函数按如下方式计算位置:
VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
VertexShaderOutput output;
float4 worldPosition = mul(input.Position, World);
float4 viewPosition = mul(worldPosition, View);
output.Position = mul(viewPosition, Projection);
output.TexCoord = input.TexCoord; //pass the texture coordinates further
output.Normal =mul(input.Normal,World); //get normal into world space
output.Depth.x = output.Position.z;
output.Depth.y = output.Position.w;
return output;
}
什么是output.Position.z和output.Position.w?我不确定这背后的数学。
在像素着色器中有这一行:output.Depth = input.Depth.x / input.Depth.y;
那么output.Depth是output.Position.z / outputPOsition.w?我们为什么要这样做?
最后在点光着色器(http://www.catalinzima.com/?page_id=55)中将此输出转换为代码所在的位置:
//read depth
float depthVal = tex2D(depthSampler,texCoord).r;
//compute screen-space position
float4 position;
position.xy = input.ScreenPosition.xy;
position.z = depthVal;
position.w = 1.0f;
//transform to world space
position = mul(position, InvertViewProjection);
position /= position.w;
我再也不理解这一点。我有点看到为什么我们使用InvertViewProjection,因为我们先前乘以视图投影,但整个z和现在w等于1,之后整个位置除以w会让我感到困惑。
答案 0 :(得分:3)
要完全理解这一点,您需要了解支持3D变换的代数是如何工作的。 SO并没有真正帮助(或者我不知道如何使用它)来进行矩阵数学运算,所以它必须没有花哨的公式。以下是一些高级别的解释:
如果你仔细观察,你会注意到发生在顶点位置(从模型到世界到视图到剪辑坐标)的所有变换都恰好使用4D向量。那就对了。 4D。为什么,当我们生活在3D世界中?因为在该4D表示中,我们通常想要对顶点进行的所有变换都可表示为矩阵乘法。如果我们保持3D表示,这不的情况。矩阵乘法是GPU擅长的。
3D中的顶点与4D中的对应点是什么?这是它变得有趣的地方。 (x, y, z)
点对应于行(a.x, a.y, a.z, a)
。我们可以抓住这一行上的任何一点来进行我们需要的数学计算,我们通常选择最简单的一个,a=1
(这样,我们不需要进行任何乘法,只需设置w=1
)
所以这几乎可以解答你所看到的所有数学问题。为了在4D中投射3D点,我们设置w = 1,从4D矢量中获取一个组件,我们想要与3D中的标准尺寸进行比较,我们必须将该组件除以w。
如果您想深入了解,此坐标系称为homogeneous coordinates
。