From 8a870a07ae918025b68a3a567470457078dc3ce9 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Sun, 20 Dec 2020 10:22:54 +0100 Subject: [PATCH] Cleanup some old unused shader code --- Content/Shaders/AtmospherePreCompute.flax | 4 +- Content/Shaders/ColorGrading.flax | 4 +- Content/Shaders/Histogram.flax | 4 +- Content/Shaders/PostProcessing.flax | 4 +- Content/Shaders/ProbesFilter.flax | 4 +- Content/Shaders/VolumetricFog.flax | 4 +- Source/Shaders/Atmosphere.hlsl | 126 ++++++--------- Source/Shaders/AtmosphereFog.hlsl | 53 +----- Source/Shaders/AtmospherePreCompute.shader | 12 +- Source/Shaders/BRDF.hlsl | 180 ++------------------- Source/Shaders/Collisions.hlsl | 63 -------- Source/Shaders/ColorGrading.shader | 59 +++---- Source/Shaders/Common.hlsl | 19 --- Source/Shaders/GammaCorrectionCommon.hlsl | 121 ++------------ Source/Shaders/Histogram.shader | 12 -- Source/Shaders/IESProfile.hlsl | 16 +- Source/Shaders/LightingCommon.hlsl | 4 +- Source/Shaders/Math.hlsl | 96 +++++------ Source/Shaders/MonteCarlo.hlsl | 6 +- Source/Shaders/PostProcessing.shader | 1 - Source/Shaders/ProbesFilter.shader | 47 +++--- Source/Shaders/Random.hlsl | 3 + Source/Shaders/SH.hlsl | 19 ++- Source/Shaders/ShadowsCommon.hlsl | 3 - Source/Shaders/VolumetricFog.shader | 20 +-- 25 files changed, 199 insertions(+), 685 deletions(-) diff --git a/Content/Shaders/AtmospherePreCompute.flax b/Content/Shaders/AtmospherePreCompute.flax index 80279402c..099575745 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:71772e7059bc377bd2fc14e5e193af24e4e4c03f1d782fbf779e87901db0c329 -size 13430 +oid sha256:7bb50886a9a240de754b0f81d6119338846a082f7e452f32376de958917d2e14 +size 13312 diff --git a/Content/Shaders/ColorGrading.flax b/Content/Shaders/ColorGrading.flax index 7ffc7ff4f..d04902528 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:a5b9c4b320ca1926bbc5a0c0b57b758e89cbc15cfa801db8c11714c06decc578 -size 11553 +oid sha256:b893fa98d125fa5ca5cf8e930aaf6cf62b7130652c4b8f1530713e22289e92a1 +size 11344 diff --git a/Content/Shaders/Histogram.flax b/Content/Shaders/Histogram.flax index 0579197bd..557232811 100644 --- a/Content/Shaders/Histogram.flax +++ b/Content/Shaders/Histogram.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ccd2302c7b28d088ea2f810d22f81bb5beccd7e483ae0f7248ccbe0fd64ce70b -size 2928 +oid sha256:d308ec40abf308fe3d713abb124dbc7f0094c8e141dfa9a9600888deb0601804 +size 2609 diff --git a/Content/Shaders/PostProcessing.flax b/Content/Shaders/PostProcessing.flax index 7ce10e953..d65d507f1 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:f8d7c53061c2f0f6335cae78f09e11f08818196a3f0f40f3bced2c9b46cfe0b5 -size 16988 +oid sha256:40c02e02b48f76a7dadfc525f5a800903ac8f01375ea0e1ed8979faea4b5a48b +size 16917 diff --git a/Content/Shaders/ProbesFilter.flax b/Content/Shaders/ProbesFilter.flax index 7a8c0b14d..bf958ef9e 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:3cb6bf18e4179a4e2d85b23b3a7877dc50354d5030b0357cc365fc204b7a968f -size 5395 +oid sha256:3d37f8e0d6293d937e97ffb59292da551f6ca41e6b4256d578b5ee5138cf98db +size 5128 diff --git a/Content/Shaders/VolumetricFog.flax b/Content/Shaders/VolumetricFog.flax index e8a1ae9ca..e62d7f4c1 100644 --- a/Content/Shaders/VolumetricFog.flax +++ b/Content/Shaders/VolumetricFog.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:be3a9f6acede8a4901e9f3944b9a0ae586adee234eb3be44b343f21f21728b05 -size 16131 +oid sha256:daa92cd2b9f3dbc55923cf92561d6d91ab8f5d14dec183f418e03932d09f26b3 +size 15820 diff --git a/Source/Shaders/Atmosphere.hlsl b/Source/Shaders/Atmosphere.hlsl index 411586946..9ac9f2a63 100644 --- a/Source/Shaders/Atmosphere.hlsl +++ b/Source/Shaders/Atmosphere.hlsl @@ -90,15 +90,15 @@ Texture3D AtmosphereInscatterTexture : register(t2); float2 GetTransmittanceUV(float radius, float Mu) { - float U, V; + float u, v; #if TRANSMITTANCE_NON_LINEAR - V = sqrt((radius - RadiusGround) / (RadiusAtmosphere - RadiusGround)); - U = atan((Mu + 0.15) / (1.0 + 0.15) * tan(1.5)) / 1.5; + v = sqrt((radius - RadiusGround) / (RadiusAtmosphere - RadiusGround)); + u = atan((Mu + 0.15) / (1.0 + 0.15) * tan(1.5)) / 1.5; #else - V = (radius - RadiusGround) / (RadiusAtmosphere - RadiusGround); - U = (Mu + 0.15) / (1.0 + 0.15); + v = (radius - RadiusGround) / (RadiusAtmosphere - RadiusGround); + u = (Mu + 0.15) / (1.0 + 0.15); #endif - return float2(U, V); + return float2(u, v); } void GetTransmittanceRMuS(float2 uv, out float radius, out float MuS) @@ -116,9 +116,9 @@ void GetTransmittanceRMuS(float2 uv, out float radius, out float MuS) float2 GetIrradianceUV(float radius, float MuS) { - float V = (radius - RadiusGround) / (RadiusAtmosphere - RadiusGround); - float U = (MuS + 0.2) / (1.0 + 0.2); - return float2(U, V); + float v = (radius - RadiusGround) / (RadiusAtmosphere - RadiusGround); + float u = (MuS + 0.2) / (1.0 + 0.2); + return float2(u, v); } void GetIrradianceRMuS(float2 uv, out float radius, out float MuS) @@ -137,9 +137,6 @@ float4 Texture4DSample(Texture3D tex, float radius, float Mu, float MuS, float N float4 TexOffset = RMu < 0.0 && Delta > 0.0 ? float4(1.0, 0.0, 0.0, 0.5 - 0.5 / float(InscatterMuNum)) : float4(-1.0, H * H, H, 0.5 + 0.5 / float(InscatterMuNum)); float MuR = 0.5 / float(AtmosphericFogInscatterAltitudeSampleNum) + Rho / H * (1.0 - 1.0 / float(AtmosphericFogInscatterAltitudeSampleNum)); float MuMu = TexOffset.w + (RMu * TexOffset.x + sqrt(Delta + TexOffset.y)) / (Rho + TexOffset.z) * (0.5 - 1.0 / float(InscatterMuNum)); - // paper formula - //float MuMuS = 0.5 / float(InscatterMuSNum) + max((1.0 - exp(-3.0 * MuS - 0.6)) / (1.0 - exp(-3.6)), 0.0) * (1.0 - 1.0 / float(InscatterMuSNum)); - // better formula float MuMuS = 0.5 / float(InscatterMuSNum) + (atan(max(MuS, -0.1975) * tan(1.26 * 1.1)) / 1.1 + (1.0 - 0.26)) * 0.5 * (1.0 - 1.0 / float(InscatterMuSNum)); #else float MuR = 0.5 / float(AtmosphericFogInscatterAltitudeSampleNum) + Rho / H * (1.0 - 1.0 / float(AtmosphericFogInscatterAltitudeSampleNum)); @@ -154,35 +151,32 @@ float4 Texture4DSample(Texture3D tex, float radius, float Mu, float MuS, float N + tex.SampleLevel(SamplerLinearClamp, float3((MuNu + MuMuS + 1.0) / float(InscatterNuNum), MuMu, MuR), 0) * LerpValue; } -float Mod(float X, float Y) +float Mod(float x, float y) { - return X - Y * floor(X/Y); + return x - y * floor(x / y); } void GetMuMuSNu(float2 uv, float radius, float4 DhdH, out float Mu, out float MuS, out float Nu) { - float X = uv.x * float(InscatterMuSNum * InscatterNuNum) - 0.5; - float Y = uv.y * float(InscatterMuNum) - 0.5; + float x = uv.x * float(InscatterMuSNum * InscatterNuNum) - 0.5; + float y = uv.y * float(InscatterMuNum) - 0.5; #if INSCATTER_NON_LINEAR - if (Y < float(InscatterMuNum) * 0.5f) + if (y < float(InscatterMuNum) * 0.5f) { - float D = 1.0 - Y / (float(InscatterMuNum) * 0.5f - 1.0); - D = min(max(DhdH.z, D * DhdH.w), DhdH.w * 0.999); - Mu = (RadiusGround * RadiusGround - radius * radius - D * D) / (2.0 * radius * D); + float d = 1.0 - y / (float(InscatterMuNum) * 0.5f - 1.0); + d = min(max(DhdH.z, d * DhdH.w), DhdH.w * 0.999); + Mu = (RadiusGround * RadiusGround - radius * radius - d * d) / (2.0 * radius * d); Mu = min(Mu, -sqrt(1.0 - (RadiusGround / radius) * (RadiusGround / radius)) - 0.001); } else { - float D = (Y - float(InscatterMuNum) * 0.5f) / (float(InscatterMuNum) * 0.5f - 1.0); - D = min(max(DhdH.x, D * DhdH.y), DhdH.y * 0.999); - Mu = (RadiusAtmosphere * RadiusAtmosphere - radius * radius - D * D) / (2.0 * radius * D); + float d = (y - float(InscatterMuNum) * 0.5f) / (float(InscatterMuNum) * 0.5f - 1.0); + d = min(max(DhdH.x, d * DhdH.y), DhdH.y * 0.999); + Mu = (RadiusAtmosphere * RadiusAtmosphere - radius * radius - d * d) / (2.0 * radius * d); } - MuS = Mod(X, float(InscatterMuSNum)) / (float(InscatterMuSNum) - 1.0); - // paper formula - //MuS = -(0.6 + log(1.0 - MuS * (1.0 - exp(-3.6)))) / 3.0; - // better formula + MuS = Mod(x, float(InscatterMuSNum)) / (float(InscatterMuSNum) - 1.0); MuS = tan((2.0 * MuS - 1.0 + 0.26) * 1.1) / tan(1.26 * 1.1); - Nu = -1.0 + floor(X / float(InscatterMuSNum)) / (float(InscatterNuNum) - 1.0) * 2.0; + Nu = -1.0 + floor(x / float(InscatterMuSNum)) / (float(InscatterNuNum) - 1.0) * 2.0; #else Mu = -1.0 + 2.0 * Y / (float(InscatterMuNum) - 1.0); MuS = Mod(X, float(InscatterMuSNum)) / (float(InscatterMuSNum) - 1.0); @@ -191,10 +185,7 @@ void GetMuMuSNu(float2 uv, float radius, float4 DhdH, out float Mu, out float Mu #endif } -/** - * Nearest intersection of ray r,mu with ground or top atmosphere boundary - * mu=cos(ray zenith angle at ray origin) - */ +// Nearest intersection of ray r,mu with ground or top atmosphere boundary, mu=cos(ray zenith angle at ray origin) float Limit(float radius, float Mu) { float Dout = -radius * Mu + sqrt(radius * radius * (Mu * Mu - 1.0) + RadiusLimit * RadiusLimit); @@ -210,32 +201,20 @@ float Limit(float radius, float Mu) return Dout; } -/** - * Transmittance(=transparency) of atmosphere for infinite ray (r,mu) - * (mu=cos(view zenith angle)), intersections with ground ignored - */ +// Transmittance(=transparency) of atmosphere for infinite ray (r,mu) (mu=cos(view zenith angle)), intersections with ground ignored float3 Transmittance(float radius, float Mu) { float2 uv = GetTransmittanceUV(radius, Mu); return AtmosphereTransmittanceTexture.SampleLevel(SamplerLinearClamp, uv, 0).rgb; } -/** - * Transmittance(=transparency) of atmosphere for infinite ray (r,mu) - * (mu=cos(view zenith angle)), or zero if ray intersects ground - */ +// Transmittance(=transparency) of atmosphere for infinite ray (r,mu) (mu=cos(view zenith angle)), or zero if ray intersects ground float3 TransmittanceWithShadow(float radius, float Mu) { - // Need to correct calculation based on shadow feature, currently don't consider - //return Mu < -sqrt(1.0 - (RadiusGround / radius) * (RadiusGround / radius)) ? float3(0.f, 0.f, 0.f) : Transmittance(Radius, Mu); return Transmittance(radius, Mu); } -/** - * Transmittance(=transparency) of atmosphere between x and x0 - * Assume segment x,x0 not intersecting ground - * D = Distance between x and x0, mu=cos(zenith angle of [x,x0) ray at x) - */ +//Transmittance(=transparency) of atmosphere between x and x0. Assume segment x,x0 not intersecting ground. D = Distance between x and x0, mu=cos(zenith angle of [x,x0) ray at x) float3 TransmittanceWithDistance(float radius, float Mu, float D) { float3 result; @@ -252,42 +231,36 @@ float3 TransmittanceWithDistance(float radius, float Mu, float D) return result; } -/** - * Transmittance(=transparency) of atmosphere between x and x0 - * Assume segment x,x0 not intersecting ground - * radius=||x||, Mu=cos(zenith angle of [x,x0) ray at x), v=unit direction vector of [x,x0) ray - */ +// Transmittance(=transparency) of atmosphere between x and x0. Assume segment x,x0 not intersecting ground radius=||x||, Mu=cos(zenith angle of [x,x0) ray at x), v=unit direction vector of [x,x0) ray float3 TransmittanceWithDistance(float radius, float Mu, float3 V, float3 X0) { float3 result; - float R1 = length(X0); + float d1 = length(X0); float Mu1 = dot(X0, V) / radius; if (Mu > 0.0) - { - result = min(Transmittance(radius, Mu) / Transmittance(R1, Mu1), 1.0); - } + result = min(Transmittance(radius, Mu) / Transmittance(d1, Mu1), 1.0); else - { - result = min(Transmittance(R1, -Mu1) / Transmittance(radius, -Mu), 1.0); - } + result = min(Transmittance(d1, -Mu1) / Transmittance(radius, -Mu), 1.0); return result; } -/** - * Optical depth for ray (r,mu) of length d, using analytic formula - * (mu=cos(view zenith angle)), intersections with ground ignored - * H=height scale of exponential density function - */ +// Optical depth for ray (r,mu) of length d, using analytic formula (mu=cos(view zenith angle)), intersections with ground ignored H=height scale of exponential density function float OpticalDepthWithDistance(float H, float radius, float Mu, float D) { float particleDensity = 6.2831; // REK 04, Table 2 - float A = sqrt((0.5/H)*radius); - float2 A01 = A * float2(Mu, Mu + D / radius); + float a = sqrt(0.5 / H * radius); + float2 A01 = a * float2(Mu, Mu + D / radius); float2 A01Sign = sign(A01); float2 A01Squared = A01*A01; - float X = A01Sign.y > A01Sign.x ? exp(A01Squared.x) : 0.0; - float2 Y = A01Sign / (2.3193 * abs(A01) + sqrt(1.52 * A01Squared + 4.0)) * float2(1.0, exp(-D / H*(D / (2.0 * radius) + Mu))); - return sqrt((particleDensity * H)*radius) * exp((RadiusGround - radius) / H) * (X + dot(Y, float2(1.0, -1.0))); + float x = A01Sign.y > A01Sign.x ? exp(A01Squared.x) : 0.0; + float2 y = A01Sign / (2.3193 * abs(A01) + sqrt(1.52 * A01Squared + 4.0)) * float2(1.0, exp(-D / H*(D / (2.0 * radius) + Mu))); + return sqrt((particleDensity * H)*radius) * exp((RadiusGround - radius) / H) * (x + dot(y, float2(1.0, -1.0))); +} + +// Transmittance(=transparency) of atmosphere for ray (r,mu) of length d (mu=cos(view zenith angle)), intersections with ground ignored uses analytic formula instead of transmittance texture, REK 04, Atmospheric Transparency +float3 AnalyticTransmittance(float R, float Mu, float D) +{ + return exp(- BetaRayleighScattering * OpticalDepthWithDistance(HeightScaleRayleigh, R, Mu, D) - BetaMieExtinction * OpticalDepthWithDistance(HeightScaleMie, R, Mu, D)); } float3 Irradiance(Texture2D tex, float r, float muS) @@ -296,32 +269,23 @@ float3 Irradiance(Texture2D tex, float r, float muS) return tex.SampleLevel(SamplerLinearClamp, uv, 0).rgb; } -/** Rayleigh phase function */ +// Rayleigh phase function float PhaseFunctionR(float Mu) { return (3.0 / (16.0 * PI)) * (1.0 + Mu * Mu); } -/** Mie phase function */ +// Mie phase function float PhaseFunctionM(float Mu) { return 1.5 * 1.0 / (4.0 * PI) * (1.0 - MieG * MieG) * pow(1.0 + (MieG * MieG) - 2.0 * MieG * Mu, -3.0/2.0) * (1.0 + Mu * Mu) / (2.0 + MieG * MieG); } -/** Approximated single Mie scattering (cf. approximate Cm in paragraph "Angular precision") */ +// Approximated single Mie scattering (cf. approximate Cm in paragraph "Angular precision") float3 GetMie(float4 RayMie) { // RayMie.rgb=C*, RayMie.w=Cm,r return RayMie.rgb * RayMie.w / max(RayMie.r, 1e-4) * (BetaRayleighScattering.rrr / BetaRayleighScattering.rgb); } -/** Transmittance(=transparency) of atmosphere for ray (r,mu) of length d - * (mu=cos(view zenith angle)), intersections with ground ignored - * uses analytic formula instead of transmittance texture, REK 04, Atmospheric Transparency - */ -float3 AnalyticTransmittance(float R, float Mu, float D) -{ - return exp(- BetaRayleighScattering * OpticalDepthWithDistance(HeightScaleRayleigh, R, Mu, D) - BetaMieExtinction * OpticalDepthWithDistance(HeightScaleMie, R, Mu, D)); -} - #endif diff --git a/Source/Shaders/AtmosphereFog.hlsl b/Source/Shaders/AtmosphereFog.hlsl index 69bbaefc6..43693e26d 100644 --- a/Source/Shaders/AtmosphereFog.hlsl +++ b/Source/Shaders/AtmosphereFog.hlsl @@ -298,57 +298,6 @@ float3 inscatter(inout float3 x, inout float t, float3 v, float3 s, out float r, return result; } -/* -//ground radiance at end of ray x+tv, when sun in direction s -//attenuated bewteen ground and viewer (=R[L0]+R[L*]) -float3 groundColor(float3 x, float t, float3 v, float3 s, float r, float mu, float3 attenuation) -{ - float3 result; - if (t > 0.0) - { - // if ray hits ground surface - // ground reflectance at end of ray, x0 - float3 x0 = x + t * v; - float r0 = length(x0); - float3 n = x0 / r0; - - float4 SceneColor = 0; - - SceneColor.xyz = saturate(SceneColor.xyz + 0.05); - - float4 Reflectance = SceneColor * float4(0.2, 0.2, 0.2, 1.0); - - if (r0 > RadiusGround + 0.01) - { - reflectance = float4(0.4, 0.4, 0.4, 0.0); - } - - // direct sun light (radiance) reaching x0 - float muS = dot(n, s); - float3 sunLight = transmittanceWithShadow(r0, muS); - - // precomputed sky light (irradiance) (=E[L*]) at x0 - float3 groundSkyLight = Irradiance(AtmosphereIrradianceTexture, r0, muS); - - // light reflected at x0 (=(R[L0]+R[L*])/T(x,x0)) - float3 groundColor = reflectance.rgb * (max(muS, 0.0) * sunLight + groundSkyLight) * ISun / M_PI; - - // water specular color due to sunLight - if (reflectance.w > 0.0) - { - float3 h = normalize(s - v); - float fresnel = 0.02 + 0.98 * pow(1.0 - dot(-v, h), 5.0); - float waterBrdf = fresnel * pow(max(dot(h, n), 0.0), 150.0); - groundColor += reflectance.w * max(waterBrdf, 0.0) * sunLight * ISun; - } - - result = attenuation * groundColor; //=R[L0]+R[L*] - } else { // ray looking at the sky - result = 0.0; - } -return result; -} -*/ static const float EPSILON_ATMOSPHERE = 0.002f; static const float EPSILON_INSCATTER = 0.004f; @@ -534,7 +483,7 @@ float4 GetAtmosphericFog(AtmosphericFogData atmosphericFog, float viewFar, float #if 1 - // TODO: scale viewPosition from cm to km !!!!!!! + // TODO: scale viewPosition from cm to km float scale = 0.0001f * atmosphericFog.AtmosphericFogDistanceScale; viewPosition.y = (viewPosition.y - atmosphericFog.AtmosphericFogGroundOffset) * atmosphericFog.AtmosphericFogAltitudeScale; diff --git a/Source/Shaders/AtmospherePreCompute.shader b/Source/Shaders/AtmospherePreCompute.shader index 76e2309d0..e5013cbd3 100644 --- a/Source/Shaders/AtmospherePreCompute.shader +++ b/Source/Shaders/AtmospherePreCompute.shader @@ -66,16 +66,16 @@ void GS_Atmosphere(triangle Quad_VS2PS input[3], inout TriangleStream= 0 ? rcp( max(NoL, NoV)) : 1); - return diffuseColor / PI * (C1 + C2) * (1 + roughness * 0.5); -} - -float PhongShadingPow(float x, float y) -{ - return ClampedPow(x, y); -} - -// [Blinn 1977, "Models of light reflection for computer synthesized pictures"] -float D_Blinn(float roughness, float NoH) -{ - float a = roughness * roughness; - float a2 = a * a; - float n = 2 / a2 - 2; - return (n + 2) / (2 * PI) * PhongShadingPow(NoH, n); -} - -// [Beckmann 1963, "The scattering of electromagnetic waves from rough surfaces"] -float D_Beckmann(float roughness, float NoH) -{ - float a = roughness * roughness; - float a2 = a * a; - float NoH2 = NoH * NoH; - return exp((NoH2 - 1) / (a2 * NoH2)) / (PI * a2 * NoH2 * NoH2); -} - // GGX / Trowbridge-Reitz // [Walter et al. 2007, "Microfacet models for refraction through rough surfaces"] float D_GGX(float roughness, float NoH) @@ -70,36 +20,6 @@ float D_GGX(float roughness, float NoH) return a2 / (PI * d * d); } -// Anisotropic GGX -// [Burley 2012, "Physically-Based Shading at Disney"] -float D_GGXaniso(float roughnessX, float roughnessY, float NoH, float3 H, float3 X, float3 Y) -{ - float ax = roughnessX * roughnessX; - float ay = roughnessY * roughnessY; - float XoH = dot(X, H); - float YoH = dot(Y, H); - float d = XoH * XoH / (ax * ax) + YoH * YoH / (ay * ay) + NoH * NoH; - return 1 / (PI * ax * ay * d * d); -} - -float Vis_Implicit() -{ - return 0.25; -} - -// [Neumann et al. 1999, "Compact metallic reflectance models"] -float Vis_Neumann(float NoV, float NoL) -{ - return 1 / (4 * max(NoL, NoV)); -} - -// [Kelemen 2001, "A microfacet based coupled specular-matte brdf model with importance sampling"] -float Vis_Kelemen(float VoH) -{ - // constant to prevent NaN - return rcp(4 * VoH * VoH + 1e-5); -} - // Tuned to match behavior of Vis_Smith // [Schlick 1994, "An Inexpensive BRDF Model for Physically-Based Rendering"] float Vis_Schlick(float roughness, float NoV, float NoL) @@ -116,8 +36,8 @@ float Vis_Smith(float roughness, float NoV, float NoL) { float a = Square(roughness); float a2 = a * a; - float vis_SmithV = NoV + sqrt( NoV * (NoV - NoV * a2) + a2); - float vis_SmithL = NoL + sqrt( NoL * (NoL - NoL * a2) + a2); + float vis_SmithV = NoV + sqrt(NoV * (NoV - NoV * a2) + a2); + float vis_SmithL = NoL + sqrt(NoL * (NoL - NoL * a2) + a2); return rcp(vis_SmithV * vis_SmithL); } @@ -126,14 +46,9 @@ float Vis_Smith(float roughness, float NoV, float NoL) float Vis_SmithJointApprox(float roughness, float NoV, float NoL) { float a = Square(roughness); - float vis_SmithV = NoL * (NoV * (1 - a) + a); - float vis_SmithL = NoV * (NoL * (1 - a) + a); - return 0.5 * rcp(vis_SmithV + vis_SmithL); -} - -float3 F_None(float3 specularColor) -{ - return specularColor; + float visSmithV = NoL * (NoV * (1 - a) + a); + float visSmithL = NoV * (NoL * (1 - a) + a); + return 0.5 * rcp(visSmithV + visSmithL); } // [Schlick 1994, "An Inexpensive BRDF Model for Physically-Based Rendering"] @@ -143,86 +58,43 @@ float3 F_Schlick(float3 specularColor, float VoH) return saturate(50.0 * specularColor.g) * fc + (1 - fc) * specularColor; } -float3 F_Fresnel(float3 specularColor, float VoH) -{ - float3 specularColorSqrt = sqrt(clamp(float3(0, 0, 0), float3(0.99, 0.99, 0.99), specularColor)); - float3 n = (1 + specularColorSqrt ) / (1 - specularColorSqrt); - float3 g = sqrt(n * n + VoH * VoH - 1); - return 0.5 * Square((g - VoH) / (g + VoH)) * (1 + Square(((g + VoH) * VoH - 1) / ((g - VoH) * VoH + 1))); -} - -float D_InvBlinn(float roughness, float NoH) -{ - float m = roughness * roughness; - float m2 = m * m; - float A = 4; - float cos2h = NoH * NoH; - return rcp( PI * (1 + A * m2)) * (1 + A * exp(-cos2h / m2)); -} - -float D_InvBeckmann(float roughness, float NoH) -{ - float m = roughness * roughness; - float m2 = m * m; - float A = 4; - float cos2h = NoH * NoH; - float sin2h = 1 - cos2h; - float sin4h = sin2h * sin2h; - return rcp(PI * (1 + A * m2) * sin4h) * (sin4h + A * exp(-cos2h / (m2 * sin2h))); -} - -float D_InvGGX(float roughness, float NoH) -{ - float a = roughness * roughness; - float a2 = a * a; - float A = 4; - float d = (NoH - a2 * NoH) * NoH + a2; - return rcp(PI * (1 + A * a2)) * (1 + 4 * a2 * a2 / (d * d)); -} - -float Vis_Cloth(float NoV, float NoL) -{ - return rcp(4 * (NoL + NoV - NoL * NoV)); -} - #define REFLECTION_CAPTURE_NUM_MIPS 7 #define REFLECTION_CAPTURE_ROUGHEST_MIP 1 #define REFLECTION_CAPTURE_ROUGHNESS_MIP_SCALE 1.2 half ProbeMipFromRoughness(half roughness) { - half levelFrom1x1 = REFLECTION_CAPTURE_ROUGHEST_MIP - REFLECTION_CAPTURE_ROUGHNESS_MIP_SCALE * log2(roughness); - return REFLECTION_CAPTURE_NUM_MIPS - 1 - levelFrom1x1; + half mip1px = REFLECTION_CAPTURE_ROUGHEST_MIP - REFLECTION_CAPTURE_ROUGHNESS_MIP_SCALE * log2(roughness); + return REFLECTION_CAPTURE_NUM_MIPS - 1 - mip1px; } half SSRMipFromRoughness(half roughness) { - half levelFrom1x1 = 4 - REFLECTION_CAPTURE_ROUGHNESS_MIP_SCALE * log2(roughness); - return max(1, 10 - levelFrom1x1); + half mip1px = 4 - REFLECTION_CAPTURE_ROUGHNESS_MIP_SCALE * log2(roughness); + return max(1, 10 - mip1px); } float ComputeReflectionCaptureRoughnessFromMip(float mip) { - float levelFrom1x1 = REFLECTION_CAPTURE_NUM_MIPS - 1 - mip; - return exp2((REFLECTION_CAPTURE_ROUGHEST_MIP - levelFrom1x1) / REFLECTION_CAPTURE_ROUGHNESS_MIP_SCALE); + float mip1px = REFLECTION_CAPTURE_NUM_MIPS - 1 - mip; + return exp2((REFLECTION_CAPTURE_ROUGHEST_MIP - mip1px) / REFLECTION_CAPTURE_ROUGHNESS_MIP_SCALE); } // [Lazarov 2013, "Getting More Physical in Call of Duty: Black Ops II"] float3 EnvBRDFApprox(float3 specularColor, float roughness, float NoV) { // Approximate version, base for pre integrated version - const half4 c0 = {-1, -0.0275, -0.572, 0.022}; - const half4 c1 = {1, 0.0425, 1.04, -0.04}; + const half4 c0 = { -1, -0.0275, -0.572, 0.022 }; + const half4 c1 = { 1, 0.0425, 1.04, -0.04 }; half4 r = roughness * c0 + c1; half a004 = min(r.x * r.x, exp2(-9.28 * NoV)) * r.x + r.y; half2 ab = half2(-1.04, 1.04) * a004 + r.zw; return specularColor * ab.x + saturate(50.0 * specularColor.g) * ab.y; } -// Pre integrated environment GF +// Importance sampled preintegrated G * F float3 EnvBRDF(Texture2D preIntegratedGF, float3 specularColor, float roughness, float NoV) { - // Importance sampled preintegrated G * F float2 ab = preIntegratedGF.SampleLevel(SamplerLinearClamp, float2(NoV, roughness), 0).rg; return specularColor * ab.x + saturate(50.0 * specularColor.g) * ab.y; } @@ -231,29 +103,7 @@ float3 EnvBRDF(Texture2D preIntegratedGF, float3 specularColor, float roughness, float RoughnessToSpecularPower(float roughness) { - // TODO: use path tracer as a reference and calculate valid params for this conversion - return pow(2, 13 * (1 - roughness)); - -#if 0 - - float coeff = pow(4, roughness); - coeff = max(coeff, 2.0f / (MAX_SPECULAR_POWER + 2.0f)); - return 2.0f / coeff - 2.0f; - - //const float Log2Of1OnLn2_Plus1 = 1.52876637294; // log2(1 / ln(2)) + 1 - //return exp2(10 * roughness + Log2Of1OnLn2_Plus1); - - //return pow(2, 2 * (1 - roughness)); - return pow(2, 13 * (1 - roughness)); - - //return exp2(10 * roughness + 1); -#endif } -/* -float SpecularPowerToRoughness(float specularPower) -{ - return pow(-0.25f, specularPower * 0.5f + 1.0f); -} -*/ + #endif diff --git a/Source/Shaders/Collisions.hlsl b/Source/Shaders/Collisions.hlsl index a372d649b..7d5a36a52 100644 --- a/Source/Shaders/Collisions.hlsl +++ b/Source/Shaders/Collisions.hlsl @@ -18,67 +18,4 @@ bool RayHitRect(float3 r, float3 rectCenter, float3 rectX, float3 rectY, float3 return inExtentX && inExtentY; } -// Computes where a ray hits a sphere (which is centered at the origin). -// \param[in] rayOrigin The start position of the ray. -// \param[in] rayDirection The normalized direction of the ray. -// \param[in] radius The radius of the sphere. -// \param[out] enter The ray parameter where the ray enters the sphere. -// 0 if the ray is already in the sphere. -// \param[out] exit The ray parameter where the ray exits the sphere. -// \return 0 or a positive value if the ray hits the sphere. A negative value -// if the ray does not touch the sphere. -float HitSphere(float3 rayOrigin, float3 rayDirection, float radius, out float enter, out float exit) -{ - // Solve the equation: ||rayOrigin + distance * rayDirection|| = r - // - // This is a straight-forward quadratic equation: - // ||O + d * D|| = r - // => (O + d * D)2 = r2 where V2 means V.V - // => d2 * D2 + 2 * d * (O.D) + O2 - r2 = 0 - // D2 is 1 because the rayDirection is normalized. - // => d = -O.D + sqrt((O.D)2 - O2 + r2) - - float OD = dot(rayOrigin, rayDirection); - float OO = dot(rayOrigin, rayOrigin); - float radicand = OD * OD - OO + radius * radius; - enter = max(0, -OD - sqrt(radicand)); - exit = -OD + sqrt(radicand); - - // If radicand is negative then we do not have a result - no hit. - return radicand; -} - -// Clips a ray to an AABB. Does not handle rays parallel to any of the planes. -// -// @param rayOrigin - The origin of the ray in world space. -// @param rayEnd - The end of the ray in world space. -// @param boxMin - The minimum extrema of the box. -// @param boxMax - The maximum extrema of the box. -// @return - Returns the closest intersection along the ray in x, and furthest in y. -// If the ray did not intersect the box, then the furthest intersection <= the closest intersection. -// The intersections will always be in the range [0,1], which corresponds to [rayOrigin, rayEnd] in worldspace. -// To find the world space position of either intersection, simply plug it back into the ray equation: -// WorldPos = RayOrigin + (rayEnd - RayOrigin) * Intersection; -float2 LineBoxIntersect(float3 rayOrigin, float3 rayEnd, float3 boxMin, float3 boxMax) -{ - float3 invRayDir = 1.0f / (rayEnd - rayOrigin); - - //find the ray intersection with each of the 3 planes defined by the minimum extrema. - float3 planeIntersections1 = (boxMin - rayOrigin) * invRayDir; - //find the ray intersection with each of the 3 planes defined by the maximum extrema. - float3 planeIntersections2 = (boxMax - rayOrigin) * invRayDir; - //get the closest of these intersections along the ray - float3 closestPlaneIntersections = min(planeIntersections1, planeIntersections2); - //get the furthest of these intersections along the ray - float3 furthestPlaneIntersections = max(planeIntersections1, planeIntersections2); - - float2 boxIntersections; - //find the furthest near intersection - boxIntersections.x = max(closestPlaneIntersections.x, max(closestPlaneIntersections.y, closestPlaneIntersections.z)); - //find the closest far intersection - boxIntersections.y = min(furthestPlaneIntersections.x, min(furthestPlaneIntersections.y, furthestPlaneIntersections.z)); - //clamp the intersections to be between rayOrigin and RayEnd on the ray - return saturate(boxIntersections); -} - #endif diff --git a/Source/Shaders/ColorGrading.shader b/Source/Shaders/ColorGrading.shader index d86004a31..6e4204f79 100644 --- a/Source/Shaders/ColorGrading.shader +++ b/Source/Shaders/ColorGrading.shader @@ -45,31 +45,20 @@ Texture2D LutTexture : register(t0); // [Krystek 1985, "An algorithm to calculate correlated colour temperature"] float2 PlanckianLocusChromaticity(float temp) { - float u = ( 0.860117757f + 1.54118254e-4f * temp + 1.28641212e-7f * temp*temp ) / ( 1.0f + 8.42420235e-4f * temp + 7.08145163e-7f * temp*temp ); - float v = ( 0.317398726f + 4.22806245e-5f * temp + 4.20481691e-8f * temp*temp ) / ( 1.0f - 2.89741816e-5f * temp + 1.61456053e-7f * temp*temp ); - - float x = 3*u / ( 2*u - 8*v + 4 ); - float y = 2*v / ( 2*u - 8*v + 4 ); - - return float2(x,y); + float u = (0.860117757f + 1.54118254e-4f * temp + 1.28641212e-7f * temp * temp) / (1.0f + 8.42420235e-4f * temp + 7.08145163e-7f * temp * temp); + float v = (0.317398726f + 4.22806245e-5f * temp + 4.20481691e-8f * temp * temp) / (1.0f - 2.89741816e-5f * temp + 1.61456053e-7f * temp * temp); + float x = 3 * u / (2 * u - 8 * v + 4); + float y = 2 * v / (2 * u - 8 * v + 4); + return float2(x, y); } -// Accurate for 4000K < temp < 25000K -// in: correlated color temperature -// out: CIE 1931 chromaticity -float2 D_IlluminantChromaticity(float temp) +// Calculates chromaticity from temperature +float2 IlluminantChromaticity(float temp) { - // Correct for revision of Plank's law - // This makes 6500 == D65 temp *= 1.4388 / 1.438; - - float x = temp <= 7000 ? - 0.244063 + ( 0.09911e3 + ( 2.9678e6 - 4.6070e9 / temp ) / temp ) / temp : - 0.237040 + ( 0.24748e3 + ( 1.9018e6 - 2.0064e9 / temp ) / temp ) / temp; - - float y = -3 * x*x + 2.87 * x - 0.275; - - return float2(x,y); + float x = temp <= 7000 ? 0.244063 + (0.09911e3 + (2.9678e6 - 4.6070e9 / temp) / temp) / temp : 0.237040 + (0.24748e3 + (1.9018e6 - 2.0064e9 / temp) / temp) / temp; + float y = -3 * x * x + 2.87 * x - 0.275; + return float2(x, y); } // Find closest color temperature to chromaticity @@ -77,38 +66,31 @@ float2 D_IlluminantChromaticity(float temp) float CorrelatedColortemperature(float x, float y) { float n = (x - 0.3320) / (0.1858 - y); - return -449 * n*n*n + 3525 * n*n - 6823.3 * n + 5520.33; + return -449 * n * n * n + 3525 * n * n - 6823.3 * n + 5520.33; } +// [McCamy 1992, "Correlated color temperature as an explicit function of chromaticity coordinates"] float2 PlanckianIsothermal(float temp, float tint) { - float u = ( 0.860117757f + 1.54118254e-4f * temp + 1.28641212e-7f * temp*temp ) / ( 1.0f + 8.42420235e-4f * temp + 7.08145163e-7f * temp*temp ); - float v = ( 0.317398726f + 4.22806245e-5f * temp + 4.20481691e-8f * temp*temp ) / ( 1.0f - 2.89741816e-5f * temp + 1.61456053e-7f * temp*temp ); - - float ud = ( -1.13758118e9f - 1.91615621e6f * temp - 1.53177f * temp*temp ) / Square( 1.41213984e6f + 1189.62f * temp + temp*temp ); - float vd = ( 1.97471536e9f - 705674.0f * temp - 308.607f * temp*temp ) / Square( 6.19363586e6f - 179.456f * temp + temp*temp ); - - float2 uvd = normalize( float2( u, v ) ); - - // Correlated color temperature is meaningful within +/- 0.05 + float u = (0.860117757f + 1.54118254e-4f * temp + 1.28641212e-7f * temp * temp) / (1.0f + 8.42420235e-4f * temp + 7.08145163e-7f * temp * temp); + float v = (0.317398726f + 4.22806245e-5f * temp + 4.20481691e-8f * temp * temp) / (1.0f - 2.89741816e-5f * temp + 1.61456053e-7f * temp * temp); + float ud = (-1.13758118e9f - 1.91615621e6f * temp - 1.53177f * temp * temp) / Square(1.41213984e6f + 1189.62f * temp + temp * temp); + float vd = (1.97471536e9f - 705674.0f * temp - 308.607f * temp * temp) / Square(6.19363586e6f - 179.456f * temp + temp * temp); + float2 uvd = normalize(float2(u, v)); u += -uvd.y * tint * 0.05; v += uvd.x * tint * 0.05; - - float x = 3*u / ( 2*u - 8*v + 4 ); - float y = 2*v / ( 2*u - 8*v + 4 ); - + float x = 3 * u / (2 * u - 8 * v + 4); + float y = 2 * v / (2 * u - 8 * v + 4); return float2(x,y); } float3 WhiteBalance(float3 linearColor) { - float2 srcWhiteDaylight = D_IlluminantChromaticity(WhiteTemp); + float2 srcWhiteDaylight = IlluminantChromaticity(WhiteTemp); float2 srcWhitePlankian = PlanckianLocusChromaticity(WhiteTemp); float2 srcWhite = WhiteTemp < 4000 ? srcWhitePlankian : srcWhiteDaylight; float2 d65White = float2(0.31270, 0.32900); - - // Offset along isotherm float2 isothermal = PlanckianIsothermal(WhiteTemp, WhiteTint) - srcWhitePlankian; srcWhite += isothermal; @@ -280,7 +262,6 @@ float4 CombineLUTs(float2 uv, uint layerIndex) // Move from encoded LUT color space to linear color //float3 linearColor = encodedColor.rgb; // Default - //float3 linearColor = LogCToLinear(encodedColor.rgb); // LogC float3 linearColor = LogToLinear(encodedColor.rgb) - LogToLinear(0); // Log // Apply white balance diff --git a/Source/Shaders/Common.hlsl b/Source/Shaders/Common.hlsl index 79692d1ac..9d0365e98 100644 --- a/Source/Shaders/Common.hlsl +++ b/Source/Shaders/Common.hlsl @@ -196,25 +196,6 @@ struct Quad_GS2PS uint LayerIndex : SV_RenderTargetArrayIndex; }; -float VisualizeTextureGrid(float2 texCoord, float2 textureSize, float gridSize) -{ - if (gridSize > 0) - { - float2 t = frac(texCoord * textureSize); - return (t.x < gridSize || t.x > 1 - gridSize) || (t.y < gridSize || t.y > 1 - gridSize); - } - else - { - int2 t = int2(texCoord * textureSize); - return (t.x % 2 == 0 && t.y % 2 == 0) || (t.x % 2 == 1 && t.y % 2 == 1); - } -} - -float BiasedNDotL(float NoL) -{ - return saturate(NoL * 1.08f - 0.08f); -} - float Luminance(float3 color) { return dot(color, float3(0.299f, 0.587f, 0.114f)); diff --git a/Source/Shaders/GammaCorrectionCommon.hlsl b/Source/Shaders/GammaCorrectionCommon.hlsl index e08e902a1..7a1d1f6cf 100644 --- a/Source/Shaders/GammaCorrectionCommon.hlsl +++ b/Source/Shaders/GammaCorrectionCommon.hlsl @@ -9,73 +9,50 @@ // http://gpuopen.com/optimized-reversible-tonemapper-for-resolve/ float3 FastTonemap(float3 c) { - return c * rcp(max(max(c.r, c.g), c.b) + 1.0); + return c * rcp(max(max(c.r, c.g), c.b) + 1.0); } float4 FastTonemap(float4 c) { - return float4(FastTonemap(c.rgb), c.a); + return float4(FastTonemap(c.rgb), c.a); } float3 FastTonemap(float3 c, float w) { - return c * (w * rcp(max(max(c.r, c.g), c.b) + 1.0)); + return c * (w * rcp(max(max(c.r, c.g), c.b) + 1.0)); } float4 FastTonemap(float4 c, float w) { - return float4(FastTonemap(c.rgb, w), c.a); + return float4(FastTonemap(c.rgb, w), c.a); } float3 FastTonemapInvert(float3 c) { - return c * rcp(1.0 - max(max(c.r, c.g), c.b)); + return c * rcp(1.0 - max(max(c.r, c.g), c.b)); } float4 FastTonemapInvert(float4 c) { - return float4(FastTonemapInvert(c.rgb), c.a); + return float4(FastTonemapInvert(c.rgb), c.a); } -half3 LinearTo709Branchless(half3 linearColor) -{ - linearColor = max(6.10352e-5, linearColor); - return min(linearColor * 4.5, pow(max(linearColor, 0.018), 0.45) * 1.099 - 0.099); -} - -half3 LinearToSrgbBranchless(half3 linearColor) -{ - linearColor = max(6.10352e-5, linearColor); - return min(linearColor * 12.92, pow(max(linearColor, 0.00313067), 1.0/2.4) * 1.055 - 0.055); -} - -half LinearToSrgbBranchingChannel(half linearColor) +half LinearToSrgbChannel(half linearColor) { if (linearColor < 0.00313067) return linearColor * 12.92; - return pow(linearColor, (1.0/2.4)) * 1.055 - 0.055; + return pow(linearColor, (1.0 / 2.4)) * 1.055 - 0.055; } -half3 LinearToSrgbBranching(half3 linearColor) +half3 LinearToSrgb(half3 linearColor) { return half3( - LinearToSrgbBranchingChannel(linearColor.r), - LinearToSrgbBranchingChannel(linearColor.g), - LinearToSrgbBranchingChannel(linearColor.b)); + LinearToSrgbChannel(linearColor.r), + LinearToSrgbChannel(linearColor.g), + LinearToSrgbChannel(linearColor.b)); } -half3 LinearToSrgb(half3 linearColor) -{ -#if FEATURE_LEVEL >= FEATURE_LEVEL_SM4 - // Branching is faster than branchless on PC - return LinearToSrgbBranching(linearColor); -#else - // Use branchless on mobile - return LinearToSrgbBranchless(linearColor); -#endif -} - -half3 sRGBToLinear(half3 color) +half3 sRGBToLinear(half3 color) { color = max(6.10352e-5, color); return color > 0.04045 ? pow(color * (1.0 / 1.055) + 0.0521327, 2.4) : color * (1.0 / 12.92); @@ -103,7 +80,7 @@ float3 LinearToLog(float3 linearColor) const float exposureGrey = 444; // Using stripped down, 'pure log', formula. Parameterized by grey points and dynamic range covered. - float3 logColor = log2(linearColor) / linearRange - log2(linearGrey) / linearRange + exposureGrey / 1023.0; // scalar: 3log2 3mad + float3 logColor = log2(linearColor) / linearRange - log2(linearGrey) / linearRange + exposureGrey / 1023.0; // scalar: 3log2 3mad //float3 logColor = (log2(linearColor) - log2(linearGrey)) / linearRange + exposureGrey / 1023.0; //float3 logColor = log2(linearColor / linearGrey) / linearRange + exposureGrey / 1023.0; //float3 logColor = (0.432699 * log10(0.5 * linearColor + 0.037584) + 0.616596) + 0.03; // SLog @@ -113,74 +90,4 @@ float3 LinearToLog(float3 linearColor) return logColor; } -// Alexa LogC converters (El 1000) -// See http://www.vocas.nl/webfm_send/964 -// Max range is ~58.85666 - -struct ParamsLogC -{ - float cut; - float a, b, c, d, e, f; -}; - -static const ParamsLogC LogC = -{ - 0.011361, // cut - 5.555556, // a - 0.047996, // b - 0.244161, // c - 0.386036, // d - 5.301883, // e - 0.092819 // f -}; - -float3 LinearToLogC(float3 linearColor) -{ - return LogC.c * log10(LogC.a * linearColor + LogC.b) + LogC.d; -} - -float3 LogCToLinear(float3 logcColor) -{ - return (pow(10.0, (logcColor - LogC.d) / LogC.c) - LogC.b) / LogC.a; -} - -// Dolby PQ transforms -float3 ST2084ToLinear(float3 pq) -{ - const float m1 = 0.1593017578125; // = 2610. / 4096. * .25; - const float m2 = 78.84375; // = 2523. / 4096. * 128; - const float c1 = 0.8359375; // = 2392. / 4096. * 32 - 2413./4096.*32 + 1; - const float c2 = 18.8515625; // = 2413. / 4096. * 32; - const float c3 = 18.6875; // = 2392. / 4096. * 32; - const float C = 10000.; - - float3 Np = pow(pq, 1.0 / m2); - float3 L = Np - c1; - L = max(0.0, L); - L = L / (c2 - c3 * Np); - L = pow(L, 1.0 / m1); - float3 P = L * C; - - return P; -} - -float3 LinearToST2084(float3 lin) -{ - const float m1 = 0.1593017578125; // = 2610. / 4096. * .25; - const float m2 = 78.84375; // = 2523. / 4096. * 128; - const float c1 = 0.8359375; // = 2392. / 4096. * 32 - 2413./4096.*32 + 1; - const float c2 = 18.8515625; // = 2413. / 4096. * 32; - const float c3 = 18.6875; // = 2392. / 4096. * 32; - const float C = 10000.0; - - float3 L = lin / C; - float3 Lm = pow(L, m1); - float3 N1 = (c1 + c2 * Lm); - float3 N2 = (1.0 + c3 * Lm); - float3 N = N1 * rcp(N2); - float3 P = pow(N, m2); - - return P; -} - #endif diff --git a/Source/Shaders/Histogram.shader b/Source/Shaders/Histogram.shader index 32fb8eb1a..233983eb8 100644 --- a/Source/Shaders/Histogram.shader +++ b/Source/Shaders/Histogram.shader @@ -60,18 +60,6 @@ void CS_GenerateHistogram(uint3 groupId : SV_GroupID, uint3 dispatchThreadId : S if (dispatchThreadId.x < InputSize.x && dispatchThreadId.y < InputSize.y) { uint weight = 1u; - - // Vignette weighting to add more focus on the center of the screen -#if 0 - { - float2 uv = float2(dispatchThreadId.xy) / float2(InputSize.x, InputSize.y); - float2 d = abs(uv - (0.5).xx); - float factor = saturate(1.0 - dot(d, d)); - factor *= factor; - weight = (uint)(64.0 * factor); - } -#endif - float3 color = Input[dispatchThreadId.xy].xyz; float luminance = Luminance(color); float logLuminance = ComputeHistogramPositionFromLuminance(luminance); diff --git a/Source/Shaders/IESProfile.hlsl b/Source/Shaders/IESProfile.hlsl index f01be6aca..f1641a17e 100644 --- a/Source/Shaders/IESProfile.hlsl +++ b/Source/Shaders/IESProfile.hlsl @@ -3,19 +3,13 @@ #ifndef __IES_PROFILE__ #define __IES_PROFILE__ -// Apply 1D IES light profile texture +// Calculate IES light profile from 1D texture float ComputeLightProfileMultiplier(Texture2D tex, float3 worldPosition, float3 lightPosition, float3 lightDirection) { - float3 negLightDirection = normalize(worldPosition - lightPosition); - - // -1..1 - float dotProd = dot(negLightDirection, lightDirection); - // -PI..PI (this distortion could be put into the texture but not without quality loss or more memory) - float angle = asin(dotProd); - // 0..1 - float normAngle = angle / PI + 0.5f; - - return tex.SampleLevel(SamplerLinearClamp, float2(normAngle, 0), 0).r; + float3 l = normalize(worldPosition - lightPosition); + float d = dot(lightPosition, lightDirection); + float angle = asin(d) / PI + 0.5f; + return tex.SampleLevel(SamplerLinearClamp, float2(angle, 0), 0).r; } #endif diff --git a/Source/Shaders/LightingCommon.hlsl b/Source/Shaders/LightingCommon.hlsl index 43303d316..250715de7 100644 --- a/Source/Shaders/LightingCommon.hlsl +++ b/Source/Shaders/LightingCommon.hlsl @@ -47,8 +47,8 @@ struct LightingData // WorldLightVector is the vector from the position being shaded to the light, divided by the radius of the light. float RadialAttenuation(float3 worldLightVector, half falloffExponent) { - float normalizeDistanceSquared = dot(worldLightVector, worldLightVector); - return pow(1.0f - saturate(normalizeDistanceSquared), falloffExponent); + float t = dot(worldLightVector, worldLightVector); + return pow(1.0f - saturate(t), falloffExponent); } // Calculates attenuation for a spot light. Where L normalize vector to light. diff --git a/Source/Shaders/Math.hlsl b/Source/Shaders/Math.hlsl index 1287cc4af..a4bec9788 100644 --- a/Source/Shaders/Math.hlsl +++ b/Source/Shaders/Math.hlsl @@ -5,8 +5,8 @@ uint NextPow2(uint value) { - uint mask = (1 << firstbithigh(value)) - 1; - return (value + mask) & ~mask; + uint mask = (1 << firstbithigh(value)) - 1; + return (value + mask) & ~mask; } float3 SafeNormalize(float3 v) @@ -17,7 +17,6 @@ float3 SafeNormalize(float3 v) float3 ExtractLargestComponent(float3 v) { float3 a = abs(v); - if (a.x > a.y) { if (a.x > a.z) @@ -32,161 +31,160 @@ float3 ExtractLargestComponent(float3 v) return float3(0, v.y > 0 ? 1 : -1, 0); } } - return float3(0, 0, v.z > 0 ? 1 : -1); } float Square(float x) { - return x*x; + return x * x; } float2 Square(float2 x) { - return x*x; + return x * x; } float3 Square(float3 x) { - return x*x; + return x * x; } float4 Square(float4 x) { - return x*x; + return x * x; } float Pow2(float x) { - return x*x; + return x * x; } float2 Pow2(float2 x) { - return x*x; + return x * x; } float3 Pow2(float3 x) { - return x*x; + return x * x; } float4 Pow2(float4 x) { - return x*x; + return x * x; } float Pow3(float x) { - return x*x*x; + return x * x * x; } float2 Pow3(float2 x) { - return x*x*x; + return x * x * x; } float3 Pow3(float3 x) { - return x*x*x; + return x * x * x; } float4 Pow3(float4 x) { - return x*x*x; + return x * x * x; } float Pow4(float x) { - float xx = x*x; + float xx = x * x; return xx * xx; } float2 Pow4(float2 x) { - float2 xx = x*x; + float2 xx = x * x; return xx * xx; } float3 Pow4(float3 x) { - float3 xx = x*x; + float3 xx = x * x; return xx * xx; } float4 Pow4(float4 x) { - float4 xx = x*x; + float4 xx = x * x; return xx * xx; } float Pow5(float x) { - float xx = x*x; + float xx = x * x; return xx * xx * x; } float2 Pow5(float2 x) { - float2 xx = x*x; + float2 xx = x * x; return xx * xx * x; } float3 Pow5(float3 x) { - float3 xx = x*x; + float3 xx = x * x; return xx * xx * x; } float4 Pow5(float4 x) { - float4 xx = x*x; + float4 xx = x * x; return xx * xx * x; } float Pow6(float x) { - float xx = x*x; + float xx = x * x; return xx * xx * xx; } float2 Pow6(float2 x) { - float2 xx = x*x; + float2 xx = x * x; return xx * xx * xx; } float3 Pow6(float3 x) { - float3 xx = x*x; + float3 xx = x * x; return xx * xx * xx; } float4 Pow6(float4 x) { - float4 xx = x*x; + float4 xx = x * x; return xx * xx * xx; } -float ClampedPow(float x,float y) +float ClampedPow(float x, float y) { - return pow(max(abs(x), 0.000001f),y); + return pow(max(abs(x), 0.000001f), y); } -float2 ClampedPow(float2 x,float2 y) +float2 ClampedPow(float2 x, float2 y) { return pow(max(abs(x), float2(0.000001f, 0.000001f)), y); } -float3 ClampedPow(float3 x,float3 y) +float3 ClampedPow(float3 x, float3 y) { return pow(max(abs(x), float3(0.000001f, 0.000001f, 0.000001f)), y); -} +} -float4 ClampedPow(float4 x,float4 y) +float4 ClampedPow(float4 x, float4 y) { return pow(max(abs(x), float4(0.000001f, 0.000001f, 0.000001f, 0.000001f)), y); -} +} float4 FindQuatBetween(float3 from, float3 to) { @@ -208,8 +206,8 @@ float4 FindQuatBetween(float3 from, float3 to) { w = 0.f; result = abs(from.x) > abs(from.y) - ? float4(-from.z, 0.f, from.x, w) - : float4(0.f, -from.z, from.y, w); + ? float4(-from.z, 0.f, from.x, w) + : float4(0.f, -from.z, from.y, w); } return normalize(result); @@ -218,23 +216,13 @@ float4 FindQuatBetween(float3 from, float3 to) // Rotates Position about the given axis by the given angle, in radians, and returns the offset to position float3 RotateAboutAxis(float4 normalizedRotationAxisAndAngle, float3 positionOnAxis, float3 position) { - // Project position onto the rotation axis and find the closest point on the axis to Position - float3 closestPointOnAxis = positionOnAxis + normalizedRotationAxisAndAngle.xyz * dot(normalizedRotationAxisAndAngle.xyz, position - positionOnAxis); - - // Construct orthogonal axes in the plane of the rotation - float3 axisU = position - closestPointOnAxis; - float3 axisV = cross(normalizedRotationAxisAndAngle.xyz, axisU); - float cosAngle, sinAngle; - sincos(normalizedRotationAxisAndAngle.w, sinAngle, cosAngle); - - // Rotate using the orthogonal axes - float3 rotation = axisU * cosAngle + axisV * sinAngle; - - // Reconstruct the rotated world space position - float3 rotatedPosition = closestPointOnAxis + rotation; - - // Convert from position to a position offset - return rotatedPosition - position; + float3 pointOnAxis = positionOnAxis + normalizedRotationAxisAndAngle.xyz * dot(normalizedRotationAxisAndAngle.xyz, position - positionOnAxis); + float3 axisU = position - pointOnAxis; + float3 axisV = cross(normalizedRotationAxisAndAngle.xyz, axisU); + float cosAngle, sinAngle; + sincos(normalizedRotationAxisAndAngle.w, sinAngle, cosAngle); + float3 rotation = axisU * cosAngle + axisV * sinAngle; + return pointOnAxis + rotation - position; } #endif diff --git a/Source/Shaders/MonteCarlo.hlsl b/Source/Shaders/MonteCarlo.hlsl index 1faf7742b..e89f7770c 100644 --- a/Source/Shaders/MonteCarlo.hlsl +++ b/Source/Shaders/MonteCarlo.hlsl @@ -133,10 +133,10 @@ float4 ImportanceSampleGGX(float2 e, float roughness) // Multiple importance sampling power heuristic of two functions with a power of two. // [Veach 1997, "Robust Monte Carlo Methods for Light Transport Simulation"] -float MISWeight(uint number, float pdf, uint otherNumber, float otherpdf) +float MISWeight(uint number, float PDF, uint otherNumber, float otherPDF) { - float weight = number * pdf; - float otherWeight = otherNumber * otherpdf; + float weight = number * PDF; + float otherWeight = otherNumber * otherPDF; return weight * weight / (weight * weight + otherWeight * otherWeight); } diff --git a/Source/Shaders/PostProcessing.shader b/Source/Shaders/PostProcessing.shader index 7ac812f06..1993ff8e9 100644 --- a/Source/Shaders/PostProcessing.shader +++ b/Source/Shaders/PostProcessing.shader @@ -107,7 +107,6 @@ half3 ColorLookupTable(half3 linearColor) { // Move from linear color to encoded LUT color space //float3 encodedColor = linearColor; // Default - //float3 encodedColor = saturate(LinearToLogC(linearColor)); // LogC float3 encodedColor = LinearToLog(linearColor + LogToLinear(0)); // Log float3 uvw = encodedColor * ((LUTSize - 1) / LUTSize) + (0.5f / LUTSize); diff --git a/Source/Shaders/ProbesFilter.shader b/Source/Shaders/ProbesFilter.shader index 112cd9974..59cfe131b 100644 --- a/Source/Shaders/ProbesFilter.shader +++ b/Source/Shaders/ProbesFilter.shader @@ -25,44 +25,42 @@ float4 SampleCubemap(float3 uv) return Cube.SampleLevel(SamplerLinearClamp, uv, SourceMipIndex); } -float3 GetCubemapVector(float2 scaledUVs) +float3 GetCubemapVector(float2 uv) { - float3 cubeCoordinates; - + float3 coords; if (CubeFace == 0) { - cubeCoordinates = float3(1, -scaledUVs.y, -scaledUVs.x); + coords = float3(1, -uv.y, -uv.x); } else if (CubeFace == 1) { - cubeCoordinates = float3(-1, -scaledUVs.y, scaledUVs.x); + coords = float3(-1, -uv.y, uv.x); } else if (CubeFace == 2) { - cubeCoordinates = float3(scaledUVs.x, 1, scaledUVs.y); + coords = float3(uv.x, 1, uv.y); } else if (CubeFace == 3) { - cubeCoordinates = float3(scaledUVs.x, -1, -scaledUVs.y); + coords = float3(uv.x, -1, -uv.y); } else if (CubeFace == 4) { - cubeCoordinates = float3(scaledUVs.x, -scaledUVs.y, 1); + coords = float3(uv.x, -uv.y, 1); } else { - cubeCoordinates = float3(-scaledUVs.x, -scaledUVs.y, -1); + coords = float3(-uv.x, -uv.y, -1); } - - return cubeCoordinates; + return coords; } // Pixel Shader for filtring probe mip levels META_PS(true, FEATURE_LEVEL_ES2) float4 PS_FilterFace(Quad_VS2PS input) : SV_Target { - float2 scaledUVs = input.TexCoord * 2 - 1; - float3 cubeCoordinates = GetCubemapVector(scaledUVs); + float2 uv = input.TexCoord * 2 - 1; + float3 cubeCoordinates = GetCubemapVector(uv); #define NUM_FILTER_SAMPLES 512 @@ -102,10 +100,9 @@ float4 PS_CopyFace(Quad_VS2PS input) : SV_Target META_PS(true, FEATURE_LEVEL_ES2) float4 PS_CalcDiffuseIrradiance(Quad_VS2PS input) : SV_Target { - float2 scaledUVs = input.TexCoord * 2 - 1; - float3 cubeCoordinates = normalize(GetCubemapVector(scaledUVs)); - - float squaredUVs = 1 + dot(scaledUVs, scaledUVs); + float2 uv = input.TexCoord * 2 - 1; + float3 cubeCoordinates = normalize(GetCubemapVector(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); @@ -124,23 +121,23 @@ float4 PS_AccDiffuseIrradiance(Quad_VS2PS input) : SV_Target { float4 result = 0; { - float2 scaledUVs = saturate(input.TexCoord + Sample01.xy) * 2 - 1; - float3 cubeCoordinates = GetCubemapVector(scaledUVs); + float2 uv = saturate(input.TexCoord + Sample01.xy) * 2 - 1; + float3 cubeCoordinates = GetCubemapVector(uv); result += SampleCubemap(cubeCoordinates); } { - float2 scaledUVs = saturate(input.TexCoord + Sample01.zw) * 2 - 1; - float3 cubeCoordinates = GetCubemapVector(scaledUVs); + float2 uv = saturate(input.TexCoord + Sample01.zw) * 2 - 1; + float3 cubeCoordinates = GetCubemapVector(uv); result += SampleCubemap(cubeCoordinates); } { - float2 scaledUVs = saturate(input.TexCoord + Sample23.xy) * 2 - 1; - float3 cubeCoordinates = GetCubemapVector(scaledUVs); + float2 uv = saturate(input.TexCoord + Sample23.xy) * 2 - 1; + float3 cubeCoordinates = GetCubemapVector(uv); result += SampleCubemap(cubeCoordinates); } { - float2 scaledUVs = saturate(input.TexCoord + Sample23.zw) * 2 - 1; - float3 cubeCoordinates = GetCubemapVector(scaledUVs); + float2 uv = saturate(input.TexCoord + Sample23.zw) * 2 - 1; + float3 cubeCoordinates = GetCubemapVector(uv); result += SampleCubemap(cubeCoordinates); } return result / 4.0f; diff --git a/Source/Shaders/Random.hlsl b/Source/Shaders/Random.hlsl index 98eb0beba..01378ba09 100644 --- a/Source/Shaders/Random.hlsl +++ b/Source/Shaders/Random.hlsl @@ -24,14 +24,17 @@ float PerlinRamp(in float t) { return t * t * t * (t * (t * 6 - 15) + 10); } + float2 PerlinRamp(in float2 t) { return t * t * t * (t * (t * 6 - 15) + 10); } + float3 PerlinRamp(in float3 t) { return t * t * t * (t * (t * 6 - 15) + 10); } + float4 PerlinRamp(in float4 t) { return t * t * t * (t * (t * 6 - 15) + 10); diff --git a/Source/Shaders/SH.hlsl b/Source/Shaders/SH.hlsl index c845c5a5d..b038554db 100644 --- a/Source/Shaders/SH.hlsl +++ b/Source/Shaders/SH.hlsl @@ -11,21 +11,20 @@ struct ThreeBandSHVector half V2; }; -ThreeBandSHVector SHBasisFunction3(half3 inputVector) +ThreeBandSHVector SHBasisFunction3(half3 v) { ThreeBandSHVector result; result.V0.x = 0.282095f; - result.V0.y = -0.488603f * inputVector.y; - result.V0.z = 0.488603f * inputVector.z; - result.V0.w = -0.488603f * inputVector.x; + result.V0.y = -0.488603f * v.y; + result.V0.z = 0.488603f * v.z; + result.V0.w = -0.488603f * v.x; - half3 vectorSquared = inputVector * inputVector; - result.V1.x = 1.092548f * inputVector.x * inputVector.y; - result.V1.y = -1.092548f * inputVector.y * inputVector.z; - result.V1.z = 0.315392f * (3.0f * inputVector.z - 1.0f); - result.V1.w = -1.092548f * inputVector.x * inputVector.z; - result.V2 = 0.546274f * (inputVector.x - inputVector.y); + result.V1.x = 1.092548f * v.x * v.y; + result.V1.y = -1.092548f * v.y * v.z; + result.V1.z = 0.315392f * (3.0f * v.z - 1.0f); + result.V1.w = -1.092548f * v.x * v.z; + result.V2 = 0.546274f * (v.x - v.y); return result; } diff --git a/Source/Shaders/ShadowsCommon.hlsl b/Source/Shaders/ShadowsCommon.hlsl index ad83fb7e5..81b7d33ea 100644 --- a/Source/Shaders/ShadowsCommon.hlsl +++ b/Source/Shaders/ShadowsCommon.hlsl @@ -57,7 +57,6 @@ int GetCubeFaceIndex(float3 direction) float3 GetShadowPositionOffset(float offsetScale, float NoL, float3 normal) { - // Note: offsetScale should be multiplied by 2*ShadowMapTextureTexelSize on CPU float normalOffsetScale = saturate(1.0f - NoL); return normal * (offsetScale * normalOffsetScale); } @@ -65,8 +64,6 @@ float3 GetShadowPositionOffset(float offsetScale, float NoL, float3 normal) float CalculateSubsurfaceOcclusion(float opacity, float sceneDepth, float shadowMapDepth) { float thickness = max(sceneDepth - shadowMapDepth, 0); - //float density = -0.05f * log(1 - min(opacity, 0.999f)); - //float occlusion = saturate(exp(-thickness * density)); float occlusion = 1 - thickness * lerp(1.0f, 100.0f, opacity); return shadowMapDepth > 0.99f ? 1 : occlusion; } diff --git a/Source/Shaders/VolumetricFog.shader b/Source/Shaders/VolumetricFog.shader index 169e7db5e..cc07de293 100644 --- a/Source/Shaders/VolumetricFog.shader +++ b/Source/Shaders/VolumetricFog.shader @@ -103,30 +103,12 @@ float3 ComputeVolumeUV(float3 worldPosition, float4x4 worldToClip) return float3(ndcPosition.xy * float2(0.5f, -0.5f) + 0.5f, ComputeNormalizedZSliceFromDepth(ndcPosition.w)); } -float IsotropicPhase() -{ - return 1 / (4 * PI); -} - float HenyeyGreensteinPhase(float g, float cosTheta) { return (1 - g * g) / (4 * PI * pow(1 + g * g + 2 * g * cosTheta, 1.5f)); } -float SchlickPhase(float k, float cosTheta) -{ - float t = (1 + k * cosTheta); - return (1 - k * k) / (4 * PI * t * t); -} - -float RaleighPhase(float cosTheta) -{ - return 3.0f * (1.0f + cosTheta * cosTheta) / (16.0f * PI); -} - -// Positive g = forward scattering -// Zero g = isotropic -// Negative g = backward scattering +// +g = forward scattering, 0=g = isotropic, -g = backward scattering float PhaseFunction(float g, float cosTheta) { return HenyeyGreensteinPhase(g, cosTheta);