| name | threejs-webgpu-rendering |
| description | Guide for implementing Three.js WebGPU/WebGL rendering with mobile-first optimization. Use this when working with 3D rendering, WebGPU initialization, renderer configuration, or graphics performance. |
Three.js WebGPU Rendering for Mobile Games
This skill provides guidance for implementing high-performance 3D rendering using Three.js with WebGPU (primary) and WebGL 2 (fallback) for mobile-first browser games.
Technology Stack
- Three.js r182+ with WebGPU support
- WebGPU API for modern browsers (iOS 26+, Chrome 121+ Android)
- WebGL 2.0 fallback for 95%+ device coverage
WebGPU Feature Detection and Initialization
Always implement progressive enhancement with proper fallbacks:
async function initializeRenderer(): Promise<THREE.WebGPURenderer | THREE.WebGLRenderer> {
if (navigator.gpu) {
try {
const adapter = await navigator.gpu.requestAdapter({
powerPreference: 'high-performance'
});
if (adapter) {
console.log('WebGPU available');
const renderer = new THREE.WebGPURenderer({
antialias: deviceTier > 1,
alpha: false,
stencil: false,
powerPreference: 'high-performance'
});
await renderer.init();
return renderer;
}
} catch (err) {
console.warn('WebGPU initialization failed:', err);
}
}
console.log('Using WebGL 2 fallback');
return new THREE.WebGLRenderer({
antialias: true,
powerPreference: 'high-performance'
});
}
Mobile-First Renderer Configuration
const pixelRatio = Math.min(window.devicePixelRatio, 2.0);
renderer.setPixelRatio(pixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setAnimationLoop(animate);
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.toneMappingExposure = 1.0;
Device Tier Classification
Detect and classify devices for adaptive quality:
| Tier | Devices | Target FPS |
|---|
| 1 (Flagship) | iPhone 14+, Snapdragon 8 Gen 2+, A16+ | 60 fps |
| 2 (Mid-Range) | iPhone SE 2022, Snapdragon 778G, A15 | 45 fps |
| 3 (Budget) | iPhone 11, Snapdragon 695, A13 | 30 fps |
function detectDeviceTier(): 'high' | 'medium' | 'low' {
const gpu = (navigator as any).gpu;
const memory = (navigator as any).deviceMemory || 4;
const cores = navigator.hardwareConcurrency || 4;
if (gpu && memory >= 8 && cores >= 6) return 'high';
if (memory >= 4 && cores >= 4) return 'medium';
return 'low';
}
Level of Detail (LOD) System
Implement LOD for maintaining visual fidelity at distance:
| Distance | Triangles | Texture Res | Shadows |
|---|
| 0-20 units | 8000 | 2048x2048 | Full |
| 20-50 units | 2000 | 1024x1024 | Medium |
| 50+ units | 500 | 512x512 | None |
const lod = new THREE.LOD();
const highDetail = createMesh(highGeometry, highMaterial);
lod.addLevel(highDetail, 0);
const mediumDetail = createMesh(mediumGeometry, mediumMaterial);
lod.addLevel(mediumDetail, 20);
const lowDetail = createMesh(lowGeometry, lowMaterial);
lod.addLevel(lowDetail, 50);
scene.add(lod);
Shadow Mapping Configuration
Optimize shadows based on device tier:
light.castShadow = true;
light.shadow.mapSize.width = 1024;
light.shadow.mapSize.height = 1024;
Progressive Enhancement Strategy
WebGPU Available:
- Full visual fidelity with advanced shaders (WGSL)
- Compute-based particle systems
- High-resolution shadow maps (1024x1024)
- Post-processing effects (bloom, depth of field)
WebGL 2 Fallback:
- Simplified lighting model
- Reduced particle count (50% density)
- Lower shadow resolution (512x512)
- Disabled post-processing
WebGL 1 Emergency Fallback:
- Basic Phong shading
- No dynamic shadows
- Minimal particles
- Maintain 30fps minimum
Import Pattern for WebGPU
import * as THREE from 'three/webgpu';
import { pass, texture, uniform } from 'three/tsl';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
Performance Optimization Techniques
- Geometry Instancing - For crowds and repeated objects
- Texture Atlasing - Reduce texture binding overhead
- Frustum Culling - Eliminate off-screen draw calls
- Dynamic Shadow Resolution - Based on FPS monitoring
- Object Pooling - Reuse objects to prevent GC
- Static Batching - Mark static objects for optimization
mesh.static = true;
const instancedMesh = new THREE.InstancedMesh(geometry, material, count);
Asset Loading Best Practices
const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath('/draco/');
const gltfLoader = new GLTFLoader();
gltfLoader.setDRACOLoader(dracoLoader);
const ktx2Loader = new KTX2Loader();
ktx2Loader.setTranscoderPath('/basis/');
References