13 ms·
Fast 2D rendering on GPU has represented the last few months of concentrated work for me, and I'm happy to present the results now. It's required going pretty d
by raphlinus 6y ago
Fast 2D rendering on GPU has represented the last few months of concentrated work for me, and I'm happy to present the results now. It's required going pretty deep into various aspects of GPU compute, so feel free to ask me about that, 2D vector graphics, or anything related.
- tenaciousDaniel 6y agoHi! This looks interesting, although I confess I'm very new to this area. I'm writing a programming language specifically for UI designers, and currently I'm building a naive implementation in html5 canvas. I know very little about low-level rendering - just really know how to use drawing API's like canvas and Quartz 2D. With that being said, I'm looking to delve deeper into this subject. Do you have any recommendations on where to start? Whenever I look beyond simple drawing API's, the focus seems to be entirely on 3D rendering (which is interesting but not my main focus right now).
- raphlinus 6y agoIt's a good question, as honestly the knowledge for 2D graphics is pretty arcane, as opposed to 3D being so widely taught. I actually started a github repo for a book on 2d graphics but have no idea whether I'll actually finish it. In the meantime, antigrain.com is one good (if old) source. The original PostScript "red book" was extremely influential in its time (it's where I learned a lot of this stuff) but is quite dated now. Best of luck, and I'm also happy to field requests for more specific areas. For example, for color theory (an important aspect of 2D graphics!), handprint.com is quite a remarkable resource.
- tenaciousDaniel 6y agoThanks!
- blondin 6y ago> knowledge for 2D graphics is pretty arcane such an unfortunate state of affairs! i am currently learning how to render graphics using the GPU on my mac using apple metal. what i am getting is that the GPU has been optimized for 3D rendering?! GPUs make no provision or easy way for rendering 2D graphics? it makes no sense to me... that's where you start...
- dungdang 6y agonow this may be a dimb question, but why would you start there? as far as i understand, 2d and 3d have literally zero to do with each other in how they are rendered. one is a bunch of triangles. the other is lines, curves, thickness, gradients, and fonts (which are essentially little programs)
- blondin 6y agothat's not a dumb question! it's my own fault. i only have knowledge of 2D graphics.
- chrisseaton 6y ago> the other is lines, curves, thickness, gradients, and fonts You can reduce all these to drawing triangles.
- deleted 6y ago[deleted]
- Jasper_ 6y agoDoing that reduction is surprisingly difficult, and usually a serial algorithm that runs on the CPU, and a naive approach is a resulting triangle set is not efficient to a GPU, but that's what toolkits like cairo, Direct2D, nanovg do. Raph is describing an architecture where path evaluation happens on the GPU, without being baked to triangles.
- raphlinus 6y ago> You can reduce all these to drawing triangles. You can, people have tried this, and it sucks. The main problem is that the conversion of Bézier paths to triangles is a hard problem with lots of conditional branching. Even when you do it, there is the other problem of rendering triangles with really good antialiasing, MSAA forces a compromise between performance and quality. By contrast, piet-gpu does an exact-area calculation for antialiasing. So it's not a question of whether you can do it, but whether it works well, and approaches like piet-gpu absolutely stomp triangles.
- smallstepforman 6y agoHaiku OS AppServer (the screen rendering component, similar to Unix X11) is a full GUI system implemented with AntiGrain Geometry as the renderer.
- gct 6y agoI think that blend2d (https://blend2d.com/ https://blend2d.com/) is a worthy successor to AGG, and it's under active development.
- longstation 6y agoThank you for the link. It was a great reading. But I just want to point out that Blender2D is a software renderer.
- gct 6y agoSo is/was AGG
- syspec 6y agoI recommend the blog of the OP, so many gems
- awfulaxolotl 6y agoHow well does this approach work for something like 2D data visualization where most of the visual elements are the same -- i.e. can be instanced in OpenGL/etc? Thanks for publishing this, it's awesome work! I'm looking forward to progression to wgpu hinted in the Github README.
- raphlinus 6y agoI absolutely have data visualization in mind for this, as I think it can benefit greatly from the scale. But the pipeline I've built is very agile, it will easily handle a diverse mix of items. It's not like OpenGL etc where there's a certain amount of overhead for a draw call so there are significant gains to be had from instancing and batching. It is likely that CPU-side encoding can be made more efficient, though, by just filling in quantities to a template, rather than encoding from scratch.
- leeoniya 6y agoany relation to the work currently being done here by pcwalton? https://github.com/servo/pathfinder/pull/350 https://github.com/servo/pathfinder/pull/350 hopefully you guys aren't doing identical work in parallel (no pun intended) :)
- pcwalton 6y agoYes, there's been a lot of influence in both directions. The approaches have a lot in common, but also have significant differences. I plan to write up a description of the Pathfinder compute work soonish.
- paufernandez 6y agoI would love that!
- raphlinus 6y agoAs Patrick indicated, there's a lot of cross-fertilization of ideas, and one of the best outcomes of this work would be for high performance compute rendering to ship in Pathfinder.
- RivieraKid 6y ago- Shouldn't 2D rendering be a solved problem given that it's basically a subset of 3D rendering? - Don't libraries like Skia, Qt, Cairo use GPU rendering? I've always assumed so. I mean, this is 2020, GPUs have been around for decades.
- pcwalton 6y ago> - Shouldn't 2D rendering be a solved problem given that it's basically a subset of 3D rendering? The problem is that primitives artists use are different. 3D rendering tends to all consist of polygon meshes, which are relatively easy to render. 2D rendering (basically) consists of Bezier paths, which are harder. The equivalent in 3D, which is adaptive subdivision, is not really a solved problem in real-time either. Additionally, 2D rendering quality tends to be more important than 3D rendering quality. Whereas you can get away with 4xMSAA or hacks like FXAA in 3D, true 16xAA (without hacks) is the absolute minimum for 2D rendering quality nowadays, and even it isn't considered great for some tasks like font rendering (Pathfinder and piet-gpu both use analytic AA which is effectively 256xAA). > - Don't libraries like Skia, Qt, Cairo use GPU rendering? I've always assumed so. I mean, this is 2020, GPUs have been around for decades. There's a difference between renderers with GPU support and renderers that are oriented around using the GPU efficiently. In many cases this results in an order-of-magnitude speedup. On the GPU, state changes are expensive, and many such renderers that have GPU support don't really go out of their way to avoid them. There are also occlusion culling optimizations that most renderers don't do, but piet-gpu and Pathfinder do.
- stanfordkid 6y agoThings like multi-resolution font-rendering are actually more complicated than one might imagine. The easy way is to just tesselate the font into polygons -- but this tesselation often depends on the zoom level. The same thing can be said about implicit curves etc. Most libraries do use GPU's for basic draw operations (e.g rendering a gradient), but to build something like Photoshop -- you need much more complexity.
- raphlinus 6y agoOthers have spoken to this, but as a general introduction I highly recommend Jasper's post "Why are 2D vector graphics so much harder than 3D?" In short, no, it's not a solved problem. Also, I see a lot of variations of this question, but I should state this more clearly. There's been accelerated graphics in one form or another for a long time, but what I'm doing is a completely different type of thing. In my world, on the CPU you just encode the scene into a binary representation that's optimized for GPU but in many ways is like flatbuffers, and then the GPU runs a highly parallel program to render the whole thing. In previous approaches, the CPU is deeply involved in taking the scene apart and putting it back together in a form that's well suited to relatively dumb pixel pipes. Now that GPUs are really fast, that approach runs into limitations. It also depends what you're trying to do. I'm focusing here on dynamic paths (and thus font rendering), while most of the libraries optimized for UI put text into texture atlases and then use the GPU to composite quads to the final surface, something they can do well. https://blog.mecheye.net/2019/05/why-is-2d-graphics-is-harder-than-3d-graphics/ https://blog.mecheye.net/2019/05/why-is-2d-graphics-is-harde...
- moonchild 6y agoIt looks like the main fruit of this is piet-gpu[1]. How close would you say it is to stable? And how complete a realisation of the concepts put forth in the OP? I'm currently working on a ui library, and evaluating alternatives for hw acceleration. The whole library wants to be in c, so I would want to rewrite the library by release-time to use it, but don't want to waste time doing that now if it's still really volatile. 1. https://github.com/linebender/piet-gpu https://github.com/linebender/piet-gpu
- raphlinus 6y agoNot very, and not very. This is research, it depends on compute capabilities that have really only gone mainstream in GPU lately, and the current codebase is about trying out the ideas. Best of luck in your project!
- MrBuddyCasino 6y agoWow, those numbers look very impressive on an absolute basis! Do you have an idea on how piet-gpu compares to Skia? I'm not a graphics guy, my impression was that it is currently the dominant vector graphics renderer.
- structural 6y agoWhat's been your overall experience with using Vulkan shaders for compute? Are there basic primitives that are missing from shading languages and/or have you found any impedence mismatches between writing shaders vs. how you might describe the same algorithms in other languages?
- NotCamelCase 6y agoI pondered on the same subject recently as I was implementing the same algorithm (i.e. Mandelbrot set) on the CPU (scalar vs SIMD) and GPU compute using fixed-point and floating-point for comparisons (if interested: https://tayfunkayhan.wordpress.com/2020/06/03/mandelbrot-in-floating-point-vs-fixed-point https://tayfunkayhan.wordpress.com/2020/06/03/mandelbrot-in-...). It bothers me how little progress has been done on "shading" languages front compared to overall many-core computation models and capabilities over the years. And, that is despite the fact that shaders are very often where the most time is spent in modern workloads. Compute with Vulkan is another story. It offers some nice abstractions, but it shows that it's mostly intended for async-compute/work-offloading for rendering, IMO. Too much fruction.
- raphlinus 6y agoThat's a big topic. I've been able to work around the missing primitives (for example, I autogenerate code for Rust-style structs and enums), but have had much bigger struggles around two issues: tools, which are still quite primitive, and understanding performance, which is extremely difficult. These two problems intersect because I can imagine a lot better tools for digging into performance issues. One that I would have paid good money for is an instruction-level simulator that would highlight the source code to tell me where the stalls, bank conflicts, divergence problems, etc. are in the source code. Such a thing is possible (there are academic papers like [1]), but not as far as I know usable in daily development. The "impedance mismatch" is that you (generally) have to write in a style to extract lots of parallelism. This tends to be very different than the way you'd write scalar CPU code, but not completely alien to me as it has a lot of similarity with the way you'd write SIMD. I've pretty much gotten the hang of it now. I'm thinking of a blog post of redoing path_coarse.comp from its current basically scalar style to a more parallel version, as that would I think illuminate the issues. [1] http://comparch.gatech.edu/hparch/papers/gera_ispass18.pdf http://comparch.gatech.edu/hparch/papers/gera_ispass18.pdf
- deleted 6y ago[deleted]