nwatson
nwatson

Reputation: 33

Simple vertex shader not working correctly in Monogame

I am very new to both shaders and to Monogame, so forgive me if I am missing something obvious.

I am following this tutorial very loosely: http://www.david-gouveia.com/portfolio/scrolling-textures-with-zoom-and-rotation/

I want exactly the same effect as in the tutorial in my own game: a texture that draws based on the camera rotation/zoom/position.

Here is my shader code:

sampler TextureSampler : register(s0);

struct VertexShaderInput
{
    float4 Color: COLOR0;
    float2 TexCoord : TEXCOORD0;
    float4 Position : SV_Position0;
};

struct VertexShaderOutput
{
    float4 Color: COLOR0;
    float2 TexCoord : TEXCOORD0;
    float4 Position : SV_Position0;
};

float2   ViewportSize;
float4x4 ScrollMatrix;

VertexShaderOutput SpriteVertexShader(VertexShaderInput input)
{
    VertexShaderOutput output;
    float4 position = input.Position;

    // Half pixel offset for correct texel centering.
    position.xy -= 0.5;

    // Viewport adjustment.
    position.xy = position.xy / ViewportSize;
    position.xy *= float2(2, -2);
    position.xy -= float2(1, -1);

    // Transform our texture coordinates to account for camera
    output.TexCoord = mul(float4(input.TexCoord.xy, 0, 1), ScrollMatrix).xy;
    output.Position = position;
    output.Color = input.Color;

    return output;
}

technique SpriteBatch
{
    pass
    {
        VertexShader = compile vs_4_0_level_9_1  SpriteVertexShader();
    }
}

I load it into monogame:

Effect effect = content.Load<Effect>("SpriteEffects\\infinite");
effect.Parameters["ViewportSize"].SetValue(new Vector2(viewport.Width,viewport.Height));

Function for getting the Effect at drawing:

public Effect getScrollEffect()
        {
            //This should use a matrix based on the camera, but I'm using an Identity matrix for testing
            effect.Parameters["ScrollMatrix"].SetValue(Matrix.Identity);
            return effect;
        }

And then drawing it:

spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.LinearWrap, null, null, getScrollEffect());
spriteBatch.Draw(texture, viewport.Bounds, viewport.Bounds, Color.White);
spriteBatch.End();

The texture looks like this:

enter image description here

My result looks like this:

enter image description here

What is going on? My shader doesn't even touch the color. Even when I remove the "Color" variable from the input and output it turns out the same. It looks like it is somehow confusing the coordinates of one variable with color values somehow. Am I using the shader wrong?

Thank you for your help.

Upvotes: 1

Views: 2212

Answers (1)

user3821985
user3821985

Reputation: 54

This is based on my experience with XNA but I can NOT imagine there is anything that would let you skip whole pixel shader stage in mono (and replace it with default). Geometry shader is optional, pixel shader isn´t.

Simply put: You need pixel shader to map your texture on geometry using UVcoords passed from vertex shader.

float4 PixelShader(VertexShaderOutput input) : COLOR0
{
   float4 Diffuse =  tex2D(DiffuseSampler, input.TexCoord);
   return Diffuse * input.Color;
} 

input.Color is vertex color, spritebatch set it to vertices, in your case Color.White, used as tint.

Don´t forget

PixelShader = compile ps_4_0_level_9_1  PixelShader();

Upvotes: 1

Related Questions