calculateIntensity method

double calculateIntensity(
  1. Vector3 surfacePoint,
  2. Vector3 surfaceNormal
)

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);
  }
}