flutter3d
Showcase Changelog 38 packages API reference

WebGPU: the source

since 0.6.0 Backends

Regions the guide quotes: flag (line 39), read (line 49).

1/// The fourth backend, tried before WebGL2 only when a web build asks for
2/// it by name at compile time.
3///
4/// Quoted by `backend_webgpu.md` and shown whole in the Source tab.
5library;
6
7import 'package:flutter/widgets.dart';
8import 'package:flutter3d/flutter3d.dart';
9import 'package:flutter3d_showcase/src/demo/demo.dart';
10import 'package:vector_math/vector_math.dart';
12final class BackendWebgpuDemo extends ShowcaseDemo {
13 late final GraphicsDevice _device;
15 @override
16 Scene build(DemoContext context) {
17 _device = context.device;
18 final Material stone = Material(
19 name: 'stone',
20 baseColor: Vector4(0.55, 0.4, 0.65, 1.0),
21 roughness: 0.6,
22 );
23 final MeshNode ball = MeshNode(
24 DeviceMesh.upload(
25 context.device,
26 SphereShape(segments: 24, rings: 12).build(),
27 ),
28 stone,
29 name: 'ball',
30 );
31 return Scene()
32 ..add(ball)
33 ..add(
34 LightNode(name: 'sun', intensity: 3.0)
35 ..setLocalForward(Vector3(-0.4, -1.0, -0.3)),
36 );
37 }
39 // Trying WebGPU is a build-time choice, not a runtime one, because
40 // finding out whether a browser hands out an adapter means asking, and
41 // asking means the WebGPU device, its encoder and its WGSL are all
42 // reachable code the moment a build opts in:
43 //
44 // flutter build web --dart-define=FLUTTER3D_WEBGPU=true
45 //
46 // An ordinary build never registers it, so a build that did not ask never
47 // ships the bytes either.
49 String _report(GraphicsDevice device) =>
50 'wireframe: ${device.supportsWireframe}\n'
51 'blend constant: ${device.supportsBlendColor}\n'
52 'max colour attachments: ${device.maxColorAttachments}';
54 @override
55 Widget? customBody(
56 BuildContext buildContext,
57 DemoContext context,
58 ) => Container(
59 color: const Color(0xFF14161A),
60 padding: const EdgeInsets.all(24),
61 alignment: Alignment.topLeft,
62 child: DefaultTextStyle(
63 style: const TextStyle(color: Color(0xFFE8E8EC), fontSize: 16),
64 child: Text(
65 'WebGPU has a blend factor for a constant colour but no way to split '
66 'it between colour and alpha the way this engine\'s blend states '
67 'ask, and no polygon fill mode at all, so it declines a blend '
68 'constant and wireframe by name rather than quietly doing nothing '
69 'with either.\n\n'
70 'What the device actually open right now answers:\n\n'
71 '${_report(context.device)}',
72 ),
73 ),
74 );
76 @override
77 void verify(Scene scene, FrameResult frame) {
78 if (frame.drawCalls < 1) {
79 throw StateError('the ball was not drawn');
80 }
81 // A modern API opens several colour attachments in one pass; the one
82 // capability this page names, maxColorAttachments, has to actually
83 // answer more than the bare minimum on the device that opened.
84 if (_device.maxColorAttachments < 2) {
85 throw StateError(
86 'the open device answers fewer colour attachments than this page '
87 'claims a modern backend offers',
88 );
89 }
90 }