// hemisphere light

Hemisphere light

A hemisphere light is a soft, position-less light that blends two colors by which way a surface faces: a sky color on surfaces facing up and a ground color on surfaces facing down, blending through the middle. It is a cheap way to get natural-looking shading and to keep the undersides of shapes from going pure black.

It has no position and no falloff. It lights the whole scene evenly, like ambient light that has a direction. It replaces the skyColor / groundColor parameters that Fiber3DCanvas had in 0.1.x.

// demo

Demo

A sphere and a chamfered box lit by a hemisphere light only: the blue sky color on top, the orange-brown ground color underneath, and a blend through the middle.

// how to use it

How to use it

Add a Fiber3DHemisphereLight to the canvas's lights list. In practice you will combine it with other lights:

dart
Fiber3DCanvas(
  lights: const [
    Fiber3DHemisphereLight(
      skyColor: 0x88aaff,
      groundColor: 0x443322,
      intensity: 1.0,
    ),
    Fiber3DPointLight(
      color: 0xffffff,
      intensity: 3.0,
      position: Fiber3DVector3(3, 4, 5),
    ),
  ],
  // ...
)

The demo below uses only a hemisphere light, with no other light and environment reflections turned off, so you can see the sky and ground tint on its own:

dart
import 'package:flutter/material.dart';
import 'package:flutter_fiber/flutter_fiber.dart';

void main() => runApp(const HemisphereLightDemo());

/// Only a hemisphere light: no ambient, no point light, and environment
/// reflections switched off (envMapIntensity: 0.0), so the sky/ground tint
/// is the only thing you see.
class HemisphereLightDemo extends StatelessWidget {
  const HemisphereLightDemo({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(title: const Text('flutter_fiber: HemisphereLight')),
        body: Fiber3DCanvas(
          backgroundColor: 0x202020,
          camera: Fiber3DCamera(
            position: const Fiber3DVector3(0, 0, 6),
            target: const Fiber3DVector3.zero(),
          ),
          orbitEnabled: true,
          lights: const [
            Fiber3DHemisphereLight(
              skyColor: 0x4488ff,      // blue on surfaces facing up
              groundColor: 0xaa5522,   // orange-brown on surfaces facing down
              intensity: 1.0,
              direction: Fiber3DVector3(0, 1, 0), // "up"
            ),
          ],
          children: [
            Fiber3DMesh(
              geometry: Fiber3DSphere(radius: 1.1),
              material: Fiber3DStandardMaterial(
                color: 0xffffff,
                roughness: 1.0,
                metalness: 0.0,
                envMapIntensity: 0.0,
              ),
              showEdges: false,
              onFrame: (elapsed, delta, transform) {
                transform.position.set(-1.6, 0, 0);
                transform.rotation.y += (delta.inMicroseconds / 1e6) * 0.4;
              },
            ),
            Fiber3DMesh(
              geometry: Fiber3DChamferedBox(
                width: 1.7,
                height: 1.7,
                depth: 1.7,
                chamferAmount: 0.3,
              ),
              material: Fiber3DStandardMaterial(
                color: 0xffffff,
                roughness: 1.0,
                metalness: 0.0,
                envMapIntensity: 0.0,
              ),
              showEdges: false,
              onFrame: (elapsed, delta, transform) {
                transform.position.set(1.6, 0, 0);
                transform.rotation.y += (delta.inMicroseconds / 1e6) * 0.4;
              },
            ),
          ],
        ),
      ),
    );
  }
}

// parameters

Parameters

skyColor

default 0xffffff

Color blended onto surfaces that face toward direction (the "sky" side).

groundColor

default 0x444444

Color blended onto surfaces that face away from direction (the "ground" side).

intensity

default 1.0

Strength of the light.

direction

default Fiber3DVector3(0, 1, 0)

World-space direction that counts as "up". Pass a normalized vector (length 1).

// tips & limits

Tips & limits

  • Only the first hemisphere light in the list is used. Extra ones are ignored.
  • It affects Fiber3DStandardMaterial only. The other materials ignore it.
  • The direction is in world space, so the sky color stays on top no matter how a shape rotates.
  • In the demo, envMapIntensity: 0.0 switches off the material's environment reflections so the hemisphere tint is the only light you see. In a real scene you normally leave it at its default.
  • Subtle colors (a pale blue sky and a warm dark ground) look natural. The strong blue and orange in the demo are there to make the effect obvious.