hasenbanck / egui_wgpu_backend Goto Github PK
View Code? Open in Web Editor NEWBackend code to use egui with wgpu.
License: Apache License 2.0
Backend code to use egui with wgpu.
License: Apache License 2.0
181 | let rpass_egui = RenderPass::new(device, surface_cfg.format, 1);
| ^^^^^^^^^^^^^^^ ------ ------------------ expected enum `egui_wgpu_backend::wgpu::TextureFormat`, found enum `wgpu::TextureFormat`
| |
How should we tackle this? Thank you.
Hello,
Would it be possible to publish a new version? I'm looking to publish a new nannou_egui and it would be neat if I could add a dependency on egui_wgpu_backend
that allows sample count to be specified.
Thanks,
Alex
Currently egui_wgpu breaks when running on Firefox or Chrome using the wgpu WebGL backend, because it has a minimum buffer size restriction of 16.
Presumably it could be fixed by padding UniformBuffer with some extra zeroes, but I've not looked into it much beyond that.
I have a use case where I'm embedding a wgpu rendered texture target inside a window as an egui::Image
. The window is dynamically sized requiring that the underlying wgpu render texture target be resized. In wgpu, textures can not be resized so I make a new wgpu::Texture
on resize. This invalidates the egui::TextureId
made with egui_wgpu_backend::egui_texture_from_wgpu_texture
. I could create a new egui::TextureId
using that function every time a new wgpu::Texture
is made as a render target, but this has two downsides.
egui::TextureId
and underlying RenderPass::user_textures
Vec
would grow monotonically. Because resizes can happen thousands of times, many times per second, this represents a waste of memory, even after using free
to forget the old textures.egui
does layout, the size of the egui::Image
widget is only known after it is placed, which requires knowing the egui::TextureId
ahead of time. If a resize is needed after the TextureId
is already committed, that will mean there is a single frame delay between a resize happening and having the properly sized texture. An extra repaint will also be needed.I could solve this issue by replacing the backing wgpu::Texture
for an already allocated TextureId
. I have prototyped this using a method on RenderPass
like this:
/// Registers a `wgpu::Texture` with an existing `egui::TextureId`.
///
/// This enables applications to reuse `TextureId`s
pub fn update_egui_texture_from_wgpu_texture(
&mut self,
device: &wgpu::Device,
texture: &wgpu::Texture,
texture_filter: wgpu::FilterMode,
id: egui::TextureId,
) { ... }
The implementation was a mostly trivial copy of egui_texture_from_wgpu_texture
.
I am currently working on a specialized image viewer program using Egui and WGPU. My image viewer needs to be able to properly blend pixels when zooming out of an image (using FilterMode::Linear
for MIN filter) but allow the image to become pixelated when zooming in (using FilterMode::Nearest
for MAG filter) for better per-pixel controls.
Currently the RenderPass
API only supports supplying WGPU textures with a single FilterMode
for both MIN and MAG filters. It would be useful to have WGPU texture methods that allow users to specify both MIN and MAG FilterMode
s individually.
One way to solve this problem would be to add separate WGPU texture methods accepting entire BindGroup
s instead of just Texture
s and FilterMode
s. These methods would specify the required bind group and sampler parameters but would leave the rest up to the API user. In order to allow creation of custom BindGroup
s, a method for exposing a reference to the RenderPass
's BindGroupLayout
should be added.
BindGroup
s?RenderPass
's internal BindGroupLayout
?BindGroup
s being submitted? From what I can tell:
TextureView
s should refer to textures with format TextureFormat::Rgba8UnormSrgb
and usage TextureUsage::SAMPLED
.TextureView
s should have the dimension D2
.Sampler
s should not have the compare function.BindGroup
should consist of 2 entries. The first entry should have the binding 0
and the texture view as its resource. The second entry should have the binding 1
and the sampler as its resource.My plan is to submit a pull request to solve this issue by adding new API methods for exposing the RenderPass
's BindGroupLayout
and creating and updating texture ids from BindGroup
s.
Does this crate support the web target?
If rendering egui to the surface texture, there is a decent chance it will not be a srgb texture (Chrome/WebGPU is Bgra8Unorm right now, and GL likes to be SRGB-less due to how silly GL is). It would be nice to somehow be able to instantiate a egui backend that does the srgb conversion in the shader. This is how we ended up doing it in the wgpu imgui backend.
Colors are extremely dark and washed-out when using wgpu's OpenGLES backend.
Vulkan:
https://i.imgur.com/M8Zcxzi.png
I would like to be able to run this on the web, however as mentioned in #9, the web display format is non-srgb, e.g. Bgra8Unorm
. We're currently converting from linear colour to srgb colour in the vertex shader which looks wrong on wasm but if we change this line:
egui_wgpu_backend/src/shader/egui.vert
Line 26 in 9d03ad3
v_color = color / 255.0;
Then the output looks perfect on wasm!
The best way to go about this is probably to have 2 shaders, and switch between them either on output_format
or a feature flag.
I was wondering if you had any success with converting egui_wgpu_backend to work for the web?
I'm testing on firefox nightly and getting close (I have been able to get it to draw a test triangle) but feeding in the tessellated data from egui just shows me a black screen which doesn't give much clue about what could be wrong, I've tried many different things without success. :(
New egui, new API.
Just making an issue to keep track of progress in switching egui to the latest version.
Things I found:
Sometimes, you don't have a wgpu::Texture
, just a wgpu::TextureView
. Methods like RenderPass::egui_texture_from_wgpu_texture
are not useful in that case, but looking at the implementation, the only reason those methods take a Texture
is to create a TextureView
.
I think making the methods take TextureView
just relaxes the requirements of the API (everywhere you have a Texture
, you can trivially create the view). But this has the unfortunate side effect of breaking the public API.
I'd be happy to send in a PR if you let me know what's your preferred fix for this ๐
Hi,
I'm not sure if I've run into a bug or I've misunderstood something, but could you try this code ?
in Cargo.toml
egui = "0.11"
epi = "0.11"
egui_wgpu_backend = "0.7"
egui_winit_platform = "0.6"
wgpu = "0.8"
winit = "0.24"
before the event_loop :
let width_image = 32;
let height_image = 32;
let mut pixels = Vec::<egui::epaint::color::Color32>::with_capacity(width_image*height_image);
for _ in 0..width_image*height_image {
pixels.push(egui::epaint::color::Color32::from_rgb(0,128,0));
}
let mut texture_ids = Vec::<egui::TextureId>::new();
for _ in 0..20 {
texture_ids.push(egui_rpass.alloc_srgba_premultiplied((width_image, height_image), &pixels) );
}
and in the event_loop :
let w1 = egui::Window::new("Window");
w1.show(&ctx, |ui| {
let scroll_area = egui::ScrollArea::from_max_height(480.);
scroll_area.show(ui, |ui| {
for id in &texture_ids {
ui.image(*id, (width_image as f32, height_image as f32));
}
});
});
and should end up with :
thread 'main' panicked at 'Buffer slices can not be empty', /home/frank/.cargo/registry/src/github.com-1ecc6299db9ec823/wgpu-0.8.0/src/lib.rs:1733:39
thanks,
Currently, this library creates a new render pass every time execute is called.
According to the documentation here, it can incur latency and a round-trip to the GPU when 3d rendering and a 2d UI overlay are not part of the same render pass.
Over at ennona, we are currently running a render pass with multiple render pipelines in it to render cameras and points in a point cloud. It would be possible to create only one wgpu::RenderPass
if we could pass the render pass into egui_wgpu_backend
. Since it creates a new render pass internally before adding things to that render pass, it should be trivial to create a new method that is passed the render pass to use. For instance, this could be called execute_with_render_pass
, and then execute
could call this method.
Does this sound good? I can submit a PR.
A new version of wgpu has been released.
The git version of winit has fixed issue of transparent window. But running on linux with egui_wgpu_backend still get no transparent background.
When allocating a texture and freeing it immediately like the code below, after a few hundred frames rendered, it crashes with a no memory left
error.
Code:
let image_tex_id = tex_allocator.alloc_srgba_premultiplied(pixels_size, &pixels);
ui.image(image_tex_id, size);
tex_allocator.free(image_tex_id);
Error:
ERROR wgpu_hal::dx12::descriptor > Unable to allocate descriptors: RangeAllocationError { fragmented_free_length: 0 }
ERROR wgpu::backend::direct > Handling wgpu errors as fatal by default
thread 'main' panicked at 'wgpu error: Validation Error
Caused by:
In Device::create_bind_group
note: label = `user_texture2046_texture_bind_group`
not enough memory left
', C:\Users\luukv\.cargo\registry\src\github.com-1ecc6299db9ec823\wgpu-0.11.0\src\backend\direct.rs:2195:5
Seems like there is an issue freeing textures like this? My texture changes every frame, and it is not a WGPU texture so I figured this would be a quick solution, and I don't see a problem with doing this either.
Due to how mobile gpus work, it is advantageous to use as few renderpasses as possible. It should be near-trivial to convert execute's interface to take an external renderpass so that users can share renderpasses between egui and other rendering operations.
We could also make there be two executes, one on a texture with an internal renderpass, and one with a external renderpass if you want to keep the ease-of-use option.
If you're down with this, I can pr both this and #46 probably tomorrow.
Great work on implementing the back end!
I noticed your docs were failing to build because of a timeout. I assume this is due to the high compile time of shaderc-sys and wgpu. The shaderc-sys dependency could be removed if you precompiled your shaders like in the wgpu examples.
Hey, now that you've updated to egui 0.10.0
9d03ad3, could you please push a new version to crates.io so we can use that? Thanks!!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.