xna 4.0 sprite + MRT + pixelshader

时间:2012-09-16 18:39:44

标签: xna xna-4.0 pixel-shader rendertarget spritebatch

我正在尝试将2个渲染图(颜色和法线)组合成漫射闪光并在屏幕上渲染结果。我们的想法是使用一个效果仅包含像素着色器的精灵来组合纹理的渲染图。 XNA代码:

GraphicsDevice.SetRenderTarget(null);
GraphicsDevice.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.Black, 1.0f, 0);
effect.CurrentTechnique = effect.Techniques["show_buffer"];
effect.Parameters["normalTex"].SetValue(normalRendertarget);
effect.Parameters["colorTex"].SetValue(colorRendertarget);
effect.Parameters["AmbientIntensity"].SetValue(ambientIntesity);
effect.Parameters["LightDirection"].SetValue(lightDirection);
effect.Parameters["DiffuseIntensity"].SetValue(diffuseIntensity);

spriteBatch.Begin(0, BlendState.Opaque, null, null, null,effect);
spriteBatch.Draw(normalRT, Vector2.Zero, Color.White);
spriteBatch.End();

由于某种原因,spriteBatch.Draw()中使用的rendertarget会影响结果。

Pixel Shader:

void Tex_PixelShader(float2 texCoord : TEXCOORD0, out float4 color : COLOR0)
{
 float4 normal = tex2D(normalTexSampler, texCoord);
 //tranform normal back into [-1,1] range
 normal.rgb = (normal.rgb*2)-1; 
 float4 baseColor = tex2D(colorTexSampler, texCoord);
 float3 lightDirectionNorm = normalize(LightDirection);
 float diffuse = saturate(dot(-lightDirectionNorm,normal.rgb));

 //only works with normalRT in spriteBatch.Draw()
 //colorRT  in spriteBatch.Draw() gives colorRT but darker as result
 color = float4 (baseColor.rgb * (AmbientIntensity + diffuse*DiffuseIntensity), 1.0f);

 //only works with colorRT in spriteBatch.Draw()
 //normalRT in spriteBatch.Draw() gives normalRT as result
 //color = tex2D(colorTexSampler, texCoord); 

 //only works with NormalRT
 //colorRT in spriteBatch.Draw() gives colorRT as result
 //color=tex2D(normalTexSampler, texCoord);

 // works with any rendertarget in spriteBatch.Draw()
 //color = float4(0.0f,1.0f,0.0f,1.0f);
}

两个rendertargets中的alpha值始终为1.向效果添加顶点着色器会产生黑色。使用spriteBatch.Draw()绘制一个没有任何效果的rendertarget表明每个rendertarget的内容都很好。我无法理解这一点。有什么想法吗?

1 个答案:

答案 0 :(得分:0)

使用 GraphicsDevice.Textures [1] = tex; 而不是 effect.Parameters [“tex”] = tex; 设置纹理。谢谢安德鲁。

将xna代码更改为:

GraphicsDevice.SetRenderTarget(null);
GraphicsDevice.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.Black, 1.0f, 0);
effect.CurrentTechnique = effect.Techniques["show_buffer"];
GraphicsDevice.Textures[1] = normalRT;   //changed
GraphicsDevice.Textures[2] = colorRT;    //changed
effect.Parameters["AmbientIntensity"].SetValue(ambientIntesity);
effect.Parameters["LightDirection"].SetValue(lightDirection);
effect.Parameters["DiffuseIntensity"].SetValue(diffuseIntensity);

spriteBatch.Begin(0, BlendState.Opaque, null, null, null,effect);
spriteBatch.Draw((Texture2D)colorRT, Vector2.Zero, Color.White);
spriteBatch.End();

着色器代码:

sampler normalSampler: register(s1);   //added
sampler colorSampler: register(s2);    //added

void Tex_PixelShader(float2 texCoord : TEXCOORD0, out float4 color : COLOR0)
{
 float4 normal = tex2D(normalSampler, texCoord); //changed
 normal.rgb = (normal.rgb*2)-1;
 float4 baseColor = tex2D(colorSampler, texCoord);  //changed

 float3 lightDirectionNorm = normalize(LightDirection);
 float diffuse = saturate(dot(-lightDirectionNorm,normal.rgb));

 color = float4 (baseColor.rgb * (AmbientIntensity + diffuse*DiffuseIntensity), 1.0f);
}