diff --git a/Content/Shaders/AtmospherePreCompute.flax b/Content/Shaders/AtmospherePreCompute.flax index 2a778c8df..753bb46dc 100644 --- a/Content/Shaders/AtmospherePreCompute.flax +++ b/Content/Shaders/AtmospherePreCompute.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:17e3ad3624b4662280ef28e989768a8e6f139568f8ec9fd20f0e0b62fd3713eb +oid sha256:7435c6133694bd0f4fbff46978b5813bdbf9faa21763e9cf702410a6cd041585 size 11720 diff --git a/Content/Shaders/ColorGrading.flax b/Content/Shaders/ColorGrading.flax index d04902528..eef24db35 100644 --- a/Content/Shaders/ColorGrading.flax +++ b/Content/Shaders/ColorGrading.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b893fa98d125fa5ca5cf8e930aaf6cf62b7130652c4b8f1530713e22289e92a1 -size 11344 +oid sha256:e25c173644fa6e459791e1222514b77d71847bcc1d063accbf5e94e16d83527f +size 11057 diff --git a/Content/Shaders/Fog.flax b/Content/Shaders/Fog.flax index 3bb6a755e..126388165 100644 --- a/Content/Shaders/Fog.flax +++ b/Content/Shaders/Fog.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f87bf73c8c4f77c4817d80d0fea85e006369ae508fb0f8922a502c393176f7b8 -size 3129 +oid sha256:17bb8171cdafe227429d694733060a5ce7c647a48da9d6f4215f336ada03dc56 +size 2943 diff --git a/Content/Shaders/PostProcessing.flax b/Content/Shaders/PostProcessing.flax index d65d507f1..cd3923673 100644 --- a/Content/Shaders/PostProcessing.flax +++ b/Content/Shaders/PostProcessing.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:40c02e02b48f76a7dadfc525f5a800903ac8f01375ea0e1ed8979faea4b5a48b -size 16917 +oid sha256:6933ed1b8e8257ca9bd0a5e25deda41d3d79fff2d3aefb2b6be5b8e8d308c5f6 +size 17028 diff --git a/Content/Shaders/ProbesFilter.flax b/Content/Shaders/ProbesFilter.flax index bf958ef9e..c95b5aac3 100644 --- a/Content/Shaders/ProbesFilter.flax +++ b/Content/Shaders/ProbesFilter.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3d37f8e0d6293d937e97ffb59292da551f6ca41e6b4256d578b5ee5138cf98db -size 5128 +oid sha256:24e0095be6046f8cd05ed79f25c6b90b8c257420b686e050fdcedb6b210d963c +size 4999 diff --git a/Source/Shaders/ColorGrading.shader b/Source/Shaders/ColorGrading.shader index 6e4204f79..51015658c 100644 --- a/Source/Shaders/ColorGrading.shader +++ b/Source/Shaders/ColorGrading.shader @@ -90,7 +90,7 @@ float3 WhiteBalance(float3 linearColor) float2 srcWhitePlankian = PlanckianLocusChromaticity(WhiteTemp); float2 srcWhite = WhiteTemp < 4000 ? srcWhitePlankian : srcWhiteDaylight; - float2 d65White = float2(0.31270, 0.32900); + float2 d65White = float2(0.31270f, 0.32900f); float2 isothermal = PlanckianIsothermal(WhiteTemp, WhiteTint) - srcWhitePlankian; srcWhite += isothermal; @@ -103,8 +103,8 @@ float3 WhiteBalance(float3 linearColor) float3 ColorCorrect(float3 color, float luma, float4 saturation, float4 contrast, float4 gamma, float4 gain, float4 offset) { color = max(0, lerp(luma.xxx, color, saturation.xyz * saturation.w)); - color = pow(color * (1.0 / 0.18), contrast.xyz * contrast.w) * 0.18; - color = pow(color, 1.0 / (gamma.xyz * gamma.w)); + color = pow(color * (1.0f / 0.18f), contrast.xyz * contrast.w) * 0.18f; + color = pow(color, 1.0f / (gamma.xyz * gamma.w)); color = color * (gain.xyz * gain.w) + (offset.xyz + offset.w); return color; } @@ -112,35 +112,12 @@ float3 ColorCorrect(float3 color, float luma, float4 saturation, float4 contrast float3 ColorCorrectAll(float3 color) { float luma = dot(color, AP1_RGB2Y); - - // Shadow CC - float3 ccColorShadows = ColorCorrect(color, luma, - ColorSaturationShadows, - ColorContrastShadows, - ColorGammaShadows, - ColorGainShadows, - ColorOffsetShadows); + float3 ccColorShadows = ColorCorrect(color, luma, ColorSaturationShadows, ColorContrastShadows, ColorGammaShadows, ColorGainShadows, ColorOffsetShadows); float ccWeightShadows = 1 - smoothstep(0, ColorCorrectionShadowsMax, luma); - - // Highlight CC - float3 ccColorHighlights = ColorCorrect(color, luma, - ColorSaturationHighlights, - ColorContrastHighlights, - ColorGammaHighlights, - ColorGainHighlights, - ColorOffsetHighlights); + float3 ccColorHighlights = ColorCorrect(color, luma,ColorSaturationHighlights, ColorContrastHighlights, ColorGammaHighlights, ColorGainHighlights, ColorOffsetHighlights); float ccWeightHighlights = smoothstep(ColorCorrectionHighlightsMin, 1, luma); - - // Midtone CC - float3 ccColorMidtones = ColorCorrect(color, luma, - ColorSaturationMidtones, - ColorContrastMidtones, - ColorGammaMidtones, - ColorGainMidtones, - ColorOffsetMidtones); + float3 ccColorMidtones = ColorCorrect(color, luma, ColorSaturationMidtones, ColorContrastMidtones, ColorGammaMidtones, ColorGainMidtones, ColorOffsetMidtones); float ccWeightMidtones = 1 - ccWeightShadows - ccWeightHighlights; - - // Blend shadow, midtone and highlight CCs return ccColorShadows * ccWeightShadows + ccColorMidtones * ccWeightMidtones + ccColorHighlights * ccWeightHighlights; } @@ -189,8 +166,7 @@ float3 TonemapNeutral(float3 linearColor) float3 TonemapACES(float3 linearColor) { - // The code in this file was originally written by Stephen Hill (@self_shadow), who deserves all - // credit for coming up with this fit and implementing it. Buy him a beer next time you see him. :) + // The code was originally written by Stephen Hill (@self_shadow). // sRGB => XYZ => D65_2_D60 => AP1 => RRT_SAT static const float3x3 ACESInputMat = diff --git a/Source/Shaders/Fog.shader b/Source/Shaders/Fog.shader index 254fa9c69..7ddfe88ae 100644 --- a/Source/Shaders/Fog.shader +++ b/Source/Shaders/Fog.shader @@ -38,22 +38,14 @@ float4 CalculateCombinedFog(float3 worldPosition, float sceneDepth, float3 volum float excludeDistance = 0; #if VOLUMETRIC_FOG - - // Volumetric fog covers up to MaxDistance along ViewZ, exclude analytical fog from this range excludeDistance = max(ExponentialHeightFog.VolumetricFogMaxDistance - 100, 0); - #endif float4 fog = GetExponentialHeightFog(ExponentialHeightFog, worldPosition, GBuffer.ViewPos, excludeDistance); #if VOLUMETRIC_FOG - - // Sample volumetric fog lookup table float4 volumetricFog = IntegratedLightScattering.SampleLevel(SamplerLinearClamp, volumeUV, 0); - - // Mix volumetric and analytical fog fog = float4(volumetricFog.rgb + fog.rgb * volumetricFog.a, volumetricFog.a * fog.a); - #endif return fog; diff --git a/Source/Shaders/Lighting.hlsl b/Source/Shaders/Lighting.hlsl index bee5b3606..f626afa0b 100644 --- a/Source/Shaders/Lighting.hlsl +++ b/Source/Shaders/Lighting.hlsl @@ -28,7 +28,6 @@ LightingData StandardShading(GBufferSample gBuffer, float energy, float3 L, floa float NoH = saturate(dot(N, H)); float VoH = saturate(dot(V, H)); - // Generalized microfacet specular float D = D_GGX(gBuffer.Roughness, NoH) * energy; float Vis = Vis_SmithJointApprox(gBuffer.Roughness, NoV, NoL); float3 F = F_Schlick(specularColor, VoH); @@ -113,7 +112,6 @@ float4 GetLighting(float3 viewPos, LightData lightData, GBufferSample gBuffer, f { float4 result = 0; float3 V = normalize(viewPos - gBuffer.WorldPos); - float3 ToLight = lightData.Direction; float3 N = gBuffer.Normal; float3 L = lightData.Direction; // no need to normalize float NoL = saturate(dot(N, L)); @@ -124,7 +122,7 @@ float4 GetLighting(float3 viewPos, LightData lightData, GBufferSample gBuffer, f // Calculate attenuation if (isRadial) { - GetRadialLightAttenuation(lightData, isSpotLight, gBuffer.WorldPos, N, 1, ToLight, L, NoL, distanceAttenuation, lightRadiusMask, spotAttenuation); + GetRadialLightAttenuation(lightData, isSpotLight, gBuffer.WorldPos, N, 1, lightData.Direction, L, NoL, distanceAttenuation, lightRadiusMask, spotAttenuation); } float attenuation = distanceAttenuation * lightRadiusMask * spotAttenuation; @@ -132,13 +130,13 @@ float4 GetLighting(float3 viewPos, LightData lightData, GBufferSample gBuffer, f ShadowData shadow = GetShadow(lightData, gBuffer, shadowMask); // Reduce shadow mapping artifacts - shadow.SurfaceShadow *= saturate(NoL * 6 - 0.2); + shadow.SurfaceShadow *= saturate(NoL * 6.0f - 0.2f); BRANCH if (shadow.SurfaceShadow + shadow.TransmissionShadow > 0) { gBuffer.Roughness = max(gBuffer.Roughness, lightData.MinRoughness); - float energy = AreaLightSpecular(lightData, gBuffer.Roughness, ToLight, L, V, N); + float energy = AreaLightSpecular(lightData, gBuffer.Roughness, lightData.Direction, L, V, N); // Calculate direct lighting LightingData lighting = SurfaceShading(gBuffer, energy, L, V, N); diff --git a/Source/Shaders/LightingCommon.hlsl b/Source/Shaders/LightingCommon.hlsl index 250715de7..ac98ef360 100644 --- a/Source/Shaders/LightingCommon.hlsl +++ b/Source/Shaders/LightingCommon.hlsl @@ -127,30 +127,21 @@ float AreaLightSpecular(LightData lightData, float roughness, inout float3 toLig BRANCH if (lightData.SourceLength > 0) { - // Energy conservation float lineAngle = saturate(lightData.SourceLength * invDistToLight); energy *= m / saturate(m + 0.5 * lineAngle); - - // Closest point on line segment to ray float3 l01 = lightData.Direction * lightData.SourceLength; float3 l0 = toLight - 0.5 * l01; - float3 l1 = toLight + 0.5 * l01; - float a = Square(lightData.SourceLength); float b = dot(r, l01); float t = saturate(dot(l0, b * r - l01) / (a - b * b)); - toLight = l0 + t * l01; } BRANCH if (lightData.SourceRadius > 0) { - // Energy conservation float sphereAngle = saturate(lightData.SourceRadius * invDistToLight); energy *= Square(m / saturate(m + 0.5 * sphereAngle)); - - // Closest point on sphere to ray float3 closestPointOnRay = dot(toLight, r) * r; float3 centerToRay = closestPointOnRay - toLight; float3 closestPointOnSphere = toLight + centerToRay * saturate(lightData.SourceRadius * rsqrt(dot(centerToRay, centerToRay))); diff --git a/Source/Shaders/PostProcessing.shader b/Source/Shaders/PostProcessing.shader index 1993ff8e9..1b8db3638 100644 --- a/Source/Shaders/PostProcessing.shader +++ b/Source/Shaders/PostProcessing.shader @@ -15,6 +15,10 @@ // // Perlin noise shader by toneburst: // http://machinesdontcare.wordpress.com/2009/06/25/3d-perlin-noise-sphere-vertex-shader-sourcecode/ +// +// Lens flares by John Chapman: +//https://john-chapman.github.io/2017/11/05/pseudo-lens-flare.html +// #include "./Flax/Common.hlsl" #include "./Flax/Random.hlsl" diff --git a/Source/Shaders/ProbesFilter.shader b/Source/Shaders/ProbesFilter.shader index 59cfe131b..8ff0f8536 100644 --- a/Source/Shaders/ProbesFilter.shader +++ b/Source/Shaders/ProbesFilter.shader @@ -25,7 +25,7 @@ float4 SampleCubemap(float3 uv) return Cube.SampleLevel(SamplerLinearClamp, uv, SourceMipIndex); } -float3 GetCubemapVector(float2 uv) +float3 UvToCubeMapUv(float2 uv) { float3 coords; if (CubeFace == 0) @@ -60,9 +60,9 @@ META_PS(true, FEATURE_LEVEL_ES2) float4 PS_FilterFace(Quad_VS2PS input) : SV_Target { float2 uv = input.TexCoord * 2 - 1; - float3 cubeCoordinates = GetCubemapVector(uv); + float3 cubeCoordinates = UvToCubeMapUv(uv); - #define NUM_FILTER_SAMPLES 512 +#define NUM_FILTER_SAMPLES 512 float3 N = normalize(cubeCoordinates); float roughness = ComputeReflectionCaptureRoughnessFromMip(SourceMipIndex); @@ -101,17 +101,14 @@ META_PS(true, FEATURE_LEVEL_ES2) float4 PS_CalcDiffuseIrradiance(Quad_VS2PS input) : SV_Target { float2 uv = input.TexCoord * 2 - 1; - float3 cubeCoordinates = normalize(GetCubemapVector(uv)); + float3 cubeCoordinates = normalize(UvToCubeMapUv(uv)); float squaredUVs = 1 + dot(uv, uv); - - // Dividing by NumSamples here to keep the sum in the range of fp16, once we get down to the 1x1 mip float weight = 4 / (sqrt(squaredUVs) * squaredUVs); ThreeBandSHVector shCoefficients = SHBasisFunction3(cubeCoordinates); float currentSHCoefficient = dot(shCoefficients.V0, CoefficientMask0) + dot(shCoefficients.V1, CoefficientMask1) + shCoefficients.V2 * CoefficientMask2; float3 radiance = SampleCubemap(cubeCoordinates).rgb; - return float4(radiance * currentSHCoefficient * weight, weight); } @@ -122,22 +119,22 @@ float4 PS_AccDiffuseIrradiance(Quad_VS2PS input) : SV_Target float4 result = 0; { float2 uv = saturate(input.TexCoord + Sample01.xy) * 2 - 1; - float3 cubeCoordinates = GetCubemapVector(uv); + float3 cubeCoordinates = UvToCubeMapUv(uv); result += SampleCubemap(cubeCoordinates); } { float2 uv = saturate(input.TexCoord + Sample01.zw) * 2 - 1; - float3 cubeCoordinates = GetCubemapVector(uv); + float3 cubeCoordinates = UvToCubeMapUv(uv); result += SampleCubemap(cubeCoordinates); } { float2 uv = saturate(input.TexCoord + Sample23.xy) * 2 - 1; - float3 cubeCoordinates = GetCubemapVector(uv); + float3 cubeCoordinates = UvToCubeMapUv(uv); result += SampleCubemap(cubeCoordinates); } { float2 uv = saturate(input.TexCoord + Sample23.zw) * 2 - 1; - float3 cubeCoordinates = GetCubemapVector(uv); + float3 cubeCoordinates = UvToCubeMapUv(uv); result += SampleCubemap(cubeCoordinates); } return result / 4.0f; diff --git a/Source/Shaders/ShadowsCommon.hlsl b/Source/Shaders/ShadowsCommon.hlsl index 81b7d33ea..81128adc4 100644 --- a/Source/Shaders/ShadowsCommon.hlsl +++ b/Source/Shaders/ShadowsCommon.hlsl @@ -39,22 +39,6 @@ struct LightShadowData #define DECLARE_LIGHTSHADOWDATA_ACCESS(uniformName) LightShadowData Get##uniformName##Data() { return uniformName; } #endif -// Gets the cube texture face index to use for shadow map sampling for the given view-to-light direction vector -// Where: direction = normalize(worldPosition - lightPosition) -int GetCubeFaceIndex(float3 direction) -{ - int cubeFaceIndex; - float3 absDirection = abs(direction); - float maxDirection = max(absDirection.x, max(absDirection.y, absDirection.z)); - if (maxDirection == absDirection.x) - cubeFaceIndex = absDirection.x == direction.x ? 0 : 1; - else if (maxDirection == absDirection.y) - cubeFaceIndex = absDirection.y == direction.y ? 2 : 3; - else - cubeFaceIndex = absDirection.z == direction.z ? 4 : 5; - return cubeFaceIndex; -} - float3 GetShadowPositionOffset(float offsetScale, float NoL, float3 normal) { float normalOffsetScale = saturate(1.0f - NoL); diff --git a/Source/Shaders/ShadowsSampling.hlsl b/Source/Shaders/ShadowsSampling.hlsl index 694f24f72..fbadc64de 100644 --- a/Source/Shaders/ShadowsSampling.hlsl +++ b/Source/Shaders/ShadowsSampling.hlsl @@ -42,6 +42,22 @@ #include "./Flax/PCFKernels.hlsl" #endif +// Gets the cube texture face index to use for shadow map sampling for the given view-to-light direction vector +// Where: direction = normalize(worldPosition - lightPosition) +int GetCubeFaceIndex(float3 direction) +{ + int cubeFaceIndex; + float3 absDirection = abs(direction); + float maxDirection = max(absDirection.x, max(absDirection.y, absDirection.z)); + if (maxDirection == absDirection.x) + cubeFaceIndex = absDirection.x == direction.x ? 0 : 1; + else if (maxDirection == absDirection.y) + cubeFaceIndex = absDirection.y == direction.y ? 2 : 3; + else + cubeFaceIndex = absDirection.z == direction.z ? 4 : 5; + return cubeFaceIndex; +} + // Samples the shadow map with a fixed-size PCF kernel optimized with GatherCmpRed. // Uses code from "Fast Conventional Shadow Filtering" by Holger Gruen, in GPU Pro. float SampleShadowMapFixedSizePCF(Texture2DArray shadowMap, float2 shadowMapSize, float sceneDepth, float2 shadowPos, uint cascadeIndex)