2D tile based game, shows gaps between the tile sprites when I zoom in with the camera?
Asked Answered
H

5

1

I am using the D3DXSPRITE method to draw my map tiles to the screen, i just added a zoom function which zooms in when you hold the up arrow, but noticed you can now see gaps between the tiles, here's some screen shots

normal size (32x32) per tile

enter image description here

zoomed in (you can see white gaps between the tiles)

enter image description here

zoomed out (even worst!)

enter image description here

Here's the code snipplet which I translate and scale the world with.

D3DXMATRIX matScale, matPos;

D3DXMatrixScaling(&matScale, zoom_, zoom_, 0.0f);
D3DXMatrixTranslation(&matPos, xpos_, ypos_, 0.0f);

device_->SetTransform(D3DTS_WORLD, &(matPos * matScale));

And this is my drawing of the map, (tiles are in a vector of a vector of tiles.. and I haven't done culling yet)

LayerInfo *p_linfo = NULL;
  RECT rect = {0};
  D3DXVECTOR3 pos;
  pos.x = 0.0f;
  pos.y = 0.0f;
  pos.z = 0.0f;

  for (short y = 0; 
    y < BottomTile(); ++y)
  {
    for (short x = 0; 
          x < RightTile(); ++x)
    {
      for (int i = 0; i < TILE_LAYER_COUNT; ++i)
      {
        p_linfo = tile_grid_[y][x].Layer(i);

        if (p_linfo->Visible())
        {
          p_linfo->GetTextureRect(&rect);

          sprite_batch->Draw(
            p_engine_->GetTexture(p_linfo->texture_id), 
            &rect, NULL, &pos, 0xFFFFFFFF);
        }
      }
      pos.x += p_engine_->TileWidth();
    }
    pos.x = 0;
    pos.y += p_engine_->TileHeight();
  }
Handbill answered 28/5, 2011 at 16:16 Comment(4)
Does the lines change color if you change the background color? That might be intresting to know to actually rule out that there isn't someting going on with your textures or filtering.Hoxsie
You really need to use shaders and ID3DXEffect, not fixed-function.Razzia
the lines don't change color, just look white, i tried clear as red, blue, black, all look the same.Handbill
i'll have a look at d3dxeffectHandbill
H
0

Welcome to the world of floating-point. Those gaps exist due to imperfections using floating-point numbers.

You might be able to improve the situation by being really careful when doing your floating-point math but those seams will be there unless you make one whole mesh out of your terrain.

It's the rasterizer that given the view and projection matrix as well as the vertex positions is slightly off. You maybe able to improve on that but I don't know how successful you'll be.

Instead of drawing different quads you can index only the visible vertexes that make up your terrain and instead use texture tiling techniques to paint different stuff on there. I believe that won't get you the ugly seam because in that case, there technically isn't one.

Hoxsie answered 28/5, 2011 at 16:26 Comment(7)
This isn't FP-imperfection, it's much too regular.Razzia
@DeadMG Hmm, No. I'll bet you it's a rounding problem going on in the rasterizer. Given how things are set up. You can minimize the visiblity of such issues but they'll always be there.Hoxsie
Rounding problems would not produce an effect regularly, as floating-point representation is not spread equally. The artifacts would be either more or less present towards the lower range.Razzia
Okay, but what if the view and/or projection matrices were setup unfavourably?Hoxsie
I have this exact same problem in Unity. I'm pretty sure its fp imperfection.Kovrov
This answer is wrong. The vertex coordinates passed to two adjacent triangles should be the same. This is the programmer's responsibility. Inprecise or not, if you pass the same value, the card will deterministically interpolate and you won't get ugly seams.Boil
@Boil cannot delete accepted answer, I dunno why, maybe because the author attempted my suggested workaround. Anyway, the point I was trying to make is that the coordinates aren't aligned on top of each other properly. Why that happens is a different matter.Hoxsie
R
4

Your texture indices are wrong. 0,0,32,32 is not the correct value- it should be 0,0,31,31. A zero-based index into your texture atlas of 256 pixels would yield values of 0 to 255, not 0 to 256, and a 32x32 texture should yield 0,0,31,31. In this case, the colour of the incorrect pixels depends on the colour of the next texture along the right and the bottom.

Razzia answered 28/5, 2011 at 16:55 Comment(7)
The seams are the colors of the texture to the right and bottom! but i tried returning a rect of 0,0,31,31 and now i have a 1 pixel gap. How come i can only see the seams when i'm zoomed in or out then? and if i screenshot and check in paint, each tile is now 31 pixels wide and missing a column of pixelsHandbill
@Kaije: Could well be that your layout code is off for positioning them on the screen.Razzia
Each tile is positioned 32 pixels apart in the loop, and with 0,0,31,31, each tile has a 1 pixel gap on every side, when i screenshot and zoom in i count the pixels of 1 tile, and its 31x31 pixels with some of the texture missingHandbill
I think it needs 0-32 because usually when your looping through something, you do like (i=0; i < 32; i++), it will go through 0-31Handbill
@Kaije: You should try loading the texture individually and passing NULL for the rect, and see if that solves the problem at ahndRazzia
I just tried, 32x32 grass texture, passed NULL as rectangle, and it looks better, but when you zoom in, the textures don't look seamless and when you zoom out, theres like a light green line separating each tile (my clear color is solid red)Handbill
i might try some textured quads instead of the sprite batch wrapperHandbill
H
2

That's the problem of magnification and minification. Your textures should have invisible border populated with part of adjacent texture. Then magnification and minification filters will use that border to calculate color of edge pixels rather than default (white) color.

I think so.

Hazelwood answered 28/5, 2011 at 16:42 Comment(1)
I think this is the real answer. Texture interpolation accesses several texels. On a border some texels don't have values this leads to these artifacts. Mipmapping exacerbates those problems. However your texture looks so simple, maybe you can set the mode to repeat.Sherlocke
S
1

I also had a similar problem with texture mapping. What worked for me was changing the texture address mode in the sampler state description; texture address mode is used to control what direct3d does with texture coordinates outside of the ([0.0f, 1.0f]) range: i changed the ADDRESS_U, ADDRESS_V, ADDRESS_W members to D3D11_TEXTURE_ADDRESS_CLAMP which basically clamps all out-of-range values for the texture coordinates into the [0.0f, 1.0f] range.

Spectrophotometer answered 14/2, 2014 at 22:35 Comment(0)
U
1

After a long time searching and testing people solutions I found this rules are the most complete rules that I've ever read.

pixel-perfect-2d from Official Unity WebSite

plus with my own experience i found out that if sprite PPI is 72(for example), you should try to use more PPI for that Image(96 maybe or more).It actually make sprite more dense and make no space for white gaps to show up.

Unboned answered 18/6, 2016 at 14:42 Comment(1)
See also forum.unity3d.com/threads/tile-map-tearing-problems.225777/…Kirkwood
H
0

Welcome to the world of floating-point. Those gaps exist due to imperfections using floating-point numbers.

You might be able to improve the situation by being really careful when doing your floating-point math but those seams will be there unless you make one whole mesh out of your terrain.

It's the rasterizer that given the view and projection matrix as well as the vertex positions is slightly off. You maybe able to improve on that but I don't know how successful you'll be.

Instead of drawing different quads you can index only the visible vertexes that make up your terrain and instead use texture tiling techniques to paint different stuff on there. I believe that won't get you the ugly seam because in that case, there technically isn't one.

Hoxsie answered 28/5, 2011 at 16:26 Comment(7)
This isn't FP-imperfection, it's much too regular.Razzia
@DeadMG Hmm, No. I'll bet you it's a rounding problem going on in the rasterizer. Given how things are set up. You can minimize the visiblity of such issues but they'll always be there.Hoxsie
Rounding problems would not produce an effect regularly, as floating-point representation is not spread equally. The artifacts would be either more or less present towards the lower range.Razzia
Okay, but what if the view and/or projection matrices were setup unfavourably?Hoxsie
I have this exact same problem in Unity. I'm pretty sure its fp imperfection.Kovrov
This answer is wrong. The vertex coordinates passed to two adjacent triangles should be the same. This is the programmer's responsibility. Inprecise or not, if you pass the same value, the card will deterministically interpolate and you won't get ugly seams.Boil
@Boil cannot delete accepted answer, I dunno why, maybe because the author attempted my suggested workaround. Anyway, the point I was trying to make is that the coordinates aren't aligned on top of each other properly. Why that happens is a different matter.Hoxsie

© 2022 - 2024 — McMap. All rights reserved.