diff --git a/WickedEngine/shaders/ShaderInterop_Postprocess.h b/WickedEngine/shaders/ShaderInterop_Postprocess.h index 687dd3d72..63a97531e 100644 --- a/WickedEngine/shaders/ShaderInterop_Postprocess.h +++ b/WickedEngine/shaders/ShaderInterop_Postprocess.h @@ -122,6 +122,9 @@ struct PushConstantsTonemap float2 resolution_rcp; float exposure; float dither; + float brightness; + float contrast; + float saturation; int texture_input; int buffer_input_luminance; diff --git a/WickedEngine/shaders/screenspaceshadowCS.hlsl b/WickedEngine/shaders/screenspaceshadowCS.hlsl index 9f015c459..c1346a3db 100644 --- a/WickedEngine/shaders/screenspaceshadowCS.hlsl +++ b/WickedEngine/shaders/screenspaceshadowCS.hlsl @@ -200,7 +200,6 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint3 GTid : float shadow = 0; ray.Direction = normalize(lerp(L, mul(hemispherepoint_cos(bluenoise.x, bluenoise.y), get_tangentspace(L)), 0.025 + max3(surface.sss))); - #ifdef RTAPI RayQuery< RAY_FLAG_SKIP_PROCEDURAL_PRIMITIVES | diff --git a/WickedEngine/shaders/tonemapCS.hlsl b/WickedEngine/shaders/tonemapCS.hlsl index 3dab04708..fc9a78a57 100644 --- a/WickedEngine/shaders/tonemapCS.hlsl +++ b/WickedEngine/shaders/tonemapCS.hlsl @@ -42,6 +42,47 @@ float3 ACESFitted(float3 color) return color; } +float4x4 saturationMatrix(float saturate) +{ + float3 luminance = float3(0.3086f, 0.6094f, 0.0820f); + float oneMinusSat = 1.0f - saturate; + + float3 red = float3(luminance * oneMinusSat); + red += float3(saturate, 0, 0); + + float3 green = float3(luminance * oneMinusSat); + green += float3(0, saturate, 0); + + float3 blue = float3(luminance * oneMinusSat); + blue += float3(0, 0, saturate); + + return float4x4(red, 0, green, 0, blue, 0, 0, 0, 0, 1); +} + +#undef WICKED_ENGINE_DEFAULT_ROOTSIGNATURE // don't use auto root signature! +[RootSignature( + "RootConstants(num32BitConstants=16, b999)," + "DescriptorTable( " + "SRV(t0, space = 2, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," + "SRV(t0, space = 3, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," + "SRV(t0, space = 4, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," + "SRV(t0, space = 5, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," + "SRV(t0, space = 6, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," + "SRV(t0, space = 7, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," + "SRV(t0, space = 8, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," + "SRV(t0, space = 9, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," + "SRV(t0, space = 10, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," + "SRV(t0, space = 11, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," + "SRV(t0, space = 12, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," + "SRV(t0, space = 13, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," + "UAV(u0, space = 14, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," + "UAV(u0, space = 15, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," + "UAV(u0, space = 16, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," + "UAV(u0, space = 17, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)" + "), " + "StaticSampler(s100, addressU = TEXTURE_ADDRESS_CLAMP, addressV = TEXTURE_ADDRESS_CLAMP, addressW = TEXTURE_ADDRESS_CLAMP, filter = FILTER_MIN_MAG_MIP_LINEAR)" +)] + [numthreads(POSTPROCESS_BLOCKSIZE, POSTPROCESS_BLOCKSIZE, 1)] void main(uint3 DTid : SV_DispatchThreadID) { @@ -98,6 +139,31 @@ void main(uint3 DTid : SV_DispatchThreadID) result.rgb += (dither((float2)DTid.xy) - 0.5f) / 64.0f; } + float saturationIntensity = 1.0f; + float brightness = 0.0f; + float contrast = 1.0f; + + [branch] + if (tonemap_push.brightness >= 0) + { + brightness = tonemap_push.brightness; + } + + [branch] + if (tonemap_push.contrast >= 0) + { + contrast = tonemap_push.contrast; + } + + [branch] + if (tonemap_push.saturation >= 0) + { + saturationIntensity = tonemap_push.saturation; + } + + result.rgb = (result.rgb - 0.5f) * contrast + 0.5f + brightness; + result.rgb = (float3)(mul(saturationMatrix(saturationIntensity), result)); + [branch] if (tonemap_push.texture_output >= 0) { diff --git a/WickedEngine/wiRenderPath3D.cpp b/WickedEngine/wiRenderPath3D.cpp index 1d22bc7fd..f2424ea59 100644 --- a/WickedEngine/wiRenderPath3D.cpp +++ b/WickedEngine/wiRenderPath3D.cpp @@ -1663,6 +1663,9 @@ namespace wi *rt_write, cmd, getExposure(), + getBrightness(), + getContrast(), + getSaturation(), getDitherEnabled(), getColorGradingEnabled() ? (scene->weather.colorGradingMap.IsValid() ? &scene->weather.colorGradingMap.GetTexture() : nullptr) : nullptr, getMSAASampleCount() > 1 ? &rtParticleDistortion_Resolved : &rtParticleDistortion, diff --git a/WickedEngine/wiRenderPath3D.h b/WickedEngine/wiRenderPath3D.h index 3d659c52e..93d9ed35c 100644 --- a/WickedEngine/wiRenderPath3D.h +++ b/WickedEngine/wiRenderPath3D.h @@ -23,6 +23,9 @@ namespace wi }; private: float exposure = 1.0f; + float brightness = 0.0f; + float contrast = 1.0f; + float saturation = 1.0f; float bloomThreshold = 1.0f; float motionBlurStrength = 100.0f; float dofStrength = 10.0f; @@ -179,6 +182,9 @@ namespace wi const wi::graphics::Texture* GetGUIBlurredBackground() const override { return &rtGUIBlurredBackground[2]; } constexpr float getExposure() const { return exposure; } + constexpr float getBrightness() const { return brightness; } + constexpr float getContrast() const { return contrast; } + constexpr float getSaturation() const { return saturation; } constexpr float getBloomThreshold() const { return bloomThreshold; } constexpr float getMotionBlurStrength() const { return motionBlurStrength; } constexpr float getDepthOfFieldStrength() const { return dofStrength; } @@ -227,6 +233,9 @@ namespace wi constexpr uint32_t getMSAASampleCount() const { return msaaSampleCount; } constexpr void setExposure(float value) { exposure = value; } + constexpr void setBrightness(float value) { brightness = value; } + constexpr void setContrast(float value) { contrast = value; } + constexpr void setSaturation(float value) { saturation = value; } constexpr void setBloomThreshold(float value) { bloomThreshold = value; } constexpr void setMotionBlurStrength(float value) { motionBlurStrength = value; } constexpr void setDepthOfFieldStrength(float value) { dofStrength = value; } diff --git a/WickedEngine/wiRenderPath3D_PathTracing.cpp b/WickedEngine/wiRenderPath3D_PathTracing.cpp index 86613f594..04b53bc22 100644 --- a/WickedEngine/wiRenderPath3D_PathTracing.cpp +++ b/WickedEngine/wiRenderPath3D_PathTracing.cpp @@ -364,6 +364,9 @@ namespace wi rtPostprocess, cmd, getExposure(), + getBrightness(), + getContrast(), + getSaturation(), getDitherEnabled(), getColorGradingEnabled() ? (scene->weather.colorGradingMap.IsValid() ? &scene->weather.colorGradingMap.GetTexture() : nullptr) : nullptr, nullptr, diff --git a/WickedEngine/wiRenderer.cpp b/WickedEngine/wiRenderer.cpp index 0678314e5..21844b2c7 100644 --- a/WickedEngine/wiRenderer.cpp +++ b/WickedEngine/wiRenderer.cpp @@ -13078,6 +13078,9 @@ void Postprocess_Tonemap( const Texture& output, CommandList cmd, float exposure, + float brightness, + float contrast, + float saturation, bool dither, const Texture* texture_colorgradinglut, const Texture* texture_distortion, @@ -13105,6 +13108,9 @@ void Postprocess_Tonemap( tonemap_push.resolution_rcp.y = 1.0f / desc.height; tonemap_push.exposure = exposure; tonemap_push.dither = dither ? 1.0f : 0.0f; + tonemap_push.brightness = brightness; + tonemap_push.contrast = contrast; + tonemap_push.saturation = saturation; tonemap_push.texture_input = device->GetDescriptorIndex(&input, SubresourceType::SRV); tonemap_push.buffer_input_luminance = device->GetDescriptorIndex((buffer_luminance == nullptr) ? &luminance_dummy : buffer_luminance, SubresourceType::SRV); tonemap_push.texture_input_distortion = device->GetDescriptorIndex(texture_distortion, SubresourceType::SRV); diff --git a/WickedEngine/wiRenderer.h b/WickedEngine/wiRenderer.h index 46f61b959..0cdc0c785 100644 --- a/WickedEngine/wiRenderer.h +++ b/WickedEngine/wiRenderer.h @@ -687,6 +687,9 @@ namespace wi::renderer const wi::graphics::Texture& output, wi::graphics::CommandList cmd, float exposure, + float brightness, + float contrast, + float saturation, bool dither, const wi::graphics::Texture* texture_colorgradinglut = nullptr, const wi::graphics::Texture* texture_distortion = nullptr,