Pages: 1
  Print  
Author Topic: Font Pixel Alignment  (Read 9117 times)
Offline (Male) Goombert
Posted on: July 31, 2014, 09:27:02 pm

Developer
Location: Cappuccino, CA
Joined: Jan 2013
Posts: 2993

View Profile
Ok so I need to describe a fault in our text drawing functions in detail. Some of you may have noticed the interpolation distorts your fonts, but not in the way you would expect. Examine the following.

Note: It really helps to open these images in Paint or another program with no filtering and zoom down to examine the pixels.

In this first image we see what happens when we draw the text at full integer coordinates with interpolation enabled. Notice interpolation does not effect most of the characters and most have crisp edges, as if interpolation is not even enabled.


In this second image we see what happens when we draw the text at half integer coordinates with interpolation. Notice interpolation is mostly working on most of the characters but a few have crisp edges.


Note: This is the behavior observed in Direct3D9 as well, except the behavior appears to be reversed appearing interpolated with full integer coordinates and not with half integer coordinates.

This is not something which can be fixed purely by disabling interpolation or padding the font textures though they still need to be anyway. This could have also been the cause of other font anomalies for some of you at an earlier time. I have also confirmed this issue to be the result of characters rendering at different locations between OGL and D3D if we round and draw at full integer coordinates the characters appear at the exact same location in all graphics systems. The problem exists in our text rendering functions, they either all need to be at full integer coordinates or all at half. Generally they should always be at half integer coordinates with vector graphics, like half pixel alignment in Inkscape.

However, when scrolling backgrounds or text it helps to allow them to transition between half and full pixel integer coordinates to make them blend smoothly. My proposal is simple, we merely need to align all the characters of a draw_text call to either full or half integer coordinates and no in-between, this is something we can all mutually agree on. Now me and Josh disagree however about when extra spacing should be applied, Josh believes it should be every 3rd or 4th character where as I believe the excess spacing should be applied immediately after it reaches a whole number.

It basically has to do with how we handle xx as you can examine on the following line.
https://github.com/enigma-dev/enigma-dev/blob/master/ENIGMAsystem/SHELL/Graphics_Systems/General/GSfont.cpp#L374

With the following modification to the drawn text function, the text and all characters are drawn at full integer coordinates and properly and evenly spaced between all graphics systems at the exact same coordinates with or without interpolation enabled.
Code: (cpp) [Select]
            unsigned xxx = xx;
            draw_vertex_texture(x + xxx + g->x,  yy + g->y, g->tx, g->ty);
            draw_vertex_texture(x + xxx + g->x2, yy + g->y, g->tx2, g->ty);
            draw_vertex_texture(x + xxx + g->x,  yy + g->y2, g->tx,  g->ty2);
            draw_vertex_texture(x + xxx + g->x2, yy + g->y2, g->tx2, g->ty2);
            draw_primitive_end();

These are the results with the above changes. The following is drawn starting at full pixel passed to the draw text function and interpolation enabled, this is actually what it should look like with interpolation enabled when the font texture is not padded.


The following is drawn starting at half pixels passed to the draw text function with interpolation enabled, this is how GM avoids interpolation on font textures, it always draws at full integer coordinates like most game engines.


Now as I said GM and most game engines always render fonts at full integer coordinates, but this can cause them to be blocky when you want scrolling text, it makes the transition much more abrupt, you want this blurring that is caused by half integer coordinates when drawing 2D objects, sprites, backgrounds, and text. Therefore, I believe I will temporarily prepare a pull request to be merged immediately that draws our text at full integer coordinates like everyone else until we can come up with an alternative or decide on a solution.

It would help if everyone including Josh could weigh in and offer their opinions.
« Last Edit: July 31, 2014, 09:50:57 pm by Robert B Colton » Logged
I think it was Leonardo da Vinci who once said something along the lines of "If you build the robots, they will make games." or something to that effect.

Offline (Unknown gender) Darkstar2
Reply #1 Posted on: July 31, 2014, 11:49:08 pm
Member
Joined: Jan 2014
Posts: 1238

View Profile Email
It's weird I have never seen this font anomaly before....I thought we had fixed this before and it worked great for everyone, where did this come from all of a sudden ???

There is nothing worse than BLURRING shite.

Why would anybody want blurry fonts !?!?!?

Are you talking about the slight blurring only during movement of sprite, fonts etc ? I would personally not use anything that adds any type of blurring or scrolling anomalies in my games.

With or without interpolation I have never had the problems described in your screenshots.   Is this another graphic card specific issue?
« Last Edit: July 31, 2014, 11:51:56 pm by Darkstar2 » Logged
Offline (Male) Goombert
Reply #2 Posted on: August 01, 2014, 12:00:44 am

Developer
Location: Cappuccino, CA
Joined: Jan 2013
Posts: 2993

View Profile
Quote
Are you talking about the slight blurring only during movement of sprite, fonts etc ?
Yes as I said this is specifically to make it both clear and allow it to interpolate properly for scrolling text. Make a scrolling background and make the x and y values round() instead of being floating point or half integer and you'll notice the scrolling is much more abrupt, it goes directly to the next pixels instead of interpolating and blending in between. You want this blurring in certain cases is what I am arguing.

Quote
With or without interpolation I have never had the problems described in your screenshots. Is this another graphic card specific issue?
You've never seen because in your local copy before texture handling was made compatible with Studio I was blocking interpolation for fonts which is no longer feasible. And no this is probably directly related to the font anomalies you guys were having before, we duck tapped over it instead of fixing the underlying issue, remember?
Logged
I think it was Leonardo da Vinci who once said something along the lines of "If you build the robots, they will make games." or something to that effect.

Offline (Unknown gender) Darkstar2
Reply #3 Posted on: August 01, 2014, 12:13:15 am
Member
Joined: Jan 2014
Posts: 1238

View Profile Email
Yes as I said this is specifically to make it both clear and allow it to interpolate properly for scrolling text. Make a scrolling background and make the x and y values round() instead of being floating point or half integer and you'll notice the scrolling is much more abrupt, it goes directly to the next pixels instead of interpolating and blending
in between.

Oh yes that I know exactly what you mean, that blurring effects masks things.  And yes I know what you mean by abrupt transition, though people using LCD monitors as opposed to CRT, will have the natural "blending" effect, particularly on faster scrolls.

Quote
You've never seen because in your local copy before texture handling was made compatible with Studio I was blocking interpolation for fonts which is no longer feasible. And no this is probably directly related to the font anomalies you guys were having before, we duck tapped over it instead of fixing the underlying issue, remember?

Yes I remember how can I forget this shit, it was a nightmare and a pain in my arse! :D
But as I replied to your PM, the lines you've given me DID NOT fix the font artifacts. So I disagree this issue was unrelated, as when I applied your lines it had no effect.  Once you have this official and the option to turn it on/off in LGM because nobody wants forced crap a-la-YYG, then I'll test it without the fix and see, though I still think the issue was more complex.

Logged
Offline (Unknown gender) TheExDeus
Reply #4 Posted on: August 01, 2014, 04:37:50 am

Developer
Joined: Apr 2008
Posts: 1860

View Profile
Quote
These are the results with the above changes. The following is drawn starting at full pixel passed to the draw text function and interpolation enabled, this is actually what it should look like with interpolation enabled when the font texture is not padded.
Would the padding really help here? It seems the problem is not "leaks" from nearby glyphs, it's the fact that it blurs the texture by itself. So if you padded, it would still look bad.
Logged
Offline (Male) Josh @ Dreamland
Reply #5 Posted on: August 01, 2014, 07:02:48 am

Prince of all Goldfish
Developer
Location: Pittsburgh, PA, USA
Joined: Feb 2008
Posts: 2950

View Profile Email
No. The purpose of padding is to prevent noise around glyph bounding rectangle edges from nearby glyphs being interpolated across those boundaries. This is due to the fact that every time someone tries to half-pixel align ENIGMA's orthographic projections, as they should be, there's a 16-week debate about how this actually makes some cards rendering worse. Of course, in this case, it doesn't seem to matter. Every other glyph is drawn correctly, which means to me that someone is adding half-pixels to the font coordinates and not rounding them before drawing.
Logged
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble
"I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
Offline (Male) Goombert
Reply #6 Posted on: August 01, 2014, 03:12:18 pm

Developer
Location: Cappuccino, CA
Joined: Jan 2013
Posts: 2993

View Profile
Quote from: JoshDreamland
The purpose of padding is to prevent noise around glyph bounding rectangle edges from nearby glyphs being interpolated across those boundaries.
This is the single most important thing you guys should pay attention to, this is why I suggested downloading and examining the screenshots above at a closer view. This is only one of our issues.

Quote from: JoshDreamland
This is due to the fact that every time someone tries to half-pixel align ENIGMA's orthographic projections, as they should be, there's a 16-week debate about how this actually makes some cards rendering worse.
Because there is no need to align our projection functions to fix issues in draw text. That was the ugliest hack ever.

Quote from: JoshDreamland
Every other glyph is drawn correctly, which means to me that someone is adding half-pixels to the font coordinates and not rounding them before drawing.
Yes, glyph->xs is float remember?
https://github.com/enigma-dev/enigma-dev/blob/master/ENIGMAsystem/SHELL/Universal_System/fontstruct.h#L32
https://github.com/enigma-dev/enigma-dev/blob/master/ENIGMAsystem/SHELL/Universal_System/fontinit.cpp#L137

Basically, what I am saying here you guys is this. First thing we want to do is get either all of the characters at half pixels or none of them at half pixels, that will allow smooth transition with scrolling text. Then we need to make sure the characters appear at the same locations in Direct3D and OpenGL. Then we need to add padding to the font texture. Then we can add blocking of texture interpolation on text rendering functions.
« Last Edit: August 01, 2014, 03:18:08 pm by Robert B Colton » Logged
I think it was Leonardo da Vinci who once said something along the lines of "If you build the robots, they will make games." or something to that effect.

Offline (Unknown gender) TheExDeus
Reply #7 Posted on: August 01, 2014, 06:53:33 pm

Developer
Joined: Apr 2008
Posts: 1860

View Profile
Quote
No. The purpose of padding is to prevent noise around glyph bounding rectangle edges from nearby glyphs being interpolated across those boundaries.
Yes, but in those screenshots the most noticeable thing for me is the faintness of the text. So even if it renders correctly (like number "8") it is still very faint and transparent, because it's interpolated. Lack of padding creates the problem in the first screenshot, which is what we hackishly fixed with the projection offset.
Logged
Offline (Male) Goombert
Reply #8 Posted on: August 01, 2014, 11:45:22 pm

Developer
Location: Cappuccino, CA
Joined: Jan 2013
Posts: 2993

View Profile
Lack of padding is noticeable in every one of the screenshots except the last. And the near invisibility of the text is because it's so small if it were a bigger font that would not be the case, only the edges would be that way, the font is so small and skinny the character is practically all edge.

The essence of this entire post is that I was able to draw perfectly crisp text that looks completely uninterpolated with interpolation enabled under special circumstances! I am actually interested to understand more about how interpolation and text filtering is calculated, it seems odd to me that it would have anything to do with screenspace.
« Last Edit: August 01, 2014, 11:47:21 pm by Robert B Colton » Logged
I think it was Leonardo da Vinci who once said something along the lines of "If you build the robots, they will make games." or something to that effect.

Offline (Male) Josh @ Dreamland
Reply #9 Posted on: August 02, 2014, 10:55:38 am

Prince of all Goldfish
Developer
Location: Pittsburgh, PA, USA
Joined: Feb 2008
Posts: 2950

View Profile Email
The text is faint where pixels from a 1px-wide vertical portion are drawn horizontally across two pixels, and likewise where pixels from 1px-thick horizontal portion are drawn across two pixels vertically. This happens when the pixels are not contained in integer bounds—i.e, when the center of the pixel is drawn anywhere but a half-pixel boundary. From what I'm seeing, this happens every other glyph, meaning that at some point, they *are* aligned, and at some point, they aren't. Considering it alternates, the only logical conclusion is that someone is adding floating point numbers to the font spacing accumulator, which I told Robert would require rounding before drawing at those coordinates. It seems he's figured that much out.

Setting the projection to half-pixel coordinates should be the default behavior for draw_/d3d_set_projection_ortho. This isn't just for fonts; it's for every single sprite-based resource. With interpolated lines, it'll also be clear really quick that the projection is not half-pixel aligned.

Again, fonts should be drawn at whole-integer bounds. The projection should be set with a half-integer shift. That's just how 2D game projections work.
Logged
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble
"I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
Offline (Male) Goombert
Reply #10 Posted on: August 02, 2014, 03:14:35 pm

Developer
Location: Cappuccino, CA
Joined: Jan 2013
Posts: 2993

View Profile
Quote from: JoshDreamland
Considering it alternates, the only logical conclusion is that someone is adding floating point numbers to the font spacing accumulator, which I told Robert would require rounding before drawing at those coordinates. It seems he's figured that much out.
Yes, glyph->xs is float remember?
https://github.com/enigma-dev/enigma-dev/blob/master/ENIGMAsystem/SHELL/Universal_System/fontstruct.h#L32
https://github.com/enigma-dev/enigma-dev/blob/master/ENIGMAsystem/SHELL/Universal_System/fontinit.cpp#L137

Quote from: JoshDreamland
With interpolated lines, it'll also be clear really quick that the projection is not half-pixel aligned.
I am sorry but you are incorrect, this is the entire reason GM8.1 < have the option to enable interpolation to make scaling and rotating sprites smoother. Half pixel aligning the projection just attempts to mask the interpolation/blurring because apparently some people do not understand the purpose.

I have only noticed issues such as gaps between scrolling backgrounds with the projection being pixel aligned. Also important to note is that when characters are drawn at whole integer coordinates they appear EXACTLY the same between Direct3D and OpenGL, the exact same coordinates, spacing, and everything down to each and every pixel.

And again, what about people that want scrolling text to interpolate smoothly?
Logged
I think it was Leonardo da Vinci who once said something along the lines of "If you build the robots, they will make games." or something to that effect.

Offline (Male) Josh @ Dreamland
Reply #11 Posted on: August 03, 2014, 11:43:55 am

Prince of all Goldfish
Developer
Location: Pittsburgh, PA, USA
Joined: Feb 2008
Posts: 2950

View Profile Email
...Interpolation occurs when scaling or when drawing across pixel boundaries. If you aren't scaling the text, then the only reason you will have "blurred" fonts is if you are not keeping the vertices on half-pixel bounds.

For our purpose, the projection should always be offset by a half pixel in either direction.

And at this point, I think that all the problems we've had in the past with projection have been less to do with people's cards not working and more to do that no one could ever stop fucking panicking and changing stupid shit long enough to just see if something was working. Has there ever been a point in any of ENIGMA's history wherein we had half-pixel projection offsets, and were making sure to draw font glyphs on whole-integer bounds? I seriously fucking doubt it, at this point.

if you're going to ask "what about the people who want <x>," you should start considering the people who want a 128×96 views blown up to 480p or 600p.
« Last Edit: August 03, 2014, 11:46:30 am by Josh @ Dreamland » Logged
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble
"I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
Offline (Unknown gender) Darkstar2
Reply #12 Posted on: August 03, 2014, 02:12:40 pm
Member
Joined: Jan 2014
Posts: 1238

View Profile Email
you should start considering the people who want a 128×96 views blown up to 480p or 600p.

ZZZZZZZZINNNGGGGG!   :D ;D
Logged
Offline (Male) Josh @ Dreamland
Reply #13 Posted on: August 03, 2014, 04:43:46 pm

Prince of all Goldfish
Developer
Location: Pittsburgh, PA, USA
Joined: Feb 2008
Posts: 2950

View Profile Email
No; believe it or not, that was for srs. I used to get complaints about that when I'd leave coordinates as integers, because graphics would hop around as if snapped to a grid (namely, integers :P).
Logged
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble
"I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
Offline (Unknown gender) Darkstar2
Reply #14 Posted on: August 03, 2014, 07:09:18 pm
Member
Joined: Jan 2014
Posts: 1238

View Profile Email
No; believe it or not, that was for srs. I used to get complaints about that when I'd leave coordinates as integers, because graphics would hop around as if snapped to a grid (namely, integers :P).

Well we are in 2014, and there is nothing worse than the shitty "hopping around" as you call it effect of scrolling graphic and text, it makes it look very unprofessional !  I like the idea of having smooth transitions (scrolling/movement) etc, that might come with a small cost, however what I would not like is for the still image to be blurry or significant blurring during movement.

Your 128x96 blown up to 480p gave me a good laugh I needed that actually thanks :D

Logged
Pages: 1
  Print