B.002■ SIGNAL LOG ■--:--
← SIGNAL LOG
#0022025-03-15

Bridging Three.js and Flutter: Real-Time WebGL in a WebView

Three.jsFlutterWebGLMobile

Getting a physics-based 3D game running inside a Flutter WebView without killing performance. Here's the approach.

Most Flutter developers avoid WebView for anything complex. After shipping a real-time 3D penalty kick game inside one, I can tell you it's harder than it sounds — but very doable.

The fundamental problem is communication. Flutter and WebGL live in different worlds. The bridge is JavaScript channels: Flutter injects a JS interface, and your Three.js code calls it. Simple in theory, painful in practice because you have to serialize everything.

For game events (shoot, score, miss), I used a simple string protocol: "EVENT:shoot:power=85:angle=12". Parse on the Flutter side. Fast enough for game events, terrible for high-frequency data.

The physics layer (Rapier3D via WASM) runs entirely in WebGL. Flutter knows nothing about it. This is the right separation — keep the game logic self-contained, only push outcomes to Flutter.

Performance was the real challenge. Rapier3D WASM has a cold start cost. I preload the WASM module during the Flutter splash screen. By the time the user reaches the game, it's already initialized.

Rendering budget: I cap at 30fps on mobile instead of trying for 60. Users don't notice the difference in a casual game, but battery life definitely does.

The ACESFilmic tone mapping was the biggest visual upgrade. It compresses the dynamic range so the scene looks cinematic even with cheap lighting. Single line of code, huge difference.

POST #002YY.DEV