flutter3d
Showcase Changelog 38 packages API reference

Rough metals and rough clay: the source

since 0.8.0 Shading and materials

Regions the guide quotes: metals (line 34), clay (line 50), light (line 65), settings (line 73).

1/// Gold from polished to rough above, grey clay from half rough to fully rough
2/// below: the two frame settings that keep rough surfaces from losing light.
3///
4/// Quoted by `rough_surfaces.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 RoughSurfacesDemo extends ShowcaseDemo {
12 bool compensate = true;
13 bool orenNayar = true;
15 static const List<double> _metalRoughness = <double>[0.1, 0.3, 0.5, 0.7, 0.9];
16 static const List<double> _clayRoughness = <double>[0.5, 0.75, 1.0];
18 @override
19 void configureView(DemoContext context) {
20 context.orbit
21 ..distance = 7.0
22 ..yaw = 0.0
23 ..pitch = 0.05;
24 }
26 @override
27 Scene build(DemoContext context) {
28 final DeviceMesh ball = DeviceMesh.upload(
29 context.device,
30 SphereShape(radius: 0.5, segments: 48, rings: 24).build(),
31 );
32 final Scene scene = Scene()..ambientIntensity = 0.1;
34 for (var i = 0; i < _metalRoughness.length; i++) {
35 scene.add(
36 MeshNode(
37 ball,
38 Material(
39 name: 'gold ${_metalRoughness[i]}',
40 lighting: LightingModel.pbr,
41 baseColor: Vector4(1.0, 0.78, 0.34, 1.0),
42 metallic: 1.0,
43 roughness: _metalRoughness[i],
44 ),
45 name: 'gold',
46 )..setPosition((i - 2) * 1.15, 0.65, 0.0),
47 );
48 }
50 for (var i = 0; i < _clayRoughness.length; i++) {
51 scene.add(
52 MeshNode(
53 ball,
54 Material(
55 name: 'clay ${_clayRoughness[i]}',
56 lighting: LightingModel.pbr,
57 baseColor: Vector4(0.42, 0.42, 0.42, 1.0),
58 roughness: _clayRoughness[i],
59 ),
60 name: 'clay',
61 )..setPosition((i - 1) * 1.15, -0.65, 0.0),
62 );
63 }
65 return scene..add(
66 LightNode(name: 'key', intensity: 3.0)
67 ..setLocalForward(Vector3(-0.3, -0.4, -1.0).normalized()),
68 );
69 }
71 @override
72 RenderSettings settings(DemoContext context) => RenderSettings(
73 energyCompensation: compensate,
74 diffuseModel: orenNayar ? DiffuseModel.eon : DiffuseModel.lambert,
75 );
77 @override
78 List<DemoControl> controls(DemoContext context) => <DemoControl>[
79 ToggleControl(
80 'Energy compensation',
81 value: () => compensate,
82 onChanged: (bool v) => compensate = v,
83 ),
84 ToggleControl(
85 'Energy-preserving diffuse',
86 value: () => orenNayar,
87 onChanged: (bool v) => orenNayar = v,
88 ),
89 ];
91 @override
92 void verify(Scene scene, FrameResult frame) {
93 final FramePass? pass = frame.passes
94 .where((FramePass p) => p.name == 'scene')
95 .firstOrNull;
96 final int spheres = _metalRoughness.length + _clayRoughness.length;
97 if (pass == null || pass.drawCalls < spheres) {
98 throw StateError('the scene pass did not draw all $spheres spheres');
99 }
100 }