-
Notifications
You must be signed in to change notification settings - Fork 195
Egui Integration #42
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
base: main
Are you sure you want to change the base?
Egui Integration #42
Conversation
|
Sorry for the delay here! I've nerd-sniped myself with looking at HDR -> LDR color mapping the past few weeks 😅 Will have a look tomorrow! |
h3r2tic
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for this! ❤️🚀 The code looks good -- I only have some minor nitpicks 🕵️
Quick question first: Have you tested whether Vulkan validation layers are happy with the use of the API?
Now for the main course: I do have a high-level concern -- currently there's no way to test the egui renderer in main, which means that it will likely get broken at some point, and rot over time. Upon realizing this, I attempted to add support for egui to the kajiya-simple crate, thinking that it would be neat to use it in a stand-alone example using egui (alongside the view and hello binaries). I quickly ran into my unfamiliarity with egui however, and some confusion with the backend implementation (see comments about prepare_frame and handle_event).
Would you perchance be interested in adding egui support to kajiya-simple? 😅 Otherwise this PR will probably have to wait until I can allocate the time -- it's important that all features of the renderer can be tested (ideally by CI -- though the dlss feature is an exception due to licensing reasons) and checked against Vulkan validation layers.
crates/lib/ash-egui/src/lib.rs
Outdated
| physical_device_properties: &vk::PhysicalDeviceProperties, | ||
| physical_device_memory_properties: &vk::PhysicalDeviceMemoryProperties, | ||
| egui: &mut CtxRef, | ||
| raw_input: RawInput, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Feels weird to be passing input to the renderer's constructor. Are all the fields actually needed? The doc from egui says "Set the values that make sense, leave the rest at their Default::default()." Maybe an instance of RawInput with only the fields relevant to the font texture creation could be constructed in-place before the call to egui.run?
crates/lib/ash-egui/src/lib.rs
Outdated
|
|
||
| assert_eq!(texture.pixels.len(), texture.width * texture.height); | ||
| let srgba_pixels: Vec<u8> = texture | ||
| .srgba_pixels(0.25) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
0.25 looks oddly close to the 0.24 which would be used for sRGB gamma correction. I think if you used R8G8B8A8_SRGB for the texture format, you might find that 1.0 works correctly.
Also it looks like the source font texture is actually just alpha, so R8_SRGB should be sufficient (though I'm not sure if the shader you're using is compatible with a red-only texture font).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With all of the changes to the backend after fixing vulkan settings, 0.5 seems to produce the clearest image. Not sure why that number... do you think that's fine?
crates/lib/ash-egui/src/lib.rs
Outdated
| // TODO: NEED??? | ||
| // update font texture | ||
| // self.upload_font_texture(command_buffer, &self.egui.fonts().texture()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would be good to resolve 😅
crates/lib/ash-egui/src/lib.rs
Outdated
| let next_vertex_offset = vertex_offset + mesh.vertices.len(); | ||
| let next_index_offset = index_offset + mesh.indices.len(); | ||
| // if next_vertex_offset > Renderer::VERTEX_COUNT_PER_FRAME | ||
| // || next_index_offset > Renderer::INDEX_COUNT_PER_FRAME | ||
| // { | ||
| // break; | ||
| // } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What will happen if the number of vertices is greater than the size of the preallocated buffers? If it crashes, then this check needs to happen similarly to the egui renderer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added the check back to make sure buffer offset does not exceed buffer size
| pub fn handle_event( | ||
| &mut self, | ||
| _window: &winit::window::Window, | ||
| _egui: &mut ash_egui::egui::Context, | ||
| _event: &winit::event::Event<'_, ()>, | ||
| ) { | ||
| } | ||
|
|
||
| pub fn prepare_frame(&mut self, context: &mut CtxRef, dt: f32) { | ||
| // update time | ||
| if let Some(time) = self.raw_input.time { | ||
| self.raw_input.time = Some(time + dt as f64); | ||
| } else { | ||
| self.raw_input.time = Some(0.0); | ||
| } | ||
|
|
||
| context.begin_frame(self.raw_input.take()); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
handle_event is obviously dead code, so probably shouldn't be here, but prepare_frame I don't know about -- I don't see it being used anywhere here or in your bevy_kajiya_egui, so I'm a bit confused how the backend is supposed to be used 👀
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed the frame prep API to this: EguiBackend::prepare_frame(&mut self.egui); (self.egui is of type EguiState) and you may wonder why this is now a static function, and that is because prepare_frame() only operates on fields of EguiState, while it has no need for data in EguiBackend, unlike in imgui.
Basically, EguiState contains the egui Context instance and RawInput input state that the user of the library will interact with directly, while EguiBackend needs the data passed from EguiState once a frame to render.
The decoupling of the backend into EguiState and EguiBackend makes it trivial for me to use kajiya-egui in either kajiya-simple or in bevy-kajiya-egui.
| impl EguiBackend { | ||
| pub fn new( | ||
| device: Arc<Device>, | ||
| window_settings: (u32, u32, f64), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would probably be better as the individual scalars that you deconstruct this to in the body of the function.
|
|
||
| layout(binding = 0, set = 0) uniform sampler2D font_texture; | ||
|
|
||
| void main() { outColor = inColor.rgba * texture(font_texture, inUV); } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would allow us to use a single-component texture -- or do you have plans for using the other components?
| void main() { outColor = inColor.rgba * texture(font_texture, inUV); } | |
| void main() { outColor = inColor.rgba * texture(font_texture, inUV).r; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No plans? Is it wasteful to leave the other components unused?
|
I agree. I will implement it in |
|
Hey! I've finally had some time to come back to this 😅 The PR pretty well, and I have some fixes to make it work better 😀 In this commit I've done a bunch of fixes and improvements:
Now almost everything works, except one bit which I haven't figured out yet: |
|
Poke... I know it's been eons, but I have some time to close this out. Still worth it after all the changes since this was last touched? @h3r2tic |
|
Hmm, good question, I'm not sure! On the one hand, if egui is useful to folks (such as yourself), it would be great to have it! Up to you! :) |
Checklist
Description of Changes
Adds two new crates:
ash-eguiandkajiya-egui. They're heavily based off of theirimguicounterparts with exception to a few modifications to work withegui.Related Issues
List related issues here