无限的无缝背景Monogame中的HLSL着色器不适用于非方形纹理

我正在尝试着写一个在Monogame中无限制地绘制无缝背景的着色器。

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(); } } 

我正在使用Monogame.Extended,所以我可以使用他们的Camera2D类。 我有这个function来绘制我的纹理:

 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(); } 

这整个事情工作正常的纹理,但是当宽度和高度是不同的,当我旋转我的相机发生扭曲。

在下一个图像中,有两个纹理,一个是正方形,另一个是矩形。

这是没有旋转的样子: 没有相机旋转

这是一些轮换看起来像什么: 随着一些相机旋转

红色纹理具有方形尺寸(500×500)。 白色的纹理有矩形的尺寸(1280×720)。

我相信这是一个简单的修复,但我无法弄清楚。

    经过这一段时间,我find了一个解决scheme。 就像其他人在评论中所说,在旋转之前进行缩放时会发生剪切。 原来我texCoord的比例是错误的。 它需要使用纹理的比例。 着色器非常好,但是我需要在旋转之前将纹理的比率应用到我的matrix。

     public static void drawSeamlessBackground(SpriteBatch s, Texture2D t, GraphicsDevice gd, float parallax, Camera2D cam) { Vector2 textureSize = new Vector2(t.Width, t.Height); Rectangle view = gd.Viewport.Bounds; Vector2 textureRatio = new Vector2(t.Width / t.Height, 1); if (t.Width < t.Height) { textureRatio = new Vector2(1, t.Height / t.Width); } Matrix m = Matrix.CreateTranslation(new Vector3(-cam.Origin / textureSize, 0.0f)) * Matrix.CreateScale(1f / cam.Zoom) * Matrix.CreateScale(textureRatio.X, textureRatio.Y, 1) * Matrix.CreateRotationZ(-cam.Rotation) * Matrix.CreateScale(1f / textureRatio.X, 1f /textureRatio.Y, 1) * Matrix.CreateTranslation(new Vector3(cam.Origin / textureSize, 0.0f)) * Matrix.CreateTranslation(new Vector3((cam.Position * parallax) / textureSize, 0.0f)); infiniteShader.Parameters["ScrollMatrix"].SetValue(m); 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(); } 

    由于四舍五入错误,最好使用比例好的纹理。 例如,如果我的纹理尺寸为1920×1080(比率为1,777777777777778),我仍然可以剪切,但是如果我制作了2000×1000(比率为2),我什么也得不到。