diff --git a/features/Dynamic Cubemaps/Shaders/DynamicCubemaps/DynamicCubemaps.hlsli b/features/Dynamic Cubemaps/Shaders/DynamicCubemaps/DynamicCubemaps.hlsli index 2028a0085..6e7440dea 100644 --- a/features/Dynamic Cubemaps/Shaders/DynamicCubemaps/DynamicCubemaps.hlsli +++ b/features/Dynamic Cubemaps/Shaders/DynamicCubemaps/DynamicCubemaps.hlsli @@ -38,8 +38,8 @@ namespace DynamicCubemaps float3 finalIrradiance = 0; - float directionalAmbientColorSpecular = Color::RGBToLuminance( - max(0, mul(SharedData::DirectionalAmbient, float4(R, 1.0))) + float directionalAmbientColorSpecular = Color::RGBToLuminance(Color::Ambient( + max(0, mul(SharedData::DirectionalAmbient, float4(R, 1.0)))) ) * Color::ReflectionNormalisationScale; # if defined(IBL) && defined(LIGHTING) @@ -59,7 +59,7 @@ namespace DynamicCubemaps float specularIrradianceLuminance = Color::RGBToLuminance(EnvTexture.SampleLevel(SampColorSampler, R, 15)); specularIrradiance = (specularIrradiance / max(specularIrradianceLuminance, 0.001)) * directionalAmbientColorSpecular; - specularIrradiance = Color::GammaToLinear(specularIrradiance); + specularIrradiance = Color::IrradianceToLinear(specularIrradiance); finalIrradiance = specularIrradiance; return finalIrradiance; @@ -79,7 +79,7 @@ namespace DynamicCubemaps float specularIrradianceReflectionsLuminance = Color::RGBToLuminance(EnvReflectionsTexture.SampleLevel(SampColorSampler, R, 15)); specularIrradianceReflections = (specularIrradianceReflections / max(specularIrradianceReflectionsLuminance, 0.001)) * directionalAmbientColorSpecular; - specularIrradianceReflections = Color::GammaToLinear(specularIrradianceReflections); + specularIrradianceReflections = Color::IrradianceToLinear(specularIrradianceReflections); } float3 specularIrradiance = 0.0; @@ -89,12 +89,12 @@ namespace DynamicCubemaps float specularIrradianceLuminance = Color::RGBToLuminance(EnvTexture.SampleLevel(SampColorSampler, R, 15)); - directionalAmbientColorSpecular = Color::GammaToLinear(directionalAmbientColorSpecular); + directionalAmbientColorSpecular = Color::IrradianceToLinear(directionalAmbientColorSpecular); directionalAmbientColorSpecular *= skylightingSpecular; - directionalAmbientColorSpecular = Color::LinearToGamma(directionalAmbientColorSpecular); + directionalAmbientColorSpecular = Color::IrradianceToGamma(directionalAmbientColorSpecular); specularIrradiance = (specularIrradiance / max(specularIrradianceLuminance, 0.001)) * directionalAmbientColorSpecular; - specularIrradiance = Color::GammaToLinear(specularIrradiance); + specularIrradiance = Color::IrradianceToLinear(specularIrradiance); } finalIrradiance = lerp(specularIrradiance, specularIrradianceReflections, skylightingSpecular); @@ -104,7 +104,7 @@ namespace DynamicCubemaps float specularIrradianceLuminance = Color::RGBToLuminance(EnvReflectionsTexture.SampleLevel(SampColorSampler, R, 15)); specularIrradiance = (specularIrradiance / max(specularIrradianceLuminance, 0.001)) * directionalAmbientColorSpecular; - specularIrradiance = Color::GammaToLinear(specularIrradiance); + specularIrradiance = Color::IrradianceToLinear(specularIrradiance); finalIrradiance = specularIrradiance; # endif @@ -154,7 +154,7 @@ namespace DynamicCubemaps float specularIrradianceLuminance = Color::RGBToLuminance(EnvTexture.SampleLevel(SampColorSampler, R, 15)); specularIrradiance = (specularIrradiance / max(specularIrradianceLuminance, 0.001)) * directionalAmbientColorSpecular; - specularIrradiance = Color::GammaToLinear(specularIrradiance); + specularIrradiance = Color::IrradianceToLinear(specularIrradiance); finalIrradiance = specularIrradiance; return horizon * (F0 * specularBRDF.x + specularBRDF.y) * finalIrradiance; @@ -176,7 +176,7 @@ namespace DynamicCubemaps float specularIrradianceLuminance = Color::RGBToLuminance(EnvTexture.SampleLevel(SampColorSampler, R, 15)); specularIrradiance = (specularIrradiance / max(specularIrradianceLuminance, 0.001)) * directionalAmbientColorSpecular; - specularIrradiance = Color::GammaToLinear(specularIrradiance); + specularIrradiance = Color::IrradianceToLinear(specularIrradiance); } float3 specularIrradianceReflections = 1.0; @@ -187,7 +187,7 @@ namespace DynamicCubemaps float specularIrradianceReflectionsLuminance = Color::RGBToLuminance(EnvReflectionsTexture.SampleLevel(SampColorSampler, R, 15)); specularIrradianceReflections = (specularIrradianceReflections / max(specularIrradianceReflectionsLuminance, 0.001)) * directionalAmbientColorSpecular; - specularIrradianceReflections = Color::GammaToLinear(specularIrradianceReflections); + specularIrradianceReflections = Color::IrradianceToLinear(specularIrradianceReflections); } finalIrradiance = lerp(specularIrradiance, specularIrradianceReflections, skylightingSpecular); @@ -197,7 +197,7 @@ namespace DynamicCubemaps float specularIrradianceLuminance = Color::RGBToLuminance(EnvReflectionsTexture.SampleLevel(SampColorSampler, R, 15)); specularIrradiance = (specularIrradiance / max(specularIrradianceLuminance, 0.001)) * directionalAmbientColorSpecular; - specularIrradiance = Color::GammaToLinear(specularIrradiance); + specularIrradiance = Color::IrradianceToLinear(specularIrradiance); finalIrradiance = specularIrradiance; # endif diff --git a/features/Dynamic Cubemaps/Shaders/DynamicCubemaps/InferCubemapCS.hlsl b/features/Dynamic Cubemaps/Shaders/DynamicCubemaps/InferCubemapCS.hlsl index ee2549e8b..b4b25d473 100644 --- a/features/Dynamic Cubemaps/Shaders/DynamicCubemaps/InferCubemapCS.hlsl +++ b/features/Dynamic Cubemaps/Shaders/DynamicCubemaps/InferCubemapCS.hlsl @@ -1,4 +1,5 @@ #include "Common/Color.hlsli" +#include "Common/SharedData.hlsli" TextureCube EnvCaptureTexture : register(t0); TextureCube ReflectionsTexture : register(t1); @@ -90,11 +91,11 @@ float3 GetSamplingVector(uint3 ThreadID, in RWTexture2DArray OutputTextu } #if defined(REFLECTIONS) - color.rgb = lerp(color.rgb, Color::GammaToLinear(ReflectionsTexture.SampleLevel(LinearSampler, uv, 0.0).rgb), saturate(mipLevel / 7.0)); + color.rgb = lerp(color.rgb, Color::IrradianceToLinear(ReflectionsTexture.SampleLevel(LinearSampler, uv, 0.0).rgb), saturate(mipLevel / 7.0)); #else color.rgb = lerp(color.rgb, color.rgb * DefaultCubemap.SampleLevel(LinearSampler, uv, 0.0).xyz, saturate(mipLevel / 7.0)); #endif - color.rgb = Color::LinearToGamma(color.rgb); + color.rgb = Color::IrradianceToGamma(color.rgb); EnvInferredTexture[ThreadID] = max(0, color); } diff --git a/features/Dynamic Cubemaps/Shaders/DynamicCubemaps/SpecularIrradianceCS.hlsl b/features/Dynamic Cubemaps/Shaders/DynamicCubemaps/SpecularIrradianceCS.hlsl index 4dca5a558..a2ed18884 100644 --- a/features/Dynamic Cubemaps/Shaders/DynamicCubemaps/SpecularIrradianceCS.hlsl +++ b/features/Dynamic Cubemaps/Shaders/DynamicCubemaps/SpecularIrradianceCS.hlsl @@ -172,11 +172,11 @@ float3 tangentToWorld(const float3 v, const float3 N, const float3 S, const floa // Mip level to sample from. float mipLevel = max(0.5 * log2(ws / wt) + 1.0, 0.0); - color += Color::GammaToLinear(inputTexture.SampleLevel(linear_wrap_sampler, Li, mipLevel).rgb) * cosLi; + color += Color::IrradianceToLinear(inputTexture.SampleLevel(linear_wrap_sampler, Li, mipLevel).rgb) * cosLi; weight += cosLi; } } color /= weight; - outputTexture[ThreadID] = float4(Color::LinearToGamma(color), 1.0); + outputTexture[ThreadID] = float4(Color::IrradianceToGamma(color), 1.0); } diff --git a/features/Dynamic Cubemaps/Shaders/DynamicCubemaps/UpdateCubemapCS.hlsl b/features/Dynamic Cubemaps/Shaders/DynamicCubemaps/UpdateCubemapCS.hlsl index f460397e9..bcae227bd 100644 --- a/features/Dynamic Cubemaps/Shaders/DynamicCubemaps/UpdateCubemapCS.hlsl +++ b/features/Dynamic Cubemaps/Shaders/DynamicCubemaps/UpdateCubemapCS.hlsl @@ -99,7 +99,7 @@ float smoothbumpstep(float edge0, float edge1, float x) color /= weight; float4 positionFinal = float4(position.xyz * 0.001, length(position) < (4096.0 * 2.5)); - float4 colorFinal = float4(Color::GammaToLinear(color), 1.0); + float4 colorFinal = float4(Color::IrradianceToLinear(color), 1.0); float lerpFactor = 0.5; diff --git a/features/Hair Specular/Shaders/Hair/Hair.hlsli b/features/Hair Specular/Shaders/Hair/Hair.hlsli index 40ec13e53..67b71fcb7 100644 --- a/features/Hair Specular/Shaders/Hair/Hair.hlsli +++ b/features/Hair Specular/Shaders/Hair/Hair.hlsli @@ -2,11 +2,10 @@ #define __HAIR_DEPENDENCY_HLSL__ #include "Common/BRDF.hlsli" +#include "Common/Color.hlsli" #include "Common/Game.hlsli" #include "Common/Math.hlsli" -#define HAIR_LIGHTING_MULTIPLIER Math::PI // Compensating to adapt to vanilla lighting model - namespace Hair { Texture2D TexTangentShift : register(t73); @@ -194,7 +193,7 @@ namespace Hair void GetHairDirectLightMarschner(out float3 dirDiffuse, out float3 dirSpecular, out float3 dirTransmission, float3 T, float3 L, float3 V, float3 N, float3 VN, float3 lightColor, float shininess, float selfShadow, float2 uv, float3 baseColor) { - lightColor *= HAIR_LIGHTING_MULTIPLIER * selfShadow; + lightColor *= Color::PBRLightingCompensation * selfShadow; dirDiffuse = 0; dirSpecular = 0; dirTransmission = 0; diff --git a/features/Linear Lighting/CORE b/features/Linear Lighting/CORE new file mode 100644 index 000000000..e69de29bb diff --git a/features/Linear Lighting/Shaders/Features/LinearLighting.ini b/features/Linear Lighting/Shaders/Features/LinearLighting.ini new file mode 100644 index 000000000..19f01444d --- /dev/null +++ b/features/Linear Lighting/Shaders/Features/LinearLighting.ini @@ -0,0 +1,2 @@ +[Info] +Version = 1-0-0 \ No newline at end of file diff --git a/features/Screen Space GI/Shaders/ScreenSpaceGI/radianceDisocc.cs.hlsl b/features/Screen Space GI/Shaders/ScreenSpaceGI/radianceDisocc.cs.hlsl index e2f2c718f..7cf03dafe 100644 --- a/features/Screen Space GI/Shaders/ScreenSpaceGI/radianceDisocc.cs.hlsl +++ b/features/Screen Space GI/Shaders/ScreenSpaceGI/radianceDisocc.cs.hlsl @@ -135,7 +135,7 @@ void readHistory( half3 radiance = 0; #ifdef GI - radiance = Color::GammaToLinear(FULLRES_LOAD(srcDiffuse, pixCoord, uv * frameScale, samplerLinearClamp).rgb * GIStrength); + radiance = Color::RadianceToLinear(FULLRES_LOAD(srcDiffuse, pixCoord, uv * frameScale, samplerLinearClamp).rgb * GIStrength); radiance = filterNaN(radiance); radiance = filterInf(radiance); outRadianceDisocc[pixCoord] = radiance; diff --git a/features/Skylighting/Shaders/Skylighting/Skylighting.hlsli b/features/Skylighting/Shaders/Skylighting/Skylighting.hlsli index 0ae3be0eb..dc883bb06 100644 --- a/features/Skylighting/Shaders/Skylighting/Skylighting.hlsli +++ b/features/Skylighting/Shaders/Skylighting/Skylighting.hlsli @@ -49,7 +49,7 @@ namespace Skylighting diffuseColor = max(0.0, diffuseColor - directionalAmbientColor); - directionalAmbientColor = Color::LinearToGamma(Color::GammaToLinear(directionalAmbientColor) * Color::MultiBounceAO(Color::GammaToLinear(albedo / Color::PBRLightingScale), skylightingDiffuse)); + directionalAmbientColor = Color::IrradianceToGamma(Color::IrradianceToLinear(directionalAmbientColor) * Color::MultiBounceAO(Color::IrradianceToLinear(albedo / Color::PBRLightingScale), skylightingDiffuse)); diffuseColor += directionalAmbientColor; } diff --git a/features/Subsurface Scattering/Shaders/SubsurfaceScattering/Burley.hlsli b/features/Subsurface Scattering/Shaders/SubsurfaceScattering/Burley.hlsli index 34a44b08c..3227014d4 100644 --- a/features/Subsurface Scattering/Shaders/SubsurfaceScattering/Burley.hlsli +++ b/features/Subsurface Scattering/Shaders/SubsurfaceScattering/Burley.hlsli @@ -59,7 +59,7 @@ float4 BurleyNormalizedSS(uint2 DTid, float2 texCoord, uint eyeIndex, float sssA } float4 surfaceAlbedo = AlbedoTexture[DTid]; - float3 originalColor = Color::GammaToLinear(centerColor.xyz / max(surfaceAlbedo.xyz, EPSILON_SSS_ALBEDO)); + float3 originalColor = Color::IrradianceToLinear(centerColor.xyz / max(surfaceAlbedo.xyz, EPSILON_SSS_ALBEDO)); float4 diffuseMeanFreePath = humanProfile ? MeanFreePathHuman : MeanFreePathBase; diffuseMeanFreePath.xyz = float3(max(diffuseMeanFreePath.x, 1e-5f), max(diffuseMeanFreePath.y, 1e-5f), max(diffuseMeanFreePath.z, 1e-5f)); @@ -114,7 +114,7 @@ float4 BurleyNormalizedSS(uint2 DTid, float2 texCoord, uint eyeIndex, float sssA if (!mask) continue; - float3 sampleColor = Color::GammaToLinear(ColorTexture[samplePixcoord].xyz * maskSample / max(AlbedoTexture[samplePixcoord].xyz, EPSILON_SSS_ALBEDO)); + float3 sampleColor = Color::IrradianceToLinear(ColorTexture[samplePixcoord].xyz * maskSample / max(AlbedoTexture[samplePixcoord].xyz, EPSILON_SSS_ALBEDO)); float sampleDepth = SharedData::GetScreenDepth(DepthTexture[samplePixcoord].x); float3 sampleNormalVS = GBuffer::DecodeNormal(NormalTexture[samplePixcoord].xy); float3 sampleNormalWS = normalize(mul(FrameBuffer::CameraViewInverse[eyeIndex], float4(sampleNormalVS, 0)).xyz); @@ -132,7 +132,7 @@ float4 BurleyNormalizedSS(uint2 DTid, float2 texCoord, uint eyeIndex, float sssA colorSum *= any(weightSum == 0.0f) ? 0.0f : (1.0f / weightSum); colorSum = lerp(colorSum, originalColor, saturate(centerWeight)); - float3 color = Color::LinearToGamma(colorSum) * AlbedoTexture[DTid.xy].xyz; + float3 color = Color::IrradianceToGamma(colorSum) * AlbedoTexture[DTid.xy].xyz; color = lerp(centerColor.xyz, color, saturate(sssAmount)); float4 outColor = float4(color, ColorTexture[DTid.xy].w); diff --git a/features/Subsurface Scattering/Shaders/SubsurfaceScattering/SeparableSSS.hlsli b/features/Subsurface Scattering/Shaders/SubsurfaceScattering/SeparableSSS.hlsli index c55aef743..65b89e7de 100644 --- a/features/Subsurface Scattering/Shaders/SubsurfaceScattering/SeparableSSS.hlsli +++ b/features/Subsurface Scattering/Shaders/SubsurfaceScattering/SeparableSSS.hlsli @@ -102,7 +102,7 @@ float4 SSSSBlurCS( float4 colorM = ColorTexture[DTid.xy]; #if defined(HORIZONTAL) - colorM.rgb = Color::GammaToLinear(colorM.rgb); + colorM.rgb = Color::IrradianceToLinear(colorM.rgb); #endif if (sssAmount == 0) @@ -152,7 +152,7 @@ float4 SSSSBlurCS( float3 color = ColorTexture[coords].rgb; #if defined(HORIZONTAL) - color.rgb = Color::GammaToLinear(color.rgb); + color.rgb = Color::IrradianceToLinear(color.rgb); #endif float depth = DepthTexture[coords].r; diff --git a/features/Subsurface Scattering/Shaders/SubsurfaceScattering/SeparableSSSCS.hlsl b/features/Subsurface Scattering/Shaders/SubsurfaceScattering/SeparableSSSCS.hlsl index 632b5e83f..b6331051b 100644 --- a/features/Subsurface Scattering/Shaders/SubsurfaceScattering/SeparableSSSCS.hlsl +++ b/features/Subsurface Scattering/Shaders/SubsurfaceScattering/SeparableSSSCS.hlsl @@ -63,7 +63,7 @@ cbuffer PerFrameSSS : register(b1) bool humanProfile = MaskTexture[DTid.xy].y > 0.0; float4 color = SSSSBlurCS(DTid.xy, texCoord, float2(0.0, 1.0), sssAmount, humanProfile); - color.rgb = Color::LinearToGamma(color.rgb); + color.rgb = Color::IrradianceToGamma(color.rgb); SSSRW[DTid.xy] = float4(color.rgb, 1.0); } diff --git a/package/Shaders/Common/Color.hlsli b/package/Shaders/Common/Color.hlsli index c7770044f..84751f28a 100644 --- a/package/Shaders/Common/Color.hlsli +++ b/package/Shaders/Common/Color.hlsli @@ -2,6 +2,9 @@ #define __COLOR_DEPENDENCY_HLSL__ #include "Common/Math.hlsli" +#include "Common/SharedData.hlsli" + +#define ENABLE_LL SharedData::linearLightingSettings.enableLinearLighting namespace Color { @@ -65,12 +68,6 @@ namespace Color return color; } - // Attempt to match vanilla materials that are darker than PBR - const static float PBRLightingScale = 0.65; - - // Attempt to normalise reflection brightness against DALC - const static float ReflectionNormalisationScale = 0.65; - float GammaToLinear(float color) { return pow(abs(color), 1.6); @@ -101,23 +98,209 @@ namespace Color return pow(abs(color), 1.0 / 2.2); } +#if defined(PSHADER) || defined(CSHADER) || defined(COMPUTESHADER) + // Attempt to match vanilla materials that are darker than PBR + const static float PBRLightingScale = ENABLE_LL ? 1.0 : 0.65; + + // Attempt to normalise reflection brightness against DALC + const static float ReflectionNormalisationScale = ENABLE_LL ? 1.0 : 0.65; + + const static float PBRLightingCompensation = ENABLE_LL ? 1.0 : Math::PI; + + float3 GammaToLinearLuminancePreserving(float3 color) + { + if (!ENABLE_LL) { + return color; + } + float originalLuminance = max(RGBToLuminance(color), 1e-5); + float3 linearColorRaw = GammaToLinear(color / originalLuminance); + float scale = GammaToLinear(originalLuminance).x; + return linearColorRaw * scale; + } + + float3 GammaToLinearLuminancePreservingLight(float3 color) + { + if (!ENABLE_LL) { + return color; + } + float originalLuminance = max(RGBToLuminance(color), 1e-5); + float3 linearColorRaw = pow(abs(color / originalLuminance), SharedData::linearLightingSettings.lightGamma); + float scale = originalLuminance; + return linearColorRaw * scale; + } + + // Linear Lighting Functions + float3 LLGammaToLinear(float3 color) + { + return ENABLE_LL ? GammaToLinear(color) : color; + } + + float3 LLLinearToGamma(float3 color) + { + return ENABLE_LL ? LinearToGamma(color) : color; + } + float3 Diffuse(float3 color) { -#if defined(TRUE_PBR) - return TrueLinearToGamma(color); -#else +# if defined(TRUE_PBR) + return ENABLE_LL ? color : TrueLinearToGamma(color); +# else + return ENABLE_LL ? pow(abs(color), SharedData::linearLightingSettings.colorGamma) * SharedData::linearLightingSettings.vanillaDiffuseColorMult : color; +# endif + } + + float3 Light(float3 color, bool isLinear = false) + { + color = (ENABLE_LL && !isLinear) ? pow(abs(color), SharedData::linearLightingSettings.lightGamma) * SharedData::linearLightingSettings.lightMult : color; +# if defined(TRUE_PBR) + return color * PBRLightingCompensation; // Compensate for traditional Lambertian diffuse +# else return color; -#endif +# endif + } + + float3 DirectionalLight(float3 color, bool isLinear = false) + { + return Light(color, isLinear) * (ENABLE_LL ? SharedData::linearLightingSettings.directionalLightMult : 1.0f); + } + + float3 PointLight(float3 color, bool isLinear = false) + { + return Light(color, isLinear) * (ENABLE_LL ? SharedData::linearLightingSettings.pointLightMult : 1.0f); + } + + float3 EmitColor(float3 color) + { + return ENABLE_LL ? pow(abs(color), SharedData::linearLightingSettings.emitColorGamma) * SharedData::linearLightingSettings.emitColorMult : color; + } + + float3 Glowmap(float3 color) + { +# if defined(TRUE_PBR) + return ENABLE_LL ? color * SharedData::linearLightingSettings.glowmapMult : TrueLinearToGamma(color); +# else + return ENABLE_LL ? pow(abs(color), SharedData::linearLightingSettings.glowmapGamma) * SharedData::linearLightingSettings.glowmapMult : color; +# endif + } + + float3 Ambient(float3 color) + { + return ENABLE_LL ? pow(abs(color), SharedData::linearLightingSettings.ambientGamma) : color; + } + + float3 Fog(float3 color) + { + return ENABLE_LL ? pow(abs(color), SharedData::linearLightingSettings.fogGamma) : color; + } + + float FogAlpha(float alpha) + { + return ENABLE_LL ? pow(abs(alpha), SharedData::linearLightingSettings.fogAlphaGamma) : alpha; + } + + float3 Effect(float3 color) + { + return ENABLE_LL ? pow(abs(color), SharedData::linearLightingSettings.effectGamma) : color; } - float3 Light(float3 color) + float3 EffectMult(float3 color) { -#if defined(TRUE_PBR) - return color * Math::PI; // Compensate for traditional Lambertian diffuse -#else + if (ENABLE_LL) { +# if defined(MEMBRANE) + color *= SharedData::linearLightingSettings.membraneEffectMult; +# elif defined(BLOOD) + color *= SharedData::linearLightingSettings.bloodEffectMult; +# elif defined(PROJECTED_UV) + color *= SharedData::linearLightingSettings.projectedEffectMult; +# elif defined(DEFERRED) + color *= SharedData::linearLightingSettings.deferredEffectMult; +# else + color *= SharedData::linearLightingSettings.otherEffectMult; +# endif + } return color; -#endif } + + float EffectLightingMult() + { + return ENABLE_LL ? SharedData::linearLightingSettings.effectLightingMult : 1.0f; + } + + float EffectAlpha(float alpha) + { + return ENABLE_LL ? pow(abs(alpha), SharedData::linearLightingSettings.effectAlphaGamma) : alpha; + } + + float3 Sky(float3 color) + { + return ENABLE_LL ? pow(abs(color), SharedData::linearLightingSettings.skyGamma) : color; + } + + float3 Water(float3 color) + { + return ENABLE_LL ? pow(abs(color), SharedData::linearLightingSettings.waterGamma) : color; + } + + float3 VolumetricLighting(float3 color) + { + return ENABLE_LL ? pow(abs(color), SharedData::linearLightingSettings.vlGamma) : color; + } + + float3 ColorToLinear(float3 color) + { + return ENABLE_LL ? pow(abs(color), SharedData::linearLightingSettings.colorGamma) : color; + } + + float3 RadianceToLinear(float3 color) + { + return ENABLE_LL ? color : GammaToLinear(color); + } + + float IrradianceToLinear(float color) + { + return ENABLE_LL ? color : GammaToLinear(color); + } + + float IrradianceToGamma(float color) + { + return ENABLE_LL ? color : LinearToGamma(color); + } + + float3 IrradianceToLinear(float3 color) + { + return ENABLE_LL ? color : GammaToLinear(color); + } + + float3 IrradianceToGamma(float3 color) + { + return ENABLE_LL ? color : LinearToGamma(color); + } + + float VanillaDiffuseMult() + { + return ENABLE_LL ? SharedData::linearLightingSettings.vanillaDiffuseMult : 1.0f; + } + + float VanillaSpecularMult() + { + return ENABLE_LL ? SharedData::linearLightingSettings.vanillaSpecularMult : 1.0f; + } + + float GrassDiffuseMult() + { + return ENABLE_LL ? SharedData::linearLightingSettings.grassDiffuseMult : 1.0f; + } + + float GrassSpecularMult() + { + return ENABLE_LL ? SharedData::linearLightingSettings.grassSpecularMult : 1.0f; + } + + float VanillaDiffuseColorMult() + { + return ENABLE_LL ? SharedData::linearLightingSettings.vanillaDiffuseColorMult : 1.0f; + } +#endif } #endif //__COLOR_DEPENDENCY_HLSL__ \ No newline at end of file diff --git a/package/Shaders/Common/SharedData.hlsli b/package/Shaders/Common/SharedData.hlsli index f1121a5df..c77822eb4 100644 --- a/package/Shaders/Common/SharedData.hlsli +++ b/package/Shaders/Common/SharedData.hlsli @@ -194,6 +194,42 @@ namespace SharedData float Strength; // [0, 1.0] The inverse blend weight of the effect }; + struct LinearLightingSettings + { + uint enableLinearLighting; + uint enableGammaCorrection; + uint isDirLightLinear; + float dirLightMult; + float lightGamma; + float colorGamma; + float emitColorGamma; + float glowmapGamma; + float ambientGamma; + float fogGamma; + float fogAlphaGamma; + float effectGamma; + float effectAlphaGamma; + float skyGamma; + float waterGamma; + float vlGamma; + float vanillaDiffuseMult; + float vanillaSpecularMult; + float grassDiffuseMult; + float grassSpecularMult; + float vanillaDiffuseColorMult; + float lightMult; + float directionalLightMult; + float pointLightMult; + float emitColorMult; + float glowmapMult; + float effectLightingMult; + float membraneEffectMult; + float bloodEffectMult; + float projectedEffectMult; + float deferredEffectMult; + float otherEffectMult; + }; + cbuffer FeatureData : register(b6) { GrassLightingSettings grassLightingSettings; @@ -209,6 +245,7 @@ namespace SharedData TerrainVariationSettings terrainVariationSettings; IBLSettings iblSettings; ExtendedTranslucencySettings extendedTranslucencySettings; + LinearLightingSettings linearLightingSettings; }; Texture2D DepthTexture : register(t17); diff --git a/package/Shaders/DeferredCompositeCS.hlsl b/package/Shaders/DeferredCompositeCS.hlsl index 632033dbe..79cba37ee 100644 --- a/package/Shaders/DeferredCompositeCS.hlsl +++ b/package/Shaders/DeferredCompositeCS.hlsl @@ -109,7 +109,7 @@ void SampleSSGISpecular(uint2 pixCoord, sh2 lobe, out float ao, out float3 il, i float glossiness = normalGlossiness.z; - float3 linDiffuseColor = Color::GammaToLinear(diffuseColor); + float3 linDiffuseColor = Color::IrradianceToLinear(diffuseColor); float3 normalWS = normalize(mul(FrameBuffer::CameraViewInverse[eyeIndex], float4(normalVS, 0)).xyz); #if defined(SSGI) @@ -118,7 +118,7 @@ void SampleSSGISpecular(uint2 pixCoord, sh2 lobe, out float ao, out float3 il, i float3 ssgiIl; SampleSSGI(dispatchID.xy, normalWS, ssgiAo, ssgiIl); - float3 directionalAmbientColor = max(0, mul(SharedData::DirectionalAmbient, float4(normalWS, 1.0))); + float3 directionalAmbientColor = Color::Ambient(max(0, mul(SharedData::DirectionalAmbient, float4(normalWS, 1.0)))); directionalAmbientColor *= albedo; directionalAmbientColor = Color::RGBToYCoCg(directionalAmbientColor); @@ -137,19 +137,19 @@ void SampleSSGISpecular(uint2 pixCoord, sh2 lobe, out float ao, out float3 il, i diffuseColor = max(0.0, diffuseColor - directionalAmbientColor); - linDiffuseColor = Color::GammaToLinear(diffuseColor); + linDiffuseColor = Color::IrradianceToLinear(diffuseColor); - float3 linAlbedo = Color::GammaToLinear(albedo / Color::PBRLightingScale); + float3 linAlbedo = Color::IrradianceToLinear(albedo / Color::PBRLightingScale); float3 multiBounceAO = Color::MultiBounceAO(linAlbedo, ssgiAo); linDiffuseColor *= sqrt(multiBounceAO); - diffuseColor = Color::LinearToGamma(linDiffuseColor); + diffuseColor = Color::IrradianceToGamma(linDiffuseColor); - diffuseColor += Color::LinearToGamma(Color::GammaToLinear(directionalAmbientColor) * multiBounceAO); + diffuseColor += Color::IrradianceToGamma(Color::IrradianceToLinear(directionalAmbientColor) * multiBounceAO); - linDiffuseColor = Color::GammaToLinear(diffuseColor); + linDiffuseColor = Color::IrradianceToLinear(diffuseColor); linDiffuseColor += ssgiIl * linAlbedo; #endif @@ -183,13 +183,13 @@ void SampleSSGISpecular(uint2 pixCoord, sh2 lobe, out float ao, out float3 il, i if (SharedData::iblSettings.EnableDiffuseIBL && SharedData::iblSettings.EnableInterior) { directionalAmbientColorSpecular *= SharedData::iblSettings.DALCAmount; iblColor += Color::Saturation(ImageBasedLighting::GetIBLColor(-R), SharedData::iblSettings.IBLSaturation) * SharedData::iblSettings.DiffuseIBLScale; - float iblColorLuminance = Color::RGBToLuminance(Color::LinearToGamma(iblColor)); + float iblColorLuminance = Color::RGBToLuminance(Color::IrradianceToGamma(iblColor)); directionalAmbientColorSpecular += iblColorLuminance; } # endif specularIrradiance = (specularIrradiance / max(specularIrradianceLuminance, 0.001)) * directionalAmbientColorSpecular; - finalIrradiance = Color::GammaToLinear(specularIrradiance); + finalIrradiance = Color::IrradianceToLinear(specularIrradiance); # elif defined(SKYLIGHTING) # if defined(VR) float3 positionMS = positionWS.xyz + FrameBuffer::CameraPosAdjust[eyeIndex].xyz - FrameBuffer::CameraPosAdjust[0].xyz; @@ -208,7 +208,7 @@ void SampleSSGISpecular(uint2 pixCoord, sh2 lobe, out float ao, out float3 il, i if (SharedData::iblSettings.EnableDiffuseIBL) { directionalAmbientColorSpecular *= SharedData::iblSettings.DALCAmount; iblColor += Color::Saturation(ImageBasedLighting::GetIBLColor(-R, skylightingSpecular), SharedData::iblSettings.IBLSaturation) * SharedData::iblSettings.DiffuseIBLScale; - float iblColorLuminance = Color::RGBToLuminance(Color::LinearToGamma(iblColor)); + float iblColorLuminance = Color::RGBToLuminance(Color::IrradianceToGamma(iblColor)); directionalAmbientColorSpecular += iblColorLuminance; } # endif @@ -222,7 +222,7 @@ void SampleSSGISpecular(uint2 pixCoord, sh2 lobe, out float ao, out float3 il, i specularIrradianceReflections = (specularIrradianceReflections / max(specularIrradianceLuminance, 0.001)) * directionalAmbientColorSpecular; - specularIrradianceReflections = Color::GammaToLinear(specularIrradianceReflections); + specularIrradianceReflections = Color::IrradianceToLinear(specularIrradianceReflections); } @@ -233,13 +233,13 @@ void SampleSSGISpecular(uint2 pixCoord, sh2 lobe, out float ao, out float3 il, i float specularIrradianceLuminance = Color::RGBToLuminance(EnvTexture.SampleLevel(LinearSampler, R, 15)); - directionalAmbientColorSpecular = Color::GammaToLinear(directionalAmbientColorSpecular); + directionalAmbientColorSpecular = Color::IrradianceToLinear(directionalAmbientColorSpecular); directionalAmbientColorSpecular *= skylightingSpecular; - directionalAmbientColorSpecular = Color::LinearToGamma(directionalAmbientColorSpecular); + directionalAmbientColorSpecular = Color::IrradianceToGamma(directionalAmbientColorSpecular); specularIrradiance = (specularIrradiance / max(specularIrradianceLuminance, 0.001)) * directionalAmbientColorSpecular; - specularIrradiance = Color::GammaToLinear(specularIrradiance); + specularIrradiance = Color::IrradianceToLinear(specularIrradiance); } finalIrradiance = lerp(specularIrradiance, specularIrradianceReflections, skylightingSpecular); @@ -249,7 +249,7 @@ void SampleSSGISpecular(uint2 pixCoord, sh2 lobe, out float ao, out float3 il, i if (SharedData::iblSettings.EnableDiffuseIBL) { directionalAmbientColorSpecular *= SharedData::iblSettings.DALCAmount; iblColor += Color::Saturation(ImageBasedLighting::GetIBLColor(-R), SharedData::iblSettings.IBLSaturation) * SharedData::iblSettings.DiffuseIBLScale; - float iblColorLuminance = Color::RGBToLuminance(Color::LinearToGamma(iblColor)); + float iblColorLuminance = Color::RGBToLuminance(Color::IrradianceToGamma(iblColor)); directionalAmbientColorSpecular += iblColorLuminance; } # endif @@ -259,7 +259,7 @@ void SampleSSGISpecular(uint2 pixCoord, sh2 lobe, out float ao, out float3 il, i specularIrradianceReflections = (specularIrradianceReflections / max(specularIrradianceReflectionsLuminance, 0.001)) * directionalAmbientColorSpecular; - finalIrradiance = Color::GammaToLinear(specularIrradianceReflections); + finalIrradiance = Color::IrradianceToLinear(specularIrradianceReflections); # endif # if defined(SSGI) @@ -280,7 +280,7 @@ void SampleSSGISpecular(uint2 pixCoord, sh2 lobe, out float ao, out float3 il, i #endif - color = Color::LinearToGamma(color); + color = Color::IrradianceToGamma(color); #if defined(DEBUG) diff --git a/package/Shaders/DistantTree.hlsl b/package/Shaders/DistantTree.hlsl index 76a653ed3..82c173308 100644 --- a/package/Shaders/DistantTree.hlsl +++ b/package/Shaders/DistantTree.hlsl @@ -214,6 +214,7 @@ PS_OUTPUT main(PS_INPUT input) psout.Diffuse.w = 0; # else float4 baseColor = TexDiffuse.SampleBias(SampDiffuse, input.TexCoord.xy, SharedData::MipBias); + baseColor.xyz = Color::Diffuse(baseColor.xyz); if ((baseColor.w - AlphaTestRefRS) < 0) { discard; @@ -233,13 +234,14 @@ PS_OUTPUT main(PS_INPUT input) if (dirShadow != 0.0) dirShadow *= ShadowSampling::GetWorldShadow(input.WorldPosition.xyz, FrameBuffer::CameraPosAdjust[eyeIndex].xyz, eyeIndex); - float3 diffuseColor = SharedData::DirLightColor.xyz * dirShadow * 0.5; + float llDirLightMult = (SharedData::linearLightingSettings.enableLinearLighting && !SharedData::linearLightingSettings.isDirLightLinear) ? SharedData::linearLightingSettings.dirLightMult : 1.0f; + float3 diffuseColor = Color::DirectionalLight(SharedData::DirLightColor.xyz / max(llDirLightMult, 1e-5), SharedData::linearLightingSettings.isDirLightLinear) * dirShadow * 0.5 * llDirLightMult * Color::VanillaDiffuseMult(); float3 ddx = ddx_coarse(input.WorldPosition.xyz); float3 ddy = ddy_coarse(input.WorldPosition.xyz); float3 normal = -normalize(cross(ddx, ddy)); - float3 directionalAmbientColor = max(0, mul(SharedData::DirectionalAmbient, float4(normal, 1.0))); + float3 directionalAmbientColor = max(0, Color::Ambient(mul(SharedData::DirectionalAmbient, float4(normal, 1.0)))); # if defined(IBL) float3 iblColor = 0; if (SharedData::iblSettings.EnableDiffuseIBL) { @@ -249,7 +251,7 @@ PS_OUTPUT main(PS_INPUT input) # else iblColor += Color::Saturation(ImageBasedLighting::GetIBLColor(-normal), SharedData::iblSettings.IBLSaturation) * SharedData::iblSettings.DiffuseIBLScale; # endif - directionalAmbientColor += Color::LinearToGamma(iblColor); + directionalAmbientColor += Color::IrradianceToGamma(iblColor); } # endif diffuseColor += directionalAmbientColor; @@ -267,13 +269,14 @@ PS_OUTPUT main(PS_INPUT input) # else float dirShadow = ShadowSampling::GetWorldShadow(input.WorldPosition.xyz, FrameBuffer::CameraPosAdjust[eyeIndex].xyz, eyeIndex); - float3 diffuseColor = SharedData::DirLightColor.xyz * dirShadow * 0.5; + float llDirLightMult = (SharedData::linearLightingSettings.enableLinearLighting && !SharedData::linearLightingSettings.isDirLightLinear) ? SharedData::linearLightingSettings.dirLightMult : 1.0f; + float3 diffuseColor = Color::DirectionalLight(SharedData::DirLightColor.xyz / max(llDirLightMult, 1e-5), SharedData::linearLightingSettings.isDirLightLinear) * dirShadow * 0.5 * llDirLightMult * Color::VanillaDiffuseMult(); float3 ddx = ddx_coarse(input.WorldPosition.xyz); float3 ddy = ddy_coarse(input.WorldPosition.xyz); float3 normal = normalize(cross(ddx, ddy)); - float3 directionalAmbientColor = mul(SharedData::DirectionalAmbient, float4(normal, 1.0)); + float3 directionalAmbientColor = Color::Ambient(mul(SharedData::DirectionalAmbient, float4(normal, 1.0))); # if defined(IBL) float3 iblColor = 0; if (SharedData::iblSettings.EnableDiffuseIBL) { @@ -283,7 +286,7 @@ PS_OUTPUT main(PS_INPUT input) # else iblColor += Color::Saturation(ImageBasedLighting::GetIBLColor(-normal), SharedData::iblSettings.IBLSaturation) * SharedData::iblSettings.DiffuseIBLScale; # endif - directionalAmbientColor += Color::LinearToGamma(iblColor); + directionalAmbientColor += Color::IrradianceToGamma(iblColor); } # endif diffuseColor += directionalAmbientColor; diff --git a/package/Shaders/Effect.hlsl b/package/Shaders/Effect.hlsl index 5a00822dd..0ebf6224e 100644 --- a/package/Shaders/Effect.hlsl +++ b/package/Shaders/Effect.hlsl @@ -547,10 +547,11 @@ float3 GetLightingColor(float3 msPosition, float3 worldPosition, float4 screenPo float4 lightDistanceSquared = (PLightPositionX[eyeIndex] - msPosition.xxxx) * (PLightPositionX[eyeIndex] - msPosition.xxxx) + (PLightPositionY[eyeIndex] - msPosition.yyyy) * (PLightPositionY[eyeIndex] - msPosition.yyyy) + (PLightPositionZ[eyeIndex] - msPosition.zzzz) * (PLightPositionZ[eyeIndex] - msPosition.zzzz); float4 lightFadeMul = 1.0.xxxx - saturate(PLightingRadiusInverseSquared * lightDistanceSquared); - float3 color = DLightColor.xyz; + float3 color = DLightColor.xyz * Color::EffectLightingMult(); if ((Permutation::ExtraShaderDescriptor & Permutation::ExtraFlags::EffectShadows)) { - float3 dirLightColor = SharedData::DirLightColor.xyz * 0.5; + float llDirLightMult = (SharedData::linearLightingSettings.enableLinearLighting && !SharedData::linearLightingSettings.isDirLightLinear) ? SharedData::linearLightingSettings.dirLightMult : 1.0f; + float3 dirLightColor = Color::DirectionalLight(SharedData::DirLightColor.xyz / max(llDirLightMult, 1e-5), SharedData::linearLightingSettings.isDirLightLinear) * llDirLightMult * 0.5 * Color::EffectLightingMult(); float3 ambientColor = max(0, mul(SharedData::DirectionalAmbient, float4(0, 0, 1, 1))); # if defined(IBL) @@ -574,9 +575,9 @@ float3 GetLightingColor(float3 msPosition, float3 worldPosition, float4 screenPo skylightingDiffuse = lerp(1.0, skylightingDiffuse, Skylighting::getFadeOutFactor(worldPosition)); skylightingDiffuse = Skylighting::mixDiffuse(SharedData::skylightingSettings, skylightingDiffuse); - color = Color::GammaToLinear(color); + color = Color::IrradianceToLinear(color); color *= skylightingDiffuse; - color = Color::LinearToGamma(color); + color = Color::IrradianceToGamma(color); # endif # if defined(IBL) @@ -589,7 +590,7 @@ float3 GetLightingColor(float3 msPosition, float3 worldPosition, float4 screenPo # else iblColor += Color::Saturation(ImageBasedLighting::GetIBLColor(float3(0, 0, -1)), SharedData::iblSettings.IBLSaturation) * SharedData::iblSettings.DiffuseIBLScale; # endif - color += Color::LinearToGamma(iblColor); + color += Color::IrradianceToGamma(iblColor); } } # endif @@ -620,9 +621,9 @@ float3 GetLightingColor(float3 msPosition, float3 worldPosition, float4 screenPo skylightingDiffuse = lerp(1.0, skylightingDiffuse, Skylighting::getFadeOutFactor(worldPosition)); skylightingDiffuse = Skylighting::mixDiffuse(SharedData::skylightingSettings, skylightingDiffuse); - color = Color::GammaToLinear(color); + color = Color::IrradianceToLinear(color); color *= skylightingDiffuse; - color = Color::LinearToGamma(color); + color = Color::IrradianceToGamma(color); } # endif } @@ -631,9 +632,9 @@ float3 GetLightingColor(float3 msPosition, float3 worldPosition, float4 screenPo if (!(Permutation::ExtraShaderDescriptor & Permutation::ExtraFlags::InWorld)) # endif { - color.x += dot(PLightColorR * lightFadeMul, 1.0.xxxx); - color.y += dot(PLightColorG * lightFadeMul, 1.0.xxxx); - color.z += dot(PLightColorB * lightFadeMul, 1.0.xxxx); + color.x += dot(Color::PointLight(PLightColorR.xxx).x * lightFadeMul * Color::EffectLightingMult(), 1.0.xxxx); + color.y += dot(Color::PointLight(PLightColorG.xxx).x * lightFadeMul * Color::EffectLightingMult(), 1.0.xxxx); + color.z += dot(Color::PointLight(PLightColorB.xxx).x * lightFadeMul * Color::EffectLightingMult(), 1.0.xxxx); } return color; @@ -694,7 +695,7 @@ PS_OUTPUT main(PS_INPUT input) # endif float lightingInfluence = LightingInfluence.x; - float3 propertyColor = PropertyColor.xyz; + float3 propertyColor = Color::Effect(PropertyColor.xyz); float shadowVariance = 1.0; # if defined(LIGHTING) @@ -728,7 +729,7 @@ PS_OUTPUT main(PS_INPUT input) float intensityMultiplier = 1 - intensityFactor * intensityFactor; # endif - float3 lightColor = light.color.xyz * intensityMultiplier * 0.5; + float3 lightColor = Color::PointLight(light.color.xyz) * intensityMultiplier * 0.5 * light.fade * Color::EffectLightingMult(); propertyColor += lightColor; } } @@ -746,6 +747,7 @@ PS_OUTPUT main(PS_INPUT input) # endif { baseTexColor = TexBaseSampler.Sample(SampBaseSampler, input.TexCoord0.xy); + baseTexColor.xyz = Color::Effect(baseTexColor.xyz); baseColor *= baseTexColor; if (Permutation::PixelShaderDescriptor & Permutation::EffectFlags::IgnoreTexAlpha || Permutation::PixelShaderDescriptor & Permutation::EffectFlags::GrayscaleToAlpha) { baseColor.w = 1; @@ -756,8 +758,9 @@ PS_OUTPUT main(PS_INPUT input) float4 baseColorMul = float4(1, 1, 1, 1); # else float4 baseColorMul = BaseColor; + baseColorMul.xyz = Color::Effect(baseColorMul.xyz); # if defined(VC) && !defined(PROJECTED_UV) - baseColorMul *= input.Color; + baseColorMul *= float4(Color::Effect(input.Color.xyz), input.Color.w); # endif # endif @@ -810,7 +813,7 @@ PS_OUTPUT main(PS_INPUT input) # if defined(MEMBRANE) grayscaleToColorUv.y = PropertyColor.x; # endif - baseColor.xyz = baseColorScale * TexGrayscaleSampler.Sample(SampGrayscaleSampler, grayscaleToColorUv).xyz; + baseColor.xyz = Color::Effect(baseColorScale * TexGrayscaleSampler.Sample(SampGrayscaleSampler, grayscaleToColorUv).xyz); } float3 lightColor = lerp(baseColor.xyz, propertyColor * baseColor.xyz, lightingInfluence.xxx); @@ -823,23 +826,25 @@ PS_OUTPUT main(PS_INPUT input) # if !defined(MOTIONVECTORS_NORMALS) # if defined(ADDBLEND) - float3 blendedColor = lightColor * (1 - input.FogParam.www); + float3 blendedColor = lightColor * (1 - Color::FogAlpha(input.FogParam.w).xxx); # elif defined(MULTBLEND) || defined(MULTBLEND_DECAL) - float3 blendedColor = lerp(lightColor, 1.0.xxx, saturate(1.5 * input.FogParam.w).xxx); + float3 blendedColor = lerp(lightColor, 1.0.xxx, saturate(1.5 * Color::FogAlpha(input.FogParam.w)).xxx); # else - float3 fogColor = input.FogParam.xyz; + float3 fogColor = Color::Fog(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); + float3 blendedColor = lerp(lightColor, fogColor, Color::FogAlpha(input.FogParam.w).xxx); # endif # else float3 blendedColor = lightColor.xyz; # endif - float4 finalColor = float4(blendedColor, alpha); + alpha = Color::EffectAlpha(alpha); + + float4 finalColor = float4(Color::EffectMult(blendedColor), alpha); # if defined(MULTBLEND_DECAL) finalColor.xyz *= alpha; # else @@ -902,6 +907,9 @@ PS_OUTPUT main(PS_INPUT input) psout.Color2 = finalColor; # endif + if (!(Permutation::ExtraShaderDescriptor & Permutation::ExtraFlags::InWorld) && SharedData::linearLightingSettings.enableLinearLighting) { + psout.Diffuse.xyz = Color::TrueLinearToGamma(psout.Diffuse.xyz); + } return psout; } #endif \ No newline at end of file diff --git a/package/Shaders/ISCompositeLensFlareVolumetricLighting.hlsl b/package/Shaders/ISCompositeLensFlareVolumetricLighting.hlsl index bb929127c..37a759be2 100644 --- a/package/Shaders/ISCompositeLensFlareVolumetricLighting.hlsl +++ b/package/Shaders/ISCompositeLensFlareVolumetricLighting.hlsl @@ -1,5 +1,7 @@ +#include "Common/Color.hlsli" #include "Common/DummyVSTexCoord.hlsl" #include "Common/FrameBuffer.hlsli" +#include "Common/SharedData.hlsli" typedef VS_OUTPUT PS_INPUT; @@ -29,12 +31,16 @@ PS_OUTPUT main(PS_INPUT input) # if defined(VOLUMETRIC_LIGHTING) float2 screenPosition = FrameBuffer::GetDynamicResolutionAdjustedScreenPosition(input.TexCoord); float volumetricLightingPower = VLSourceTex.Sample(VLSourceSampler, screenPosition).x; - color += VolumetricLightingColor.xyz * volumetricLightingPower; + color += VolumetricLightingColor.xyz * Color::VolumetricLighting(volumetricLightingPower.xxx).x; # endif # if defined(LENS_FLARE) float3 lensFlareColor = LFSourceTex.Sample(LFSourceSampler, input.TexCoord).xyz; - color += lensFlareColor; + if (SharedData::linearLightingSettings.enableLinearLighting) { + color += Color::GammaToLinear(lensFlareColor); + } else { + color += lensFlareColor; + } # endif psout.Color = color; diff --git a/package/Shaders/ISHDR.hlsl b/package/Shaders/ISHDR.hlsl index 3e008c857..24322bc8b 100644 --- a/package/Shaders/ISHDR.hlsl +++ b/package/Shaders/ISHDR.hlsl @@ -1,6 +1,7 @@ #include "Common/Color.hlsli" #include "Common/DummyVSTexCoord.hlsl" #include "Common/FrameBuffer.hlsli" +#include "Common/SharedData.hlsli" typedef VS_OUTPUT PS_INPUT; @@ -135,6 +136,9 @@ PS_OUTPUT main(PS_INPUT input) srgbColor = lerp(srgbColor, Fade.xyz, Fade.w); # endif + if (SharedData::linearLightingSettings.enableLinearLighting && SharedData::linearLightingSettings.enableGammaCorrection) { + srgbColor = Color::TrueLinearToGamma(srgbColor); + } srgbColor = FrameBuffer::ToSRGBColor(srgbColor); psout.Color = float4(srgbColor, 1.0); diff --git a/package/Shaders/ISSAOComposite.hlsl b/package/Shaders/ISSAOComposite.hlsl index 793686448..61440520f 100644 --- a/package/Shaders/ISSAOComposite.hlsl +++ b/package/Shaders/ISSAOComposite.hlsl @@ -1,6 +1,7 @@ #include "Common/Color.hlsli" #include "Common/DummyVSTexCoord.hlsl" #include "Common/FrameBuffer.hlsli" +#include "Common/SharedData.hlsli" typedef VS_OUTPUT PS_INPUT; @@ -163,9 +164,9 @@ PS_OUTPUT main(PS_INPUT input) if (EyePosition.w != 0 && 1e-5 < snowMask) { ao = min(1, SparklesParameters3.x + ao); } - composedColor.xyz = Color::GammaToLinear(composedColor.xyz); - composedColor.xyz *= Color::GammaToLinear(ao); - composedColor.xyz = Color::LinearToGamma(composedColor.xyz); + composedColor.xyz = Color::IrradianceToLinear(composedColor.xyz); + composedColor.xyz *= Color::IrradianceToLinear(ao); + composedColor.xyz = Color::IrradianceToGamma(composedColor.xyz); # endif float depth = depthTex.SampleLevel(depthSampler, screenPosition, 0).x; @@ -173,14 +174,14 @@ PS_OUTPUT main(PS_INPUT input) # if defined(APPLY_FOG) 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); + float3 fogColor = Color::Fog(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); + composedColor.xyz = FogNearColor.w * lerp(composedColor.xyz, fogColor, Color::FogAlpha(fogFactor)); } # endif diff --git a/package/Shaders/Lighting.hlsl b/package/Shaders/Lighting.hlsl index 7fe40e894..add51e886 100644 --- a/package/Shaders/Lighting.hlsl +++ b/package/Shaders/Lighting.hlsl @@ -850,6 +850,7 @@ float3 GetWorldMapBaseColor(float3 originalBaseColor, float3 rawBaseColor, float # if defined(LODOBJECTS) float4 lodColorMul = lodMultiplier.xxxx * float4(0.269999981, 0.281000018, 0.441000015, 0.441000015) + float4(0.0780000091, 0.09799999, -0.0349999964, 0.465000004); float4 lodColor = lodColorMul.xyzw * 2.0.xxxx; + lodColor.xyz = Color::Diffuse(lodColor.xyz); bool useLodColorZ = lodColorMul.w > 0.5; lodColor.xyz = max(lodColor.xyz, rawBaseColor.xyz); lodColor.w = useLodColorZ ? lodColor.z : min(lodColor.w, rawBaseColor.z); @@ -857,6 +858,7 @@ float3 GetWorldMapBaseColor(float3 originalBaseColor, float3 rawBaseColor, float # else float4 lodColorMul = lodMultiplier.xxxx * float4(0.199999988, 0.441000015, 0.269999981, 0.281000018) + float4(0.300000012, 0.465000004, 0.0780000091, 0.09799999); float3 lodColor = lodColorMul.zwy * 2.0.xxx; + lodColor.xyz = Color::Diffuse(lodColor.xyz); lodColor.xy = max(lodColor.xy, rawBaseColor.xy); lodColor.z = lodColorMul.y > 0.5 ? max((lodMultiplier * 0.441 + -0.0349999964) * 2, rawBaseColor.z) : min(lodColor.z, rawBaseColor.z); return lodColorMul.xxx * (lodColor - rawBaseColor.xyz) + rawBaseColor; @@ -991,6 +993,7 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace : SV_IsFrontFace) # else const bool inWorld = (Permutation::ExtraShaderDescriptor & Permutation::ExtraFlags::InWorld); # endif + const bool inReflection = Permutation::ExtraShaderDescriptor & Permutation::ExtraFlags::InReflection; float nearFactor = smoothstep(4096.0 * 2.5, 0.0, viewPosition.z); @@ -1897,16 +1900,24 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace : SV_IsFrontFace) # endif // defined (EMAT) && defined(ENVMAP) # if defined(FACEGEN) - baseColor.xyz = GetFacegenBaseColor(baseColor.xyz, uv); + if (!SharedData::linearLightingSettings.enableLinearLighting) { + baseColor.xyz = GetFacegenBaseColor(baseColor.xyz, uv); + } else { + baseColor.xyz = Color::GammaToLinear(GetFacegenBaseColor(Color::LinearToGamma(baseColor.xyz), uv)); + } # elif defined(FACEGEN_RGB_TINT) - baseColor.xyz = GetFacegenRGBTintBaseColor(baseColor.xyz, uv); + if (!SharedData::linearLightingSettings.enableLinearLighting) { + baseColor.xyz = GetFacegenRGBTintBaseColor(baseColor.xyz, uv); + } else { + baseColor.xyz = Color::GammaToLinear(GetFacegenRGBTintBaseColor(Color::LinearToGamma(baseColor.xyz), uv)); + } # endif // FACEGEN # if defined(HAIR) && defined(CS_HAIR) float3 hairTint = 0; if (SharedData::hairSpecularSettings.Enabled) { - hairTint = lerp(1, TintColor.xyz, input.Color.y); + hairTint = lerp(1, Color::Diffuse(TintColor.xyz), Color::ColorToLinear(input.Color.y)); baseColor.xyz *= hairTint; baseColor.xyz = Hair::Saturation(baseColor.xyz, SharedData::hairSpecularSettings.HairSaturation); baseColor.xyz *= SharedData::hairSpecularSettings.BaseColorMult; @@ -1944,6 +1955,7 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace : SV_IsFrontFace) lodLandColor = TexLandLodBlend1Sampler.Sample(SampLandLodBlend1Sampler, input.TexCoord0.zw); # endif + lodLandColor.xyz = Color::ColorToLinear(lodLandColor.xyz) * Color::VanillaDiffuseColorMult(); # if defined(LOD_BLENDING) lodLandColor.xyz *= SharedData::lodBlendingSettings.LODTerrainBrightness; # endif // LOD_BLENDING @@ -2031,10 +2043,10 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace : SV_IsFrontFace) float2 projDetailNormalUv = ProjectedUVParams3.y * projNoiseUv; float3 projDetailNormal = TexProjDetail.Sample(SampProjDetailSampler, projDetailNormalUv).xyz; float3 finalProjNormal = normalize(TransformNormal(projDetailNormal) * float3(1, 1, projNormal.z) + float3(projNormal.xy, 0)); - float3 projBaseColor = TexProjDiffuseSampler.Sample(SampProjDiffuseSampler, projNormalDiffuseUv).xyz * ProjectedUVParams2.xyz; + float3 projBaseColor = Color::ColorToLinear(TexProjDiffuseSampler.Sample(SampProjDiffuseSampler, projNormalDiffuseUv).xyz) * ProjectedUVParams2.xyz; projectedMaterialWeight = smoothstep(0, 1, 5 * (0.1 + projWeight)); # if defined(TRUE_PBR) - projBaseColor = saturate(EnvmapData.xyz * projBaseColor); + projBaseColor = saturate(Color::ColorToLinear(EnvmapData.xyz) * projBaseColor); rawRMAOS.xyw = lerp(rawRMAOS.xyw, float3(ParallaxOccData.x, 0, ParallaxOccData.y), projectedMaterialWeight); float4 projectedGlintParameters = 0; if ((PBRFlags & PBR::Flags::ProjectedGlint) != 0) { @@ -2053,7 +2065,7 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace : SV_IsFrontFace) # endif // SNOW } else { if (projWeight > 0) { - baseColor.xyz = ProjectedUVParams2.xyz; + baseColor.xyz = Color::ColorToLinear(ProjectedUVParams2.xyz); # if defined(SNOW) useSnowDecalSpecular = true; psout.Parameters.y = GetSnowParameterY(projWeight, baseColor.w); @@ -2114,7 +2126,11 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace : SV_IsFrontFace) pbrSurfaceProperties.Roughness = clamp(rawRMAOS.x, PBR::Constants::MinRoughness, PBR::Constants::MaxRoughness); pbrSurfaceProperties.Metallic = saturate(rawRMAOS.y); pbrSurfaceProperties.AO = rawRMAOS.z; - pbrSurfaceProperties.F0 = lerp(saturate(rawRMAOS.w), Color::GammaToTrueLinear(baseColor.xyz), pbrSurfaceProperties.Metallic); + if (!SharedData::linearLightingSettings.enableLinearLighting) { + pbrSurfaceProperties.F0 = lerp(saturate(rawRMAOS.w), Color::GammaToTrueLinear(baseColor.xyz), pbrSurfaceProperties.Metallic); + } else { + pbrSurfaceProperties.F0 = lerp(saturate(rawRMAOS.w), baseColor.xyz, pbrSurfaceProperties.Metallic); + } pbrSurfaceProperties.GlintScreenSpaceScale = max(1, glintParameters.x); pbrSurfaceProperties.GlintLogMicrofacetDensity = clamp(PBR::Constants::MaxGlintDensity - glintParameters.y, PBR::Constants::MinGlintDensity, PBR::Constants::MaxGlintDensity); @@ -2294,7 +2310,8 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace : SV_IsFrontFace) waterRoughnessSpecular = 1.0 - wetnessGlossinessSpecular; # endif - float3 dirLightColor = Color::Light(DirLightColor.xyz); + float llDirLightMult = SharedData::linearLightingSettings.enableLinearLighting && !SharedData::linearLightingSettings.isDirLightLinear && (inWorld || inReflection) && !SharedData::InInterior ? SharedData::linearLightingSettings.dirLightMult : 1.0f; + float3 dirLightColor = Color::DirectionalLight(DirLightColor.xyz / max(llDirLightMult, 1e-5), SharedData::linearLightingSettings.isDirLightLinear) * llDirLightMult; float3 dirLightColorMultiplier = 1; # if defined(WATER_EFFECTS) @@ -2331,8 +2348,6 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace : SV_IsFrontFace) float dirShadow = 1.0; float parallaxShadow = 1; - bool inReflection = Permutation::ExtraShaderDescriptor & Permutation::ExtraFlags::InReflection; - # if defined(SCREEN_SPACE_SHADOWS) && defined(DEFERRED) if (!SharedData::InInterior) dirDetailShadow = ScreenSpaceShadows::GetScreenSpaceShadow(input.Position.xyz, screenUV, screenNoise, eyeIndex); @@ -2409,18 +2424,18 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace : SV_IsFrontFace) dirDetailShadow *= parallaxShadow; dirLightColor *= dirLightColorMultiplier; - float3 dirDiffuseColor = dirLightColor * saturate(dirLightAngle) * dirDetailShadow; + float3 dirDiffuseColor = dirLightColor * saturate(dirLightAngle) * dirDetailShadow * Color::VanillaDiffuseMult(); # if defined(SOFT_LIGHTING) - lightsDiffuseColor += dirLightColor * GetSoftLightMultiplier(dirLightAngle) * rimSoftLightColor.xyz; + lightsDiffuseColor += dirLightColor * GetSoftLightMultiplier(dirLightAngle) * rimSoftLightColor.xyz * Color::VanillaDiffuseMult(); # endif # if defined(RIM_LIGHTING) - lightsDiffuseColor += dirLightColor * GetRimLightMultiplier(DirLightDirection, viewDirection, worldNormal.xyz) * rimSoftLightColor.xyz; + lightsDiffuseColor += dirLightColor * GetRimLightMultiplier(DirLightDirection, viewDirection, worldNormal.xyz) * rimSoftLightColor.xyz * Color::VanillaDiffuseMult(); # endif # if defined(BACK_LIGHTING) - lightsDiffuseColor += dirLightColor * saturate(-dirLightAngle) * backLightColor.xyz; + lightsDiffuseColor += dirLightColor * saturate(-dirLightAngle) * backLightColor.xyz * Color::VanillaDiffuseMult(); # endif if (useSnowSpecular && useSnowDecalSpecular) { @@ -2437,11 +2452,11 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace : SV_IsFrontFace) } else { # if defined(SPECULAR) - lightsSpecularColor = GetLightSpecularInput(input, DirLightDirection, viewDirection, worldNormal.xyz, dirLightColor.xyz * dirDetailShadow, shininess, uv); + lightsSpecularColor = GetLightSpecularInput(input, DirLightDirection, viewDirection, worldNormal.xyz, dirLightColor.xyz * dirDetailShadow, shininess, uv) * Color::VanillaSpecularMult(); # endif } # elif defined(SPECULAR) || defined(SPARKLE) - lightsSpecularColor = GetLightSpecularInput(input, DirLightDirection, viewDirection, worldNormal.xyz, dirLightColor.xyz * dirDetailShadow, shininess, uv); + lightsSpecularColor = GetLightSpecularInput(input, DirLightDirection, viewDirection, worldNormal.xyz, dirLightColor.xyz * dirDetailShadow, shininess, uv) * Color::VanillaSpecularMult(); # endif } @@ -2464,7 +2479,7 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace : SV_IsFrontFace) continue; float intensityMultiplier = 1 - intensityFactor * intensityFactor; - float3 lightColor = Color::Light(PointLightColor[lightIndex].xyz) * intensityMultiplier; + float3 lightColor = Color::PointLight(PointLightColor[lightIndex].xyz) * intensityMultiplier; float lightShadow = 1.f; if (Permutation::PixelShaderDescriptor & Permutation::LightingFlags::DefShadow) { if (lightIndex < numShadowLights) { @@ -2495,18 +2510,18 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace : SV_IsFrontFace) # else lightColor *= lightShadow; float lightAngle = dot(worldNormal.xyz, normalizedLightDirection.xyz); - float3 lightDiffuseColor = lightColor * saturate(lightAngle.xxx); + float3 lightDiffuseColor = lightColor * saturate(lightAngle.xxx) * Color::VanillaDiffuseMult(); # if defined(SOFT_LIGHTING) - lightDiffuseColor += lightColor * GetSoftLightMultiplier(lightAngle) * rimSoftLightColor.xyz; + lightDiffuseColor += lightColor * GetSoftLightMultiplier(lightAngle) * rimSoftLightColor.xyz * Color::VanillaDiffuseMult(); # endif // SOFT_LIGHTING # if defined(RIM_LIGHTING) - lightDiffuseColor += lightColor * GetRimLightMultiplier(normalizedLightDirection, viewDirection, worldNormal.xyz) * rimSoftLightColor.xyz; + lightDiffuseColor += lightColor * GetRimLightMultiplier(normalizedLightDirection, viewDirection, worldNormal.xyz) * rimSoftLightColor.xyz * Color::VanillaDiffuseMult(); # endif // RIM_LIGHTING # if defined(BACK_LIGHTING) - lightDiffuseColor += lightColor * saturate(-lightAngle) * backLightColor.xyz; + lightDiffuseColor += lightColor * saturate(-lightAngle) * backLightColor.xyz * Color::VanillaDiffuseMult(); # endif // BACK_LIGHTING # if defined(HAIR) && defined(CS_HAIR) if (SharedData::hairSpecularSettings.Enabled) { @@ -2518,11 +2533,11 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace : SV_IsFrontFace) transmissionColor += lightTransmissionColor; } else { # if defined(SPECULAR) - lightsSpecularColor += GetLightSpecularInput(input, normalizedLightDirection, viewDirection, worldNormal.xyz, lightColor, shininess, uv); + lightsSpecularColor += GetLightSpecularInput(input, normalizedLightDirection, viewDirection, worldNormal.xyz, lightColor, shininess, uv) * Color::VanillaSpecularMult(); # endif } # elif defined(SPECULAR) || (defined(SPARKLE) && !defined(SNOW)) - lightsSpecularColor += GetLightSpecularInput(input, normalizedLightDirection, viewDirection, worldNormal.xyz, lightColor, shininess, uv); + lightsSpecularColor += GetLightSpecularInput(input, normalizedLightDirection, viewDirection, worldNormal.xyz, lightColor, shininess, uv) * Color::VanillaSpecularMult(); # endif // defined (SPECULAR) || (defined (SPARKLE) && !defined(SNOW)) lightsDiffuseColor += lightDiffuseColor; @@ -2568,7 +2583,7 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace : SV_IsFrontFace) float intensityMultiplier = 1 - intensityFactor * intensityFactor; # endif - float3 lightColor = Color::Light(light.color.xyz) * intensityMultiplier; + float3 lightColor = Color::PointLight(light.color.xyz) * intensityMultiplier * light.fade; float lightShadow = 1.0; float shadowComponent = 1.0; @@ -2642,19 +2657,19 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace : SV_IsFrontFace) # else lightColor *= lightShadow; - float3 lightDiffuseColor = lightColor * parallaxShadow * saturate(lightAngle.xxx); + float3 lightDiffuseColor = lightColor * parallaxShadow * saturate(lightAngle.xxx) * Color::VanillaDiffuseMult(); float lightBacklighting = 1.0 + saturate(dot(normalizedLightDirection.xyz, viewDirection)); # if defined(SOFT_LIGHTING) - lightDiffuseColor += lightBacklighting * lightColor * GetSoftLightMultiplier(lightAngle) * rimSoftLightColor.xyz; + lightDiffuseColor += lightBacklighting * lightColor * GetSoftLightMultiplier(lightAngle) * rimSoftLightColor.xyz * Color::VanillaDiffuseMult(); # endif # if defined(RIM_LIGHTING) - lightDiffuseColor += lightBacklighting * lightColor * GetRimLightMultiplier(normalizedLightDirection, viewDirection, worldNormal.xyz) * rimSoftLightColor.xyz; + lightDiffuseColor += lightBacklighting * lightColor * GetRimLightMultiplier(normalizedLightDirection, viewDirection, worldNormal.xyz) * rimSoftLightColor.xyz * Color::VanillaDiffuseMult(); # endif # if defined(BACK_LIGHTING) - lightDiffuseColor += lightBacklighting * lightColor * saturate(-lightAngle) * backLightColor.xyz; + lightDiffuseColor += lightBacklighting * lightColor * saturate(-lightAngle) * backLightColor.xyz * Color::VanillaDiffuseMult(); # endif # if defined(HAIR) && defined(CS_HAIR) && (defined(SKINNED) || !defined(MODELSPACENORMALS)) @@ -2667,11 +2682,11 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace : SV_IsFrontFace) transmissionColor += lightTransmissionColor; } else { # if defined(SPECULAR) - lightsSpecularColor += GetLightSpecularInput(input, normalizedLightDirection, viewDirection, worldNormal.xyz, lightColor, shininess, uv); + lightsSpecularColor += GetLightSpecularInput(input, normalizedLightDirection, viewDirection, worldNormal.xyz, lightColor, shininess, uv) * Color::VanillaSpecularMult(); # endif } # elif defined(SPECULAR) || (defined(SPARKLE) && !defined(SNOW)) - lightsSpecularColor += GetLightSpecularInput(input, normalizedLightDirection, viewDirection, worldNormal.xyz, lightColor, shininess, uv); + lightsSpecularColor += GetLightSpecularInput(input, normalizedLightDirection, viewDirection, worldNormal.xyz, lightColor, shininess, uv) * Color::VanillaSpecularMult(); # endif lightsDiffuseColor += lightDiffuseColor; @@ -2700,7 +2715,7 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace : SV_IsFrontFace) worldNormal.xyz = input.EyeNormal; # endif // EYE - float3 emitColor = EmitColor; + float3 emitColor = Color::EmitColor(EmitColor); # if !defined(LANDSCAPE) && !defined(LODLANDSCAPE) bool hasEmissive = (0x3F & (Permutation::PixelShaderDescriptor >> 24)) == Permutation::LightingTechnique::Glowmap; # if defined(TRUE_PBR) @@ -2708,7 +2723,7 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace : SV_IsFrontFace) # endif [branch] if (hasEmissive) { - float3 glowColor = Color::Diffuse(TexGlowSampler.Sample(SampGlowSampler, uv).xyz); + float3 glowColor = Color::Glowmap(TexGlowSampler.Sample(SampGlowSampler, uv).xyz); emitColor *= glowColor; } # endif @@ -2723,7 +2738,7 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace : SV_IsFrontFace) ambientNormal = normalize(viewDirection - hairT * dot(viewDirection, hairT)); # endif - float3 directionalAmbientColor = max(0, mul(DirectionalAmbient, float4(ambientNormal, 1.0))); + float3 directionalAmbientColor = Color::Ambient(max(0, mul(DirectionalAmbient, float4(ambientNormal, 1.0)))); # if defined(IBL) if (SharedData::iblSettings.EnableDiffuseIBL) { @@ -2757,7 +2772,7 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace : SV_IsFrontFace) # else iblColor += Color::Saturation(ImageBasedLighting::GetIBLColor(-ambientNormal), SharedData::iblSettings.IBLSaturation) * SharedData::iblSettings.DiffuseIBLScale; # endif - iblColor = Color::LinearToGamma(iblColor); + iblColor = Color::IrradianceToGamma(iblColor); directionalAmbientColor += iblColor; } } @@ -2910,7 +2925,7 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace : SV_IsFrontFace) # endif # if defined(HAIR) - float3 vertexColor = lerp(1, TintColor.xyz, input.Color.y); + float3 vertexColor = lerp(1, Color::ColorToLinear(TintColor.xyz), Color::ColorToLinear(input.Color.y)); # if defined(CS_HAIR) float3 indirectDiffuseLobeWeight, indirectSpecularLobeWeightPrim, indirectSpecularLobeWeightSec; if (SharedData::hairSpecularSettings.Enabled) @@ -3065,7 +3080,7 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace : SV_IsFrontFace) specularColor = 0; # endif - specularColor = Color::GammaToLinear(specularColor); + specularColor = Color::IrradianceToLinear(specularColor); diffuseColor = reflectionDiffuseColor; @@ -3073,7 +3088,7 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace : SV_IsFrontFace) # if defined(DYNAMIC_CUBEMAPS) if (!dynamicCubemap) # endif - specularColor += envColor * Color::GammaToLinear(diffuseColor); + specularColor += envColor * Color::IrradianceToLinear(diffuseColor); # endif # if defined(EMAT_ENVMAP) @@ -3134,15 +3149,15 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace : SV_IsFrontFace) # endif # if !defined(DEFERRED) - color.xyz = Color::LinearToGamma(Color::GammaToLinear(color.xyz) + specularColor); - float3 fogColor = input.FogParam.xyz; + color.xyz = Color::IrradianceToGamma(Color::IrradianceToLinear(color.xyz) + specularColor); + float3 fogColor = Color::Fog(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, fogColor, input.FogParam.w); + color.xyz = lerp(color.xyz, fogColor, Color::FogAlpha(input.FogParam.w)); # endif # if defined(TESTCUBEMAP) && defined(ENVMAP) && defined(DYNAMIC_CUBEMAPS) @@ -3373,6 +3388,10 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace : SV_IsFrontFace) psout.NormalGlossiness.w = stochasticBlend; # endif + if ((!inWorld && !inReflection) && SharedData::linearLightingSettings.enableLinearLighting && !(Permutation::PixelShaderDescriptor & Permutation::LightingFlags::DefShadow)) { + psout.Diffuse.xyz = Color::TrueLinearToGamma(psout.Diffuse.xyz); + } + return psout; } #endif // PSHADER diff --git a/package/Shaders/Particle.hlsl b/package/Shaders/Particle.hlsl index b320b1033..dc382890d 100644 --- a/package/Shaders/Particle.hlsl +++ b/package/Shaders/Particle.hlsl @@ -1,3 +1,4 @@ +#include "Common/Color.hlsli" #include "Common/FrameBuffer.hlsli" #include "Common/VR.hlsli" @@ -262,6 +263,7 @@ PS_OUTPUT main(PS_INPUT input) float4 sourceColor = TexSourceTexture.Sample(SampSourceTexture, input.TexCoord0); float4 baseColor = input.Color * sourceColor; + baseColor.xyz = Color::Diffuse(baseColor.xyz); # if defined(GRAYSCALE_TO_COLOR) float3 grayScaleColor = TexGrayscaleTexture.Sample(SampGrayscaleTexture, float2(sourceColor.y, input.Color.x)).xyz; diff --git a/package/Shaders/RunGrass.hlsl b/package/Shaders/RunGrass.hlsl index 6438df741..9ada03866 100644 --- a/package/Shaders/RunGrass.hlsl +++ b/package/Shaders/RunGrass.hlsl @@ -496,6 +496,8 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace : SV_IsFrontFace) baseColor = TexBaseSampler.SampleBias(SampBaseSampler, input.TexCoord.xy, SharedData::MipBias); } + baseColor.xyz = Color::Diffuse(baseColor.xyz); + # if defined(RENDER_DEPTH) float diffuseAlpha = input.VertexColor.w * baseColor.w; if ((diffuseAlpha - AlphaTestRefRS) < 0) { @@ -578,7 +580,8 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace : SV_IsFrontFace) float3 transmissionColor = 0; # endif // TRUE_PBR - float3 dirLightColor = SharedData::DirLightColor.xyz; + float llDirLightMult = (SharedData::linearLightingSettings.enableLinearLighting && !SharedData::linearLightingSettings.isDirLightLinear) ? SharedData::linearLightingSettings.dirLightMult : 1.0f; + float3 dirLightColor = Color::DirectionalLight(SharedData::DirLightColor.xyz / max(llDirLightMult, 1e-5), SharedData::linearLightingSettings.isDirLightLinear) * llDirLightMult; float3 dirLightColorMultiplier = 1; float dirLightAngle = dot(normal, SharedData::DirLightDirection.xyz); @@ -624,7 +627,7 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace : SV_IsFrontFace) dirLightColor *= dirShadow; dirLightColor *= dirDetailShadow; - lightsDiffuseColor += dirLightColor * saturate(dirLightAngle); + lightsDiffuseColor += dirLightColor * saturate(dirLightAngle) * Color::GrassDiffuseMult(); float3 vertexColor = input.VertexColor.xyz; @@ -636,13 +639,13 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace : SV_IsFrontFace) } # endif - float3 albedo = max(0, baseColor.xyz * vertexColor); + float3 albedo = max(0, baseColor.xyz * Color::ColorToLinear(vertexColor)); float3 subsurfaceColor = lerp(dot(albedo, 1.0 / 3.0), albedo, 2.0) * saturate(input.VertexNormal.w * 10.0); - float3 sss = dirLightColor * saturate(-dirLightAngle); + float3 sss = dirLightColor * saturate(-dirLightAngle) * Color::GrassDiffuseMult(); if (complex) - lightsSpecularColor += GrassLighting::GetLightSpecularInput(DirLightDirection, viewDirection, normal, dirLightColor, SharedData::grassLightingSettings.Glossiness); + lightsSpecularColor += GrassLighting::GetLightSpecularInput(DirLightDirection, viewDirection, normal, dirLightColor, SharedData::grassLightingSettings.Glossiness) * Color::GrassSpecularMult(); # endif # if defined(LIGHT_LIMIT_FIX) @@ -674,8 +677,7 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace : SV_IsFrontFace) float intensityMultiplier = 1 - intensityFactor * intensityFactor; # endif - float3 lightColor = light.color.xyz * intensityMultiplier; - + float3 lightColor = Color::PointLight(light.color.xyz) * intensityMultiplier * light.fade; float lightShadow = 1.0; float shadowComponent = 1.0; @@ -705,10 +707,10 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace : SV_IsFrontFace) sss += lightColor * saturate(-lightAngle); - lightsDiffuseColor += lightDiffuseColor; + lightsDiffuseColor += lightDiffuseColor * Color::GrassDiffuseMult(); if (complex) - lightsSpecularColor += GrassLighting::GetLightSpecularInput(normalizedLightDirection, viewDirection, normal, lightColor, SharedData::grassLightingSettings.Glossiness) * intensityMultiplier; + lightsSpecularColor += GrassLighting::GetLightSpecularInput(normalizedLightDirection, viewDirection, normal, lightColor, SharedData::grassLightingSettings.Glossiness) * Color::GrassSpecularMult(); # endif } } @@ -723,11 +725,11 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace : SV_IsFrontFace) diffuseColor.xyz += transmissionColor; specularColor.xyz += specularColorPBR; - specularColor.xyz = Color::LinearToGamma(specularColor.xyz); - diffuseColor.xyz = Color::LinearToGamma(diffuseColor.xyz); + specularColor.xyz = Color::IrradianceToGamma(specularColor.xyz); + diffuseColor.xyz = Color::IrradianceToGamma(diffuseColor.xyz); # else - float3 directionalAmbientColor = max(0, mul(SharedData::DirectionalAmbient, float4(normal, 1.0))); + float3 directionalAmbientColor = Color::Ambient(max(0, mul(SharedData::DirectionalAmbient, float4(normal, 1.0)))); # if defined(IBL) if (SharedData::iblSettings.EnableDiffuseIBL && (!SharedData::InInterior || SharedData::iblSettings.EnableInterior)) { @@ -761,7 +763,7 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace : SV_IsFrontFace) # else iblColor += Color::Saturation(ImageBasedLighting::GetIBLColor(-normal), SharedData::iblSettings.IBLSaturation) * SharedData::iblSettings.DiffuseIBLScale; # endif - iblColor = Color::LinearToGamma(iblColor); + iblColor = Color::IrradianceToGamma(iblColor); directionalAmbientColor += iblColor; } } @@ -787,7 +789,7 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace : SV_IsFrontFace) specularColor += lightsSpecularColor; specularColor *= specColor.w * SharedData::grassLightingSettings.SpecularStrength; - specularColor = Color::GammaToLinear(specularColor); + specularColor = Color::IrradianceToLinear(specularColor); # endif # if defined(LIGHT_LIMIT_FIX) && defined(LLFDEBUG) @@ -808,7 +810,7 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace : SV_IsFrontFace) float3 normalVS = normalize(FrameBuffer::WorldToView(normal, false, eyeIndex)); # if defined(TRUE_PBR) - psout.Albedo = float4(Color::LinearToGamma(indirectDiffuseLobeWeight), 1); + psout.Albedo = float4(Color::IrradianceToGamma(indirectDiffuseLobeWeight), 1); psout.NormalGlossiness = float4(GBuffer::EncodeNormal(normalVS), 1 - pbrSurfaceProperties.Roughness, 1); psout.Reflectance = float4(indirectSpecularLobeWeight, 1); psout.Parameters = float4(0, 0, 1, 1); @@ -870,7 +872,8 @@ PS_OUTPUT main(PS_INPUT input) # endif } - float3 diffuseColor = SharedData::DirLightColor.xyz * dirShadow * dirDetailShadow * 0.5; + float llDirLightMult = (SharedData::linearLightingSettings.enableLinearLighting && !SharedData::linearLightingSettings.isDirLightLinear) ? SharedData::linearLightingSettings.dirLightMult : 1.0f; + float3 diffuseColor = Color::DirectionalLight(SharedData::DirLightColor.xyz / max(llDirLightMult, 1e-5), SharedData::linearLightingSettings.isDirLightLinear) * dirShadow * dirDetailShadow * 0.5 * llDirLightMult; # if defined(LIGHT_LIMIT_FIX) uint clusterIndex = 0; @@ -901,7 +904,7 @@ PS_OUTPUT main(PS_INPUT input) float intensityMultiplier = 1 - intensityFactor * intensityFactor; # endif - float3 lightColor = light.color.xyz * intensityMultiplier; + float3 lightColor = Color::PointLight(light.color.xyz) * intensityMultiplier * light.fade; float lightShadow = 1.0; @@ -935,7 +938,7 @@ PS_OUTPUT main(PS_INPUT input) } # endif - float3 directionalAmbientColor = max(0, mul(SharedData::DirectionalAmbient, float4(normal, 1.0))); + float3 directionalAmbientColor = Color::Ambient(max(0, mul(SharedData::DirectionalAmbient, float4(normal, 1.0)))); # if defined(IBL) if (SharedData::iblSettings.EnableDiffuseIBL && (!SharedData::InInterior || SharedData::iblSettings.EnableInterior)) { @@ -969,7 +972,7 @@ PS_OUTPUT main(PS_INPUT input) # else iblColor += Color::Saturation(ImageBasedLighting::GetIBLColor(-normal), SharedData::iblSettings.IBLSaturation) * SharedData::iblSettings.DiffuseIBLScale; # endif - iblColor = Color::LinearToGamma(iblColor); + iblColor = Color::IrradianceToGamma(iblColor); directionalAmbientColor += iblColor; } } diff --git a/package/Shaders/Sky.hlsl b/package/Shaders/Sky.hlsl index 3e8189d8e..0c76946a8 100644 --- a/package/Shaders/Sky.hlsl +++ b/package/Shaders/Sky.hlsl @@ -1,3 +1,4 @@ +#include "Common/Color.hlsli" #include "Common/FrameBuffer.hlsli" #include "Common/VR.hlsli" @@ -192,6 +193,7 @@ Texture2D TexDepthSampler : register(t17); PS_OUTPUT main(PS_INPUT input) { PS_OUTPUT psout; + float3 yyy = Color::Sky(PParams.yyy); # if !defined(VR) uint eyeIndex = 0; # else @@ -201,12 +203,15 @@ PS_OUTPUT main(PS_INPUT input) # ifndef OCCLUSION # ifndef TEXLERP float4 baseColor = TexBaseSampler.Sample(SampBaseSampler, input.TexCoord0.xy); + baseColor.xyz = Color::Sky(baseColor.xyz); # ifdef TEXFADE baseColor.w *= PParams.x; # endif # else float4 blendColor = TexBlendSampler.Sample(SampBlendSampler, input.TexCoord1.xy); float4 baseColor = TexBaseSampler.Sample(SampBaseSampler, input.TexCoord0.xy); + blendColor.xyz = Color::Sky(blendColor.xyz); + baseColor.xyz = Color::Sky(baseColor.xyz); baseColor = PParams.xxxx * (-baseColor + blendColor) + baseColor; # endif @@ -216,10 +221,10 @@ PS_OUTPUT main(PS_INPUT input) TexNoiseGradSampler.Sample(SampNoiseGradSampler, noiseGradUv).x * 0.03125 + -0.0078125; # ifdef TEX - psout.Color.xyz = (input.Color.xyz * baseColor.xyz + PParams.yyy) + noiseGrad; + psout.Color.xyz = (Color::Sky(input.Color.xyz) * baseColor.xyz + yyy) + noiseGrad; psout.Color.w = baseColor.w * input.Color.w; # else - psout.Color.xyz = (PParams.yyy + input.Color.xyz) + noiseGrad; + psout.Color.xyz = (yyy + Color::Sky(input.Color.xyz)) + noiseGrad; psout.Color.w = input.Color.w; # endif // TEX @@ -231,11 +236,11 @@ PS_OUTPUT main(PS_INPUT input) } # elif defined(HORIZFADE) - psout.Color.xyz = float3(1.5, 1.5, 1.5) * (input.Color.xyz * baseColor.xyz + PParams.yyy); + psout.Color.xyz = float3(1.5, 1.5, 1.5) * (Color::Sky(input.Color.xyz) * baseColor.xyz + yyy); psout.Color.w = input.TexCoord2.x * (baseColor.w * input.Color.w); # else psout.Color.w = input.Color.w * baseColor.w; - psout.Color.xyz = input.Color.xyz * baseColor.xyz + PParams.yyy; + psout.Color.xyz = Color::Sky(input.Color.xyz) * baseColor.xyz + yyy; # endif # else diff --git a/package/Shaders/Water.hlsl b/package/Shaders/Water.hlsl index ed817db9e..22484d42b 100644 --- a/package/Shaders/Water.hlsl +++ b/package/Shaders/Water.hlsl @@ -762,18 +762,16 @@ float3 GetWaterSpecularColor(PS_INPUT input, float3 normal, float3 viewDirection float3 specularIrradiance = 1; if (skylightingSpecular < 1.0) { - specularIrradiance = DynamicCubemaps::EnvTexture.SampleLevel(CubeMapSampler, R, 0).xyz; - specularIrradiance = Color::GammaToLinear(specularIrradiance); + specularIrradiance = Color::IrradianceToLinear(DynamicCubemaps::EnvTexture.SampleLevel(CubeMapSampler, R, 0).xyz); } float3 specularIrradianceReflections = 1.0; if (skylightingSpecular > 0.0) { - specularIrradianceReflections = DynamicCubemaps::EnvReflectionsTexture.SampleLevel(CubeMapSampler, R, 0).xyz; - specularIrradianceReflections = Color::GammaToLinear(specularIrradianceReflections); + specularIrradianceReflections = Color::IrradianceToLinear(DynamicCubemaps::EnvReflectionsTexture.SampleLevel(CubeMapSampler, R, 0).xyz); } - dynamicCubemap = Color::LinearToGamma(lerp(specularIrradiance, specularIrradianceReflections, skylightingSpecular)); + dynamicCubemap = Color::IrradianceToGamma(lerp(specularIrradiance, specularIrradianceReflections, skylightingSpecular)); } # else float3 dynamicCubemap = DynamicCubemaps::EnvReflectionsTexture.SampleLevel(CubeMapSampler, R, 0); @@ -823,7 +821,7 @@ float3 GetWaterSpecularColor(PS_INPUT input, float3 normal, float3 viewDirection } # endif - float3 finalReflectionColor = Color::LinearToGamma(lerp(Color::GammaToLinear(reflectionColor), Color::GammaToLinear(finalSsrReflectionColor), ssrFraction)); + float3 finalReflectionColor = Color::IrradianceToGamma(lerp(Color::IrradianceToLinear(reflectionColor), Color::IrradianceToLinear(finalSsrReflectionColor), ssrFraction)); return finalReflectionColor; } return ReflectionColor.xyz * VarAmounts.y; @@ -916,7 +914,7 @@ DiffuseOutput GetWaterDiffuseColor(PS_INPUT input, float3 normal, float3 viewDir float2 refractionUV = FrameBuffer::GetDynamicResolutionAdjustedScreenPosition(refractionUvRaw); float3 refractionColor = RefractionTex.Sample(RefractionSampler, refractionUV).xyz; - float3 refractionDiffuseColor = lerp(ShallowColor.xyz, DeepColor.xyz, distanceMul.y); + float3 refractionDiffuseColor = lerp(Color::Water(ShallowColor.xyz), Color::Water(DeepColor.xyz), distanceMul.y); # if defined(UNDERWATER) float refractionMul = 0; @@ -932,7 +930,7 @@ DiffuseOutput GetWaterDiffuseColor(PS_INPUT input, float3 normal, float3 viewDir return output; # else DiffuseOutput output; - output.refractionColor = lerp(ShallowColor.xyz, DeepColor.xyz, fresnel) * GetLdotN(normal); + output.refractionColor = lerp(Color::Water(ShallowColor.xyz), Color::Water(DeepColor.xyz), fresnel) * GetLdotN(normal); output.refractionDiffuseColor = output.refractionColor; output.depth = 1; output.refractionMul = 1; @@ -951,7 +949,8 @@ float3 GetSunColor(float3 normal, float3 viewDirection) float3 reflectionDirection = reflect(viewDirection, normal); float reflectionMul = exp2(VarAmounts.x * log2(saturate(dot(reflectionDirection, SunDir.xyz)))); - return reflectionMul * SunColor.xyz * SunDir.w * DeepColor.w; + float llDirLightMult = (SharedData::linearLightingSettings.enableLinearLighting && !SharedData::linearLightingSettings.isDirLightLinear) ? SharedData::linearLightingSettings.dirLightMult : 1.0f; + return reflectionMul * Color::DirectionalLight(SunColor.xyz / max(llDirLightMult, 1e-5), SharedData::linearLightingSettings.isDirLightLinear) * SunDir.w * DeepColor.w * llDirLightMult; # endif } # endif @@ -1037,7 +1036,7 @@ PS_OUTPUT main(PS_INPUT input) float lightFade = saturate(length(lightVector) / LightPos[lightIndex].w); float lightColorMul = (1 - lightFade * lightFade); float LdotN = saturate(dot(lightDirection, normal)); - float3 lightColor = (LightColor[lightIndex].xyz * pow(LdotN, FresnelRI.z)) * lightColorMul; + float3 lightColor = (Color::PointLight(LightColor[lightIndex].xyz) * pow(LdotN, FresnelRI.z)) * lightColorMul; finalColor += lightColor; } @@ -1096,7 +1095,7 @@ PS_OUTPUT main(PS_INPUT input) float3 H = normalize(normalizedLightDirection - viewDirection); float HdotN = saturate(dot(H, normal)); - float3 lightColor = light.color.xyz * pow(HdotN, FresnelRI.z); + float3 lightColor = Color::PointLight(light.color.xyz) * pow(HdotN, FresnelRI.z) * light.fade; specularLighting += lightColor * intensityMultiplier; } } @@ -1104,7 +1103,7 @@ PS_OUTPUT main(PS_INPUT input) # endif # if defined(UNDERWATER) - float3 finalSpecularColor = lerp(ShallowColor.xyz, specularColor, 0.5); + float3 finalSpecularColor = lerp(Color::Water(ShallowColor.xyz), specularColor, 0.5); float3 finalColor = saturate(1 - input.WPosition.w * 0.002) * ((1 - fresnel) * (diffuseColor - finalSpecularColor)) + finalSpecularColor; // Add ripple and splash color effects for underwater # if defined(WETNESS_EFFECTS) && defined(DEBUG_WETNESS_EFFECTS) @@ -1124,13 +1123,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 fogColor = input.FogParam.xyz; + float3 fogColor = Color::Fog(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); + float3 finalColor = lerp(finalColorPreFog, fogColor * PosAdjust[eyeIndex].w, Color::FogAlpha(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); @@ -1142,24 +1141,24 @@ PS_OUTPUT main(PS_INPUT input) # else float specularFraction = lerp(1, fresnel, distanceFactor); float3 finalColorPreFog = lerp(diffuseOutput.refractionDiffuseColor, specularColor, specularFraction) + sunColor * depthControl.w; - float3 preFogColor = input.FogParam.xyz; + float3 preFogColor = Color::Fog(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); + finalColorPreFog = lerp(finalColorPreFog, preFogColor * PosAdjust[eyeIndex].w, Color::FogAlpha(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); + float3 fogColor = Color::Fog(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); + refractionColor = lerp(refractionColor, fogColor, Color::FogAlpha(fogFactor)); float3 finalColor = lerp(refractionColor, finalColorPreFog, diffuseOutput.refractionMul); # if defined(WETNESS_EFFECTS) && defined(DEBUG_WETNESS_EFFECTS) diff --git a/src/Feature.cpp b/src/Feature.cpp index e3facbed1..c667786d7 100644 --- a/src/Feature.cpp +++ b/src/Feature.cpp @@ -14,6 +14,7 @@ #include "Features/InverseSquareLighting.h" #include "Features/LODBlending.h" #include "Features/LightLimitFix.h" +#include "Features/LinearLighting.h" #include "Features/PerformanceOverlay.h" #include "Features/RenderDoc.h" #include "Features/ScreenSpaceGI.h" @@ -227,7 +228,8 @@ const std::vector& Feature::GetFeatureList() &globals::features::ibl, &globals::features::extendedTranslucency, &globals::features::upscaling, - &globals::features::renderDoc + &globals::features::renderDoc, + &globals::features::linearLighting }; if (REL::Module::IsVR()) { diff --git a/src/FeatureBuffer.cpp b/src/FeatureBuffer.cpp index 745480a84..2cdb61011 100644 --- a/src/FeatureBuffer.cpp +++ b/src/FeatureBuffer.cpp @@ -9,6 +9,7 @@ #include "Features/IBL.h" #include "Features/LODBlending.h" #include "Features/LightLimitFix.h" +#include "Features/LinearLighting.h" #include "Features/Skylighting.h" #include "Features/TerrainShadows.h" #include "Features/TerrainVariation.h" @@ -47,5 +48,6 @@ std::pair GetFeatureBufferData(bool a_inWorld) globals::features::hairSpecular.settings, globals::features::terrainVariation.settings, globals::features::ibl.settings, - globals::features::extendedTranslucency.GetCommonBufferData()); + globals::features::extendedTranslucency.GetCommonBufferData(), + globals::features::linearLighting.GetCommonBufferData()); } \ No newline at end of file diff --git a/src/Features/InverseSquareLighting.cpp b/src/Features/InverseSquareLighting.cpp index e26b92335..bc947c0ef 100644 --- a/src/Features/InverseSquareLighting.cpp +++ b/src/Features/InverseSquareLighting.cpp @@ -65,12 +65,12 @@ void InverseSquareLighting::ProcessLight(LightLimitFix::LightData& light, RE::BS light.fadeZone = 1.f / (light.radius * std::clamp(FadeZoneBase * light.invRadius, 0.f, 1.f)); light.sizeBias = ScaledUnitsSq * runtimeData->size * runtimeData->size * 0.5f; light.color /= std::max(0.001f, std::max(light.color.x, std::max(light.color.y, light.color.z))); - light.color *= intensity; + // light.color *= intensity; light.fade = intensity; } else { light.radius = runtimeData->radius; light.invRadius = 1.f / light.radius; - light.color *= runtimeData->fade; + // light.color *= runtimeData->fade; light.fade = runtimeData->fade; } } diff --git a/src/Features/LightLimitFix.cpp b/src/Features/LightLimitFix.cpp index 40aa95dfd..c5956237b 100644 --- a/src/Features/LightLimitFix.cpp +++ b/src/Features/LightLimitFix.cpp @@ -232,11 +232,11 @@ void LightLimitFix::BSLightingShader_SetupGeometry_GeometrySetupConstantPointLig isl.ProcessLight(light, bsLight, niLight); } else { light.radius = runtimeData.radius.x; - light.color *= runtimeData.fade; + // light.color *= runtimeData.fade; light.fade = runtimeData.fade; } - light.color *= bsLight->lodDimmer; + light.fade *= bsLight->lodDimmer; SetLightPosition(light, niLight->world.translate, inWorld); @@ -414,10 +414,11 @@ void LightLimitFix::UpdateLights() isl.ProcessLight(light, bsLight, niLight); } else { light.radius = runtimeData.radius.x; - light.color *= runtimeData.fade; + // light.color *= runtimeData.fade; + light.fade = runtimeData.fade; } - light.color *= bsLight->lodDimmer; + light.fade *= bsLight->lodDimmer; if (!IsGlobalLight(bsLight)) { // List of BSMultiBoundRooms affected by a light @@ -442,7 +443,7 @@ void LightLimitFix::UpdateLights() if (light.shadowMaskIndex != 255) { SetLightPosition(light, niLight->world.translate); - if ((light.color.x + light.color.y + light.color.z) > 1e-4 && light.radius > 1e-4) { + if ((light.color.x + light.color.y + light.color.z) * light.fade > 1e-4 && light.radius > 1e-4) { lightsData.push_back(light); } } diff --git a/src/Features/LightLimitFix.h b/src/Features/LightLimitFix.h index 024be1b43..8d84a2d2f 100644 --- a/src/Features/LightLimitFix.h +++ b/src/Features/LightLimitFix.h @@ -47,7 +47,7 @@ struct LightLimitFix : Feature struct alignas(16) LightData { float3 color; - float fade; + float fade = 1.0f; float radius; float invRadius; float fadeZone; diff --git a/src/Features/LinearLighting.cpp b/src/Features/LinearLighting.cpp new file mode 100644 index 000000000..57c1c737b --- /dev/null +++ b/src/Features/LinearLighting.cpp @@ -0,0 +1,142 @@ +#include "LinearLighting.h" + +NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT( + LinearLighting::Settings, + enableLinearLighting, + enableGammaCorrection, + lightGamma, + colorGamma, + emitColorGamma, + glowmapGamma, + ambientGamma, + fogGamma, + fogAlphaGamma, + effectGamma, + effectAlphaGamma, + skyGamma, + waterGamma, + vlGamma, + vanillaDiffuseMult, + vanillaSpecularMult, + grassDiffuseMult, + grassSpecularMult, + vanillaDiffuseColorMult, + lightMult, + directionalLightMult, + pointLightMult, + emitColorMult, + glowmapMult, + effectLightingMult, + membraneEffectMult, + bloodEffectMult, + projectedEffectMult, + deferredEffectMult, + otherEffectMult) + +void LinearLighting::DrawSettings() +{ + ImGui::Checkbox("Enable Linear Lighting", (bool*)&settings.enableLinearLighting); + ImGui::Checkbox("Enable Gamma Correction", (bool*)&settings.enableGammaCorrection); + ImGui::Text("Gamma Settings"); + ImGui::SliderFloat("Light Gamma", &settings.lightGamma, 0.1f, 3.0f, "%.2f"); + ImGui::SliderFloat("Color Gamma", &settings.colorGamma, 0.1f, 3.0f, "%.2f"); + ImGui::SliderFloat("Emissive Color Gamma", &settings.emitColorGamma, 0.1f, 3.0f, "%.2f"); + ImGui::SliderFloat("Glowmap Gamma", &settings.glowmapGamma, 0.1f, 3.0f, "%.2f"); + ImGui::SliderFloat("Ambient Gamma", &settings.ambientGamma, 0.1f, 3.0f, "%.2f"); + ImGui::SliderFloat("Fog Gamma", &settings.fogGamma, 0.1f, 3.0f, "%.2f"); + ImGui::SliderFloat("Fog Transparency Gamma", &settings.fogAlphaGamma, 0.1f, 3.0f, "%.2f"); + ImGui::SliderFloat("Effect Gamma", &settings.effectGamma, 0.1f, 3.0f, "%.2f"); + ImGui::SliderFloat("Effect Transparency Gamma", &settings.effectAlphaGamma, 0.1f, 3.0f, "%.2f"); + ImGui::SliderFloat("Sky Gamma", &settings.skyGamma, 0.1f, 3.0f, "%.2f"); + ImGui::SliderFloat("Water Gamma", &settings.waterGamma, 0.1f, 3.0f, "%.2f"); + ImGui::SliderFloat("Volumetric Lighting Gamma", &settings.vlGamma, 0.1f, 3.0f, "%.2f"); + + ImGui::SeparatorText("Multipliers"); + ImGui::SliderFloat("Vanilla Diffuse Multiplier", &settings.vanillaDiffuseMult, 0.0f, 10.0f, "%.2f"); + ImGui::SliderFloat("Vanilla Specular Multiplier", &settings.vanillaSpecularMult, 0.0f, 10.0f, "%.2f"); + ImGui::SliderFloat("Grass Diffuse Multiplier", &settings.grassDiffuseMult, 0.0f, 10.0f, "%.2f"); + ImGui::SliderFloat("Grass Specular Multiplier", &settings.grassSpecularMult, 0.0f, 10.0f, "%.2f"); + ImGui::SliderFloat("Vanilla Diffuse Color Multiplier", &settings.vanillaDiffuseColorMult, 0.0f, 10.0f, "%.2f"); + ImGui::SliderFloat("Light Multiplier", &settings.lightMult, 0.0f, 10.0f, "%.2f"); + ImGui::SliderFloat("Directional Light Multiplier", &settings.directionalLightMult, 0.0f, 10.0f, "%.2f"); + ImGui::SliderFloat("Point Light Multiplier", &settings.pointLightMult, 0.0f, 10.0f, "%.2f"); + ImGui::SliderFloat("Emissive Color Multiplier", &settings.emitColorMult, 0.0f, 10.0f, "%.2f"); + ImGui::SliderFloat("Glowmap Multiplier", &settings.glowmapMult, 0.0f, 10.0f, "%.2f"); + if (ImGui::TreeNodeEx("Effects", ImGuiTreeNodeFlags_DefaultOpen)) { + ImGui::SliderFloat("Effect Lighting Multiplier", &settings.effectLightingMult, 0.0f, 10.0f, "%.2f"); + ImGui::SliderFloat("Membrane Effects Multiplier", &settings.membraneEffectMult, 0.0f, 10.0f, "%.2f"); + ImGui::SliderFloat("Blood Effects Multiplier", &settings.bloodEffectMult, 0.0f, 10.0f, "%.2f"); + ImGui::SliderFloat("Projected Effects Multiplier", &settings.projectedEffectMult, 0.0f, 10.0f, "%.2f"); + ImGui::SliderFloat("Deferred Effects Multiplier", &settings.deferredEffectMult, 0.0f, 10.0f, "%.2f"); + ImGui::SliderFloat("Other Effects Multiplier", &settings.otherEffectMult, 0.0f, 10.0f, "%.2f"); + ImGui::TreePop(); + } +} + +void LinearLighting::LoadSettings(json& o_json) +{ + settings = o_json; +} + +void LinearLighting::SaveSettings(json& o_json) +{ + o_json = settings; +} + +void LinearLighting::RestoreDefaultSettings() +{ + settings = {}; +} + +void LinearLighting::Prepass() +{ + bool isMainLoadingMenu = globals::game::ui && (globals::game::ui->IsMenuOpen(RE::MainMenu::MENU_NAME) || globals::game::ui->IsMenuOpen(RE::LoadingMenu::MENU_NAME)); + dirLightMult = 1.0f; + if (!settings.enableLinearLighting || isMainLoadingMenu) + return; + + auto imageSpaceManager = RE::ImageSpaceManager::GetSingleton(); + if (!imageSpaceManager) + return; + + dirLightMult = !globals::game::isVR ? imageSpaceManager->GetRuntimeData().data.baseData.hdr.sunlightScale : imageSpaceManager->GetVRRuntimeData().data.baseData.hdr.sunlightScale; +} + +LinearLighting::PerFrameData LinearLighting::GetCommonBufferData() +{ + bool isMainLoadingMenu = globals::game::ui && (globals::game::ui->IsMenuOpen(RE::MainMenu::MENU_NAME) || globals::game::ui->IsMenuOpen(RE::LoadingMenu::MENU_NAME)); + auto data = PerFrameData{}; + data.enableLinearLighting = settings.enableLinearLighting && !isMainLoadingMenu; + data.enableGammaCorrection = settings.enableGammaCorrection; + data.isDirLightLinear = isDirLightLinear; + data.dirLightMult = dirLightMult; + data.lightGamma = settings.lightGamma; + data.colorGamma = settings.colorGamma; + data.emitColorGamma = settings.emitColorGamma; + data.glowmapGamma = settings.glowmapGamma; + data.ambientGamma = settings.ambientGamma; + data.fogGamma = settings.fogGamma; + data.fogAlphaGamma = settings.fogAlphaGamma; + data.effectGamma = settings.effectGamma; + data.effectAlphaGamma = settings.effectAlphaGamma; + data.skyGamma = settings.skyGamma; + data.waterGamma = settings.waterGamma; + data.vlGamma = settings.vlGamma; + data.vanillaDiffuseMult = settings.vanillaDiffuseMult; + data.vanillaSpecularMult = settings.vanillaSpecularMult; + data.grassDiffuseMult = settings.grassDiffuseMult; + data.grassSpecularMult = settings.grassSpecularMult; + data.vanillaDiffuseColorMult = settings.vanillaDiffuseColorMult; + data.lightMult = settings.lightMult; + data.directionalLightMult = settings.directionalLightMult; + data.pointLightMult = settings.pointLightMult; + data.emitColorMult = settings.emitColorMult; + data.glowmapMult = settings.glowmapMult; + data.effectLightingMult = settings.effectLightingMult; + data.membraneEffectMult = settings.membraneEffectMult; + data.bloodEffectMult = settings.bloodEffectMult; + data.projectedEffectMult = settings.projectedEffectMult; + data.deferredEffectMult = settings.deferredEffectMult; + data.otherEffectMult = settings.otherEffectMult; + return data; +} \ No newline at end of file diff --git a/src/Features/LinearLighting.h b/src/Features/LinearLighting.h new file mode 100644 index 000000000..dd0fc14c0 --- /dev/null +++ b/src/Features/LinearLighting.h @@ -0,0 +1,114 @@ +#pragma once + +struct LinearLighting : Feature +{ + static LinearLighting* GetSingleton() + { + static LinearLighting singleton; + return &singleton; + } + + virtual inline std::string GetName() override { return "Linear Lighting"; } + virtual inline std::string GetShortName() override { return "LinearLighting"; } + virtual std::string_view GetCategory() const override { return "Lighting"; } + virtual std::pair> GetFeatureSummary() override + { + return { + "Linear Lighting does internal color space conversion to improve lighting calculation accuracy.", + { "Customizable gamma correction", + "Corrects lighting calculations", + "Makes PBR really work" } + }; + } + + virtual bool SupportsVR() override { return true; }; + virtual bool IsCore() const override { return true; }; + + struct Settings + { + uint enableLinearLighting = true; + uint enableGammaCorrection = true; + float lightGamma = 1.8f; + float colorGamma = 2.2f; + float emitColorGamma = 2.2f; + float glowmapGamma = 2.2f; + float ambientGamma = 1.8f; + float fogGamma = 2.2f; + float fogAlphaGamma = 1.0f; + float effectGamma = 1.8f; + float effectAlphaGamma = 1.0f; + float skyGamma = 1.8f; + float waterGamma = 1.8f; + float vlGamma = 1.8f; + + // Lighting multipliers + float vanillaDiffuseMult = 0.32f; + float vanillaSpecularMult = 0.32f; + float grassDiffuseMult = 0.32f; + float grassSpecularMult = 0.32f; + float vanillaDiffuseColorMult = 1.5f; + float lightMult = 1.0f; + float directionalLightMult = 1.0f; + float pointLightMult = 1.0f; + float emitColorMult = 1.0f; + float glowmapMult = 1.0f; + + // Effect multipliers + float effectLightingMult = 0.32f; + float membraneEffectMult = 1.0f; + float bloodEffectMult = 1.0f; + float projectedEffectMult = 1.0f; + float deferredEffectMult = 1.0f; + float otherEffectMult = 1.0f; + } settings; + + struct alignas(16) PerFrameData + { + uint enableLinearLighting; + uint enableGammaCorrection; + uint isDirLightLinear; + float dirLightMult; + float lightGamma; + float colorGamma; + float emitColorGamma; + float glowmapGamma; + float ambientGamma; + float fogGamma; + float fogAlphaGamma; + float effectGamma; + float effectAlphaGamma; + float skyGamma; + float waterGamma; + float vlGamma; + float vanillaDiffuseMult; + float vanillaSpecularMult; + float grassDiffuseMult; + float grassSpecularMult; + float vanillaDiffuseColorMult; + float lightMult; + float directionalLightMult; + float pointLightMult; + float emitColorMult; + float glowmapMult; + float effectLightingMult; + float membraneEffectMult; + float bloodEffectMult; + float projectedEffectMult; + float deferredEffectMult; + float otherEffectMult; + }; + + uint isDirLightLinear = false; + float dirLightMult = 1.0f; + + virtual void DrawSettings() override; + + virtual void LoadSettings(json& o_json) override; + virtual void SaveSettings(json& o_json) override; + + virtual void RestoreDefaultSettings() override; + + virtual void Prepass() override; + + PerFrameData GetCommonBufferData(); +}; diff --git a/src/Globals.cpp b/src/Globals.cpp index 7d6995ad4..7c8cb44d9 100644 --- a/src/Globals.cpp +++ b/src/Globals.cpp @@ -13,6 +13,7 @@ #include "Features/InverseSquareLighting.h" #include "Features/LODBlending.h" #include "Features/LightLimitFix.h" +#include "Features/LinearLighting.h" #include "Features/PerformanceOverlay.h" #include "Features/RenderDoc.h" #include "Features/ScreenSpaceGI.h" @@ -54,6 +55,7 @@ namespace globals GrassLighting grassLighting{}; IBL ibl{}; LightLimitFix lightLimitFix{}; + LinearLighting linearLighting{}; LODBlending lodBlending{}; HairSpecular hairSpecular{}; InteriorSun interiorSun{}; diff --git a/src/Globals.h b/src/Globals.h index cf52ded48..759b58ad4 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -8,6 +8,7 @@ struct GrassLighting; struct HairSpecular; struct IBL; struct LightLimitFix; +struct LinearLighting; struct LODBlending; struct InteriorSun; struct InverseSquareLighting; @@ -59,6 +60,7 @@ namespace globals extern HairSpecular hairSpecular; extern IBL ibl; extern LightLimitFix lightLimitFix; + extern LinearLighting linearLighting; extern LODBlending lodBlending; extern InteriorSun interiorSun; extern InverseSquareLighting inverseSquareLighting;