evaluateMaterial function

List<double> evaluateMaterial(
  1. MaterialProgram program,
  2. MaterialSurfaceValues surface
)

The colour program returns for one fragment: rgb the light the surface emits, a its opacity.

program must already be through specialiseMaterial — a parameter has no value until a variant gives it one, and a backend picking a default here would be a backend disagreeing with the compiled shader.

Implementation

List<double> evaluateMaterial(
  MaterialProgram program,
  MaterialSurfaceValues surface,
) {
  final scope = <String, List<double>>{};
  for (final statement in program.body) {
    switch (statement) {
      case MaterialLet(:final name, :final value):
        scope[name] = _evaluate(value, surface, scope);
      case MaterialReturn(:final value):
        return _evaluate(value, surface, scope);
    }
  }
  // The parser refuses a body whose last statement is not a return, so this is
  // a program nobody parsed rather than a case with a sensible answer.
  throw StateError('"${program.name}" has no return.');
}