Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Tile tearing vs texture smoothing  (Read 7957 times)

0 Members and 1 Guest are viewing this topic.

_Fiction_

  • Newbie
  • *
  • Posts: 35
    • View Profile
Tile tearing vs texture smoothing
« on: June 22, 2013, 07:36:19 am »
EDIT: My initial problem was solved but I'm having a related issue which I detail on the next page. Thanks :)

I am having a problem with tearing/artifacts when rendering tiles. When rendering normally, I get the lines in the first image, which appear only horizontally. I have tried several approaches, and the only option that has successfully removed them is to use Texture::setSmooth(false) on my map textures. However, this creates a second (although less obtrusive) issue (second image) where I get some pixel choppiness on my slopes. I would like to remove both of these issues, as opposed to simply having to choose between the lesser of two evils. Any suggestions?

« Last Edit: August 17, 2013, 08:14:40 am by _Fiction_ »

FRex

  • Hero Member
  • *****
  • Posts: 1845
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: Tile tearing vs texture smoothing
« Reply #1 on: June 22, 2013, 07:39:30 am »
Smooth is off by default.
Are these actual tiles or are they rotated sprites/whatever?
Maybe show some code. ;D
Back to C++ gamedev with SFML in May 2023

_Fiction_

  • Newbie
  • *
  • Posts: 35
    • View Profile
Re: Tile tearing vs texture smoothing
« Reply #2 on: June 22, 2013, 07:45:38 am »
I think at some point in my code I turn smoothing on for all textures (so that the player and enemies rotate smoothly), which is why I have to unsmooth the map textures. Either way, its just a boolean value.

I'm not sure what you mean by "actual tiles." They are not rotated in any way, and are part of a larger texture. What part of the code are you interested in? I 've implemented it several different ways (render texture, drawing each as a sprite, vertexarray) and all have the same results.

FRex

  • Hero Member
  • *****
  • Posts: 1845
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: Tile tearing vs texture smoothing
« Reply #3 on: June 22, 2013, 07:48:11 am »
Have you tried messing with texture coords and/or position coords of vertices in quads and seeing if it helps(setting them to full integers or floats ending in .5)?
Back to C++ gamedev with SFML in May 2023

_Fiction_

  • Newbie
  • *
  • Posts: 35
    • View Profile
Re: Tile tearing vs texture smoothing
« Reply #4 on: June 22, 2013, 07:55:18 am »
Yes. Although there is a slight change visually, its the same change as simply moving the camera/character on y-axis, meaning some lines get thinner, some lines disappear, and other lines appear (they flicker if you move through the y-axis quickly). As a note, I DO have rounding on the position of my camera/view, as I recall that the lack of rounding on view position was the cause of a similar line issue for another user on the forum.

FRex

  • Hero Member
  • *****
  • Posts: 1845
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: Tile tearing vs texture smoothing
« Reply #5 on: June 22, 2013, 08:27:53 am »
I'm trying to reproduce it myself, simple, self contained int main and texture image that contains the problem would be helpful to experiment with.
Back to C++ gamedev with SFML in May 2023

_Fiction_

  • Newbie
  • *
  • Posts: 35
    • View Profile
Re: Tile tearing vs texture smoothing
« Reply #6 on: June 22, 2013, 09:19:16 am »
I will try to make the smallest version possible, although I am not as experienced as you with SFML (going off of post count) so it might take me a while longer to create a test case.

FRex

  • Hero Member
  • *****
  • Posts: 1845
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: Tile tearing vs texture smoothing
« Reply #7 on: June 22, 2013, 09:24:30 am »
This is very infamous bug/artifact, I kind of ran into it once, not sure if I fixed it or not or if it was appearing on certain machines only.
I tried that, and it works ok with a 2x2 tilesheet with 32x32 tiles(attached).
Changing bump in vert made line artifacts, but other two don't change a thing.

#include <SFML/Graphics.hpp>


sf::Vector2f vert(int x)
{
        const sf::Vector2f bump(0.f,0.f);
        switch(x)
        {
        case 1:return bump+sf::Vector2f();
        case 2:return bump+sf::Vector2f(0.f,32.f);
        case 3:return bump+sf::Vector2f(32.f,32.f);
        case 4:return bump+sf::Vector2f(32.f,0.f);
        }
}
sf::Vector2f texc(int x)
{
        switch(x)
        {
        case 0:return sf::Vector2f();
        case 1:return sf::Vector2f(32.f,0.f);
        case 2:return sf::Vector2f(0.f,32.f);
        case 3:return sf::Vector2f(32.f,32.f);
        }
}
int main(int argc,char * argv[])
{
        const sf::Vector2f bump(0.8f,0.3f);
        const int mapx=5;
        const int mapy=5;
        const int map[mapx][mapy]=
        {
                {3,3,3,3,3},
                {0,3,3,3,3},
                {3,0,3,3,3},
                {3,3,1,1,1},
                {3,3,3,3,3},
        };

        sf::RenderWindow app(sf::VideoMode(640,480),"s");
        app.setFramerateLimit(60);
        sf::Texture tex;
        tex.loadFromFile("img.png");
        sf::VertexArray array;
        array.setPrimitiveType(sf::Quads);

        const float pos=64.f;

        for(int x=0;x<mapx;++x) for(int y=0;y<mapy;++y)
        {
                const sf::Vector2f vec=texc(map[x][y]);

                array.append(sf::Vertex(bump+sf::Vector2f(pos*x,pos*y),vert(1)+vec));

                array.append(sf::Vertex(bump+sf::Vector2f(pos*x,pos*(y+1)),vert(2)+vec));

                array.append(sf::Vertex(bump+sf::Vector2f(pos*(x+1),pos*(y+1)),vert(3)+vec));

                array.append(sf::Vertex(bump+sf::Vector2f(pos*(x+1),pos*y),vert(4)+vec));
        }
//      tex.setSmooth(true);
        while(true)
        {
                sf::Event eve;
                while(app.pollEvent(eve));

                const sf::Vector2f add(0.67325f,0.12354f);
                sf::View v=app.getDefaultView();
                v.setCenter(add+sf::Vector2f(sf::Mouse::getPosition(app)));
                std::printf("%3.2f %3.2f\n",v.getCenter().x,v.getCenter().y);
                app.setView(v);

                app.clear();
                app.draw(array,&tex);
                app.display();
        }
        return 0;
}
« Last Edit: June 22, 2013, 09:27:17 am by FRex »
Back to C++ gamedev with SFML in May 2023

_Fiction_

  • Newbie
  • *
  • Posts: 35
    • View Profile
Re: Tile tearing vs texture smoothing
« Reply #8 on: June 22, 2013, 09:38:18 am »
"Changing bump in vert made line artifacts, but other two don't change a thing." Can you rephrase this line? I'm not sure I understand.

(Also, excellent job on the test case. Much better than mine would have been.)
« Last Edit: June 22, 2013, 09:49:51 am by _Fiction_ »

FRex

  • Hero Member
  • *****
  • Posts: 1845
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: Tile tearing vs texture smoothing
« Reply #9 on: June 22, 2013, 09:50:40 am »
sf::Vector2f vert(int x)
{
    const sf::Vector2f bump(0.f,0.f);
this bump value must be 0 0 or line artifacts happen, the one that gets added to position:
 const sf::Vector2f bump(0.8f,0.3f);
and view center:
 const sf::Vector2f add(0.67325f,0.12354f);
can be set to weird values(as shown) and everything looks ok.

Quote
(Also, excellent job on the test case. Much better than mine would have been.)
Ok, but if that renders without any artifacts on your card then you must have done something wrong in your code or texture.
« Last Edit: June 22, 2013, 09:53:49 am by FRex »
Back to C++ gamedev with SFML in May 2023

_Fiction_

  • Newbie
  • *
  • Posts: 35
    • View Profile
Re: Tile tearing vs texture smoothing
« Reply #10 on: June 22, 2013, 11:11:32 am »
Okay, I got a chance to actually test your code. I see you commented out setSmooth( true ). When I uncomment that line (makes the diagonals noticeably smoother) there are small lines between every tile. I'm trying to avoid the jagged pixel edges and the artifact lines simultaneously.
« Last Edit: June 22, 2013, 11:20:03 am by _Fiction_ »

FRex

  • Hero Member
  • *****
  • Posts: 1845
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: Tile tearing vs texture smoothing
« Reply #11 on: June 22, 2013, 11:26:23 am »
There are no jagged pixels appearing for me, everything is rendered 1:1 , unless by that you mean the pixels are not smoothed out and you want to use set smooth while having no artifacts.

Use this vert function and uncomment setSmooth true and see if these are the results you seek.
sf::Vector2f vert(int x)
{
        const sf::Vector2f bump(0.f,0.f);
        switch(x)
        {
        case 1:return bump+sf::Vector2f(0.5f,0.5f);
        case 2:return bump+sf::Vector2f(0.5f,31.5f);
        case 3:return bump+sf::Vector2f(31.5f,31.5f);
        case 4:return bump+sf::Vector2f(31.5f,0.5f);
        }
}
« Last Edit: June 22, 2013, 11:48:49 am by FRex »
Back to C++ gamedev with SFML in May 2023

_Fiction_

  • Newbie
  • *
  • Posts: 35
    • View Profile
Re: Tile tearing vs texture smoothing
« Reply #12 on: June 22, 2013, 12:22:42 pm »
Thank you for your help  ;D! That seems to be the behavior I'm looking for. I'm going to attempt to apply this solution to my code, and I will post any problems/results in the morning.
« Last Edit: June 22, 2013, 12:24:19 pm by _Fiction_ »

_Fiction_

  • Newbie
  • *
  • Posts: 35
    • View Profile
Re: Tile tearing vs texture smoothing
« Reply #13 on: June 22, 2013, 07:32:06 pm »
Is it more efficient to create a VertexArray of a large map a single time, and then draw the entire map each frame, or to create a new vertex array of a clipped section of the map each frame based on the view?

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Re: Tile tearing vs texture smoothing
« Reply #14 on: June 22, 2013, 07:34:16 pm »
I would guess creating (or actually filling) the vertex array again is faster, but you have to measure. Of course it depends on the map size.

Filling happens on the CPU. In the average case, there is not even a dynamic allocation, since you can reuse the container. So the operation involves only copying some objects.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

 

anything