|
@@ -7,10 +7,21 @@ struct lightingInfo
|
|
|
#endif
|
|
|
};
|
|
|
|
|
|
-float computeDistanceLightFalloff(vec3 lightOffset, float lightDistanceSquared, float range)
|
|
|
+float computeDistanceLightFalloff(vec3 lightOffset, float lightDistanceSquared, float range, float inverseSquaredRange)
|
|
|
{
|
|
|
#ifdef USEPHYSICALLIGHTFALLOFF
|
|
|
float lightDistanceFalloff = 1.0 / ((lightDistanceSquared + 0.001));
|
|
|
+ #elif defined(USEGLTFLIGHTFALLOFF)
|
|
|
+ // Prevents infinity issues at 0.
|
|
|
+ const float minDistanceSquared = 0.01*0.01;
|
|
|
+ float lightDistanceFalloff = 1.0 / (max(lightDistanceSquared, minDistanceSquared));
|
|
|
+
|
|
|
+ float factor = lightDistanceSquared * inverseSquaredRange;
|
|
|
+ float attenuation = clamp(1.0 - factor * factor, 0., 1.);
|
|
|
+ attenuation *= attenuation;
|
|
|
+
|
|
|
+ // Smooth attenuation of the falloff defined by the range.
|
|
|
+ lightDistanceFalloff *= attenuation;
|
|
|
#else
|
|
|
float lightDistanceFalloff = max(0., 1.0 - length(lightOffset) / range);
|
|
|
#endif
|
|
@@ -18,7 +29,7 @@ float computeDistanceLightFalloff(vec3 lightOffset, float lightDistanceSquared,
|
|
|
return lightDistanceFalloff;
|
|
|
}
|
|
|
|
|
|
-float computeDirectionalLightFalloff(vec3 lightDirection, vec3 directionToLightCenterW, float cosHalfAngle, float exponent)
|
|
|
+float computeDirectionalLightFalloff(vec3 lightDirection, vec3 directionToLightCenterW, float cosHalfAngle, float exponent, float lightAngleScale, float lightAngleOffset)
|
|
|
{
|
|
|
float falloff = 0.0;
|
|
|
|
|
@@ -36,6 +47,15 @@ float computeDirectionalLightFalloff(vec3 lightDirection, vec3 directionToLightC
|
|
|
// not directional light type)
|
|
|
vec4 lightDirectionSpreadSG = vec4(-lightDirection * concentrationKappa, -concentrationKappa);
|
|
|
falloff = exp2(dot(vec4(directionToLightCenterW, 1.0), lightDirectionSpreadSG));
|
|
|
+ #elif defined(USEGLTFLIGHTFALLOFF)
|
|
|
+ // On the CPU
|
|
|
+ // float lightAngleScale = 1.0 f / max (0.001f, ( cosInner - cosOuter ));
|
|
|
+ // float lightAngleOffset = -cosOuter * angleScale;
|
|
|
+
|
|
|
+ float cd = dot(-lightDirection, directionToLightCenterW);
|
|
|
+ falloff = clamp(cd * lightAngleScale + lightAngleOffset, 0., 1.);
|
|
|
+ // smooth the transition
|
|
|
+ falloff *= falloff;
|
|
|
#else
|
|
|
float cosAngle = max(0.000000000000001, dot(-lightDirection, directionToLightCenterW));
|
|
|
if (cosAngle >= cosHalfAngle)
|
|
@@ -47,32 +67,46 @@ float computeDirectionalLightFalloff(vec3 lightDirection, vec3 directionToLightC
|
|
|
return falloff;
|
|
|
}
|
|
|
|
|
|
-lightingInfo computeLighting(vec3 viewDirectionW, vec3 vNormal, vec4 lightData, vec3 diffuseColor, vec3 specularColor, float rangeRadius, float roughness, float NdotV, vec3 reflectance0, vec3 reflectance90, float geometricRoughnessFactor, out float NdotL) {
|
|
|
+lightingInfo computeDirectionalLighting(vec3 viewDirectionW, vec3 vNormal, vec4 lightData, vec3 diffuseColor, vec3 specularColor, float lightRadius, float roughness, float NdotV, vec3 reflectance0, vec3 reflectance90, float geometricRoughnessFactor, out float NdotL) {
|
|
|
+ lightingInfo result;
|
|
|
+
|
|
|
+ float lightDistance = length(-lightData.xyz);
|
|
|
+ vec3 lightDirection = normalize(-lightData.xyz);
|
|
|
+
|
|
|
+ // Roughness
|
|
|
+ roughness = adjustRoughnessFromLightProperties(roughness, lightRadius, lightDistance);
|
|
|
+
|
|
|
+ // diffuse
|
|
|
+ vec3 H = normalize(viewDirectionW + lightDirection);
|
|
|
+ NdotL = clamp(dot(vNormal, lightDirection), 0.00000000001, 1.0);
|
|
|
+ float VdotH = clamp(dot(viewDirectionW, H), 0.0, 1.0);
|
|
|
+
|
|
|
+ float diffuseTerm = computeDiffuseTerm(NdotL, NdotV, VdotH, roughness);
|
|
|
+ result.diffuse = diffuseTerm * diffuseColor;
|
|
|
+
|
|
|
+ #ifdef SPECULARTERM
|
|
|
+ // Specular
|
|
|
+ float NdotH = clamp(dot(vNormal, H), 0.000000000001, 1.0);
|
|
|
+
|
|
|
+ vec3 specTerm = computeSpecularTerm(NdotH, NdotL, NdotV, VdotH, roughness, reflectance0, reflectance90, geometricRoughnessFactor);
|
|
|
+ result.specular = specTerm * diffuseColor;
|
|
|
+ #endif
|
|
|
+
|
|
|
+ return result;
|
|
|
+}
|
|
|
+
|
|
|
+lightingInfo computePointLighting(vec3 viewDirectionW, vec3 vNormal, vec4 lightData, vec3 diffuseColor, vec3 specularColor, float lightRadius, float roughness, float NdotV, vec3 reflectance0, vec3 reflectance90, float geometricRoughnessFactor, vec4 lightFalloff, out float NdotL) {
|
|
|
lightingInfo result;
|
|
|
|
|
|
- vec3 lightDirection;
|
|
|
- float attenuation = 1.0;
|
|
|
- float lightDistance;
|
|
|
+ vec3 lightOffset = lightData.xyz - vPositionW;
|
|
|
+ float lightDistanceSquared = dot(lightOffset, lightOffset);
|
|
|
+ float attenuation = computeDistanceLightFalloff(lightOffset, lightDistanceSquared, lightFalloff.x, lightFalloff.y);
|
|
|
|
|
|
- // Point
|
|
|
- if (lightData.w == 0.)
|
|
|
- {
|
|
|
- vec3 lightOffset = lightData.xyz - vPositionW;
|
|
|
- float lightDistanceSquared = dot(lightOffset, lightOffset);
|
|
|
- attenuation = computeDistanceLightFalloff(lightOffset, lightDistanceSquared, rangeRadius);
|
|
|
-
|
|
|
- lightDistance = sqrt(lightDistanceSquared);
|
|
|
- lightDirection = normalize(lightOffset);
|
|
|
- }
|
|
|
- // Directional
|
|
|
- else
|
|
|
- {
|
|
|
- lightDistance = length(-lightData.xyz);
|
|
|
- lightDirection = normalize(-lightData.xyz);
|
|
|
- }
|
|
|
+ float lightDistance = sqrt(lightDistanceSquared);
|
|
|
+ vec3 lightDirection = normalize(lightOffset);
|
|
|
|
|
|
// Roughness
|
|
|
- roughness = adjustRoughnessFromLightProperties(roughness, rangeRadius, lightDistance);
|
|
|
+ roughness = adjustRoughnessFromLightProperties(roughness, lightRadius, lightDistance);
|
|
|
|
|
|
// diffuse
|
|
|
vec3 H = normalize(viewDirectionW + lightDirection);
|
|
@@ -93,7 +127,7 @@ lightingInfo computeLighting(vec3 viewDirectionW, vec3 vNormal, vec4 lightData,
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
-lightingInfo computeSpotLighting(vec3 viewDirectionW, vec3 vNormal, vec4 lightData, vec4 lightDirection, vec3 diffuseColor, vec3 specularColor, float rangeRadius, float roughness, float NdotV, vec3 reflectance0, vec3 reflectance90, float geometricRoughnessFactor, out float NdotL) {
|
|
|
+lightingInfo computeSpotLighting(vec3 viewDirectionW, vec3 vNormal, vec4 lightData, vec4 lightDirection, vec3 diffuseColor, vec3 specularColor, float lightRadius, float roughness, float NdotV, vec3 reflectance0, vec3 reflectance90, float geometricRoughnessFactor, vec4 lightFalloff, out float NdotL) {
|
|
|
lightingInfo result;
|
|
|
|
|
|
vec3 lightOffset = lightData.xyz - vPositionW;
|
|
@@ -101,15 +135,15 @@ lightingInfo computeSpotLighting(vec3 viewDirectionW, vec3 vNormal, vec4 lightDa
|
|
|
|
|
|
// Distance falloff.
|
|
|
float lightDistanceSquared = dot(lightOffset, lightOffset);
|
|
|
- float attenuation = computeDistanceLightFalloff(lightOffset, lightDistanceSquared, rangeRadius);
|
|
|
+ float attenuation = computeDistanceLightFalloff(lightOffset, lightDistanceSquared, lightFalloff.x, lightFalloff.y);
|
|
|
|
|
|
// Directional falloff.
|
|
|
- float directionalAttenuation = computeDirectionalLightFalloff(lightDirection.xyz, directionToLightCenterW, lightDirection.w, lightData.w);
|
|
|
+ float directionalAttenuation = computeDirectionalLightFalloff(lightDirection.xyz, directionToLightCenterW, lightDirection.w, lightData.w, lightFalloff.z, lightFalloff.w);
|
|
|
attenuation *= directionalAttenuation;
|
|
|
|
|
|
// Roughness.
|
|
|
float lightDistance = sqrt(lightDistanceSquared);
|
|
|
- roughness = adjustRoughnessFromLightProperties(roughness, rangeRadius, lightDistance);
|
|
|
+ roughness = adjustRoughnessFromLightProperties(roughness, lightRadius, lightDistance);
|
|
|
|
|
|
// Diffuse
|
|
|
vec3 H = normalize(viewDirectionW + directionToLightCenterW);
|