Skip to main content

3D Rendering (Three.js)

GameByte uses Three.js for 3D game rendering with WebGL/WebGPU support.

Basic Setup

import { createGame } from '@gamebyte/framework';
import * as THREE from 'three';

const game = createGame();
await game.initialize(canvas, '3d');

const renderer = game.make('renderer');
const scene = renderer.getScene();
const camera = renderer.getCamera();

Creating Meshes

Basic Geometries

// Box
const box = new THREE.Mesh(
new THREE.BoxGeometry(1, 1, 1),
new THREE.MeshStandardMaterial({ color: 0x4CAF50 })
);
scene.add(box);

// Sphere
const sphere = new THREE.Mesh(
new THREE.SphereGeometry(0.5, 32, 32),
new THREE.MeshStandardMaterial({ color: 0x2196F3 })
);
sphere.position.set(2, 0, 0);
scene.add(sphere);

// Plane (ground)
const ground = new THREE.Mesh(
new THREE.PlaneGeometry(10, 10),
new THREE.MeshStandardMaterial({ color: 0x808080 })
);
ground.rotation.x = -Math.PI / 2;
ground.position.y = -0.5;
scene.add(ground);
🎮3D Basic Shapes
Loading demo...
Theme Support

This demo automatically adapts to your selected theme. Try toggling the theme using the 🌙/☀️ button in the navigation bar!

Materials

Standard Material (PBR)

const material = new THREE.MeshStandardMaterial({
color: 0x4CAF50,
metalness: 0.5,
roughness: 0.3,
emissive: 0x222222,
emissiveIntensity: 0.2
});

Physical Material (Advanced PBR)

const material = new THREE.MeshPhysicalMaterial({
color: 0x88ccff,
metalness: 0,
roughness: 0,
transmission: 0.9, // Glass-like
thickness: 0.5,
clearcoat: 1,
clearcoatRoughness: 0
});

Basic Material (No Lighting)

// Unlit, always visible
const material = new THREE.MeshBasicMaterial({
color: 0xff0000,
wireframe: false
});

Lighting

Important: 3D scenes need lights to be visible!

// Ambient light (base illumination)
const ambient = new THREE.AmbientLight(0x404040, 0.5);
scene.add(ambient);

// Directional light (sun-like)
const directional = new THREE.DirectionalLight(0xffffff, 1);
directional.position.set(5, 10, 5);
directional.castShadow = true;
scene.add(directional);

// Point light (bulb-like)
const point = new THREE.PointLight(0xff6600, 1, 10);
point.position.set(0, 3, 0);
scene.add(point);

// Spot light (flashlight-like)
const spot = new THREE.SpotLight(0xffffff, 1);
spot.position.set(0, 5, 0);
spot.angle = Math.PI / 6;
spot.castShadow = true;
scene.add(spot);

Shadows

// Enable shadows on renderer
const threeRenderer = renderer.getThreeRenderer();
threeRenderer.shadowMap.enabled = true;
threeRenderer.shadowMap.type = THREE.PCFSoftShadowMap;

// Light casts shadows
directional.castShadow = true;
directional.shadow.mapSize.width = 1024;
directional.shadow.mapSize.height = 1024;

// Mesh casts shadow
mesh.castShadow = true;

// Ground receives shadow
ground.receiveShadow = true;

Camera

Perspective Camera

const camera = new THREE.PerspectiveCamera(
75, // FOV
width / height, // Aspect ratio
0.1, // Near plane
1000 // Far plane
);
camera.position.set(0, 5, 10);
camera.lookAt(0, 0, 0);

Camera Controls

import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';

const controls = new OrbitControls(camera, canvas);
controls.enableDamping = true;
controls.dampingFactor = 0.05;
controls.maxDistance = 20;
controls.minDistance = 2;

// Update in game loop
function update(deltaTime: number) {
controls.update();
}

Loading 3D Models

GLTF/GLB Models

import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';

const loader = new GLTFLoader();

loader.load('assets/character.glb', (gltf) => {
const model = gltf.scene;
model.scale.set(0.5, 0.5, 0.5);
scene.add(model);

// Access animations
const mixer = new THREE.AnimationMixer(model);
const action = mixer.clipAction(gltf.animations[0]);
action.play();
});

With GameByte Assets

import { Assets } from '@gamebyte/framework';

await Assets.load([
{ key: 'character', url: 'assets/character.glb', type: 'model' }
]);

const model = Assets.get('character');
scene.add(model.scene.clone());

Post-Processing

import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer';
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass';
import { UnrealBloomPass } from 'three/examples/jsm/postprocessing/UnrealBloomPass';

const composer = new EffectComposer(threeRenderer);
composer.addPass(new RenderPass(scene, camera));
composer.addPass(new UnrealBloomPass(
new THREE.Vector2(width, height),
0.5, // strength
0.4, // radius
0.85 // threshold
));

// Use composer instead of renderer
function render() {
composer.render();
}
🎮Post-Processing Effects
Loading demo...
Theme Support

This demo automatically adapts to your selected theme. Try toggling the theme using the 🌙/☀️ button in the navigation bar!

Animation

Using AnimationMixer

const mixer = new THREE.AnimationMixer(model);
const action = mixer.clipAction(animation);

action.play();
action.setLoop(THREE.LoopRepeat, Infinity);
action.timeScale = 1.5; // Speed up

// Update in game loop
function update(deltaTime: number) {
mixer.update(deltaTime);
}

Tween Animation

import { gsap } from 'gsap';

// Animate position
gsap.to(mesh.position, {
x: 5,
y: 2,
duration: 2,
ease: 'power2.inOut'
});

// Animate rotation
gsap.to(mesh.rotation, {
y: Math.PI * 2,
duration: 3,
repeat: -1,
ease: 'none'
});

Performance Tips

1. Use InstancedMesh for Many Similar Objects

const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshStandardMaterial({ color: 0x4CAF50 });
const instancedMesh = new THREE.InstancedMesh(geometry, material, 1000);

const matrix = new THREE.Matrix4();
for (let i = 0; i < 1000; i++) {
matrix.setPosition(Math.random() * 100 - 50, 0, Math.random() * 100 - 50);
instancedMesh.setMatrixAt(i, matrix);
}

scene.add(instancedMesh);

2. Level of Detail (LOD)

const lod = new THREE.LOD();

lod.addLevel(highDetailMesh, 0); // Close
lod.addLevel(mediumDetailMesh, 20); // Medium distance
lod.addLevel(lowDetailMesh, 50); // Far

scene.add(lod);

3. Frustum Culling

// Enabled by default
mesh.frustumCulled = true;

// Disable for always-visible objects
skybox.frustumCulled = false;

More 3D Demos

Camera Controls

🎮3D Camera Controls Demo
Loading demo...

Pathfinding in 3D

🎮3D Pathfinding Demo
Loading demo...