shadowViewProjection method

Matrix4 shadowViewProjection(
  1. Vector3 worldPosition,
  2. Vector3 worldDirection
)

The world -> clip matrix that renders and samples this spot's perspective shadow map, for a light at worldPosition aimed along worldDirection (both from the owning node's transform). The frustum is the cone, a vertical field of view of twice outerConeAngle (with a small margin) and a square aspect, out to range (or a default when the range is infinite).

Implementation

Matrix4 shadowViewProjection(Vector3 worldPosition, Vector3 worldDirection) {
  final length = worldDirection.length;
  final dir = length == 0.0
      ? Vector3(0.0, -1.0, 0.0)
      : worldDirection / length;
  final up = dir.y.abs() > 0.99
      ? Vector3(0.0, 0.0, 1.0)
      : Vector3(0.0, 1.0, 0.0);
  final view = DirectionalLight._lookAt(
    worldPosition,
    worldPosition + dir,
    up,
  );
  final far = range > 0.0 ? range : 100.0;
  // A small margin past the outer cone so its lit edge sits inside the
  // frustum rather than on its clipped border.
  final fovY = math.min(2.0 * outerConeAngle * 1.05, math.pi * 0.98);
  final projection = PerspectiveProjection(
    fovRadiansY: fovY,
    near: shadowNear,
    far: far,
  ).getProjectionMatrix(1.0);
  return projection * view;
}