diff --git a/Source/Shaders/BRDF.hlsl b/Source/Shaders/BRDF.hlsl index e637422c2..2cf86adc7 100644 --- a/Source/Shaders/BRDF.hlsl +++ b/Source/Shaders/BRDF.hlsl @@ -12,19 +12,18 @@ float3 Diffuse_Lambert(float3 diffuseColor) // GGX / Trowbridge-Reitz // [Walter et al. 2007, "Microfacet models for refraction through rough surfaces"] -float D_GGX(float roughness, float NoH) +float D_GGX(float roughnessSq, float NoH) { - float a = roughness * roughness; - float a2 = a * a; + float a2 = roughnessSq * roughnessSq; float d = (NoH * a2 - NoH) * NoH + 1; return a2 / (PI * d * d); } // Tuned to match behavior of V_Smith // [Schlick 1994, "An Inexpensive BRDF Model for Physically-Based Rendering"] -float V_Schlick(float roughness, float NoV, float NoL) +float V_Schlick(float roughnessSq, float NoV, float NoL) { - float k = Square(roughness) * 0.5; + float k = roughnessSq * 0.5; float visSchlickV = NoV * (1 - k) + k; float visSchlickL = NoL * (1 - k) + k; return 0.25 / (visSchlickV * visSchlickL); @@ -32,10 +31,9 @@ float V_Schlick(float roughness, float NoV, float NoL) // Smith term for GGX // [Smith 1967, "Geometrical shadowing of a random rough surface"] -float V_Smith(float roughness, float NoV, float NoL) +float V_Smith(float roughnessSq, float NoV, float NoL) { - float a = Square(roughness); - float a2 = a * a; + float a2 = roughnessSq * roughnessSq; float visSmithV = NoV + sqrt(NoV * (NoV - NoV * a2) + a2); float visSmithL = NoL + sqrt(NoL * (NoL - NoL * a2) + a2); return rcp(visSmithV * visSmithL); @@ -43,11 +41,10 @@ float V_Smith(float roughness, float NoV, float NoL) // Appoximation of joint Smith term for GGX // [Heitz 2014, "Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs"] -float V_SmithJointApprox(float roughness, float NoV, float NoL) +float V_SmithJointApprox(float roughnessSq, float NoV, float NoL) { - float a = Square(roughness); - float visSmithV = NoL * (NoV * (1 - a) + a); - float visSmithL = NoV * (NoL * (1 - a) + a); + float visSmithV = NoL * (NoV * (1 - roughnessSq) + roughnessSq); + float visSmithL = NoV * (NoL * (1 - roughnessSq) + roughnessSq); return 0.5 * rcp(visSmithV + visSmithL); } diff --git a/Source/Shaders/Lighting.hlsl b/Source/Shaders/Lighting.hlsl index 7965a95e8..28b8a3feb 100644 --- a/Source/Shaders/Lighting.hlsl +++ b/Source/Shaders/Lighting.hlsl @@ -33,9 +33,10 @@ LightSample StandardShading(GBufferSample gBuffer, float energy, float3 L, float lighting.Specular = 0; #else float3 specularColor = GetSpecularColor(gBuffer); + float roughnessSq = Square(gBuffer.Roughness); float3 F = F_Schlick(specularColor, VoH); - float D = D_GGX(gBuffer.Roughness, NoH) * energy; - float Vis = V_SmithJointApprox(gBuffer.Roughness, NoV, NoL); + float D = D_GGX(roughnessSq, NoH) * energy; + float Vis = V_SmithJointApprox(roughnessSq, NoV, NoL); // TODO: apply energy compensation to specular (1.0 + specularColor * (1.0 / PreIntegratedGF.y - 1.0)) lighting.Specular = (D * Vis) * F; #endif @@ -67,7 +68,7 @@ LightSample FoliageShading(GBufferSample gBuffer, float energy, float3 L, float3 float3 subsurfaceColor = gBuffer.CustomData.rgb; float wrapNoL = saturate((-dot(N, L) + 0.5f) / 2.25); float VoL = dot(V, L); - float scatter = D_GGX(0.36, saturate(-VoL)); + float scatter = D_GGX(Square(0.36), saturate(-VoL)); lighting.Transmission = subsurfaceColor * (wrapNoL * scatter); #endif return lighting;