Jump to content
  • Advertisement
Sign in to follow this  
Browser12

OpenGL Scrolling woes - either pixelated or blurry...

This topic is 3745 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

So my isometric game is scrolling around and everything just fine when the character moves. However, if I always int() the camera position vector, it looks kind of odd, because it just rapidly jumps by one pixel at a time when the character moves. It's rather noticeable since I'm working at 640 x 480. If I don't int() the camera position vector and tell OpenGL to draw everything based on whatever float value the camera position is at, then I get a lot of ugliness. For example, black lines (the normally covered-up background color) will show up between my tiles, as well as faint borders around all other objects (player, static objects) drawn. In addition, everything is rather blurry-looking. I could solve the latter problem by just int()'ing the camera position when the character is done moving. This would be ideal, but I need a way to get rid of the texture outlines. :[ I sort of understand why they're there, but is there some way to fix that? If anyone would like to know more about the scene in order to better understand, do let me know. Anyways, thanks for reading! ^^

Share this post


Link to post
Share on other sites
Advertisement
The black stuff you are seeing is because your texture contains black texels that are neighbors to the texel you use to draw your tiles. That could also mean that your tiles are not tightly packed with the background showing in between them, But you can easily fix that by matching screen coordinates between neighboring tiles : tile1 from 0.0 to 10.0, tile2 from 10.0 to 20.0 etc.

When doing bilinear filtering and arbitrary float alignment to your screen grid, your pixel center (the position where you sample) can fall between four texel centers. That means that in the center of your tile things will be blurry and in the outer limit of your tile you will sample those black texels in addition to the texel from your original tile image.

There are different options to limit that :
- The color on the outside of the tile need to be equal/close to the color of the tile next to it on the screen. (if tile1 is left to tile2, and the rightmost texels of tile1 is red, then you need the border texels outside tile2 to be red). Better said than done if your designer can set tiles arbitrarily on the screen (no way to predict which tile is going to be neighbor of which other). Also if your tiles were tightly packed in your texture surface, then that means you may have to put a "protection gutter" or border of one or two texels between each tile.

- You can render tiles aligned to the pixel grid to an offscreen rendertarget then use that as a texture to do the scrolling. Drawback is that you're rendering things twice, one for the render to texture, once for the scrolling. The first render pass ensures that all tiles are drawn where they're supposed to without black texels because there's no bilinear filtering by design in the first pass. The second does the sub pixel placement and once again no black texels will appear and boundaries across tiles will be correctly filtered.

- You can also render things once but with alpha blending to simulate the effect of bilinear filter across tiles border. For this you clear the color buffer to black, set alpha blending mode to additive (pixel output + destination color). Then you make sure that there's a protective border of black texels all around your tiles in the texture (I know it seems contradictory with what we've been suggesting in the first item). Then you render things but with tiles slightly overlapping the equivalent of half a texel over the black border (the center of the black texel is perfectly over the regular color texel of the neighbor tile).
For example, if tile1 slightly overlaps tile2 in the current pixel, the bilinear filter will do:
color of tile1 = (1-s) * texel1 + s * black
color of tile2 = (1-s) * black + s * texel2
then if you render one after the other because we are in additive mode, the two tiles overlapping will result in :
final color = (1-s) * texel1 + s * texel2
That is the equivalent of bilinear filtering of texel1 and texel2.

For sprites that's the same issue. You can for exemple use premultiplied alpha, where the border colors are black and alpha = 0, then the blending mode is srccolor + (1 - srcalpha) * dstcolor.

Now for the blurriness. That's annoying but hardly anything you can do against it in the general case with pixel art. If your screen does not scroll most of the time, or rest when the character is not moving you can use subpixel placement only for smooth scrolling and then when resting/not moving you keep a pixel aligned placement. That way you minimize blurriness only when the screen is moving. Same for the motion of sprites.
Or you can limit your motions to full pixels per frame (1 pixel per frame, 2 pixels per frames etc). But that may be too restrictive for you..

LeGreg

Share this post


Link to post
Share on other sites
Thank you very, very much for the ideas :]
I'm still sifting my way through that third one, I think it might be my best option (since #2 is going to take double rendering, and #1 won't work really with my textures / system). Thank you a -ton- :]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!