FXAA and sharpen: the source
Open the live demo · Read the guide · View on GitHub
Regions the guide quotes: card (line 38), settings (line 62), reported (line 83).
1/// FXAA: edges smoothed on the finished picture, and a sharpen pass that
2/// shares its taps.
3///
4/// Quoted by `anti_aliasing.md` and shown whole in the Source tab.
5library;
7import 'dart:math' as math;
9import 'package:flutter3d/flutter3d.dart';
10import 'package:flutter3d_showcase/src/demo/demo.dart';
11import 'package:vector_math/vector_math.dart';
13final class AntiAliasingDemo extends ShowcaseDemo {
14 bool enabled = true;
15 double sharpen = 0.0;
17 /// One diagonal card staircases at exactly one contrast step, over one
18 /// edge — too little for either pass to read as more than noise at a
19 /// glance. A dozen thin spokes cross that same centre at a dozen
20 /// different angles, so every angle a staircase can take is on screen at
21 /// once, and the same handful of pixels near the middle carry all of
22 /// them where the effect is easiest to see.
23 static const int _spokes = 14;
26 void configureView(DemoContext context) {
27 // Close enough that the spokes fill the frame — softening a single
28 // pixel-wide edge is not something a reader can see without leaning on
29 // the zoom this page never offered a reason to reach for.
30 context.orbit
31 ..distance = 1.5
32 ..pitch = 0.0
33 ..yaw = 0.0;
34 }
37 Scene build(DemoContext context) {
38 final DeviceMesh spoke = DeviceMesh.upload(
39 context.device,
40 CuboidShape(size: Vector3(0.1, 2.8, 0.1)).build(),
41 );
42 final Material material = Material(
43 name: 'spokes',
44 baseColor: Vector4(0.95, 0.95, 0.95, 1.0),
45 lighting: LightingModel.unlit,
46 );
47 final Scene scene = Scene();
48 for (var i = 0; i < _spokes; i++) {
49 // Only half a turn: a spoke through the origin looks the same rotated
50 // by pi, so a full turn would draw every angle twice.
51 final double angle = i / _spokes * math.pi;
52 scene.add(
53 MeshNode(spoke, material, name: 'spoke $i')
54 ..setLocalMatrix(Matrix4.rotationZ(angle)),
55 );
56 }
57 return scene;
58 }
61 RenderSettings settings(DemoContext context) => RenderSettings(
62 antiAlias: AntiAliasSettings(enabled: enabled, sharpen: sharpen),
63 );
66 List<DemoControl> controls(DemoContext context) => <DemoControl>[
67 ToggleControl(
68 'FXAA',
69 value: () => enabled,
70 onChanged: (bool v) => enabled = v,
71 ),
72 SliderControl(
73 'Sharpen',
74 min: 0,
75 max: 1,
76 value: () => sharpen,
77 onChanged: (double v) => sharpen = v,
78 ),
79 ];
82 void verify(Scene scene, FrameResult frame) {
83 final bool ran = frame.antiAliasing.fxaa;
84 if (ran != enabled) {
85 throw StateError(
86 'the frame reports fxaa: $ran while the page asked '
87 'for $enabled',
88 );
89 }
90 }
91}