<@UPMFG2571> and I have started <Dali>, a new 2D/3...
# of-graphics
d
@Nuno Leiria and I have started Dali, a new 2D/3D graphics API, based on signed distance fields, implemented with WebGPU. The goal is to enable the future of user interfaces and visual programming languages by providing a much richer set of graphics primitives for rendering UIs than what is supported by traditional postscript/SVG/HTML/CSS 2D vector graphics APIs. The graphics model is inspired by my Curv project, but more general and much higher performance. At this point, we have overall project goals, a list of prior art, and a design sketch for the Demo 1 release, which will demonstrate text rendering. * overall project goals: https://github.com/dali3d/dali * text rendering goals: https://github.com/dali3d/dali/wiki/Text-Rendering-(Demo-1) * prior art for text rendering: https://github.com/dali3d/dali/wiki/Prior-Art We are looking for help, especially with the architecture. * Suggestions and recommendations on the GPU data structures and algorithms to use. * Pointers to existing projects that are not in my Prior Art list, that show a better way to do things than what I've considered thus far. * Collaborators.
❤️ 9
😍 2
c
This looks great. On the GH it says "you can have a large number of primitives on the screen without slowing down." What is "large"?
d
@Chris Knott The problem I found with typical Shadertoy-style fragment shader programs is that you have a single distance function that encodes the entire scene, and that function is evaluated at each pixel. The cost of calling the distance function is linear in the number of distinct primitives that are unioned together in the scene. So you run into a performance cliff pretty quickly. We are going to fix this with an optimizing scene compiler combined with well known optimization tricks and data structures. I can't give performance numbers, because there's no code yet. The project was only conceived a few days ago. In the case of text, where the primitives are glyphs, I am expecting comparable performance to other GPU based text rendering engines.
i
Very interested in this for Hest! I'm AFK today, but look forward to reviewing what you've got and offering feedback.
r
I'd also be very interested in this for my project! I currently use troika (built on three.js) to render text if it's at all useful. Having text wrapping and selection are especially great features. https://github.com/protectwise/troika/tree/master/packages/troika-3d-text
Is it significant overhead to support WebGL as well? Full browser support for WebGPU won't be here for a while right?
d
Troika uses SDF textures, which are signed distance fields that have been sampled at some sampling resolution. The problem with this sampling is that it throws away information needed for accurate rendering, which leads to this tradeoff (from the Troika docs):
sdfGlyphSize
Allows overriding the default size of each glyph's SDF (signed distance field) used when rendering this text instance. This must be a power-of-two number. Larger sizes can improve the quality of glyph rendering by increasing the sharpness of corners and preventing loss of very thin lines, at the expense of increased memory footprint and longer SDF generation time.
Default:
64
In this scheme, when you query a signed distance value, what you actually do is perform an interpolated lookup on the SDF texture, which returns an approximation of the actual distance. What I prefer is to directly query the Bezier curves in the character glyph and compute the exact distance.
👍 1
Firefox, Chrome and Safari already have experimental support for WebGPU in developer builds, but the standard is still being designed. It's supposed to be complete by the end of the year. WebGPU will be available by the time Dali is ready to use. There won't be a WebGL version because we are using a pipeline of compute shaders for performance reasons.
👍 1
r
Sounds pretty exciting to me! I've definitely been waiting for something like this and look forward to having a play 🚀
n
@Doug Moen How does this differ from Pathfinder, which is nearing completion? Or piet-gpu, which is a sister project? Pathfinder enables massively-parallel realtime vector rendering, and will run on WebGPU as well. I've been following it pretty closely.
d
Pathfinder and Piet only support traditional 2D vector graphics. Dali is a generalized 2D/3D graphics API that supports signed distance field operations, which gives it enormous flexibility and expressiveness. In the same way that 2D vector graphics supports curved shapes that are scalable and resolution independent, Dali also supports 3D shapes that are curved, scalable and resolution independent. Dali also supports a full range of SDF operations that can be applied to any 2D or 3D shape, including many that are not supported by traditional graphics systems based on boundary representation. I already implemented this once already in my Curv project, but there's no text support, and there are performance limitations, so Dali will use a new high performance architecture. I am looking at Pathfinder and Piet to see how much I can reuse. As part of Dali, I need a text renderer that supports signed distance queries on font data, because that allows the full range of SDF operations to be applied to text. So you can apply non-affine transformations, morph, extrude text into 3D, engrave text into the surface of a 3D object, etc. I am investigating the idea that a single SDF based text renderer can be used to render text in both the 2D and 3D cases. There was already a project that worked this way: "Real Time Texture-Mapped Vector Glyphs". The paper was published in 2006, before compute shaders, before Vulkan, before Piet and Pathfinder. The GPU tech landscape has changed a lot, so I'd like to see if this architecture can be resurrected and made more efficient using current technology and ideas. Piet implements distance queries on font data to implement strokes. I'm looking at Piet to see how it can inform the Dali architecture.
n
I see. Sounds very exciting, and very ambitious too!
i
Exciting stuff, Doug! To what extent should I think of the API as stateful (a la retained mode) vs stateless (a la immediate mode)? Are you planning to use this as a new backend for Curv? (OT: I don't understand how WebGPU buys portability beyond the browser. What makes WebGPU work on native? Is there going to be (eg) some sort of WebGPU->Metal option for native iOS?) There's a long road from here to something we'll be able to use in our own projects. How can we help? FWIW — The tradeoffs listed under Text Rendering (Demo 1) are fantastic. I wouldn't change a thing, for my personal needs.
d
Google is creating an open source library called Dawn which implements WebGPU as a layer on top of Vulkan, DX12 and Metal. This implements WebGPU on all the platforms that Chrome runs on, and is used by Chrome. The WASI project is adopting WebGPU as a standard portable API for web assembly, so it will work even when you are running WASM programs outside of a web browser. You can think of WebGPU as the new OpenGL, because it runs everywhere, but it's easier to use, higher performance, and there's only one dialect, instead of OpenGL vs OpenGL ES vs WebGL.
👍 3
🎉 1
Dali is a "retained mode" API. You build a "graphics tree", where the nodes are graphics primitives and operators, then you load this tree into the GPU, which interprets and renders it. Animation and dynamic content are achieved by modifying uniform variables, and by modifying resources and nodes in the gtree. These tree modifications are synchronized with the GPU's copy of the tree.
👍 3
Dali is intended to be a new backend for Curv. But instead of burying the work inside Curv, I'm trying to create a general purpose library that is useful independent of Curv.
👍 2