[SlimDX] Blurry textures and gaps between tiles

Recommended Posts

Decept    144
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?

Share on other sites
Evil Steve    2017

Share on other sites
Decept    144
I have tried that but it only works if there is no rotating going on.

Share on other sites
Decept    144
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.

Share on other sites
Pyrogame    106
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.

Share on other sites
Decept    144
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.

Share on other sites
remigius    1172

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.

Share on other sites
Decept    144
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.

Share on other sites
jpetrie    13159
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?

Share on other sites
Decept    144
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.

Share on other sites
Decept    144
I figured out that I should probably add the offset only after all the quads matrises have been multiplied. The fix should be applied to the final matrix (world space) and not in the translation part.
One of the things that really messes things up is the anchor translation. I really want to have it, but now I'm also trying without it to simplify things. But I still can't get it to work. As soon the offset is applied somewhere the quads shake during rotation.
Maybe I should somehow check if the quad is not in 0, 90, 180, 270 degree angle and only apply the offset then, but it feels like a hack.

Any more ideas, I'm getting crazy here?

Share on other sites
remigius    1172
Quote:
 Original post by DeceptI figured out that I should probably add the offset only after all the quads matrises have been multiplied. The fix should be applied to the final matrix (world space) and not in the translation part.

This is why I suggested applying the fix in the pixel shader. That way you know for sure any and all matrix multiplications have been performed and the vertices are in place.

I went to set up a little XNA game trying to mimmick your situation to figure out what's going on, but I realized halfway in that I still don't have any clue what you're actually trying to do or what I should pass in to your matrices.

Could you provide a screenshot and/or some quad setup values?

Share on other sites
Tom KQT    1704
Is the blur really so bad?
If you rotate the quad by an angle different than 0, 90, 180, 270 you cannot aim for pixel perfect rendering because it's not possible. There must be some sampling going on and the result will never be 100% sharp. You'll get sharp result only in the basic 4 angles if you do the 0.5f correction but that's IMHO not the right way to go because it would look weird if all angles EXCEPT FOR 4 specific would be blured somehow.

Are your quads going to be mostly in the "standard" angles and only sometimes (for a short time) in some special cases rotated by some angle? Or is there only small probability of the standard angles?