13 comments

  • aappleby 3 hours ago ago

    The "right way" to do this on the GPU if you're using a monospaced console font is to have a glyph atlas, a persistently mapped text buffer, a persistently mapped attribute buffer, and then draw a single triangle that covers the viewport and do absolutely everything else (text map lookup, attribute lookup, glyph atlas lookup, blending/compositing) in the pixel shader.

    You should be able to hit 1000 fps with most modern GPUs, and the code is fairly simple after youve got the buffers and shaders set up.

    • bschwindHN 2 hours ago ago

      Essentially as it's described here, right?

      https://www.youtube.com/watch?v=lStYLF6Us_Q&t=1472s

      Casey refers to it as "backwards" rendering - starting from the pixel location and determining what should be drawn there, vs. "forward" rendering where you have things you want to draw, and you determine which pixels they will be drawn in.

    • dcrazy 3 hours ago ago

      Fullscreen tri is not necessarily the way. If the GPU has significant penalties for rejecting fragments, or your text is sparse, you should probably use form-fitting quads or polys.

      Also, monospace (and implicitly, Latin) is doing a huge amount of lifting in your comment.

      • aappleby 3 hours ago ago

        Of course, the example in the article is all monospaced console stuff. I've written a lot of text rendering over the years, everything from tiny bitmap for microcontrollers to analytically-antialiased true type based on code from some paper by Charles Loop years ago.

        If GPU is cheap and CPU is expensive, draw one tri every frame and don't worry about the rest. If CPU is cheap and GPU is expensive, do a glyph per quad and some basic dirty rectangles if needed.

  • time4tea 4 hours ago ago

    Quite conventional - its how FreeType works.

    Computing a bitmap for a glyph is expensive because of all the splines and whatnot.

    https://freetype.org/freetype2/docs/tutorial/step1.html#sect...

  • laserbeam 3 hours ago ago

    You really do need units in your tables. It is not very obvious you are talking about FPS in them… or is it milliseconds or microseconds. The only place a unit of measurement is actually mentioned (FPS) is the window title of a screenshot.

  • zokier 2 hours ago ago

    There are like at least half dozen open source terminal emulators that have decent performance text rendering if you want to look into how it is really done. It is not simple, but at this point I feel it is a largely solved problem.

  • afishhh 3 hours ago ago

    > Drawing text isn't simple

    I agree, but even this article seems to oversimplify.

    > You can't really optimize texture copies much more.

    Did the author try packing the textures in an atlas?

    Texture atlases can improve performance significantly since then you can use instanced draw calls to draw a whole bunch of glyphs at once.

    • dcrazy 3 hours ago ago

      FWIW you cannot have Unicode-correct rendering by caching at the codepoint (what many people would call “character”) level. You can cache bitmaps for the individual “glyphs”—that is, items in the font’s `glyf` table. But your shaping engine still needs to choose the correct “glyphs” to assemble into the extended grapheme clusters dictated by your Unicode-aware layout engine.

      • afishhh 2 hours ago ago

        Exactly why I referred to drawing glyphs instead of characters :)

        There's even more depth one can go into here: subpixel positioning. To correctly draw glyphs that may be on subpixel positions, you need to rasterize and cache glyphs separately for each subpixel position (with some limited amount of precision, to balance cache usefulness and accuracy).

        However I have a feeling that describing an entire Unicode-aware text stack here may not be useful, especially if TFA seems to only care about simple-script monospace LTR.

        • dcrazy an hour ago ago

          Nowadays people expect their terminals to handle UTF-8, or at least the Latin-like subset of Unicode, without dealing with arcana such as codepages. For even the simplest fonts, rendering something like í likely requires drawing multiple glyphs: one for the dotless lowercase I stem, and one for the acute accent. It so happens that dotless lowercase I maps to a codepoint, but it is not generally true that a single extended grapheme cluster can be broken down into constituent codepoints. So even “simple” console output is nowadays complected by the details of Unicode-aware text rendering.

  • evolighting 3 hours ago ago

    This blog page feels laggy in Firefox, but it works fine in Chrome.

    The floating menu with the frosted glass effect seems to be causing the problem, remove that div in F12, fix it. What’s the reason behind this?

    • louisbourgault 3 hours ago ago

      Thanks for that! I was finding it painful as well