flutter3d
Showcase Changelog 38 packages API reference

Ambient light

since 0.4.3 Shading and materials

Scene.ambientColor and Scene.ambientIntensity are the flat term a surface falls back to wherever no direct light reaches it. They are what keeps the far side of a lit object from going pure black, and the only light source in a scene that otherwise has none at all.

Step 1: One light, and a side it never reaches #

A single key light from one side leaves the far side of the ball with nothing but the ambient term to read by. That is what makes the effect visible: a scene lit evenly from everywhere would show nothing when the ambient term changed.

// One light from one side only, so the far side of the ball is lit by
// nothing but the ambient term below.
_scene = Scene()
  ..add(ball)
  ..add(
    LightNode(name: 'key', intensity: 3.0)
      ..setLocalForward(Vector3(-0.8, -0.2, -0.2)),
  )
  ..ambientColor = Vector3(0.55, 0.65, 1.0)
  ..ambientIntensity = ambientIntensity;

Step 2: Move the slider #

ambientIntensity is read back into the scene every frame, so raising it lifts exactly the shadowed side and leaves the lit side alone.

_scene.ambientIntensity = ambientIntensity;

Step 3: What this page checks #

The test cannot compare two pictures, so it checks the wiring instead: the scene's ambient intensity is the number the slider set, and there really is only one direct light, which is what leaves a side for the ambient term to fill in the first place.

if (scene.ambientIntensity != ambientIntensity) {
  throw StateError('the scene ambient did not track the slider');
}
if (scene.lights.length != 1) {
  throw StateError(
    'this page needs exactly one direct light to leave a '
    'side for the ambient term to fill',
  );
}
if (frame.drawCalls < 1) {
  throw StateError('the ball was not drawn');
}