Pixel/Texel/Shape/Font Alignment Problems

Reporter: RobertBColton  |  Status: open  |  Last Modified: Today at 01:57:48 AM

This issue has come up a lot in the past, in the form of #702, #733, #735, #721, and #656. In the past these issues may have been exacerbated by inconsistent rendering states we had set in our backends or by differences in our batching logic. However, with so much of the render states, matrices, batching logic, and models generalized now, that's much less likely the cause.

The first thing to discuss is pixel alignment. We allow fractional half-pixel coordinates to be passed to the drawing functions because most of them accept the coordinates as floating point numbers. This part of the issue is a fundamental difference in Direct3D9 because its viewport structure only accepts whole integer coordinates and internally offsets the viewport by half a pixel. This causes all of the shape drawing functions to be off from the OpenGL render.

The second thing to discuss is texel alignment. This is another fundamental Direct3D9 difference where it samples texels at corners and pixels in the center. This is what causes textured shapes, like font glyphs, to have rendering differences between GM, ENIGMA, and OpenGL.
http://wiki.ogre3d.org/-Pixel+texel+alignment
https://docs.microsoft.com/en-us/windows/desktop/direct3d9/directly-mapping-texels-to-pixels

Google's ANGLE project deals with one of these issues, the texel alignment, in its vertex shader by offsetting all vertices by a half a pixel. I attempted this in ENIGMA but still could not get all of our backends outputting half pixel lines exactly the same.

This oddity has been corrected in Direct3D 10, but for ANGLE on Direct3D 9, a half-pixel offset is required to adjust the fragment coordinates for this difference.
https://www.seas.upenn.edu/~pcozzi/OpenGLInsights/OpenGLInsights-ANGLE.pdf

RobertBColton  
>Font/Texel Workaround

I do want to mention recently that I discovered an OpenGL knowledge source that talks about bitmap font artifacts. The article recommends to disable texture repeat (equivalent to clamp to edge) and enable texture interpolation.
https://en.wikibooks.org/wiki/OpenGL_Programming/Modern_OpenGL_Tutorial_Text_Rendering_01#Rendering_lines_of_text

I believe GMSv1.4 may actually be doing this internally. We can do it now too very easily by simply tweaking our draw batch flush.

NOTE: Sprites and backgrounds are always drawn without repeating, so once you draw a sprite or background this value is reset to false. This default behaviour will not affect texture stage settings (ie: calling the function will, but the internal setting to false will not).
https://docs.yoyogames.com/source/dadiospice/002_reference/drawing/texture_set_repeat.html

The default value is false, and this can also be changed in the Global Game Settings for individual target platforms.
https://docs.yoyogames.com/source/dadiospice/002_reference/drawing/texture_set_interpolation.html

Please sign in to post comments, or you can view this issue on GitHub.