From 4d9d0728d5543f870f1d62d0dbb7a73beea0a17e Mon Sep 17 00:00:00 2001 From: Aevyrie Date: Tue, 22 Nov 2022 13:09:32 +0000 Subject: [PATCH] Fix missing sRGB conversion for dithering non-HDR pipelines (#6707) # Objective - Fixes #6706 Zoom in on the shadow in the following images: ## Current bevy/main ### HDR On - correct ![current-hdron](https://user-images.githubusercontent.com/2632925/202943151-ecad3cbe-a76e-46df-bac9-9e590a31a9f3.png) ### HDR Off - incorrect ![current-hdroff](https://user-images.githubusercontent.com/2632925/202943154-34e3f527-a00e-4546-931d-0691204cc6a4.png) ## This PR ### HDR On - correct ![new-hdron](https://user-images.githubusercontent.com/2632925/202943383-081990de-9a14-45bd-ac52-febcc4289079.png) ### HDR Off - corrected ![new-hdroff](https://user-images.githubusercontent.com/2632925/202943388-a3b05d79-a0f3-4b1e-b114-0a9f03efe351.png) ## Close-up comparison ### New ![Screenshot from 2022-11-20 17-46-46](https://user-images.githubusercontent.com/2632925/202943552-d45c3a48-841e-47a6-981f-776c5a9563f6.png) ### Old ![Screenshot from 2022-11-20 17-46-41](https://user-images.githubusercontent.com/2632925/202943562-555cb5a2-2b20-45f9-b250-89f2bc87af5f.png) ## Solution - It turns out there was an outright missing sRGB conversion for dithering non-HDR cameras. - I also tried using a precise sRGB conversion, but it had no apparent effect on the final image. --- ## Changelog - Fix deband dithering intensity for non-HDR pipelines. --- .../src/tonemapping/tonemapping_shared.wgsl | 2 +- crates/bevy_pbr/src/render/pbr.wgsl | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/crates/bevy_core_pipeline/src/tonemapping/tonemapping_shared.wgsl b/crates/bevy_core_pipeline/src/tonemapping/tonemapping_shared.wgsl index deafac0750d84..f538af1b2d812 100644 --- a/crates/bevy_core_pipeline/src/tonemapping/tonemapping_shared.wgsl +++ b/crates/bevy_core_pipeline/src/tonemapping/tonemapping_shared.wgsl @@ -34,4 +34,4 @@ fn screen_space_dither(frag_coord: vec2) -> vec3 { var dither = vec3(dot(vec2(171.0, 231.0), frag_coord)).xxx; dither = fract(dither.rgb / vec3(103.0, 71.0, 97.0)); return (dither - 0.5) / 255.0; -} \ No newline at end of file +} diff --git a/crates/bevy_pbr/src/render/pbr.wgsl b/crates/bevy_pbr/src/render/pbr.wgsl index 6f5d94edfbaf3..cfe825190d2a5 100644 --- a/crates/bevy_pbr/src/render/pbr.wgsl +++ b/crates/bevy_pbr/src/render/pbr.wgsl @@ -99,7 +99,13 @@ fn fragment(in: FragmentInput) -> @location(0) vec4 { output_color = tone_mapping(output_color); #endif #ifdef DEBAND_DITHER - output_color = dither(output_color, in.frag_coord.xy); + var output_rgb = output_color.rgb; + output_rgb = pow(output_rgb, vec3(1.0 / 2.2)); + output_rgb = output_rgb + screen_space_dither(in.frag_coord.xy); + // This conversion back to linear space is required because our output texture format is + // SRGB; the GPU will assume our output is linear and will apply an SRGB conversion. + output_rgb = pow(output_rgb, vec3(2.2)); + output_color = vec4(output_rgb, output_color.a); #endif return output_color; }