flutter3d
Showcase Changelog 38 packages API reference

Post effects on your own image: the source

since 0.7.0 Post-processing

Regions the guide quotes: source (line 37), screen (line 61), first (line 82), post (line 96), answer (line 141).

1/// Post effects on an image of your own: one render, then `renderPost` over the
2/// result, then the answer shown on a screen in the scene.
3///
4/// Quoted by `render_post.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 RenderPostDemo extends ShowcaseDemo {
12 double threshold = 0.6;
13 double intensity = 0.6;
14 double exposure = 1.0;
16 static const int _width = 320;
17 static const int _height = 180;
19 late final Scene _source;
20 late final RenderView _sourceView;
21 late final TextureHandle _output;
23 /// What the last call to `renderPost` handed back.
24 PostFrameResult? result;
26 @override
27 void configureView(DemoContext context) {
28 context.orbit
29 ..distance = 2.3
30 ..pitch = 0.0
31 ..yaw = 0.0;
32 context.orbit.target.setValues(0.0, 0.0, 0.0);
33 }
35 @override
36 Scene build(DemoContext context) {
37 final CameraNode eye = CameraNode(name: 'source eye')
38 ..setPosition(0.0, 0.0, 4.0);
39 _source = Scene()
40 ..add(
41 MeshNode(
42 DeviceMesh.upload(
43 context.device,
44 CuboidShape(size: Vector3(2.4, 0.5, 0.2)).build(),
45 ),
46 Material(
47 name: 'bar',
48 baseColor: Vector4(0.0, 0.0, 0.0, 1.0),
49 emissive: Vector3(1.0, 0.55, 0.2),
50 emissiveStrength: 6.0,
51 ),
52 name: 'bar',
53 ),
54 )
55 ..add(eye);
56 _sourceView = RenderView(
57 camera: eye,
58 clearColor: Vector4(0.0, 0.0, 0.0, 1.0),
59 );
61 _output = context.device.createTexture(
62 RenderTargetSpec(
63 width: _width,
64 height: _height,
65 format: context.device.defaultColorFormat,
66 ),
67 );
68 final MeshNode screen = MeshNode(
69 DeviceMesh.upload(
70 context.device,
71 CuboidShape(size: Vector3(3.2, 1.8, 0.02)).build(),
72 ),
73 Material(name: 'screen', lighting: LightingModel.unlit, albedo: _output),
74 name: 'screen',
75 );
77 return Scene()..add(screen);
78 }
80 @override
81 void update(DemoContext context, double dt) {
82 final TextureHandle picture = context.renderer
83 .render(
84 width: _width,
85 height: _height,
86 scene: _source,
87 views: <RenderView>[_sourceView],
88 settings: const RenderSettings(
89 bloom: BloomSettings(enabled: false),
90 shadows: ShadowSettings(enabled: false),
91 tonemap: false,
92 ),
93 )
94 .frame;
96 result = context.renderer.renderPost(
97 hdr: picture,
98 target: _output,
99 settings: RenderSettings(
100 exposure: exposure,
101 bloom: BloomSettings(threshold: threshold, intensity: intensity),
102 ),
103 );
104 }
106 @override
107 RenderSettings settings(DemoContext context) => const RenderSettings(
108 bloom: BloomSettings(enabled: false),
109 shadows: ShadowSettings(enabled: false),
110 tonemap: false,
111 exposure: 1.0,
112 );
114 @override
115 List<DemoControl> controls(DemoContext context) => <DemoControl>[
116 SliderControl(
117 'Threshold',
118 min: 0.1,
119 max: 1.5,
120 value: () => threshold,
121 onChanged: (double v) => threshold = v,
122 ),
123 SliderControl(
124 'Intensity',
125 min: 0,
126 max: 1.5,
127 value: () => intensity,
128 onChanged: (double v) => intensity = v,
129 ),
130 SliderControl(
131 'Exposure',
132 min: 0.3,
133 max: 3,
134 value: () => exposure,
135 onChanged: (double v) => exposure = v,
136 ),
137 ];
139 @override
140 void verify(Scene scene, FrameResult frame) {
141 final PostFrameResult? post = result;
142 if (post == null) {
143 throw StateError('renderPost was never called');
144 }
145 if (!identical(post.frame, _output)) {
146 throw StateError('renderPost drew somewhere other than the target');
147 }
148 }