Reputation: 33
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:
My result looks like this:
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
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