Anisotropic texture filtering: the source
Open the live demo · Read the guide · View on GitHub
Regions the guide quotes: texture (line 30), floor (line 42), settings (line 68).
1/// Anisotropic filtering: a checkerboard floor that stays sharp toward the
2/// horizon.
3///
4/// Quoted by `texture_filtering.md` and shown whole in the Source tab.
5library;
7import 'dart:typed_data';
9import 'package:flutter3d/flutter3d.dart';
10import 'package:flutter3d_showcase/src/demo/demo.dart';
11import 'package:vector_math/vector_math.dart';
13final class TextureFilteringDemo extends ShowcaseDemo {
14 int anisotropyChoice = 3;
16 static const List<int> _levels = <int>[1, 2, 4, 8, 16];
17 static const int _size = 256;
20 void configureView(DemoContext context) {
21 context.orbit
22 ..distance = 3.0
23 ..yaw = 0.0
24 ..pitch = 0.07;
25 context.orbit.target.setValues(0.0, 0.2, 0.0);
26 }
29 Scene build(DemoContext context) {
30 final ByteData pixels = const CheckerboardTexture(
31 size: _size,
32 cell: 16,
33 ).encode();
34 final TextureHandle checks = context.device.createTextureFromPixels(
35 width: _size,
36 height: _size,
37 format: TextureFormat.r8g8b8a8UNormInt,
38 pixels: pixels,
39 mipLevels: MipChain.build(pixels, _size, _size),
40 )!;
42 final Material floor = Material(
43 name: 'checks',
44 albedo: checks,
45 albedoSampler: SamplerOptions.trilinearRepeat,
46 roughness: 0.9,
47 doubleSided: true,
48 );
49 final MeshNode ground = MeshNode(
50 DeviceMesh.upload(
51 context.device,
52 const PlaneShape(width: 60, depth: 60).build(),
53 ),
54 floor,
55 name: 'floor',
56 );
58 return Scene()
59 ..add(ground)
60 ..add(
61 LightNode(name: 'sun', intensity: 3.0)
62 ..setLocalForward(Vector3(-0.3, -1.0, -0.4)),
63 );
64 }
67 RenderSettings settings(DemoContext context) => RenderSettings(
68 anisotropy: _levels[anisotropyChoice],
69 );
72 List<DemoControl> controls(DemoContext context) => <DemoControl>[
73 ChoiceControl(
74 'Anisotropy',
75 options: <String>[for (final int level in _levels) '${level}x'],
76 index: () => anisotropyChoice,
77 onChanged: (int i) => anisotropyChoice = i,
78 ),
79 ];
82 void verify(Scene scene, FrameResult frame) {
83 final Material floor = scene.meshes.first.material;
84 if (floor.albedoSampler?.mipFilter != MipFilter.linear) {
85 throw StateError('the floor sampler does not blend mip levels');
86 }
87 if (_levels[anisotropyChoice] <= 1) {
88 throw StateError('anisotropy is off, so nothing here is filtered');
89 }
90 if (frame.drawCalls < 1) throw StateError('the floor was not drawn');
91 }
92}