Bloom and halation: the source
Open the live demo · Read the guide · View on GitHub
Regions the guide quotes: lamp (line 24), glow (line 46), reach (line 48), halation (line 49).
1/// Bloom: the light that is brighter than the display spills over its edge.
2///
3/// Quoted by `bloom.md` and shown whole in the Source tab.
4library;
6import 'package:flutter3d/flutter3d.dart';
7import 'package:flutter3d_showcase/pages/post/post_stage.dart';
8import 'package:flutter3d_showcase/src/demo/demo.dart';
9import 'package:vector_math/vector_math.dart';
11final class BloomDemo extends ShowcaseDemo {
12 double threshold = 1.0;
13 double intensity = 0.35;
14 double halation = 0.0;
15 int levels = 5;
18 void configureView(DemoContext context) => PostStage.frame(context);
21 Scene build(DemoContext context) {
22 final PostStage stage = PostStage.build(context);
24 // Hung on the side the sun comes from, so the lit faces of the shapes turn
25 // towards the glow: the lamp itself lights nothing.
26 final MeshNode lamp = MeshNode(
27 DeviceMesh.upload(
28 context.device,
29 const SphereShape(radius: 0.25, segments: 24, rings: 12).build(),
30 ),
31 Material(
32 name: 'lamp',
33 baseColor: Vector4(0.1, 0.1, 0.1, 1.0),
34 emissive: Vector3(1.0, 0.85, 0.6),
35 emissiveStrength: 9.0,
36 ),
37 name: 'lamp',
38 )..setPosition(1.0, 2.3, 0.7);
40 return stage.scene..add(lamp);
41 }
44 RenderSettings settings(DemoContext context) => RenderSettings(
45 bloom: BloomSettings(
46 threshold: threshold,
47 intensity: intensity,
48 levels: levels,
49 halation: halation,
50 ),
51 );
54 List<DemoControl> controls(DemoContext context) => <DemoControl>[
55 SliderControl(
56 'Threshold',
57 min: 0,
58 max: 4,
59 value: () => threshold,
60 onChanged: (double v) => threshold = v,
61 ),
62 SliderControl(
63 'Intensity',
64 min: 0,
65 max: 1.5,
66 value: () => intensity,
67 onChanged: (double v) => intensity = v,
68 ),
69 SliderControl(
70 'Reach (levels)',
71 min: 1,
72 max: 7,
73 divisions: 6,
74 value: () => levels.toDouble(),
75 onChanged: (double v) => levels = v.round(),
76 format: (double v) => '${v.round()}',
77 ),
78 SliderControl(
79 'Halation',
80 min: 0,
81 max: 1,
82 value: () => halation,
83 onChanged: (double v) => halation = v,
84 ),
85 ];
88 void verify(Scene scene, FrameResult frame) {
89 if (!passRan(frame, 'bloom')) {
90 throw StateError('the bloom pass did not run: ${frame.skipped}');
91 }
92 }
93}