RomanLut / INAV-X-Plane-HITL

Hardware-in-the-loop plugin for X-Plane for INAV flight controller firmware
MIT License
51 stars 8 forks source link

HD OSD artefacts #21

Open shannonbaker opened 11 months ago

shannonbaker commented 11 months ago

Small graphical artefacts are observed when HD OSD is overlaid. This occurs and is consistent no matter what font is selected for any HD system. An example is the top of the ENE directional arrow. Multiple other artefacts are observed at edges of certain elements that is unrelated to the source font image. image

Scavanger commented 2 months ago

The problem is that the OSD elements are loaded as one large texture and therefore the OpenGL option CLAMP_TO_EDGE cannot be set for each element. It would be better to load each element as a single texture and let OpenGL do the work. This also simplifies the loading of the textures considerably.

RomanLut commented 2 months ago

Using 512 separate texures is extremely unefficient. This problem can be fixed by adding 2-4px padding beetween characters.

shannonbaker commented 2 months ago

Ok. So I'm torn on this. I raised it but I'm the main person in the community that developed all the fonts. (AKA SNEAKY_FPV). I'm a perfectionist and seeing this stuck out like a sore thumb. If there's enough notice by other pilots I'll see if I can generate some font examples with the glyph padding. But if no one else is complaining/noticing this, then I'll leave sleeping dogs lie.

RomanLut commented 2 months ago

Please do not regenerate fonts. Padding should be added programmatically while loading. Can be easily done, but this is not a high priority task for me.

Scavanger commented 2 months ago

Using 512 separate texures is extremely unefficient.

Normally you would use a TextureArray, but this can only be read in a shader, so no option here, unfortunately.

This problem can be fixed by adding 2-4px padding beetween characters.

We have some elements that need to be displayed side by side without a pixel gap (e.g. numbers with decimal point), wouldn't we have a gap? Or am I on the wrong track?

RomanLut commented 2 months ago

We have some elements that need to be displayed side by side without a pixel gap (e.g. numbers with decimal point), wouldn't we have a gap? Or am I on the wrong track?

Drawing side-by-side characters would be straightforward if the game operated solely in 1080p or 720p resolutions. However, since the window size can vary, scaling becomes an issue. To render such pairs correctly, the only reliable method is to place pre-defined pairs side by side on a texture, detect them, and then draw a single rectangle. This issue is distinct from the artifacts encountered when rendering individual characters.

Scavanger commented 2 months ago

Automatic detection of the pairs (sometimes there are also several tiles, e.g. the INAV LOGO, or the crosshairs) is very time-consuming and must be specially predefined, as a custom font that has the graphics ‘in one piece’ would be simpler. But I think supporting the corresponding goggles fonts would be better.

I measured the performance compared to my old, first implementation with single textures: The current plugin needs about 15 uS when drawing on my computer, the version with single textures 35 uS, which is still 0.0% compared to the rest of XPlane and has no effect on the frame rate.

RomanLut commented 2 months ago

You cannot directly measure the impact because OpenGL calls enqueue drawing commands, which don't correlate with actual drawing time. However, I agree that with the power of modern PC GPU hardware, an additional ~100 batches per frame isn't significant enough to warrant optimization efforts.

Scavanger commented 1 month ago

After a short dive into OpenGL, I think the best and solution would be to use ‘Modern OpenGL’, until now the plugin uses the outdated ‘fixed pipeline’. With ‘Modern OpenGL’ we can use a 2D texture array, which is exactly meant for such purposes, the disadvantage is that the texture array can only be accessed in the shader, so we need a separate vertex and fragment shader, which would be a bit more complex to implement, but, I think, the cleanest solution. Custom shaders are not a problem in X-PLane, by the way.

Scavanger commented 1 month ago

A simple draw Test, in X-Plane, with a INAV-Fonts, GL_TEXTURE_2D_ARRAY and shaders:

Screenshot_20241016_111531