[SlimDX] Blurry textures and gaps between tiles

Started by
11 comments, last by TomKQT 14 years, 1 month ago
I'm using SlimDX.Direct3D9 to create 2D graphics. When I render a quad using 4 TL vertices my result is often blurry. I know that if I offset my vertices by 0.5f then it will render pixel-perfect to the backbuffer. The problem is that my quads are not always positioned on exact pixels as I use floats for positioning. Not only that, but I can also rotate the quads. This makes the 0.5f offset pretty inefective. Another problem that is most certainly related is that when I try to tile quads I get small gaps between tiles. This doesn't happen if I position the tiles at a .5f position. Any ideas?
Advertisement
Why not clamp your vertex coordinates to floor(), then add 0.5f?
I have tried that but it only works if there is no rotating going on.
I have investigated this further. It seems the only way to get pixel perfect rendering is to do something like float posX = ((int)posX)-0.5f; But whenever I try something like that and also rotate the quad it "shakes" during rotation.

I need some way to detect if a matrix is rotating and scaling so that I only apply position correction when possible.

My RenderQuad() takes a transformation matrix as a parameter. It would be simpler if it was RenderQuad(texture, position, rotation, scale) but my quads are part of a hierarchy of quads, so I need matrises to multiply the quads transformations.
Hmm... what about setting the texture sampler not to linear, but to none? Then there is no interpolation for the textures and all pixels should be rendered 1:x on the polygon. If you set your texture coordinates in a proper way, you should get the result you want.
setting the sampler filtering to none does help, unless you want to rotate the quad, then it just looks awful without proper filtering. I need to be able to rotate.

It might help to apply the texel/pixel offset in the pixel shader instead of in your vertex coordinates. That way they get applied after the rotation so they're more effective and you can be sure that vertex->pixel interpolation hasn't messed anything up.
Rim van Wersch [ MDXInfo ] [ XNAInfo ] [ YouTube ] - Do yourself a favor and bookmark this excellent free online D3D/shader book!
Although I have not tried doing that in a pixel shader (not using shaders currently) I'm a little bit skeptical. Wouldn't that be about the same as moving each vertex to exactly .5f? If that's the case the result won't be good as the quad would "shake" as it rotates.
The half-pixel offset is the widely accepted solution to this problem in D3D9. I suspect the other artifacts you're seeing are related to something else. Can you post screenshots and/or code?
All my problems were somehow related to the offset and what filtering I was using. I have managed to fix everything except for 1 thing. I can get pixelperfect rendering or smooth rotation, but not both. I get pixel perfect rendering by offsetting by 0.5f. But when I do that then rotating quads "shakes" because their center of rotation jumps between pixels.

If I create my transformation matrix like this then I get both pixelperfect rendering and smooth rotation.

Matrix mat = Matrix.Identity;Matrix matScale = Matrix.Scaling(new Vector3(mScale, 1.0f));mat = Matrix.Multiply(mat, matScale);Matrix matRotation = Matrix.RotationZ(mRotation);mat = Matrix.Multiply(mat, matRotation);Matrix matTrans = Matrix.Translation(new Vector3(((int)mPosition.X) - 0.5f, ((int)mPosition.Y) - 0.5f, 0));mat = Matrix.Multiply(mat, matTrans);Matrix matAnchor = Matrix.Translation(new Vector3((int)(-mTransformAnchor.X), (int)(-mTransformAnchor.Y), 0));mat = Matrix.Multiply(matAnchor, mat);mTransform = mat;


But this only works for a single quad. I can have subquads and their transformation matrix is multiplied with their parent's transformation matrix (and their parent's and so on). When that happens the "offset fix" will get cancelled out every two levels of quads.
I have not been able to come up with a solution that works with several levels of quads. If I just apply the offset on the final resulting matrix then I get pixelperfect but rotation shakes.

This topic is closed to new replies.

Advertisement