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

Login with username, password and session length

 
Advanced search

877651 Posts in 32876 Topics- by 24313 Members - Latest Member: CWolf

May 20, 2013, 05:37:25 AM
TIGSource ForumsDeveloperTechnical (Moderators: Glaiel-Gamer, ThemsAllTook)Drawing from an opengl screen atlas, objects "bleed" at edges
Pages: [1]
Print
Author Topic: Drawing from an opengl screen atlas, objects "bleed" at edges  (Read 1165 times)
mcc
Level 10
*****


glitch


View Profile WWW Email
« on: April 04, 2012, 08:36:05 PM »

Kinda confused about this!

I have this pc game I made at Molyjam this weekend.

http://msm.runhello.com/?p=544

The title screen for this game has a routine for displaying a screen full of bitmap font. I'm trying to mimic the screen from an Apple //c. The screen, correctly drawn, looks like this. The code to draw this bitmap text is here:

https://bitbucket.org/runhello/molyjam/src/eedd07bbab66/source/dos.cpp

The way it works is I have a small 128x128 PNG containing the entire bitmap font, and I load that into a texture, then I draw single quads for letters. The important parts are english() and clipush().

What I am finding is that on the top side of single letter glyphs, there is sometimes a one-pixel-tall glitch where the glyph above that letter in the english.png leaks through. Notice above the lowercase os and above the asterisk, and also a thin black line above all |s. Notice, it is one *pixel* tall-- it is much smaller than a texel. Worse, this problem happens only on some people's computers-- not mine. It seems to only happen on computers with better video cards, there is no problem on nvidia mobile gpus Tongue

The texture is set up with _NEAREST and no mipmaps and no anisotropy.

Why might this be happening, and is there ANYTHING I can do to make it not happen, or debug it? I looked on google and what every source I found said was "add 0.5/texture_width to all of your texture coordinates". I did this and it made the problem much worse, whereas before I was not seeing the problem on my mac w/ nvidia mobile I started seeing it once I added half a texel to all the coordinates. So now I don't even know.

Even more puzzlingly, some of the people who said they saw this on their computers said they did NOT see the same artifacts in this earlier game I made, which had the same bitmap text code (look for "clipush") more or less copied and pasted (although drawn more directly with vertex arrays whereas the drawing in "Shadowland Prophesy" was done by Polycode).

I plan to reuse this bitmap font code so I want to figure out why it isn't working... Sad
Logged

My projects:<br />Games: Jumpman Retro-futuristic platforming iJumpman iPhone version Drumcircle PC+smartphone music toy<br />More: RUN HELLO
mcc
Level 10
*****


glitch


View Profile WWW Email
« Reply #1 on: April 04, 2012, 10:50:19 PM »

Confusing myself even more!

If I subtract (1/8)/texture_width from my vertical texture coordinates, the one-row-of-pixels-at-top problem goes away on those systems where it was previously occurring.

However, then if I turn the resolution up high enough (on my system, where it previously was not occurring) I have a spurious row of pixels on the bottom :/
Logged

My projects:<br />Games: Jumpman Retro-futuristic platforming iJumpman iPhone version Drumcircle PC+smartphone music toy<br />More: RUN HELLO
Netsu
Level 10
*****



View Profile WWW
« Reply #2 on: April 04, 2012, 11:17:38 PM »

I think the surest (but probably most problematic) way to get rid of this is make the characters in the texture more spaced out. Leave a 1px border around each character and don't draw this border in your game.
Logged

mcc
Level 10
*****


glitch


View Profile WWW Email
« Reply #3 on: April 04, 2012, 11:22:43 PM »

I think the surest (but probably most problematic) way to get rid of this is make the characters in the texture more spaced out. Leave a 1px border around each character and don't draw this border in your game.
This is what I usually do but this is a font and the font fills its space fully :|

I mean I guess I can just go up to 256x256... I guess it just seems startling there's no way to draw a texture and be certain which pixels you're getting in the texture.
Logged

My projects:<br />Games: Jumpman Retro-futuristic platforming iJumpman iPhone version Drumcircle PC+smartphone music toy<br />More: RUN HELLO
Ludophonic
Level 1
*


View Profile
« Reply #4 on: April 04, 2012, 11:26:32 PM »

Imagine an 8x8 grid of pixels. The texture 0.0 Y-coordinate will be the top edge of the grid (not the centre of the first row of pixels) and the 1.0 Y-coord will be the bottom edge of the grid. This is why the recommendation to add 0.5/texture_size to your texture coordinates that you found. If you're drawing to pixel positions for an exact match this will turn 0 to 7 to (0.5,7.5)/size so you'll get the centre of the pixels in the texture. If each pixel in the texture is meant to be several pixels on screen you would actually want to add 0.5/(texture_size*pixel coverage). So if you had 4x4 "pixels" then your coverage would be 4.

The above also applies to the frame buffer coordinates. When trying to specific a specific line in the frame buffer and not using the screen space vertex functions it's common practice to add 0.375 to get the exact pixel you want.

Basically if you specify a coordinate right on one of the 'gridlines' between two pixels you can't guarantee which side it's going to sample from and this will very from computer to computer because of floating point precision inconsistancies.

One test you might do is to turn on bilinear filtering and take a screenshot. The greyscale will give you an idea of where in the texture you're sampling from. 50% grey will mean you're taking right from the boundary line between two pixels.

You can also take your current screenshots and look at the position of the single pixel lines. If you're filling the screen with 4x4 'pixel' text then every character's position should be a multiple of 4 * character height. It looks like your characters are 8x8 so that means each line should start at a multiple of 32. If one of those lines is at 479 instead of 480 that would mean your math for calculating your character positions was off.
Logged
mcc
Level 10
*****


glitch


View Profile WWW Email
« Reply #5 on: April 06, 2012, 03:11:18 PM »

If each pixel in the texture is meant to be several pixels on screen you would actually want to add 0.5/(texture_size*pixel coverage). So if you had 4x4 "pixels" then your coverage would be 4.
Okay, I think this is what I was missing. I think I understand why this makes sense...

I tested this and got even more confused. I started adding (1.0/(128*colfactor*2)) where 128 is the known size of the texture and "colfactor" is the scale factor (1x,2x,3x,4x) of how many "texels" per pixel. When tested at a large scale (unfortunately, I don't have any machines that misbehave, so I can only test by mailing the game to lots of people) it works. However, when I set the scale to 1x (i.e. pixel coverage is one texel = one pixel) I get pixel bleed over:

http://i.imgur.com/XFRh1.png

Even though at that point I'm adding 1/(2*128) to each pixel and that should have me smack dab in the middle of each texel, so I don't understand how this is happening.

Quote
One test you might do is to turn on bilinear filtering and take a screenshot. The greyscale will give you an idea of where in the texture you're sampling from. 50% grey will mean you're taking right from the boundary line between two pixels.

I assume you mean at 1x scale (because at 2x scale or with higher-than-1 "pixel coverage" it would naturally be interpolating between points always). I also assume you just mean, turn on _LINEAR instead of NEAREST?

Oddly, adding (0,0) to each texture coord I see things as I expect to see things: http://i.imgur.com/iPZwP.png
Adding 1/256 I see a mess: http://i.imgur.com/ggbWO.png

This is the opposite of what I would expect.

I begin to wonder if Polycode is doing some texture coord adjustment for me, but I can't find any such thing in the source code. The shader uses gl_TextureMatrix but doesn't seem to be setting the texture matrix anywhere.

Quote
You can also take your current screenshots and look at the position of the single pixel lines. If you're filling the screen with 4x4 'pixel' text then every character's position should be a multiple of 4 * character height. It looks like your characters are 8x8 so that means each line should start at a multiple of 32. If one of those lines is at 479 instead of 480 that would mean your math for calculating your character positions was off.
You mean, assuming that the texture starts at pixel 0,0 right? Hm.

It would be nice to understand what is happening here but I am currently leaning toward the pixel doubling solution as it is the one thing guaranteed to in all circumstances work. :/
Logged

My projects:<br />Games: Jumpman Retro-futuristic platforming iJumpman iPhone version Drumcircle PC+smartphone music toy<br />More: RUN HELLO
Ludophonic
Level 1
*


View Profile
« Reply #6 on: April 06, 2012, 04:56:38 PM »

Quote
You mean, assuming that the texture starts at pixel 0,0 right? Hm.

I put a portion of your image onto a checkerboard background to show you what I mean. If your screen coordinates are correct nothing should be above the top edge of the C even if your texture coordinates are off.



So it looks like your screen coordinates are off. That's probably why you still see errors no matter how you play with your texture coordinates. You need to fix both. Different GPUs have different precision and rounding in their internal calculations so you're probably seeing the effects of one calculating 0.49999999 while another calculates 0.50000001. Try just adding/subtracting a small epsilon like 0.00001 to both your character positions and texture coordinates to make your boxes slightly smaller along each side. Add the epsilon to the smaller UV/XY coordinate and subtract it from the larger.
« Last Edit: April 06, 2012, 08:44:30 PM by Ludophonic » Logged
mcc
Level 10
*****


glitch


View Profile WWW Email
« Reply #7 on: April 07, 2012, 12:17:00 AM »

Part of the problem is I don't actually have a computer which is experiencing the problem. So all I can do is repeatedly make test builds and email them to the one tester I have. This makes it hard to experiment with small changes like different epsilons.

So I totally knew this was going to happen as soon as I saw your "checkboard" image, but, I tried the doubling solution and really it didn't work either, there are still artifacts of various kinds:

Here's what I get if I actually double the pixels at the edge (Notice: Gaps between all bars)

Here's what I get if I place a zero-alpha gap between each cell (Notice: Top texel of each letter is exactly one pixel too tall)[/url]

Dejected, I attempted to salvage things by using the pixel-doubler script to make weird Jesus porn.

Basically, as you deduced, each cell in this case is being drawn with one extra pixel "above" and one pixel too little "below".

I then tried one additional thing, experimentally. Your post made me remember that one of the things I found on google said something I didn't understand at the time, but I'm now realizing they meant you want to make sure the outlines of your rects are being drawn precisely on pixel boundaries (i.e., no placing a poly edge between two pixels). I am likely to be doing this because I'm doing this weird thing of trying to center my entire image. So instead of centering the image on the screen as I do currently, I shoved the entire thing into the upper right hand corner.

Looked like this. Everything is correct! And that is without the pixel doubling at the edge.

So, maybe I can get this to work just by trying to "snap" to a pixel...
Logged

My projects:<br />Games: Jumpman Retro-futuristic platforming iJumpman iPhone version Drumcircle PC+smartphone music toy<br />More: RUN HELLO
mcc
Level 10
*****


glitch


View Profile WWW Email
« Reply #8 on: April 08, 2012, 04:08:01 PM »

Simplified the math a bunch so that there are fewer chances for different video cards to do different things. I think it worked?
Logged

My projects:<br />Games: Jumpman Retro-futuristic platforming iJumpman iPhone version Drumcircle PC+smartphone music toy<br />More: RUN HELLO
Pages: [1]
Print
Jump to:  

Theme orange-lt created by panic