YoYoGames / GameMaker-Bugs

Public tracking for GameMaker bugs
15 stars 7 forks source link

SDF Fonts and Vertex Batch #6522

Open Patchy-DaYo opened 6 days ago

Patchy-DaYo commented 6 days ago

Description

As requested, here is another report with a demo project attached.

I noticed that my vertex batch numbers increased dramatically recently and I quickly found out the reason why: each call to draw_text() breaks the batch when using an SDF font.

I display my characters one by one to simulate an animation in a chat (pretty standard stuff). For that reason, if I display 200 characters in a text paragraph, the result is 200 additional batch breaks per frame. I can confirm that simply disabling the SDF option in the font solves the issue, it's not a mater of changing the color, or effects.

Which version of GameMaker are you reporting this issue for?

IDE v2024.6.0.157 Runtime v2024.4.1.202

Which operating system(s) are you seeing the problem on?

Windows 10.0.22621.0

Which platform(s) are you seeing the problem on?

Windows

51655728-d9aa-4a15-beaa-62f529760702

gnysek commented 5 days ago

This might be caused by using shaders for SDF and not being a bug in fact.

Patchy-DaYo commented 5 days ago

the code is not doing anything between the calls to draw_text() so shader or not, this should not cause such a performance issue imo.

gnysek commented 5 days ago

@Patchy-DaYo according to HTML5 source code, if you're using SDF fonts, every time you call draw_text, additional code is called - before and after actual draw_text - you can see it for example here: https://github.com/YoYoGames/GameMaker-HTML5/blob/965f410a6553dd8e2418006ebeda5a86bd55dba2/scripts/yyFont.js#L2400C5-L2400C30

            if (thefont.sdf) 
            { 
                this.End_Rendering_SDF(); 
            } 

This for example releases shader and changes texture interpolation, according to source code.

So without further looking into source, we can assume drawing 200 letters using separate draw_text() for each means you're setting and re-setting shader 200 times, and changing texture interpolation mode 400 times (even if in fact it switches to same mode...). Of course this is not comfort situation, as there's no simple way to bypass this*, when you need to use draw_text() to have custom spacing or something - and still it would be great if it could be somehow optimised. That might be not a bug though.

_* by copying YYG shader for it, you could make custom shader, set uniforms before first drawtext, and reset after last one, which would mean 2-4 batch breaks IMO...

SDF shaders can be found in C:\ProgramData\GameMakerStudio2\Cache\runtimes\runtime-<VERSION_2024_X_X_X>\bin\ProjectImports\

Patchy-DaYo commented 5 days ago

I understand shaders are in use in this case but SDF being now officially implemented in GameMaker, this should not affect end users like this. A fix could be implemented by the devs in several ways, including adding new functions such as a possible "prepare_draw_text()" function to cover this. Thanks for your consideration.