Babylon.js Project — Interactive 3D Product Viewer
In this tutorial, you will learn about Babylon.js Project. We cover key concepts, practical examples, and best practices to help you master this topic.
This project walks through building a full-featured 3D product viewer with Babylon.js, combining model loading, interactive controls, GUI overlays, animations, and physics interactions.
What You'll Learn
By the end of this project, you will architect a 3D viewer application, load and display 3D models with PBR materials, implement orbit and zoom controls, build material switching UI, add physics-based interaction, and deploy a performant 3D web app.
Viewer Architecture
var ProductViewer = {
scene: null,
camera: null,
engine: null,
currentModel: null,
config: {
modelUrl: './models/product.glb',
defaultColor: '#4ecdc4',
autoRotate: true
},
init: function(canvasId) {
this.engine = new BABYLON.Engine(document.getElementById(canvasId), true);
this.scene = new BABYLON.Scene(this.engine);
this.setupCamera();
this.setupLighting();
this.setupGUI();
this.loadModel();
this.engine.runRenderLoop(this.render.bind(this));
},
setupCamera: function() {
this.camera = new BABYLON.ArcRotateCamera('camera', -Math.PI/2, Math.PI/3, 5, BABYLON.Vector3.Zero(), this.scene);
this.camera.attachControl(this.engine.getRenderingCanvas(), true);
this.camera.lowerRadiusLimit = 2;
this.camera.upperRadiusLimit = 10;
}
};
Material Switching
function switchMaterial(color) {
if (!currentModel) return;
currentModel.material = new BABYLON.PBRMaterial('pbr', scene);
currentModel.material.albedoColor = BABYLON.Color3.FromHexString(color);
currentModel.material.metallic = 0.6;
currentModel.material.roughness = 0.3;
}
Common Mistakes
1. Not Handling Mobile Touch
Mobile users need touch-friendly controls. Use pinch-zoom and one-finger orbit.
2. No Loading State
Large models take time to load. Show a skeleton UI or loading spinner.
3. Not Disposing Previous Model
Switching models without disposing the previous one causes memory leaks.
4. Auto-Rotate During Interaction
Disable auto-rotate when the user interacts with the model or GUI.
5. Ignoring GUI Scale
GUI elements sized in pixels may be too small on 4K screens. Use adaptive sizing.
Practice Questions
Q1: How do you structure a Babylon.js application? A: Use a main controller object with methods for setup, loading, and interaction.
Q2: How do you switch between materials? A: Replace the mesh.material property with a new StandardMaterial or PBRMaterial.
Q3: How do you handle window resize? A: Call engine.resize() on window resize event.
Q4: How do you auto-rotate the camera? A: In the render loop, increment camera.alpha by a small amount.
Q5: How do you add environment Reflection? A: Use BABYLON.Scene.createDefaultEnvironment() with environmentTexture.
Challenge: Add a color picker that lets users change the product color. Also add a texture toggle (matte vs gloss) that changes the roughness and metallic values.
FAQ
Try It Yourself
Build a product viewer with material switching.
<!DOCTYPE html>
<html>
<head>
<title>3D Product Viewer</title>
<script src="https://cdn.babylonjs.com/babylon.js"></script>
<style>
body { margin: 0; overflow: hidden; font-family: sans-serif; }
canvas { width: 100%; height: 100vh; display: block; }
.ui { position: absolute; bottom: 20px; left: 50%; transform: translateX(-50%); display: flex; gap: 10px; }
.ui button { padding: 10px 20px; border: none; border-radius: 8px; color: white; font-weight: bold; cursor: pointer; box-shadow: 0 2px 8px rgba(0,0,0,0.2); }
.ui .c1 { background: #4ecdc4; } .ui .c2 { background: #ff6b35; } .ui .c3 { background: #2a9d8f; } .ui .c4 { background: #e8a87c; }
.ui button:hover { transform: scale(1.05); }
.info { position: absolute; top: 20px; left: 20px; color: white; background: rgba(0,0,0,0.5); padding: 8px 16px; border-radius: 8px; font-size: 14px; }
</style>
</head>
<body>
<div class="info">Drag to orbit | Scroll to zoom</div>
<div class="ui">
<button class="c1" onclick="changeColor('#4ecdc4')">Teal</button>
<button class="c2" onclick="changeColor('#ff6b35')">Orange</button>
<button class="c3" onclick="changeColor('#2a9d8f')">Green</button>
<button class="c4" onclick="changeColor('#e8a87c')">Sand</button>
</div>
<canvas id="renderCanvas"></canvas>
<script>
var canvas = document.getElementById('renderCanvas');
var engine = new BABYLON.Engine(canvas, true);
var scene = new BABYLON.Scene(engine);
var camera = new BABYLON.ArcRotateCamera('camera', -Math.PI/2, Math.PI/3, 6, BABYLON.Vector3.Zero(), scene);
camera.attachControl(canvas, true);
camera.lowerRadiusLimit = 2;
camera.upperRadiusLimit = 12;
var light = new BABYLON.HemisphericLight('light', new BABYLON.Vector3(0, 1, 0), scene);
light.intensity = 0.6;
var envLight = new BABYLON.DirectionalLight('env', new BABYLON.Vector3(-1, -2, -1), scene);
envLight.intensity = 0.4;
// Create a base model (sphere since we can't load external files easily)
var sphere = BABYLON.MeshBuilder.CreateSphere('product', { diameter: 1.5 }, scene);
sphere.position.y = 0.5;
var ground = BABYLON.MeshBuilder.CreateGround('ground', { width: 6, height: 6 }, scene);
var groundMat = new BABYLON.StandardMaterial('groundMat', scene);
groundMat.diffuseColor = new BABYLON.Color3(0.95, 0.95, 0.95);
ground.material = groundMat;
// PBR material for product
var pbr = new BABYLON.PBRMaterial('pbr', scene);
pbr.albedoColor = new BABYLON.Color3.FromHexString('#4ecdc4');
pbr.metallic = 0.5;
pbr.roughness = 0.3;
pbr.environmentIntensity = 0.7;
sphere.material = pbr;
// Auto-rotate
var autoRotate = true;
var lastInteraction = 0;
camera.onViewMatrixChangedObservable.add(function() {
lastInteraction = Date.now();
autoRotate = false;
});
scene.registerBeforeRender(function() {
if (autoRotate) {
camera.alpha += 0.005;
} else if (Date.now() - lastInteraction > 3000) {
autoRotate = true;
}
});
function changeColor(hex) {
pbr.albedoColor = BABYLON.Color3.FromHexString(hex);
}
window.addEventListener('resize', function() { engine.resize(); });
engine.runRenderLoop(function() { scene.render(); });
</script>
</body>
</html>
What's Next
Explore PixiJS for 2D rendering.
Getting Started — 2D rendering with PixiJS.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro