calculateIntensity method
Calculates the light contribution at a given surface point and normal.
Implementation
double calculateIntensity(Vector3 surfacePoint, Vector3 surfaceNormal) {
switch (type) {
case LightType.ambient:
final ground = groundColor;
if (ground == null) return intensity;
// Hemisphere blend on the scalar path: scale by the ground/sky
// luminance ratio for downward normals, full intensity upward.
final skyLum = _luminance(color);
final groundRatio = skyLum > 1e-6 ? _luminance(ground) / skyLum : 1.0;
final up = (surfaceNormal.y.clamp(-1.0, 1.0) + 1.0) * 0.5;
return intensity * (groundRatio + (1.0 - groundRatio) * up);
case LightType.directional:
final nDotL = surfaceNormal.dot(-direction);
return (nDotL * intensity).clamp(0.0, 1.0);
case LightType.point:
final lightPos = worldPosition;
final toLight = lightPos - surfacePoint;
final dist = toLight.length;
if (range > 0 && dist > range) return 0;
toLight.normalize();
final nDotL = surfaceNormal.dot(toLight);
final attenuation = range > 0
? (1 - (dist / range)).clamp(0.0, 1.0)
: 1 / (1 + dist * dist);
return (nDotL * intensity * attenuation).clamp(0.0, 1.0);
case LightType.spot:
final lightPos = worldPosition;
final toLight = (lightPos - surfacePoint)..normalize();
final spotCos = toLight.dot(-direction);
if (spotCos < (1 - spotAngle)) return 0;
final nDotL = surfaceNormal.dot(toLight);
return (nDotL * intensity * spotCos).clamp(0.0, 1.0);
}
}