applyFog function

Vector3 applyFog(
  1. Vector3 color,
  2. Float32List v,
  3. ShaderBindings b
)

ApplyFog from color.glsl: fades color toward the fog with distance.

Exponential rather than linear, for the reason the GLSL gives: linear fog has a visible plane where it starts. The early return at zero density is not an optimisation — it is what keeps a scene with no fog byte-identical, which is what the golden sets are recorded against.

A height fog (P5) is the same fog with its density averaged over the ray in closed form, from the falloff in eye.w; nought there skips it, as the GLSL does, for the same reason the early return is there.

Implementation

Vector3 applyFog(Vector3 color, Float32List v, ShaderBindings b) {
  final fog = b.vec4('FogInfo', 'fog', Vector4.zero());
  var density = fog.w;
  if (density <= 0.0) return color;

  final falloff = b.vec4('FogInfo', 'eye', Vector4.zero()).w;
  if (falloff > 0.0) {
    final eyeY = b.vec4('FogInfo', 'eye', Vector4.zero()).y;
    final k = falloff * (v[kVWorld + 1] - eyeY);
    density *= k.abs() > 1e-3 ? (1.0 - math.exp(-k)) / k : 1.0 - 0.5 * k;
  }

  final t = math.exp(-density * eyeDistance(v, b)).clamp(0.0, 1.0);

  return Vector3(
    fog.x * (1.0 - t) + color.x * t,
    fog.y * (1.0 - t) + color.y * t,
    fog.z * (1.0 - t) + color.z * t,
  );
}