flutter3d
Showcase Changelog 38 packages API reference

Depth of field: the source

since 0.7.0 Post-processing

Regions the guide quotes: row (line 27), lens (line 53), ran (line 91).

1/// Depth of field from a thin lens: a focus distance, a focal length and an
2/// f-number, the same three numbers a photographer already knows.
3///
4/// Quoted by `depth_of_field.md` and shown whole in the Source tab.
5library;
6
7import 'package:flutter3d/flutter3d.dart';
8import 'package:flutter3d_showcase/src/demo/demo.dart';
9import 'package:vector_math/vector_math.dart';
11final class DepthOfFieldDemo extends ShowcaseDemo {
12 double focusDistance = 4.0;
13 double aperture = 2.0;
14 double focalLength = 0.085;
16 @override
17 void configureView(DemoContext context) {
18 context.orbit
19 ..distance = 4.0
20 ..pitch = 0.0
21 ..yaw = 0.0;
22 context.orbit.target.setValues(0.0, 0.0, -4.0);
23 }
25 @override
26 Scene build(DemoContext context) {
27 final Scene scene = Scene();
28 final DeviceMesh post = DeviceMesh.upload(
29 context.device,
30 CuboidShape(size: Vector3(0.4, 1.6, 0.4)).build(),
31 );
32 for (var i = 0; i < 6; i++) {
33 final double z = -1.0 - i * 2.0;
34 scene.add(
35 MeshNode(
36 post,
37 Material(
38 name: 'post $i',
39 baseColor: Vector4(0.85, 0.4 + i * 0.08, 0.2, 1.0),
40 ),
41 name: 'post $i',
42 )..setPosition(0.0, 0.0, z),
43 );
44 }
45 return scene..add(
46 LightNode(name: 'sun', intensity: 3.0)
47 ..setLocalForward(Vector3(-0.3, -0.7, -0.4)),
48 );
49 }
51 @override
52 RenderSettings settings(DemoContext context) => RenderSettings(
53 depthOfField: DepthOfFieldSettings(
54 enabled: true,
55 focusDistance: focusDistance,
56 focalLength: focalLength,
57 aperture: aperture,
58 ),
59 );
61 @override
62 List<DemoControl> controls(DemoContext context) => <DemoControl>[
63 SliderControl(
64 'Focus distance',
65 min: 1,
66 max: 11,
67 value: () => focusDistance,
68 onChanged: (double v) => focusDistance = v,
69 format: (double v) => '${v.toStringAsFixed(1)} m',
70 ),
71 SliderControl(
72 'Aperture (f/)',
73 min: 1.4,
74 max: 16,
75 value: () => aperture,
76 onChanged: (double v) => aperture = v,
77 format: (double v) => v.toStringAsFixed(1),
78 ),
79 SliderControl(
80 'Focal length',
81 min: 0.024,
82 max: 0.135,
83 value: () => focalLength,
84 onChanged: (double v) => focalLength = v,
85 format: (double v) => '${(v * 1000).round()} mm',
86 ),
87 ];
89 @override
90 void verify(Scene scene, FrameResult frame) {
91 if (!frame.passes.any((FramePass p) => p.name == 'depth of field')) {
92 throw StateError('the depth of field pass did not run: ${frame.skipped}');
93 }
94 }