diff --git a/features/IBL/Shaders/IBL/IBL.hlsli b/features/IBL/Shaders/IBL/IBL.hlsli index 4b2fd697c8..927164669f 100644 --- a/features/IBL/Shaders/IBL/IBL.hlsli +++ b/features/IBL/Shaders/IBL/IBL.hlsli @@ -1,3 +1,4 @@ +#include "Common/Color.hlsli" #include "Common/Math.hlsli" #include "Common/Random.hlsli" #include "Common/SharedData.hlsli" @@ -20,6 +21,23 @@ namespace ImageBasedLighting float colorR = SphericalHarmonics::SHHallucinateZH3Irradiance(shR, rayDir); float colorG = SphericalHarmonics::SHHallucinateZH3Irradiance(shG, rayDir); float colorB = SphericalHarmonics::SHHallucinateZH3Irradiance(shB, rayDir); - return float3(colorR, colorG, colorB); + return float3(colorR, colorG, colorB) / Math::PI; + } + + float3 GetFogIBLColor(float3 fogColor) + { + float3 directionalAmbientColor = max(0, mul(SharedData::DirectionalAmbient, float4(float3(0, 0, 0), 1.0))).xyz; + float3 iblColor = directionalAmbientColor * SharedData::iblSettings.DALCAmount + Color::Saturation(GetDiffuseIBL(float3(0, 0, 0)), SharedData::iblSettings.IBLSaturation) * SharedData::iblSettings.DiffuseIBLScale; + if (SharedData::iblSettings.PreserveFogLuminance) { + const float fogLuminance = Color::RGBToLuminance2(fogColor); + const float iblLuminance = Color::RGBToLuminance2(iblColor); + if (iblLuminance > 0) { + const float scale = fogLuminance / iblLuminance; + iblColor *= scale; + } else { + iblColor = fogColor; + } + } + return lerp(fogColor, iblColor, SharedData::iblSettings.FogAmount); } } \ No newline at end of file diff --git a/package/Shaders/Common/SharedData.hlsli b/package/Shaders/Common/SharedData.hlsli index 090993f5ec..241945c700 100644 --- a/package/Shaders/Common/SharedData.hlsli +++ b/package/Shaders/Common/SharedData.hlsli @@ -178,11 +178,13 @@ namespace SharedData struct IBLSettings { uint EnableDiffuseIBL; + uint SampleUnderHorizonFromDynCube; + uint PreserveFogLuminance; + uint pad; float DiffuseIBLScale; float DALCAmount; float IBLSaturation; - uint SampleUnderHorizonFromDynCube; - uint3 pad; + float FogAmount; }; struct ExtendedTranslucencySettings diff --git a/package/Shaders/Effect.hlsl b/package/Shaders/Effect.hlsl index 818f03f399..57746721f2 100644 --- a/package/Shaders/Effect.hlsl +++ b/package/Shaders/Effect.hlsl @@ -793,7 +793,13 @@ PS_OUTPUT main(PS_INPUT input) # elif defined(MULTBLEND) || defined(MULTBLEND_DECAL) float3 blendedColor = lerp(lightColor, 1.0.xxx, saturate(1.5 * input.FogParam.w).xxx); # else - float3 blendedColor = lerp(lightColor, input.FogParam.xyz, input.FogParam.www); + float3 fogColor = input.FogParam.xyz; +# if defined(IBL) + if (SharedData::iblSettings.EnableDiffuseIBL && !SharedData::InInterior) { + fogColor = ImageBasedLighting::GetFogIBLColor(fogColor); + } +# endif + float3 blendedColor = lerp(lightColor, fogColor, input.FogParam.www); # endif # else float3 blendedColor = lightColor.xyz; diff --git a/package/Shaders/ISSAOComposite.hlsl b/package/Shaders/ISSAOComposite.hlsl index 08e1def3db..7936864489 100644 --- a/package/Shaders/ISSAOComposite.hlsl +++ b/package/Shaders/ISSAOComposite.hlsl @@ -125,6 +125,10 @@ float SimplexNoise(float3 v) dot(p2, x2), dot(p3, x3))); } +# if defined(IBL) +# include "IBL/IBL.hlsli" +# endif + PS_OUTPUT main(PS_INPUT input) { PS_OUTPUT psout; @@ -170,6 +174,11 @@ PS_OUTPUT main(PS_INPUT input) float fogDistanceFactor = (2 * CameraNearFar.x * CameraNearFar.y) / ((CameraNearFar.y + CameraNearFar.x) - (2 * (1.01 * depth - 0.01) - 1) * (CameraNearFar.y - CameraNearFar.x)); float fogFactor = min(FogParam.w, pow(saturate(fogDistanceFactor * FogParam.y - FogParam.x), FogParam.z)); float3 fogColor = lerp(FogNearColor.xyz, FogFarColor.xyz, fogFactor); +# if defined(IBL) + if (SharedData::iblSettings.EnableDiffuseIBL && !SharedData::InInterior) { + fogColor = ImageBasedLighting::GetFogIBLColor(fogColor); + } +# endif if (depth < 0.999999) { composedColor.xyz = FogNearColor.w * lerp(composedColor.xyz, fogColor, fogFactor); } diff --git a/package/Shaders/Lighting.hlsl b/package/Shaders/Lighting.hlsl index 750a5b6895..767a138ac2 100644 --- a/package/Shaders/Lighting.hlsl +++ b/package/Shaders/Lighting.hlsl @@ -3112,8 +3112,14 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace : SV_IsFrontFace) # if !defined(DEFERRED) color.xyz = Color::LinearToGamma(Color::GammaToLinear(color.xyz) + specularColor); + float3 fogColor = input.FogParam.xyz; +# if defined(IBL) + if (SharedData::iblSettings.EnableDiffuseIBL && !SharedData::InInterior) { + fogColor = ImageBasedLighting::GetFogIBLColor(fogColor); + } +# endif if (FrameBuffer::FrameParams.y && FrameBuffer::FrameParams.z) - color.xyz = lerp(color.xyz, input.FogParam.xyz, input.FogParam.w); + color.xyz = lerp(color.xyz, fogColor, input.FogParam.w); # endif # if defined(TESTCUBEMAP) && defined(ENVMAP) && defined(DYNAMIC_CUBEMAPS) diff --git a/package/Shaders/Water.hlsl b/package/Shaders/Water.hlsl index e3eb595453..affdd058d2 100644 --- a/package/Shaders/Water.hlsl +++ b/package/Shaders/Water.hlsl @@ -984,6 +984,10 @@ float3 GetSunColor(float3 normal, float3 viewDirection) # include "InverseSquareLighting/InverseSquareLighting.hlsli" # endif +# if defined(IBL) +# include "IBL/IBL.hlsli" +# endif + PS_OUTPUT main(PS_INPUT input) { PS_OUTPUT psout; @@ -1140,7 +1144,13 @@ PS_OUTPUT main(PS_INPUT input) # if defined(VC) float specularFraction = lerp(1, fresnel * diffuseOutput.refractionMul, distanceFactor); float3 finalColorPreFog = lerp(diffuseColor, specularColor, specularFraction) + sunColor * depthControl.w; - float3 finalColor = lerp(finalColorPreFog, input.FogParam.xyz * PosAdjust[eyeIndex].w, input.FogParam.w); + float3 fogColor = input.FogParam.xyz; +# if defined(IBL) + if (SharedData::iblSettings.EnableDiffuseIBL && !SharedData::InInterior) { + fogColor = ImageBasedLighting::GetFogIBLColor(fogColor); + } +# endif + float3 finalColor = lerp(finalColorPreFog, fogColor * PosAdjust[eyeIndex].w, input.FogParam.w); # if defined(WETNESS_EFFECTS) && defined(DEBUG_WETNESS_EFFECTS) // DEBUG MODE: Override water color with debug visualization float3 debugColor = WetnessEffects::GetDebugWetnessColorStandard(waterData.rippleInfo, 2.0, 3.0); @@ -1152,12 +1162,23 @@ PS_OUTPUT main(PS_INPUT input) # else float specularFraction = lerp(1, fresnel, distanceFactor); float3 finalColorPreFog = lerp(diffuseOutput.refractionDiffuseColor, specularColor, specularFraction) + sunColor * depthControl.w; - finalColorPreFog = lerp(finalColorPreFog, input.FogParam.xyz * PosAdjust[eyeIndex].w, input.FogParam.w); + float3 preFogColor = input.FogParam.xyz; +# if defined(IBL) + if (SharedData::iblSettings.EnableDiffuseIBL && !SharedData::InInterior) { + preFogColor = ImageBasedLighting::GetFogIBLColor(preFogColor); + } +# endif + finalColorPreFog = lerp(finalColorPreFog, preFogColor * PosAdjust[eyeIndex].w, input.FogParam.w); float3 refractionColor = diffuseOutput.refractionColor; float fogFactor = min(FogParam.w, pow(saturate(-diffuseOutput.depth * FogParam.y - FogParam.x), FogParam.z)); float3 fogColor = lerp(FogNearColor.xyz, FogFarColor.xyz, fogFactor); +# if defined(IBL) + if (SharedData::iblSettings.EnableDiffuseIBL && !SharedData::InInterior) { + fogColor = ImageBasedLighting::GetFogIBLColor(fogColor); + } +# endif refractionColor = lerp(refractionColor, fogColor, fogFactor); float3 finalColor = lerp(refractionColor, finalColorPreFog, diffuseOutput.refractionMul); diff --git a/src/Features/IBL.cpp b/src/Features/IBL.cpp index 0a4e70d3bd..31fef05229 100644 --- a/src/Features/IBL.cpp +++ b/src/Features/IBL.cpp @@ -8,10 +8,12 @@ NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT( IBL::Settings, EnableDiffuseIBL, + SampleUnderHorizonFromDynCube, + PreserveFogLuminance, DiffuseIBLScale, DALCAmount, IBLSaturation, - SampleUnderHorizonFromDynCube) + FogAmount) void IBL::DrawSettings() { @@ -19,6 +21,8 @@ void IBL::DrawSettings() ImGui::SliderFloat("Diffuse IBL Scale", &settings.DiffuseIBLScale, 0.0f, 10.0f, "%.2f"); ImGui::SliderFloat("Diffuse IBL Saturation", &settings.IBLSaturation, 0.0f, 2.0f, "%.2f"); ImGui::SliderFloat("DALC Amount", &settings.DALCAmount, 0.0f, 1.0f, "%.2f"); + ImGui::SliderFloat("Fog Mix", &settings.FogAmount, 0.0f, 1.0f, "%.2f"); + ImGui::Checkbox("Preserve Fog Luminance", (bool*)&settings.PreserveFogLuminance); ImGui::Checkbox("[EXP] Sample Under Horizon From Dynamic Cubemaps", (bool*)&settings.SampleUnderHorizonFromDynCube); if (auto _tt = Util::HoverTooltipWrapper()) { ImGui::Text( diff --git a/src/Features/IBL.h b/src/Features/IBL.h index 85783f0186..522fbd665f 100644 --- a/src/Features/IBL.h +++ b/src/Features/IBL.h @@ -44,11 +44,13 @@ struct IBL : Feature struct alignas(16) Settings { uint EnableDiffuseIBL = 1; - float DiffuseIBLScale = 0.5f; - float DALCAmount = 0.5f; - float IBLSaturation = 0.65f; uint SampleUnderHorizonFromDynCube = 0; - uint pad[3]; + uint PreserveFogLuminance = 0; + uint pad; + float DiffuseIBLScale = 1.0f; + float DALCAmount = 0.33f; + float IBLSaturation = 1.0f; + float FogAmount = 0.0f; } settings; ID3D11ComputeShader* GetDiffuseIBLCS();