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

Author Topic: Pixel-perfect Sprite SubRect  (Read 10926 times)

0 Members and 1 Guest are viewing this topic.

lucasncv

  • Newbie
  • *
  • Posts: 15
    • View Profile
Pixel-perfect Sprite SubRect
« on: September 26, 2011, 12:11:37 am »
I'm trying to solve a little problem that I have with SFML Sprites and low-res spritesheets (e.g. pixel art). I'm using a Sprite to draw a 16x16 subrect of a spritesheet and getting weird texture mapping results.

For example, if I draw this 16x16 subrect at a position with rounded coordinates (5.0, 5.0), everything goes fine, but when I draw it at (5.5, 6.5), the subrect exceeds its borders. Here's a screenshot of the problem reproduced using the Sprite Tutorial's code:



When I move the sprite, that line appears. I've seen another topics on this subject here, with mixed results. Some say SFML 2.0 corrected this problem, but I upgraded the tutorial's code to 2.0 and the problem persisted (but it doesn't happen as often). Some say that pixel-aligning the sprite fixes it, which is true, but trying to align sprites that represent physics entities is complicated and movement becomes weird, not as smooth as I want. Oh, and enabling nearest neighbor filtering does not fix it either.

My current workaround is by using a SFML2's 16x16 RenderTexture, I draw the tile on it, then draw it on the window, this way the problem is 100% fixed no matter where I draw it, but now my render logic is ~33% slower, and memory consumption is also higher.

So I come here today to ask you guys if there's another fix, another technique, something I've missed, anything... Development's going really fast with SFML, I love it.

Thanks in advance.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Pixel-perfect Sprite SubRect
« Reply #1 on: September 26, 2011, 06:02:45 am »
I don't think there's another way of solving it, sorry :?
Laurent Gomila - SFML developer

Disch

  • Full Member
  • ***
  • Posts: 220
    • View Profile
Pixel-perfect Sprite SubRect
« Reply #2 on: September 26, 2011, 08:49:04 am »
I would extend the texture so the tile graphics are actually 18x18, but you only draw the inner 16x16.  That way even if it blends it will just draw more of the same image and will look fine.

Another option would be to simply not have fractional positions.  IE:  don't draw to (5.5, 6.5).

lucasncv

  • Newbie
  • *
  • Posts: 15
    • View Profile
Pixel-perfect Sprite SubRect
« Reply #3 on: September 26, 2011, 02:57:24 pm »
I've been reading SFML2's code and noticed that the Renderer makes the Model View transformations itself, and not OpenGL anymore, is this correct?

If that's the case then all I'd have to do is implement my own ProcessVertex, with floor() at the end, this way everything would be pixel aligned, does that make sense? What would be the best way to do that? I don't mind rewriting a few classes, it's still simpler than handling alignment physics-side.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Pixel-perfect Sprite SubRect
« Reply #4 on: September 27, 2011, 09:18:31 pm »
Quote
If that's the case then all I'd have to do is implement my own ProcessVertex, with floor() at the end, this way everything would be pixel aligned, does that make sense? What would be the best way to do that? I don't mind rewriting a few classes, it's still simpler than handling alignment physics-side.

Yes, and that was even done before. If you look at the Git log for Renderer.cpp you can find a revision which contains this code (it's two additional lines in ProcessVertex).
Laurent Gomila - SFML developer

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Pixel-perfect Sprite SubRect
« Reply #5 on: September 27, 2011, 10:40:07 pm »
I think this is the same problem I already had here.

Do the issues persist exactly as they were in the new graphics API? Would the possibility for customization be too low-level?
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

lucasncv

  • Newbie
  • *
  • Posts: 15
    • View Profile
Pixel-perfect Sprite SubRect
« Reply #6 on: September 27, 2011, 10:50:52 pm »
Quote from: "Laurent"
Yes, and that was even done before. If you look at the Git log for Renderer.cpp you can find a revision which contains this code (it's two additional lines in ProcessVertex).


I just tried that today, but I didn't like the result... First, the movement is weird, but I can live with that. The problem is that rotating the sprite, even with all vertices having rounded coordinates, can still produce the artifact.

To complicate things even more, the way my engine draws the sprites introduces a new problem: sometimes there's a space of 1 pixel between the tiles, result of rounding the coordinates.

My conclusion is that this drawing approach I'm using doesn't go well with the spacial freedom of a physics-based game. I'll have to find another way...

Groogy

  • Hero Member
  • *****
  • Posts: 1469
    • MSN Messenger - groogy@groogy.se
    • View Profile
    • http://www.groogy.se
    • Email
Pixel-perfect Sprite SubRect
« Reply #7 on: September 27, 2011, 11:01:14 pm »
I'm not 100% sure if it got to do with this but I remember one of my class mates talking about something similar or maybe the exact thing(It's about a year ago now) and he said he fixed his problem by offsetting the sprite with 1 pixel. So instead of having origo at 0,0 it was at 1,1

Though what he used was HGE and could have been HGE specific and maybe even totally unrelated. Though couldn't hurt to mention it.

Anyhow, going with the padding solution didn't help you?
Developer and Maker of rbSFML and Programmer at Paradox Development Studio

lucasncv

  • Newbie
  • *
  • Posts: 15
    • View Profile
Pixel-perfect Sprite SubRect
« Reply #8 on: September 27, 2011, 11:04:49 pm »
Quote from: "Nexus"
I think this is the same problem I already had here.

Do the issues persist exactly as they were in the new graphics API? Would the possibility for customization be too low-level?


I've seen your topic before, my engine was entirely built around SFML 1.6, when that problem came along I decided to refactor it around SFML2. The problem persisted even though it didn't happen as often.

To reproduce the problem I used the tutorial I mentioned, in the original SFML 1.6 code, upgraded to SFML 2 and now with the rounded coordinates modification. Nothing fixed it completely. I also tried it with almost no SFML code, only direct OpenGL stuff, and the artifact was still there.

What annoys me most is that I can't find anything related to this, what I could find was here in the forums. I've never played an OpenGL game with that problem either, even the ones that look just like my game, that use spritesheets, physics, and have smooth motion. And I also never had this problem when my engine was based on Direct3D 9.

I'll have to take a day off just to think about this...

lucasncv

  • Newbie
  • *
  • Posts: 15
    • View Profile
Pixel-perfect Sprite SubRect
« Reply #9 on: September 27, 2011, 11:12:04 pm »
Quote from: "Groogy"
I'm not 100% sure if it got to do with this but I remember one of my class mates talking about something similar or maybe the exact thing(It's about a year ago now) and he said he fixed his problem by offsetting the sprite with 1 pixel. So instead of having origo at 0,0 it was at 1,1


I didn't quite get what you mean, is it like just a simple translation?

Quote from: "Groogy"
Anyhow, going with the padding solution didn't help you?


You mean the padding on the spritesheet? I could do that, it's just that I have a whole lot of animation and spritesheets ready.

The truth is that what I'm doing is rewriting an old game of mine from scratch and porting it to OpenGL (it was made with D3D), so I'd do anything possible to don't even touch the artwork. Well, if in the end nothing works...  :?

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Pixel-perfect Sprite SubRect
« Reply #10 on: September 28, 2011, 01:32:04 am »
Sorry, my question was misleading. I actually meant the new graphics API Laurent is currently developing, and wondered if this topic might be affected by it. Laurent is probably the only one who can answer that ;)
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

lucasncv

  • Newbie
  • *
  • Posts: 15
    • View Profile
Pixel-perfect Sprite SubRect
« Reply #11 on: September 28, 2011, 02:15:24 am »
Oh, I didn't know that, is it available for testing? And by the way, I just found a temporary (or maybe permanent, I don't know) solution for my problem: if I subtract exactly 0.0075 from the right and bottom coordinates of the subrect, the sprite remains the same if drawn on whole coordinates, and there's no artifact if it's drawn on fractional coordinates.

I've tried to add these little offsets before, but always at the vertices positions, never at the source rectangle. To test, I've been zooming in and out with a few different sprites on the screen, rotating and moving them, and no signal of the rasterization artifact. As I want to resume development ASAP I'll just leave this 'epsilon' there  :roll:

Maybe it only works in my low-res spritesheet scenario, who knows?


EDIT: Forgot to say that I'm doing that subtraction in the current implementation of my drawing system, the one with pure OpenGL stuff, so that epsilon is applied directly at glTexCoord2f calls.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Pixel-perfect Sprite SubRect
« Reply #12 on: September 28, 2011, 08:01:56 am »
Quote
Do the issues persist exactly as they were in the new graphics API? Would the possibility for customization be too low-level?

This is a rasterization issue, so the new API won't help.

Quote
Oh, I didn't know that, is it available for testing?

Not yet. It's still being discussed.

Quote
And by the way, I just found a temporary (or maybe permanent, I don't know) solution for my problem: if I subtract exactly 0.0075 from the right and bottom coordinates of the subrect, the sprite remains the same if drawn on whole coordinates, and there's no artifact if it's drawn on fractional coordinates.

Looks like the good old "half-pixel trick".
I'll try it (...again :lol:), thanks for your feedback.
Laurent Gomila - SFML developer

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Pixel-perfect Sprite SubRect
« Reply #13 on: September 28, 2011, 12:04:10 pm »
Quote from: "lucasncv"
And by the way, I just found a temporary (or maybe permanent, I don't know) solution for my problem: if I subtract exactly 0.0075 from the right and bottom coordinates of the subrect, the sprite remains the same if drawn on whole coordinates, and there's no artifact if it's drawn on fractional coordinates.
Doesn't the problem reappear if you offset your sprite by this value?

Quote from: "Laurent"
This is a rasterization issue, so the new API won't help.
Ah, right. I thought one could customize the rounding function, but in fact, this only shifts the issue to another coordinate...
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

lucasncv

  • Newbie
  • *
  • Posts: 15
    • View Profile
Pixel-perfect Sprite SubRect
« Reply #14 on: September 28, 2011, 03:08:36 pm »
Quote from: "Nexus"
Doesn't the problem reappear if you offset your sprite by this value?

I read your questin and went test it fearing it would make sense and the problem would reappear, to my surprise it did not. I tried drawing the same subrect as I did on my first post at .0075f and .9925f (1 - .0075) coordinates and no signal of the artifact.

My theory is that I am removing a really small area of the subrect so in the end it doesn't affect anything, but it's enough to impact rasterization when it tries to exceed the borders. Even if I draw the vertices at that offset, nothing happens since the area is actually cut down, and not just translated.

I'd love to know if this works on high-res stuff, but as I'm fed up with this graphical stuff I'll just leave the testing to someone else  :wink: