Skip to main content
Notice removed Draw attention by CommunityBot
Bounty Ended with no winning answer by CommunityBot
Tweeted twitter.com/StackGameDev/status/738808235600314368
Notice added Draw attention by Felsir
Bounty Started worth 100 reputation by Felsir
edited tags
Link
Felsir
  • 4.1k
  • 2
  • 18
  • 33
Source Link
Felsir
  • 4.1k
  • 2
  • 18
  • 33

HLSL texture not reading from register S1

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 sbis 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?)