Open emilk opened 2 years ago
I wrote a proof of concept using tiny-skia - https://gist.github.com/tinaun/f2177e6c70f5c6602ff9863e4f05e9e4
the approach I'm using for the text rendering is giving pretty bad results though (https://i.imgur.com/nqiiwYi.png) - and I don't know if the api it presents is a good match for drawing vertex colored meshes (I haven't implemented Shape::Mesh rendering yet)
won't including the images bloat the git repo or docs.rs ? or will there be some kind of git lfs setup?
We can probably checksum them and just compare checksums
Git already does the hashing, but the docs.rs has a size limit. And if we go through different images fast enough, git repo starts increasing in size too.
there's oxipng to compress images, but idk about how high the CPU usage is.
Please try to keep to the issue topic! How to store images for the docs is an interesting problem, but can be discussed in Discussions or on Discord!
@tinaun That's a very impressive start! Perhaps the text rendering just needs a half-pixel offset? It's a shame tiny-skia
doesn't have the ability to render meshes built-in, but perhaps just those parts could be copied from https://github.com/emilk/imgui_software_renderer
How is the performance?
at least on my MacBook, the example in my demo runs in about 1.2 ms, with larger examples like the demo ui taking 6-10 ms per call - I don't have any super old hardware to test on but because tiny-skia is single core performance bound most processors above one ghz should be able to reach 30fps, hopefully.
moving the text bounds did improve things a little (https://i.imgur.com/rbI8u3g.png) - I think I'm running into Srgb/gamma issues since the text feels less vibrant than the live demos
for mesh rendering I'm thinking of looking at euc
That's sounds like really good performance!
For the gamma issue, you might try changing .srgba_pixels(1.0)
into .srgba_pixels(1.0 / 2.2)
and see if it helps.
Any update on this? I'd love to see a software renderer as a built-in fallback for egui apps. Maybe piet is also worth to consider?
I've looked at Piet, but it also lacks a gradient fill option with 2d control points - only linear and radial gradients are supported. in addition, all of the backends for Piet besides the svg backend use a system library for the actual drawing steps, and I would prefer to keep this as dependency light as possible
I might play around with using a radial gradient between mutliple control points to simulate interpolation, but i'd still be drawing each triangle in the mesh twice, once for the texture and once for the vertex color
anyway I've published my current progress here as egui_rasterizer - its not on crates.io yet, and I want to either publish it as a feature in egui or its own separate crate by the release of 0.19
I made a renderer with skia-safe: https://github.com/lucasmerlin/egui_skia. It works well when rendering on the gpu but unfortunately it looks wrong when rendering on the cpu. I'm not sure why though, maybe someone has an idea?
In contrast to @tinaun's solution I draw the vertices with skia's .draw_vertices so that part is less complicated. Skia is a pretty huge dependency though, so this might not be the right thing for everyone.
Just chiming in to mention this is something I'm also interested in seeing supported!
I've got a WIP project that's hooking into the libretro API, and while libretro does support hardware rendering on some platforms, I'm hoping to keep things as compatible as possible by targeting the base software framebuffer API.
I've got a POC working with @lucasmerlin's code (where I'm seeing the same CPU rendering issues...), and I might take a stab at trying out egui_rasterizer as well.
I asked the maintainer of tiny_skia about adding an equivalent to skia's .draw_vertices()
and their response was "I don't know why anyone would use this feature", so I think moving away from skia/piet style drawing apis and just rendering the triangles manually would be the way to go, I guess.
I fixed the cpu rendering issues I had with egui_skia. Turns out it was a skia bug, there are problems when you render identical uv coordinates (e.g. 0,0 0,0 0,0), which egui does when drawing shapes. I was able to work around that by splitting the meshes. To enable the fix, there is a feature cpu_fix, so performance when using the gpu is not affected.
Also, egui_skia is now published on creates.io. The cpu example works okay on my M1 but the metal example is a lot snappier (as one would expect).
So nice, this is holy grail of my working new project. Now I've been using skia software mode instead. https://github.com/rustytsuki/egui_skia_auto_fallback_demo
I would like to have a software rasterizer for epaint, so that you can take the output shapes from
egui
and turn it into an image.This would be useful for many areas:
Primarily I would want it to be simple and accurate rather than fast. However, a fast rasterizer would also be nice (e.g. for using egui where there is no GPU).
I wrote a software renderer for Dear ImGui a few years ago (in C++) which could probably be used as a starting point: https://github.com/emilk/imgui_software_renderer