If I draw it using SpriteBatch then the texels are correctly aligned to the pixels
If I draw it using Texture Atlas look up then the texels are not correctly aligned and the x coordinate doesn't line up with the SpriteBatch result.
If I draw it straight from the original texture without the Atlas look up then the texels are not correctly aligned either.
Here is a picture demonstrating the results (All 3 quads have an x position of 100 yet they do not line up):
I'm attempting to line up the pixels to texels as follows:
(C#):
// [DirectX 9 - Align pixels to texels]
// • Find size of half a pixel for render targets based on their size
// In this case render target size is backBufferWidth * backBufferHeight
// • The reason that it is 1 / width instead of 0.5 / width is because, in clip space,
// the coordinates range from -1 to 1 (width 2), and not from 0 to 1 (width 1)
// like they do in textures, so you need to double the movement to account for that
Vector4 halfPixelTexel = new Vector4();
// Half Pixel
//halfPixelTexel.X = 1f / textureAtlas.Texture.Width;
//halfPixelTexel.Y = -1f / textureAtlas.Texture.Height;
halfPixelTexel.X = 1f / GraphicsDevice.Viewport.Width;
halfPixelTexel.Y = -1f / GraphicsDevice.Viewport.Height;
//halfPixelTexel.X = 1f / GraphicsDevice.PresentationParameters.BackBufferWidth;
//halfPixelTexel.Y = -1f / GraphicsDevice.PresentationParameters.BackBufferHeight;
// Half Texel
halfPixelTexel.Z = 0.5f / textureAtlas.Texture.Width;
halfPixelTexel.W = 0.5f / textureAtlas.Texture.Height;
//halfPixelTexel.Z = 0.5f / backBufferDim.X;
//halfPixelTexel.W = 0.5f / backBufferDim.Y;
effects[EffectName.Quadrangle].Parameters["HalfPixelTexel"].SetValue(halfPixelTexel);
effects[EffectName.QuadrangleBatch].Parameters["HalfPixelTexel"].SetValue(halfPixelTexel);
HLSL:
VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
VertexShaderOutput Output = (VertexShaderOutput)0;
// Set world transform here (don't use a static identity matrix as it is slower)
float4x4 World =
{
// [Rotation, Scale]
input.Column1.x * input.TexCoordDimension.z, // * Scale X
input.Column1.y * input.TexCoordDimension.z,
input.Column1.z * input.TexCoordDimension.z,
input.Column1.w,
input.Column2.x * input.TexCoordDimension.w, // * Scale Y
input.Column2.y * input.TexCoordDimension.w,
input.Column2.z * input.TexCoordDimension.w,
input.Column2.w,
input.Column3.x,
input.Column3.y,
input.Column3.z,
input.Column3.w,
// [Translation]
input.Column4.x,
input.Column4.y,
input.Column4.z,
input.Column4.w
};
// 'input.Position.w' should always equal 1
input.Position.w = 1;
// [Transformation]
// • Multiplying input.Position by World, then the result by ViewProjection is fast
// • Concatenating World and ViewProjection matrices then multiplying input.Position by the result is slower
input.Position = mul(input.Position, World);
Output.Position = mul(input.Position, ViewProjection);
// [Texel To Pixel Align]
// • Half pixel offset for correct texel centering)
// • Should be done AFTER transformation?
Output.Position.xy -= HalfPixelTexel.xy;
// [UV Coordinates]
Output.TextureCoordinates.xy = input.TexCoordDimension.xy;
// [Alpha]
Output.TextureCoordinates.w = input.Normal.w;
return Output;
}
When using textures larger than 8 pixels this problem does not occur.
Can anyone please explain why the texels are not lining up correctly with the pixels with smaller textures?