我试图在XNA 4.0中渲染深度纹理。我几次读了几本不同的教程,真的无法理解我做错了什么。
深度着色器:
float4x4 WVPMatrix;
struct VertexShaderOutput
{
float4 Position : position0;
float Depth : texcoord0;
};
VertexShaderOutput VertexShader1(float4 pPosition : position0)
{
VertexShaderOutput output;
output.Position = mul(pPosition, WVPMatrix);
output.Depth.x = 1 - (output.Position.z / output.Position.w);
return output;
}
float4 PixelShader1(VertexShaderOutput pOutput) : color0
{
return float4(pOutput.Depth.x, 0, 0, 1);
}
technique Technique1
{
pass Pass1
{
AlphaBlendEnable = false;
ZEnable = true;
ZWriteEnable = true;
VertexShader = compile vs_2_0 VertexShader1();
PixelShader = compile ps_2_0 PixelShader1();
}
}
图:
this.depthRenderTarget = new RenderTarget2D(
this.graphicsDevice,
this.graphicsDevice.PresentationParameters.BackBufferWidth,
this.graphicsDevice.PresentationParameters.BackBufferHeight);
...
public void Draw(GameTime pGameTime, Camera pCamera, Effect pDepthEffect, Effect pOpaqueEffect, Effect pNotOpaqueEffect)
{
this.graphicsDevice.SetRenderTarget(this.depthRenderTarget);
this.graphicsDevice.Clear(Color.CornflowerBlue);
this.DrawChunksDepth(pGameTime, pCamera, pDepthEffect);
this.graphicsDevice.SetRenderTarget(null);
this.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Opaque, SamplerState.PointClamp, null, null);
this.spriteBatch.Draw(this.depthRenderTarget, Vector2.Zero, Color.White);
this.spriteBatch.End();
}
private void DrawChunksDepth(GameTime pGameTime, Camera pCamera, Effect pDepthEffect)
{
// ...
this.graphicsDevice.RasterizerState = RasterizerState.CullClockwise;
this.graphicsDevice.DepthStencilState = DepthStencilState.Default;
// draw mesh with pDepthEffect
}
正如我看到output.Position.z总是等于output.Position.w,但为什么?
答案 0 :(得分:0)
有几种深度定义可能有用。以下是其中一些。
最简单的是相机空间中的z坐标(即在应用世界和视图变换之后)。它通常与世界坐标系具有相同的单位,并且是线性的。但是,它始终与视图方向平行测量。这意味着左/右和上/下移动不会改变距离,因为您保持在同一平面(平行于znear / zfar剪裁平面)。稍微变化是z/far
,它只是将值缩放到[0,1]间隔。
如果需要实际距离(在欧几里德度量标准中),则必须在着色器中计算它们。如果您只需要粗略值,则顶点着色器就足够了。如果值应该准确,请在像素着色器中执行此操作。基本上,您需要在应用世界和视图变换后计算位置矢量的长度。单位等于世界空间单位。
深度缓冲深度是非线性的,并针对深度缓冲进行了优化。这是投影变换(以及跟随w-clip)返回的深度。近剪裁平面被映射到深度为0,远剪裁平面被映射到深度为1.如果沿视图方向更改非常近的像素的位置,则深度值的变化远远大于远像素。同样感动。这是因为在近像素处的显示误差(由于浮点不精确)比在远像素处更明显。该深度也与视图方向平行测量。