Approaches to robust realtime text rendering in threejs (and WebGL in general) #30
Replies: 2 comments 11 replies
-
Here is a diagram of the basic architecture behind https://github.com/horizon-games/three-text-renderer. https://docs.google.com/drawings/d/1cicoJ3UzIERzDEakrRgg2WBn3AOQZ2s_NYoq6U2ssTw/edit (in case you want to modify a copy) Rendering glyphs to atlas could mean any method, including SDF and MSDF. These are a heavy topic themselves, which I look forward to expanding. |
Beta Was this translation helpful? Give feedback.
-
Nice diagram! Troika-three-text follows a pretty similar pattern, with the main difference being that the font parsing, layout solving, and glyph generation is all done async in a web worker. One small correction to the original post: it's not currently true that troika-three-text uses Harfbuzz -- it does use Typr.js, but an older JS-only version prior to the Harfbuzz integration which lacks some advanced shaping features. While I'd love to get those features, I'm not yet comfortable including a Harfbuzz WASM build due to its large size and the resulting impact on downstream users. Anything that can be done to reduce the WASM file size would be helpful in making me reconsider. |
Beta Was this translation helpful? Give feedback.
-
Hello,
I'm part of a small team (Corban Brook and myself) working on a module for robust just-in-time text rendering in threejs. We're at an experimental stage of development. The module source is here https://github.com/horizon-games/three-text-renderer
three-text-renderer uses the harfbuzz WASM build.
Another similar module is part of the troika framework. This module is published on npm and has a pretty big user-base. The source is here: https://github.com/protectwise/troika/tree/master/packages/troika-three-text
troika-three-text uses Typr.js, but it doesn't use the harfbuzz-wasm initialization (due to wasm size concerns).
I think it would be valuable to discuss technical goals and design choices to ultimately create a module that renders text quickly and with as small of a footprint as possible.
My personal involvement centers around the graphics pipeline that turns glyph shapes into SDF or MSDF atlases via some JS and GLSL. I've seen the SDF algorithm implemented purely in js/canvas but I strongly feel that there are big performance advantages to doing the work on the GPU, and not to mention, the result need to reside on the GPU anyways. The SDF/MSDF algorithms therefore need to be adapted to GLSL, and we have done some promising work in this area.
Henrik Nyman has actually demonstrated an OpenGL solution to this, and when we chatted a couple months ago, it sounded like OpenGL 2 was all that was needed (and hopefully no fancy extensions). https://github.com/nyyManni/msdfgl
One more thing I want to mention is why the focus is on threejs. This module's design is imagined to work in service of an engine like threejs or babylonjs (or any others not mentioned). This is for two reasons:
Though threejs is my engine of choice because of my experience with it, anything discussed applies to any library or framework that manages WebGL.
Anyways, my hope is that next time we need to render text in WebGL, whatever the language, whatever the font, we'll be able to, precise, beautiful and fast.
I will try to consolidate the design choices made in three-text-renderer into a UML diagram soon. I'm particularly interested in when/how the work can be best done for the smoothest end-user experience (avoid jank, webworkers are great except on iOS, expect unexpected text, etc.)
Beta Was this translation helpful? Give feedback.
All reactions