I made a simple post processing shader, that draws scanlines. This all works perfectly. I wanted to make it a bit more interesting by applying a shadowmask instead so I wanted to pass a texture to the shader. From my understanding the Spritebatch sets Texture Register(S0), so I set my shadowmask texture to Texture Register(s1).
When applying the shader is seems that both S0 and S1 contain the texture I plan to draw. I have tried to set parameters in different ways- without succes. How can I pass the Texture?
My HLSL code:
sampler ScreenTextureSampler: register (s0); // This is the texture that SpriteBatch will try to set before drawing
sampler ShadowSampler: register (s1); // This is set in GraphicsDevice.Textures[1];
int colorlines = 2;
int shadowlines = 1;
//------------------------ PIXEL SHADER ----------------------------------------
float4 PixelShaderFunction(float4 pos : SV_POSITION, float4 color1 : COLOR0, float2 texCoord : TEXCOORD0) : SV_TARGET0
{
float4 color = tex2D(ScreenTextureSampler, texCoord.xy);
float4 maskcolor = tex2D(ShadowSampler, texCoord.xy);
float ypos = pos.y;
float scanline = (ypos) % (colorlines + shadowlines);
float intensity = scanline < colorlines ? 1 : 0.20f;
//comment out one of these two return statements...
return maskcolor*intensity; //note this return has the exact same result
return color*intensity; //as this one! even though the samplers point at different registers.
}
technique Postprocessing
{
pass Pass1
{
PixelShader = compile ps_4_0 PixelShaderFunction();
}
}
This shader is loaded in an Effect
called Assets.GameArt.PostProcessor
. I have a shadowmask Texture2D
in Assets.GameArt.shadowTexture
.
My C#, Monogame code looks like this:
gd.SetRenderTarget(null);
sb.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend, SamplerState.PointClamp, DepthStencilState.None, RasterizerState.CullNone, Assets.GameArt.PostProcessor, Resolution.getTransformationMatrix());
gd.Textures[1] = Assets.GameArt.shadowTexture;
sb.Draw(_gameRenderTarget, Vector2.Zero, _camera.Viewport, Color.White);
sb.End();
gd
points to the GraphicsDevice
and sb
is the spriteBatch
. I first render my scene to a _gameRenderTarget
.
Why isn't the Texture passed via the S1 register (or: why do the texture samplers both return the same result?)