Babylon.js 89,603 (9.28.0, Apache-2.0) offers WebGPUEngine beside its WebGL Engine: create it with new BABYLON.WebGPUEngine(canvas), await engine.initAsync(), and the rest of a Babylon scene is unchanged. According to its documentation, most of Babylon's main shaders are now written in WGSL; custom GLSL shaders are converted by a downloaded WebAssembly tool, which costs startup time. Its WebGPU-only snapshot rendering (engine.snapshotRendering = true) records one frame's draw calls and replays them, saving JavaScript time but not GPU time, the same trade-off When Bundles Help measured for render bundles. Babylon.js builds the BookNest virtual bookstore on Babylon; load it as the UMD babylonjs build, since its +esm CDN transform hangs in headless Chrome 1 .
<!doctype html>
<style>
body { margin: 0; background: #f7f4ee; font: 13px system-ui, sans-serif; }
.stage { position: relative; width: 100%; max-width: 600px; }
canvas { display: block; width: 100%; height: 340px; outline: none; }
#note { position: absolute; left: 10px; top: 8px; color: #222; background: rgba(247,244,238,0.85); padding: 2px 6px; border-radius: 4px; }
</style>
<div class="stage">
<canvas id="view"></canvas>
<div id="note">Starting Babylon.js...</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/babylonjs@9.28.0/babylon.js"></script>
<script>
const canvas = document.getElementById('view');
const note = document.getElementById('note');
function createScene(engine) { // identical for WebGPUEngine and Engine
const scene = new BABYLON.Scene(engine);
scene.clearColor = new BABYLON.Color4(0.97, 0.96, 0.93, 1);
const camera = new BABYLON.ArcRotateCamera('camera', -Math.PI / 2.4, 1.2, 7, new BABYLON.Vector3(0, 0.9, 0), scene);
camera.attachControl(canvas, true);
camera.useAutoRotationBehavior = true;
new BABYLON.HemisphericLight('sky', new BABYLON.Vector3(0.3, 1, -0.4), scene).intensity = 1.1;
const wood = new BABYLON.StandardMaterial('wood', scene);
wood.diffuseColor = new BABYLON.Color3(0.55, 0.36, 0.2);
const plank = BABYLON.MeshBuilder.CreateBox('plank', { width: 4.4, height: 0.12, depth: 1 }, scene);
plank.material = wood;
const colors = ['#1f5f8b', '#5c4099', '#b5452e', '#e0990f', '#2d5d2a', '#299e8f', '#7a3b69', '#2e6bc4'];
colors.forEach((hex, i) => {
const height = 1.1 + (i % 3) * 0.18;
const book = BABYLON.MeshBuilder.CreateBox(`book${i}`, { width: 0.34, height, depth: 0.8 }, scene);
book.position = new BABYLON.Vector3(-1.9 + i * 0.5, height / 2 + 0.06, 0);
const material = new BABYLON.StandardMaterial(`cover${i}`, scene);
material.diffuseColor = BABYLON.Color3.FromHexString(hex);
material.specularColor = new BABYLON.Color3(0.15, 0.15, 0.15);
book.material = material;
});
return scene;
}
async function main() {
let engine, backend;
if (navigator.gpu && (await navigator.gpu.requestAdapter())) {
try {
engine = new BABYLON.WebGPUEngine(canvas, { antialias: true });
await engine.initAsync(); // the only WebGPU-specific step
backend = 'Babylon.js WebGPUEngine';
} catch (error) {
engine = null; // for example, a helper it could not load in this sandbox
backend = `WebGPUEngine failed (${error.message || error}); using the WebGL Engine`;
}
} else {
backend = 'WebGPU is not available in this browser: using the WebGL Engine';
}
if (!engine) engine = new BABYLON.Engine(canvas, true);
note.textContent = backend;
const scene = createScene(engine);
engine.runRenderLoop(() => scene.render());
addEventListener('resize', () => engine.resize());
}
main();
</script>