-
-
Notifications
You must be signed in to change notification settings - Fork 24.1k
[Windows] Support output to HDR monitors #94496
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: master
Are you sure you want to change the base?
Conversation
|
I gave this a quick test locally (on Windows 11 23H2 + NVIDIA 560.80 + LG C2 42"), it works as expected. This is encouraging to see, I've been wanting this for a while 🙂 I'll need to look into building more extensive scenes and getting tonemapped screenshots/videos out of this. 2D HDR also needs to be tested thoroughly. Remember that JPEG XL or AVIF for images and AV1 for videos are a must for HDR, as other formats can only store SDR data. You may need to embed those in ZIP archives and ask users to preview them in a local media player, as GitHub doesn't allow uploading those formats and browsers often struggle displaying HDR correctly. I noticed some issues for now:
See the settings exposed by the Control HDR mod for an example of a best-in-class HDR implementation (related video): control_hdr_mod_settings.mp4Interesting, that UI seems to use the term "paperwhite" in a different way, and has a dedicated setting for the brightness of UI and HUD elements. |
88beb60 to
8df131d
Compare
Thanks for taking a look!
Odd that NVidia's RTX HDR doesn't detect the HDR color space and avoid messing with the final swap chain buffer. Auto-HDR in Windows 11 appears to avoid messing with Godot when HDR is enabled. Updating the NVidia Profile may be outside the scope of this PR and be best done with a more focused PR.
For the initial draft, yes, everything is mapped using the same tonemapper. However, we should map UI elements to a different brightness to avoid them being too bright. For now, that can be worked around with dimming the brightness of any UI elements via the theme, but I would like to fix that in this PR.
I haven't looked into configuring the editor to use HDR yet. Will do after I figure out how to properly tone map UI elements, if you enable HDR on the editor now, the UI is a little unpleasant.
Agreed, UI elements and other 2D elements should probably be mapped to a different brightness curve. I'll probably have to figure out where in the engine 3D and 2D elements are composited together and perform the tone mapping there.
That might be outside of the scope of this PR. I'm not sure how I would indicate that certain 3D elements need to be mapped using a different brightness curve once they are all combined into the same buffer. It would be similar to trying to avoid sRGB mapping certain rendered elements. For now, this can be worked around by decreasing the brightness of the color of these elements.
Baldur's Gate 3 and Cyberpunk 2077 also have really nice HDR settings menus. I've been basing some of this work off their approach, though modifying contrast and brightness I'm leaving up to Environment since those effects are already there. Thanks again for your comments! I'll add some TODO items to the description for tracking. |
b89985a to
e9742ba
Compare
e9742ba to
b2bd1a1
Compare
|
Can you use any Godot project to test this PR? Bistro-Demo-Tweaked and Crater-Province-Level both use physical light units, and use as close to reference values for luminosity on light sources. (i.e. the sun at noon is 100000 lux, the moon at midnight is 0.3 lux) I'd love to help test this PR but unfortunately I don't have HDR hardware |
|
I recently got a monitor that supports Anyway, adding HDR output to D3D12 should be trivial and I might give it a try. (No promises!) Shall we also consider implementing HDR display for the compatibility renderer? I am not sure if native OpenGL can do HDR, but it is very possible to implement on Windows with the help of ANGLE and some manual setting up. |
|
This needs a rebase on master, but I have a https://www.dell.com/en-ca/shop/alienware-34-curved-qd-oled-gaming-monitor-aw3423dw/apd/210-bcye/monitors-monitor-accessories HDR display. I can help test. |
You should be able to test with any scene, though keep in mind that the realistic light units will not map directly to the brightness of the display. Consumer desktop displays typically don't go much above 1000 nits on the high end, which is far too dim to simulate sunlight. Values from the scene will be mapped to a range fitting within the max luminosity set for the window. |
b2bd1a1 to
728912f
Compare
|
Here are the changes to get Rec. 2020 HDR output on D3D12: master...alvinhochun:godot:hdr-output-d3d12 |
|
The over-exposure in your screenshot is expected, but the colours are oversaturated because it is missing a colour space conversion. The colours need to be converted from BT.709 primaries to BT.2020 primaries. This is how it should look with the correct colours: The conversion may be done with something like this: diff --git a/servers/rendering/renderer_rd/shaders/color_space_inc.glsl b/servers/rendering/renderer_rd/shaders/color_space_inc.glsl
index 3583ee8365..76305a8a3c 100644
--- a/servers/rendering/renderer_rd/shaders/color_space_inc.glsl
+++ b/servers/rendering/renderer_rd/shaders/color_space_inc.glsl
@@ -19,6 +19,15 @@ vec3 linear_to_st2084(vec3 color, float max_luminance) {
// max_luminance is the display's peak luminance in nits
// we map it here to the native 10000 nits range of ST2084
float adjustment = max_luminance * (1.0f / 10000.0f);
+ color = color * adjustment;
+
+ // Color transformation matrix values taken from DirectXTK, may need verification.
+ const mat3 from709to2020 = mat3(
+ 0.6274040f, 0.0690970f, 0.0163916f,
+ 0.3292820f, 0.9195400f, 0.0880132f,
+ 0.0433136f, 0.0113612f, 0.8955950f
+ );
+ color = from709to2020 * color;
// Apply ST2084 curve
const float c1 = 0.8359375;
@@ -26,7 +35,7 @@ vec3 linear_to_st2084(vec3 color, float max_luminance) {
const float c3 = 18.6875;
const float m1 = 0.1593017578125;
const float m2 = 78.84375;
- vec3 cp = pow(abs(color.rgb * adjustment), vec3(m1));
+ vec3 cp = pow(abs(color.rgb), vec3(m1));
return pow((c1 + c2 * cp) / (1 + c3 * cp), vec3(m2));
}
|
728912f to
56d27a6
Compare
ba867e9 to
14268ef
Compare
Thanks for that! Squashed in most of the changes.
I ended up removing the change in logic here for a couple reasons:
This is likely a quick change to enable
Yea, that makes sense, assuming we plan to actually merge the editor changes in 4.7. Without them, the editor looks strange in places with HDR on, which is not a great experience. I requested another review since all suggestions have been completed, would love to see another approval to unblock merging. |
Oh, good catch; thanks for having my back. I thought I did a thorough search of references to it, but I must have overlooked a scenario.
Yep, for sure. I want to make sure this PR gets into 4.7 dev 1, so long as no issues are discovered with it. Editor enhancements can easily make it in shortly afterwards, but if they end up being in a different dev release, it's no big deal.
Done! I don't know of any remaining issues with this PR. I'll keep testing on Steam Deck/Wine to verify that things don't look problematically dark with the 200 nits reference luminance... |
|
While testing, I was connecting and disconnecting monitors a fair bit and got into a situation where Godot reported this error: And then stopped responding entirely to changes in I've committed and squashed a change to only stop reporting error messages instead of permanently giving up on reading |
14268ef to
1df5b65
Compare
1df5b65 to
05f5ca1
Compare
|
Another rebase to bring in the beta 1 bits. No other changes. |
|
I've made a draft for a new HDR output manual page along with a draft for an official HDR output demo project. Please give those a look and provide feedback! I'm sure many of us have had some thoughts about how best to instruct HDR output usage and how it can be demonstrated to new users, so I'd like to hear if I've captured the key points or have introduced anything that may only add confusion. I've also renamed my old test project to be a "Godot HDR output porting test project ". This older test project is designed solely for implementing the HDR output feature on new platforms. The official HDR output demo project supersedes it for general demonstration purposes. Finally, I've created trackers for HDR output-related proposals and issues & PRs. Please feel free to post on those threads whenever you create a new item that should be added to one of those trackers. @DarkKilauea Would you mind updating the description of this PR to include some of those links if you have time? (Also, I'm not sure if your old test project is entirely suitable anymore: I notice that it has the old Rec. 2020 colour triangle, but this is entirely clipped to Rec. 709 now...) No rush, of course, and thanks as always! |
05f5ca1 to
152ec0b
Compare
0e222a4 to
c373143
Compare
c373143 to
e0c6478
Compare
Thanks for that! I've added links to the description.
Links have been updated. I also updated the screenshots and getting started guide. Thanks again for all the help! |
|
Thanks! From the description:
Most of these are no longer the case. I implemented fixes in 4.6 to correct this behaviour: now only blending is different when hdr_2d is enabled. Also, I'm not sure that the advice in the Getting Started -> runtime is a good idea. Setting request HDR output is something that should be done independently of whether the window currently supports HDR output. I expect this approach of checking to see if the window currently supports HDR output should only be used for determining how player-facing settings are presented, which doesn't appear to be what this section of getting started is demonstrating. |
| Microsoft::WRL::ComPtr<IDXGIFactory4> dxgi_factory; | ||
| r_Desc = {}; | ||
|
|
||
| if (FAILED(CreateDXGIFactory2(0, IID_PPV_ARGS(&dxgi_factory)))) { |
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.
You should reuse the DXGI factory from the D3D12 rendering context driver. The IDXGIFactory2 can be upcasted to IDXGIFactory4 using QueryInterface.
Co-authored-by: Alvin Wong <[email protected]> Co-authored-by: Allen Pestaluky <[email protected]>
e0c6478 to
24c34c5
Compare
|
Rebased on top of the RC 1 bits. |
This has been fixed, thanks for pointing that out. I knew we fixed some issues, but wasn't sure as to the extent.
That's fair, I'll update. |



Implements: godotengine/godot-proposals#10817 for Windows.
Overview
This PR enables the ability for Godot to output to HDR capable displays on Windows. This allows Godot to output brighter images than allowed in SDR mode and with more vibrant colors.
HDR output is implemented using Extended Dynamic Range (EDR), which is a technique that preserves the SDR range (of 0 to 1) while extending the upper range to include brighter values, up to the maximum brightness of the display. This approach preserves the shadows and darker areas of the scene while allowing highlights to reach much brighter values.
It also allows for 2D content take advantage of HDR displays by producing brighter colors that have a value over 1.0, without having to opt into tonemapping and the effects pipeline. 2D and 3D content can also be mixed in the same scene while keeping a consistent brightness between the two, based on a shared "reference" luminance.
Testing/Sample projects:
Examples (converted to SDR to work on all browsers):
Examples (HDR images, may not display correctly on all browsers):
Supported Platforms:
Supported Graphics APIs:
Supported HDR Formats:
Supported Tonemappers:
Features:
Limitations:
hdr_2dto output the additional dynamic range needed for HDR displays. Blending may look different whenhdr_2dis enabled.hdr_2dwill automatically be enabled for windows that turn on HDR output, which may result in a change in appearance of the scene. It's advised that applications planning to support HDR output create their content withhdr_2denabled, even when HDR output is disabled.Follow up work:
white,contrast, and future HDR support to the AgX tonemapper. #106940Trackers:
Getting Started
Project Settings
display/window/hdr/enabled(you may need to enable Advanced Settings first):rendering/viewport/hdr_2d:Runtime
Help Needed
Please give this a test, either with the linked sample project or with your own projects, and give feedback. Specifically I'm looking for input on how easy this feature was to use and if you encountered any issues with your particular display, OS, or driver configuration.
Remaining Work / Issues
SDRWhiteLevel: [Windows] Support output to HDR monitors #94496 (comment)