Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

epaint software renderer #1129

Open
emilk opened this issue Jan 17, 2022 · 16 comments
Open

epaint software renderer #1129

emilk opened this issue Jan 17, 2022 · 16 comments
Labels
feature New feature or request

Comments

@emilk
Copy link
Owner

emilk commented Jan 17, 2022

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:

  • Generating regressions tests (make sure the GUI looks the same before/after)
  • Generating example images
  • Provide a reference for GPU renderers to compare themselves to.

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

@emilk emilk added the feature New feature or request label Jan 17, 2022
@emilk emilk changed the title epaint reference software rasterizer epaint software renderer Jan 17, 2022
@tinaun
Copy link

tinaun commented Jan 25, 2022

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)

@coderedart
Copy link
Contributor

won't including the images bloat the git repo or docs.rs ? or will there be some kind of git lfs setup?

@AlexApps99
Copy link
Contributor

We can probably checksum them and just compare checksums

@coderedart
Copy link
Contributor

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.

@emilk
Copy link
Owner Author

emilk commented Jan 26, 2022

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!

@emilk
Copy link
Owner Author

emilk commented Jan 26, 2022

@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?

@tinaun
Copy link

tinaun commented Jan 27, 2022

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

@emilk
Copy link
Owner Author

emilk commented Jan 29, 2022

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.

@coderedart
Copy link
Contributor

@njust
Copy link
Contributor

njust commented Mar 15, 2022

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?

@tinaun
Copy link

tinaun commented Jun 13, 2022

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

@lucasmerlin
Copy link
Collaborator

lucasmerlin commented Aug 11, 2022

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?

View Image Bildschirmfoto 2022-08-11 um 20 09 58

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.

@daniel5151
Copy link

daniel5151 commented Aug 27, 2022

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.

@tinaun
Copy link

tinaun commented Aug 29, 2022

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.

@lucasmerlin
Copy link
Collaborator

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).

@rustytsuki
Copy link

rustytsuki commented Feb 8, 2023

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature or request
Projects
None yet
Development

No branches or pull requests

8 participants