Sign in to follow this  
Spa8nky

[C#] [XNA] Bizarre bug when using ResolveTexture2D

Recommended Posts

I create a ResolveTexture2D and a RenderTarget2D that fit the entire screen in XNA as follows:
            PresentationParameters pp = GraphicsDevice.PresentationParameters;

            int width = pp.BackBufferWidth;
            int height = pp.BackBufferHeight;

            SurfaceFormat format = pp.BackBufferFormat;

            // Create a texture for reading back the backbuffer contents.
            target_Resolve = new ResolveTexture2D(GraphicsDevice, width, height, 1, format);
            rT_0 = new RenderTarget2D(GraphicsDevice, width, height, 1, format);


I now draw the following: DrawBlankRenderTarget(); DrawRenderTargetTextureQuad(); DrawBackBuffer(); The blank render target is just a black screen rendered to the target:
        private void DrawBlankRenderTarget()
        {          
            GraphicsDevice.SetRenderTarget(0, rT_0);
            GraphicsDevice.Clear(Color.Black);
            GraphicsDevice.SetRenderTarget(0, null);
        }


The render target texture is now drawn to the screen as a quadrangle that covers the entire screen:
        private void DrawRenderTargetTextureQuad()
        {
            effect.TextureEnabled = true;
            effect.Texture = rT_0.GetTexture();
            
            effect.Begin();

            effect.Techniques[0].Passes[0].Begin();

            // Draw a full screen quad
            GraphicsDevice.VertexDeclaration = new VertexDeclaration(GraphicsDevice, VertexPositionTexture.VertexElements);
            GraphicsDevice.DrawUserIndexedPrimitives<VertexPositionTexture>(PrimitiveType.TriangleStrip, vertices_FS, 0, vertices_FS.Length, indices_FS, 0, 2);

            effect.Techniques[0].Passes[0].End();

            effect.End();
        }


The fullscreen quadrangle vertices/indices are defined as follows:
        public short[] indices_FS = new short[] { 2, 0, 3, 1 }; //{ 2, 0, 3, 0, 1, 3 };

        // Define Triangles clockwise (TraingleStrip Method) so they face the Camera [TL -> TR -> BL -> BR]
        public VertexPositionTexture[] vertices_FS = new VertexPositionTexture[4]
            {
                // Screen X,Y coordinatates go from (-1,1) [Top Left] to (1,-1) [Bottom Right]
                // .Z coordinate of 0 = Draw on near clipping plane (as close to camera as possible)
                new VertexPositionTexture(new Vector3(-1.0f, 1.0f, 0), new Vector2(0, 0)),                // Top Left
                new VertexPositionTexture(new Vector3(1.0f, 1.0f, 0), new Vector2(1, 0)),                 // Top Right
                new VertexPositionTexture(new Vector3(-1.0f, -1.0f, 0), new Vector2(0, 1)),               // Bottom Left
                new VertexPositionTexture(new Vector3(1.0f, -1.0f, 0), new Vector2(1, 1))                 // Bottom Right
            };


The back buffer is now drawn 4 times across the screen (to show the border problem):
        private void DrawBackBuffer()
        {
            // Resolve the quad into a texture
            GraphicsDevice.ResolveBackBuffer(target_Resolve);

            // Render the current scene to a 2D Texture
            texture_Render = target_Resolve;

            int halfWidth = device.Viewport.Width / 2;
            int halfHeight = device.Viewport.Height / 2;

            spriteBatch.Begin(SpriteBlendMode.None);

            spriteBatch.Draw(texture_Render, new Rectangle(0, 0, halfWidth, halfHeight), Color.White);
            spriteBatch.Draw(texture_Render, new Rectangle(0, halfHeight, halfWidth, halfHeight), Color.White);
            spriteBatch.Draw(texture_Render, new Rectangle(halfWidth, 0, halfWidth, halfHeight), Color.White);
            spriteBatch.Draw(texture_Render, new Rectangle(halfWidth, halfHeight, halfWidth, halfHeight), Color.White);

            spriteBatch.End();
        }


The result of the resolved texture being drawn 4 times is the following: Texture Border Can anyone please tell me why I get a thin border the same colour as the render target around each drawn back buffer texture? This only occurs when I resolve a texture from the back buffer. The code is being run in an entirely new project with nothing else being drawn or changed so I'm really confused as to what might be causing this problem. Thank you.

Share this post


Link to post
Share on other sites
The issue is actually really simple: when you render to the screen using your quad, you're rendering to a render target that has antialiasing (MSAA). Because of this, you're getting a border due to the dreaded half-texel offset issue that is generally a pain to deal with in D3D9.

I have an article about it on my website, that should give you a really clear indication of what the problem is and how to handle it.

Hope that helps!


Josh

Share this post


Link to post
Share on other sites
You sir, are a Christmas star!

I have used this C# code to adjust the quadrangle vertex position (I will move it to HLSL):


Vector2 halfPixel = new Vector2();

halfPixel.X = -1.0f / width;
halfPixel.Y = 1.0f / height;

for (int i = 0; i < vertices_FS.Length; i++)
{
vertices_FS[i].Position += new Vector3(halfPixel, 0);
}



Thank you.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this