renderTree method
void
renderTree(
- Canvas canvas
)
override
Implementation
@override
void renderTree(Canvas canvas) {
final componentLights =
_visibleLight.where(_isLightRenderable).toList(growable: false);
final lightSources = _lightSources
.where((light) => light.enabled && _isLightSourceVisible(light))
.toList(growable: false);
if (componentLights.isEmpty && lightSources.isEmpty) {
if (_debug) {
_renderDebug(canvas, const [], _resolveOccluders());
}
return;
}
final occluders =
componentLights.any((light) => light.lighting.config!.castShadows) ||
lightSources.any((light) => light.config.castShadows)
? _resolveOccluders()
: const <LightingOccluder>[];
final additive = <_PendingLight>[];
final cutout = <_PendingLight>[];
for (final light in componentLights) {
final config = light.lighting.config!;
final pending = _resolveLight(
config: config,
center: light.absoluteCenter + config.align,
angle: light.lighting.angle,
occluders: occluders,
);
if (pending == null) {
continue;
}
(config.mode == LightingMode.additive ? additive : cutout).add(pending);
}
for (final light in lightSources) {
final config = light.config;
final pending = _resolveLight(
config: config,
center: light.position + config.align,
angle: light.angle,
occluders: occluders,
);
if (pending == null) {
continue;
}
(config.mode == LightingMode.additive ? additive : cutout).add(pending);
}
// Additive lights are composited *below* the ambient darkness, so the
// ambient color darkens them instead of the light being painted on top of
// the night color.
if (additive.isNotEmpty) {
canvas.saveLayer(bounds, paint);
canvas.save();
_applyCameraTransform(canvas);
for (final light in additive) {
_renderLight(canvas, light, cutout: false);
}
canvas.restore();
canvas.restore();
}
// A cutout light only makes sense when there is ambient darkness to erase.
if (_containColor) {
canvas.saveLayer(bounds, paint);
canvas.drawColor(color!, BlendMode.dstATop);
canvas.save();
_applyCameraTransform(canvas);
for (final light in cutout) {
_renderLight(canvas, light, cutout: true);
}
canvas.restore();
canvas.restore();
}
if (_debug) {
_renderDebug(canvas, [...additive, ...cutout], occluders);
}
}