@Apostolique wrote:
I'm trying to write a shader that draws a seamless background infinitely in Monogame. The code is based on: http://www.david-gouveia.com/portfolio/scrolling-textures-with-zoom-and-rotation/
Here are the textures I'm using for the demonstration: http://imgur.com/a/n9WrG
sampler TextureSampler : register(s0); float2 ViewportSize; float4x4 ScrollMatrix; struct VertexToPixel { float4 Position : SV_Position0; float4 TexCoord : TEXCOORD0; float4 Color : COLOR0; }; VertexToPixel SpriteVertexShader(float4 color : COLOR0, float4 texCoord : TEXCOORD0, float4 position : POSITION0) { VertexToPixel Output = (VertexToPixel)0; // 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 texCoord = mul(texCoord, ScrollMatrix); //pass position and color to PS Output.Color = color; Output.Position = position; Output.TexCoord = texCoord; return Output; } technique SpriteBatch { pass { VertexShader = compile vs_2_0 SpriteVertexShader(); } }
I'm using Monogame.Extended so I can use their Camera2D class. I have this function to draw my texture:
public static void drawSeamlessBackground(SpriteBatch s, Texture2D t, GraphicsDevice gd, float parallax, Camera2D cam) { //TODO: Make this work with non square textures. Vector2 textureSize = new Vector2(t.Width, t.Height); Rectangle view = gd.Viewport.Bounds; Matrix m = Matrix.CreateTranslation(new Vector3(-cam.Origin / textureSize, 0.0f)) * Matrix.CreateScale(1f / cam.Zoom) * Matrix.CreateRotationZ(-cam.Rotation) * Matrix.CreateTranslation(new Vector3(cam.Origin / textureSize, 0.0f)) * Matrix.CreateTranslation(new Vector3((cam.Position * parallax) / textureSize, 0.0f)); infiniteShader.Parameters["ScrollMatrix"].SetValue(m); //Normally this next line would not be here since the viewport doesn't usually change. infiniteShader.Parameters["ViewportSize"].SetValue(new Vector2(view.Width, view.Height)); s.Begin(samplerState: SamplerState.LinearWrap, effect: infiniteShader); s.Draw(t, new Vector2(0, 0), view, Color.White); s.End(); }
This whole thing works fine for square textures, but when the width and the height are different, there's distortion that happens when I rotate my camera.
In the next image, there are two textures, one that is square and one that is a rectangle.
Here is what it looks like with no rotation:
Here is what it looks like with some rotation:
The red texture has square dimensions (500x500). The white texture has rectangular dimensions (1280x720).
I'm sure this is a simple fix, but I can't figure it out.
Posts: 5
Participants: 2