我正在XNA 4.0中实现一个后处理着色器。我意识到原始图片(场景渲染器的输出)移动了一小段距离。当我尝试实现MotionBlur效果时,它变得非常明显。看图像。场景渲染器的输出在中心是一个清晰的黄色十字。应用MotionBlur后,图像变得模糊(我没有在场景中移动任何东西,因此黄色十字应该像原始十字一样清晰)。我很困惑。谁能帮我?感谢。
(好吧,我到目前为止无法上传图片......)
以下是MotionBlur计划的代码片段:
protected void CreateQuad() {
m_vertex = new VertexPositionTexture[4];
m_vertex[0] = new VertexPositionTexture(
new Vector3(1, 1, 1), new Vector2(1, 0));
m_vertex[1] = new VertexPositionTexture(
new Vector3(1, -1, 1), new Vector2(1, 1));
m_vertex[2] = new VertexPositionTexture(
new Vector3(-1, 1, 1), new Vector2(0, 0));
m_vertex[3] = new VertexPositionTexture(
new Vector3(-1, -1, 1), new Vector2(0, 1));
m_vertexBuffer = new VertexBuffer(
m_game.GraphicsDevice,
typeof(VertexPositionTexture),
4,
BufferUsage.None);
m_vertexBuffer.SetData<VertexPositionTexture>(m_vertex);
}
protected void CreateRenderTarget() {
m_color = new RenderTarget2D(m_game.GraphicsDevice,
m_game.GraphicsDevice.PresentationParameters.BackBufferWidth,
m_game.GraphicsDevice.PresentationParameters.BackBufferHeight);
m_accColorRead = new RenderTarget2D(
m_game.GraphicsDevice,
m_game.GraphicsDevice.PresentationParameters.BackBufferWidth,
m_game.GraphicsDevice.PresentationParameters.BackBufferHeight);
ClearRenderTargetContent(m_accColorRead);
m_accColorWrite = new RenderTarget2D(
m_game.GraphicsDevice,
m_game.GraphicsDevice.PresentationParameters.BackBufferWidth,
m_game.GraphicsDevice.PresentationParameters.BackBufferHeight);
}
public void DoRender(GameTime _gameTime, DebugScene _debugScene) {
m_game.GraphicsDevice.SetRenderTarget(m_color);
m_game.GraphicsDevice.Clear(Color.Blue);
_debugScene.DoRender(_gameTime);
m_game.GraphicsDevice.SetRenderTarget(null);
m_effect.CurrentTechnique = m_effect.Techniques["Main"];
// write to acc
m_game.GraphicsDevice.SetRenderTarget(m_accColorWrite);
m_effect.Parameters["ColorMap"].SetValue((Texture2D)m_color);
m_effect.Parameters["AccColorMap"].SetValue((Texture2D)m_accColorRead);
m_effect.Parameters["gBlurIntensity"].SetValue(0.9f);
m_effect.CurrentTechnique.Passes["Blur"].Apply();
m_game.GraphicsDevice.Clear(Color.Black);
DrawQuad();
m_game.GraphicsDevice.SetRenderTarget(null);
// output
m_game.GraphicsDevice.Clear(Color.Black);
m_effect.Parameters["ColorMap"].SetValue((Texture2D)m_accColorWrite);
m_effect.CurrentTechnique.Passes["Final"].Apply();
DrawQuad();
// swap
RenderTarget2D tmp = m_accColorRead;
m_accColorRead = m_accColorWrite;
m_accColorWrite = tmp;
}
以下是MotionBlur着色器的代码:
texture ColorMap;
sampler ColorMapSampler = sampler_state
{
Texture = <ColorMap>;
MinFilter = Linear;
MagFilter = Linear;
MipFilter = Linear;
AddressU = Clamp;
AddressV = Clamp;
};
texture AccColorMap;
sampler AccColorMapSampler = sampler_state
{
Texture = <AccColorMap>;
MinFilter = Linear;
MagFilter = Linear;
MipFilter = Linear;
AddressU = Clamp;
AddressV = Clamp;
};
float gBlurIntensity;
struct VS_OUT
{
float4 Pos : POSITION;
float2 Tex : TEXCOORD0;
};
VS_OUT VS(float4 pos : POSITION, float2 tex : TEXCOORD0)
{
VS_OUT Out = (VS_OUT)0;
Out.Pos = pos;
return Out;
}
float4 PS(VS_OUT IN) : COLOR
{
float4 color = tex2D(ColorMapSampler, IN.Tex);
float4 accColor = tex2D(AccColorMapSampler, IN.Tex);
return lerp(color, accColor, gBlurIntensity);
}
float4 PS_Final(VS_OUT IN) : COLOR
{
return tex2D(ColorMapSampler, IN.Tex);
}
technique Main
{
pass Blur
{
VertexShader = compile vs_2_0 VS();
ZEnable = false;
ZWriteEnable = false;
AlphaBlendEnable = false;
CullMode = None;
PixelShader = compile ps_2_0 PS();
}
pass Final
{
VertexShader = compile vs_2_0 VS();
ZEnable = false;
ZWriteEnable = false;
AlphaBlendEnable = false;
CullMode = None;
PixelShader = compile ps_2_0 PS_Final();
}
}