ValveSoftware / openvr

OpenVR SDK
http://steamvr.com
BSD 3-Clause "New" or "Revised" License
6.12k stars 1.28k forks source link

SteamVR applies unnecessary linear-to-sRGB conversion to all swapchain images supplied via OpenXR #1766

Open amini-allight opened 1 year ago

amini-allight commented 1 year ago

This bug report is for SteamVR's OpenXR runtime functionality rather than OpenVR, but I have been instructed to post such bug reports here by a Valve employee in the past.

I discovered while working on my project that known colors passed to SteamVR via OpenXR don't look correct (they are much brighter) when viewed either through the physical headset or the "Display VR View" option within SteamVR. This can be fixed by applying an sRGB-to-linear conversion function to the (already linear) color values prior to submitting them to SteamVR. The fact that this fix works suggests the issue is SteamVR doing an unnecessary linear-to-sRGB conversion on supplied images, which the fix counteracts. This issue occurs regardless of whether the swapchain images are configured to use an sRGB format like VK_FORMAT_R8G8B8A8_SRGB or a linear format like VK_FORMAT_R16G16B16A16_SFLOAT, suggesting it is an issue with general OpenXR swapchain image handling rather than an issue specifically with treating sRGB images as linear ones.

I have uploaded a program that demonstrates this bug in a repository on my GitLab and more information can be found in the readme over there.

I also found this bug report from last year which seems to be describing the same issue.

Platform info:

amini-allight commented 1 year ago

Tested this on the SteamVR 2.0.1 beta today, bug is present in that version too.

shinyquagsire23 commented 7 months ago

Been working on HDR support for ALVR and can confirm this is still the case for non-SRGB formats (RGBA float16) on SteamVR 2.4.3 on my Index. My gold standard target for HDR tests on ALVR has been a combination of OpenBrush and SpecialK, which can force the framebuffers to float16 instead of RGBA8_SRGB (normally used for flat HDR displays for people who want less banding). The skybox is a very dark gray when shown correctly (and has noticeable banding on 8-bit displays). On my Index, it displays as a very washed out light gray.

Admittedly I only tested this because I was curious if I should or should not be doing sRGB corrections on linear RGB layers received by the ALVR driver since it's a bit ambiguous (storage vs shader input vs shader output colors get extra messy with encoders involved).

Actually, if it's happening regardless of the input format, that would also explain why two titles had really odd behavior when I was testing with SpecialK: Bonelab and Beat Saber both are OpenXR apps, both output RGBA8_SRGB by default, and both required a very strange extra linear-to-sRGB pass in ALVR iff their swapchains are forced to RGBA float16. Which would imply that Unity might have a SteamVR-specific OpenXR hackfix for this now, yikes.

shinyquagsire23 commented 7 months ago

Honestly the more I look at this, the more confused I get. On an Index, I get the following results:

Edit: Gave it a think. I think that