Anyone have a working sample of VSMs?
I have been trying to get this working, but am hitting a roadblock. My Gaussian blur seems to render my shadowmap empty / blank.
Here’s how I am creating the blur render target:
_blurMap = new RenderTarget2D(AxisGame.Instance.GraphicsDevice, 2048, 2048, false, SurfaceFormat.Color, DepthFormat.Depth24);
And here’s the actual blur shader… this is straight out of the book “3D Graphics with XNA Game Studio 4.0” by Sean James (great book!).
texture Texture;
sampler2D TextureSampler = sampler_state
{
texture = <Texture>;
minfilter = point;
magfilter = point;
mipfilter = point;
};
// precalculated weights and offsets
float weights[15] =
{
0.1061154, 0.1028506, 0.1028506, 0.09364651, 0.09364651,
0.0801001, 0.0801001, 0.06436224, 0.06436224, 0.04858317,
0.04858317, 0.03445063, 0.03445063, 0.02294906, 0.02294906
};
float offsets[15] =
{
0, 0.00125, -0.00125, 0.002916667, -0.002916667,
0.004583334, -0.004583334,0.00625, -0.00625, 0.007916667,
-0.007916667, 0.009583334, -0.009583334, 0.01125, -0.01125
};
float4 BlurHorizontal(float4 position : POSITION0, float4 color : COLOR0, float2 texCoord : TEXCOORD0) : Color0
{
float4 output = float4(0, 0, 0, 1);
for (int i = 0; i < 15; i++)
{
output += tex2D(TextureSampler, texCoord + float2(offsets[i], 0)) * weights[i];
}
return output;
}
float4 BlurVertical(float4 position : POSITION0, float4 color : COLOR0, float2 texCoord : TEXCOORD0) : Color0
{
float4 output = float4(0, 0, 0, 1);
for (int i = 0; i < 15; i++)
{
output += tex2D(TextureSampler, texCoord + float2(0, offsets[i])) * weights[i];
}
return output;
}
technique Blur
{
pass Horizontal
{
#if SM4
PixelShader = compile ps_4_0 BlurHorizontal();
#else
PixelShader = compile ps_3_0 BlurHorizontal();
#endif
}
pass Vertical
{
#if SM4
PixelShader = compile ps_4_0 BlurVertical();
#else
PixelShader = compile ps_3_0 BlurVertical();
#endif
}
}
Here’s my draw code… note, _shadowMap has already been created (with the models already rendered to it), and it works perfectly without VSM. This code was added and uses _shadowMap as the source to blur it per VSM:
// blur shadow
var blurEffect = GaussianBlurEffect;
blurEffect.CurrentTechnique = blurEffect.Techniques["Blur"];
GraphicsDevice.SetRenderTarget(_blurMap);
GraphicsDevice.Clear(Color.White);
// horizontal
SpriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Opaque);
blurEffect.CurrentTechnique.Passes[0].Apply();
SpriteBatch.Draw(_shadowMap, Vector2.Zero, Color.White);
SpriteBatch.End();
GraphicsDevice.SetRenderTarget(_shadowMap);
GraphicsDevice.Clear(Color.White);
// vertical
SpriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Opaque);
blurEffect.CurrentTechnique.Passes[1].Apply();
SpriteBatch.Draw(_blurMap, Vector2.Zero, Color.White);
SpriteBatch.End();
GraphicsDevice.SetRenderTarget(null);
GraphicsDevice.BlendState = BlendState.Opaque;
GraphicsDevice.DepthStencilState = DepthStencilState.Default;
Anyone have any ideas as to why this isn’t working? The final shadowmap ends up black…
Thanks!