1
\$\begingroup\$

I am currently fiddling with Monogame, trying to work with Shaders and I have encountered a really weird issue. If the first ever draw in the application's lifetime is with a custom shader all further draws without a custom shader get this red tint (as if blue and green channels were set to 0):

(A is the correct one, the sprite is white and black)

Shader issue example

The following code produced these:

spriteBatch.Begin(); // Use this for A
//spriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, null, Gfx.MyShader); // Use this for B
spriteBatch.Draw(Gfx.PlayerStand2, new Vector2(10, 10));
spriteBatch.End();
spriteBatch.Begin();
spriteBatch.Draw(Gfx.PlayerStand2, new Vector2(50, 50));
spriteBatch.End();
spriteBatch.Begin();
spriteBatch.Draw(Gfx.PlayerStand2, new Vector2(80, 80));
spriteBatch.End();

And this is the shader:

sampler TextureSampler : register(s0);

float4 PixelShaderFunction(float2 texCoord : TEXCOORD0) : COLOR0
{
    return tex2D(TextureSampler, texCoord);
}

technique Shader1
{
    pass Pass1
    {
        PixelShader = compile ps_2_0 PixelShaderFunction();
    }
}

It all depends on the first draw - if I replace the first two lines with this:

counter++; // Starts at 0
if (counter == 1){ // Run only on the first draw
    spriteBatch.Begin(SpriteSortMode.Immediate, null, null, null, null, Gfx.GaussianBlur);
} else {
    spriteBatch.Begin();
}

They all become red. If I replace == with != they all display correctly.

I am using OpenGL for rendering. I am aware I could circumvent this problem by always using a custom shader but I fear that this is but a symptom of a greater issue that will come later to bite my bottom. Or hopefully something completely trivial that I missed.

Update: I tried to reproduce it in DirectX version and in this case the batch with the shader does not render, but the other sprites are not red. I also tried to compile the files via Monogame Pipeline with the same effect.

\$\endgroup\$
1
\$\begingroup\$

I accidentally stumbled upon a template for the shaders in Monogame installation directory and replaced the shader with this one:

#define SV_POSITION POSITION
#define VS_SHADERMODEL vs_3_0
#define PS_SHADERMODEL ps_4_0_level_9_1

Texture2D SpriteTexture;

sampler2D SpriteTextureSampler = sampler_state
{
    Texture = <SpriteTexture>;
};

struct VertexShaderOutput
{
    float4 Position : SV_POSITION;
    float4 Color : COLOR0;
    float2 TextureCoordinates : TEXCOORD0;
};

float4 MainPS(VertexShaderOutput input) : COLOR
{
    return tex2D(SpriteTextureSampler,input.TextureCoordinates) * input.Color;
}

technique SpriteDrawing
{
    pass P0
    {
        PixelShader = compile PS_SHADERMODEL MainPS();
    }
};

And it solved the issue! It works fine both in OpenGL and in DirectX. My best bet is that the shader was invalid which is why it did not work at all in DirectX and partially in OpenGL - it might've done some kind of memory corruption which affected the default shader used by Monogame (did I accidentally do a buffer overflow attack on my GPU?).

I haven't bothered to inspect exactly how much I'd need to change the working shader to reproduce the issue so I don't know where specifically the problem was.

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.