top | item 42093986

(no title)

janci | 1 year ago

Honest question as I don't know almost anything about modern computer graphics: Is it so much performance penalty to upload a small texture to GPU so you can't render the whole string to the texture in 2D and just display the texture onto two triangles?

discuss

order

nox101|1 year ago

> Is it so much performance penalty to upload a small texture to GPU so you can't render the whole string to the texture in 2D and just display the texture onto two triangles?

It's not. This technique is more about getting text on the screen in the easiest way possible for debugging. You just add some data to your shader and poof, you get text.

The converse is, you write code to generate a font atlas (so more work), or go find and existing one and need to load it (so need to write loading code so more work). And/Or draw a full message into a texture (more work) and you'll need to cache that result until the message changes (more work)

On top of all of that, you need to manage resources and bind them into the system where as here no resources are needed.

but again, it's a technique for getting "debugging text" on the screen. It is not a solution for text in general.

Note that drawing text to textures is how most browsers and OSes work. They draw fonts into texture atlases dynamically (since a atlas for all of Unicode per font per size would take too much time and memory). They then use the texture atlas glyphs to make more textures of portions of the app's window. In the browser you can turn on show texture edges to see all textures. Rendering->Layer borders will outline each texture in cyan

jamesu|1 year ago

Generally you want to avoid wasting too much memory on a GPU, even today. That large text box texture also has to go over the PCI bus which can cause stalls depending on when its uploaded and if the GPU ends up having to evict resources. If you end up having a lot of independent texture text boxes being rendered by the comparatively slower CPU, that could add up quickly and cut into your budget.

Drawing using a glyph atlas is still a way better use of resources. Modern text rendering pipelines will also often use either SDF or encoded bezier curves to improve glyph legibility when scaling which is also a great way of saving more memory.

ferbivore|1 year ago

Drawing one quad to cover N characters and picking out a glyph in the shader is going to be faster than drawing individual quads for each character (for monospace fonts, anyway). But there are only so many characters you can fill the screen with, so it's probably not a huge difference in practice.

Regarding the upload part: at the end of the day, you have X bytes of glyphs and they need to get into GPU memory somehow. Whether you get them there as textures, as uniform data or as shader constants doesn't really matter performance-wise. If anything, doing it through shader constants as described in TFA is more expensive on the CPU side, since all those constant declarations need to be processed by the shader compiler.

What does matter on the GPU side is which memory hierarchy you hit when reading glyph data (texture fetches have a dedicated L1 cache on most GPUs, larger than the "normal" L1 cache I think) and what order the data is in (textures are usually stored in some version of Morton order to avoid cache misses when you're shading blocks of pixels). For a production atlas-based text renderer you probably want to use textures.

Edit: I misread the question; you were asking about drawing individual glyphs on the GPU vs. drawing an entire block of text on the CPU, right? This is a speed/space tradeoff, the answer is going to depend on how much memory you want to blow on text, whether your text changes, whether it needs to have per-character effects applied, and so on.

Sesse__|1 year ago

You can render the entire string before upload, but then you are essentially using a CPU render, which will be slower than having the GPU do the same thing.

FWIW, this method is also a texture despite being called “texture-less”; the texture is just stored in a different format and a different place. True textureless font rendering evaluates the vector curves on the fly.

superjan|1 year ago

It depends on the application. It’s the easiest way especially if you might encounter right to left script, CJK or emoji. It is worthwhile to cache the textures, most text does not change every frame. It is good enough for us.

spookie|1 year ago

It's huge. Passing data from CPU to GPU is most likely, 90% of time, the biggest bottleneck.