-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
HDR Display Output #22563
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?
HDR Display Output #22563
Conversation
# Conflicts: # crates/bevy_ui_render/Cargo.toml
|
It looks like your PR has been selected for a highlight in the next release blog post, but you didn't provide a release note. Please review the instructions for writing release notes, then expand or revise the content in the release notes directory to showcase your changes. |
| return tonemapping_change_luminance(color, l_new); | ||
| } | ||
|
|
||
| fn tonemapping_pq(color: vec3<f32>, color_grading: ColorGrading) -> vec3<f32> { |
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 played with this a bit, needs love. Linear seems to just work ™️ on macOS.
|
Your PR caused a change in the graphical output of an example or rendering test. This might be intentional, but it could also mean that something broke! If it's expected, please add the M-Deliberate-Rendering-Change label. If this change seems unrelated to your PR, you can consider updating your PR to target the latest main branch, either by rebasing or merging main into it. |
Does this clip each channel independently? For example having (1500, 1200, 500) clipped to max 1000 gives (1000, 1000, 500). That would shift the hue since the color proportions change. |
|
Your PR caused a change in the graphical output of an example or rendering test. This might be intentional, but it could also mean that something broke! If it's expected, please add the M-Deliberate-Rendering-Change label. If this change seems unrelated to your PR, you can consider updating your PR to target the latest main branch, either by rebasing or merging main into it. |
|
Seems to be working on Windows: https://discord.com/channels/691052431525675048/743663924229963868/1463398806363181097 |
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.
Initial review.
Some stuff still TODO for me:
- Read up on HDR stuff again, it's been a while
- Check if Pq is a good tonemapping method
- Try across various displays, especially on windows/linux (linux HDR support is a little rough iirc)
- Figure out how this interacts with color spaces/gamut
- Figure out if we need anything from wgpu for this
- Figure out how this work on WebGPU
Also question: How can users check at runtime if HDR is supported or not? Can you figure that out, and then add some text to the example for when HDR is not supported?
| let mut view_key = MeshPipelineKey::from_msaa_samples(msaa.samples()) | ||
| | MeshPipelineKey::from_hdr(view.hdr); | ||
|
|
||
| if view.hdr_output { |
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 think we need the view key stuff in a lot more places? E.g. meshlet shading passes.
| for (camera, mut uniforms, bloom) in &mut views { | ||
| uniforms.hdr_output = camera.hdr_output as u32; | ||
|
|
||
| if camera.hdr_output && bloom.prefilter.threshold == 0.0 { |
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 is this for?
| if key.hdr { | ||
| ViewTarget::TEXTURE_FORMAT_HDR | ||
| } else { | ||
| TextureFormat::bevy_default() |
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.
Wait why does bloom support non-floating point (HDR) internal textures now?
Also I would really like to rename HDR now...
| format = available_format; | ||
| break; | ||
|
|
||
| if window.hdr_output { |
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.
Please abstract this out into a get_surface_format function.
| if window.hdr_output { | ||
| for available_format in &formats { | ||
| if *available_format == TextureFormat::Rgba16Float { | ||
| format = *available_format; |
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 about non-Rgba16Float HDR swapchain formats? Iirc some platforms/monitors/whatever only support other formats.
| #[derive(Clone, Copy, Hash, PartialEq, Eq)] | ||
| pub struct BoxShadowPipelineKey { | ||
| pub hdr: bool, | ||
| /// Number of samples, a higher value results in better quality shadows. |
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.
Comment was deleted.
| ] } | ||
| bevy_transform = { path = "../bevy_transform", version = "0.19.0-dev" } | ||
| bevy_utils = { path = "../bevy_utils", version = "0.19.0-dev" } | ||
| bevy_window = { path = "../bevy_window", version = "0.19.0-dev" } |
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.
@atlv24 is this ok?
|
Also, does putting the settings on ColorGrading make sense? Shouldn't they be per monitor somehow? |
|
The max luminance left/right controls in the demo seem inverted to how I expect. |
|
Is max luminance supposed to be sustained, or peak? |
|
The max luminance is just max luminance, it's up to the display if it is able to maintain that or clip. The user can also adjust the display brightness, which will override the actual luminance. You can see this if you open the example in a dark room on a macbook and play with the display brightness. As far as I understand it, the luminance values are for the case where you have a fully calibrated reference hardware pipeline, in reality there are a bunch of things that happen between the rendered f16 output and the pixels lighting up on the display that will cause that to differ.
You're just tweaking how bright paper white should be in a scene and how bright you want peak brightness to be. You can "calibrate" it, but most games let you tweak this yourself in game at runtime.
Right increases, left decreases. It's also increasing the range so the fact that paper white level (red) moves the other direction might be confusing you. |

Objective
Solution
Testing
cargo run --example hdr_calibrationScreen.Recording.2026-01-16.at.11.23.42.PM.mov
Screen.Recording.2026-01-17.at.1.02.37.AM.mov