Flutter's 3D Rendering Landscape Splits Into Two Camps: Widget-First vs. Game-First
After yesterday's release of "Flutter's New True 3D Implementation: Building a 'Minecraft' with flutter_scene", many people wondered: has Flutter become a game engine? In reality, the main application scenario is not gaming, although it can indeed be used to make 3D games. For example, besides the bdero/flutter_scene mentioned yesterday that can build a 'Minecraft', there is another project called redstone_dart, which implements a Minecraft mod rewritten in Dart with a hot load feature:
In fact, the current application of 3D effects in Flutter is more like the following. Because it uses the same underlying rendering as Flutter, based on flutter_gpu, it can seamlessly render corresponding 3D models within the same memory:
This is actually the more useful scenario for 3D capabilities in Flutter right now. Of course, the image above uses another Flutter 3D rendering library, kiddo4/glint. Yes, yet another one.
*So although the official team hasn't promoted
flutter_gputhemselves, the community has already produced many successful cases. Especially after Impeller finally added support for the Windows desktop,flutter_gpuhas essentially completed its support for full-platform app scenarios.
This kiddo4/glint is also a Flutter-first 3D rendering engine, also based on flutter_gpu, rendering glTF/GLB models natively directly within the Widget tree. It's just more direct compared to bdero/flutter_scene:
It manages 3D scenes as ordinary Flutter state (
setStateto swap materials, Widgets anchored to model surfaces, etc.), while providing a backend-agnostic set of contracts for physics, animation, particles, and audio, combined with an optional native Box3D physics backend and a SoLoud audio backend to form a complete lightweight game engine.
The main implementation of kiddo4/glint's rendering core, GlintGpuFirstLight and GlintGameView (multi-instance game loop), is similar to:
- First, asynchronously decode GLB, textures, and HDR environment maps, and upload vertices, indices, and textures all at once as GPU resident resources.
- Then, each frame only updates uniforms (MVP matrix, lighting, material factors) and calls
RenderPass.draw(), minimizing per-frame overhead. - Directional light shadows are rendered to a color texture using a separate CommandBuffer and RenderPass, with depth manually written into the red channel instead of sampling the native depth attachment. This avoids a native crash issue where two RenderPasses sharing one CommandBuffer currently occurs in Flutter GPU.
- IBL ambient light is decoded from
.hdr, combined with pre-filtered irradiance/specular maps for PBR shader sampling. - Triangle data on the CPU side is retained for Möller–Trumbore ray intersection, used for click picking and Label3D occlusion judgment.
- Physics/animation/particles/audio are all defined as pure Dart backend-agnostic contracts, such as
GlintPhysicsWorld.glint_box3d/glint_soloud/glint_basiscan serve as pluggable native implementations. - C++ extensions are compiled at build time using Dart 3.x's native assets.
- Shaders either use built-in pre-compiled
.shaderbundlefiles, or users write their own JSON Shader Graph, which is compiled offline into an Impeller shader package byshader_graph_build.dartinhook/build.dart.
Overall, kiddo4/glint is indeed much more lightweight than bdero/flutter_scene. After all, bdero/flutter_scene is really aimed at gaming.
So kiddo4/glint is a general-purpose scene graph setup. It can't make games, but it is more lightweight, belonging to the Flutter-widget-first category where scenes can be declared as Flutter state.
bdero/flutter_scene, on the other hand, is more heavyweight. Although it can also be implemented as a Widget, bdero/flutter_scene can conversely embed Flutter Widgets directly into a game, seamlessly:
For example, below are two animations of a freely controllable Dash that I easily added to a Flutter App using bdero/flutter_scene and kiddo4/glint:
So, it's time to level up your Flutter App.
Top 1 from juejin.cn, machine-translated. The original thread is authoritative.
Embedding a Flutter widget inside a game is wonderfully bizarre [thinking]