Scene, camera, renderer, geometries, materials, lighting, animations, physics, and 3D web development.
// ── Basic Setup ──
import * as THREE from 'three';
// Scene: Container for all objects
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x1a1a2e);
scene.fog = new THREE.Fog(0x1a1a2e, 10, 50);
// Camera
const camera = new THREE.PerspectiveCamera(
75, // Field of view (degrees)
window.innerWidth / window.innerHeight, // Aspect ratio
0.1, // Near clipping plane
1000 // Far clipping plane
);
camera.position.set(0, 5, 10);
camera.lookAt(0, 0, 0);
// Orthographic Camera
const orthoCamera = new THREE.OrthographicCamera(
-10 * aspect, 10 * aspect,
10, -10,
0.1, 1000
);
// Renderer
const renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true,
powerPreference: 'high-performance',
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.toneMappingExposure = 1.0;
renderer.outputColorSpace = THREE.SRGBColorSpace;
document.getElementById('canvas-container').appendChild(renderer.domElement);
// Resize handler
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
// Animation Loop
function animate() {
requestAnimationFrame(animate);
// Update objects here
renderer.render(scene, camera);
}
animate();| Type | Use Case |
|---|---|
| PerspectiveCamera | 3D scenes (perspective projection) |
| OrthographicCamera | 2D/CAD views (parallel projection) |
| CubeCamera | Reflection mapping (6 faces) |
| ArrayCamera | VR / multi-view rendering |
| Setting | Purpose |
|---|---|
| antialias: true | Smooth edges |
| alpha: true | Transparent background |
| shadowMap.enabled | Enable shadows |
| toneMapping | HDR color grading |
| outputColorSpace | Color space (sRGB) |
| setPixelRatio() | Sharp on HiDPI displays |
// ── Geometry (Shape/BufferGeometry) ──
const box = new THREE.BoxGeometry(1, 1, 1);
const sphere = new THREE.SphereGeometry(0.5, 32, 32);
const cylinder = new THREE.CylinderGeometry(0.5, 0.5, 2, 32);
const cone = new THREE.ConeGeometry(0.5, 1, 2, 32);
const torus = new THREE.TorusGeometry(0.5, 0.2, 16, 100);
const torusKnot = new THREE.TorusKnotGeometry(0.5, 0.15, 100, 16);
const plane = new THREE.PlaneGeometry(10, 10);
const circle = new THREE.CircleGeometry(0.5, 32);
// Custom geometry
const triangle = new THREE.BufferGeometry();
const vertices = new Float32Array([
0, 1, 0, // top
-1, -1, 0, // bottom left
1, -1, 0, // bottom right
]);
triangle.setAttribute('position', new THREE.BufferAttribute(vertices, 3));
// ── Materials ──
const basicMat = new THREE.MeshBasicMaterial({
color: 0x3b82f6,
wireframe: false,
transparent: true,
opacity: 0.8,
side: THREE.DoubleSide,
});
const standardMat = new THREE.MeshStandardMaterial({
color: 0xffffff,
roughness: 0.5, // 0 = smooth mirror, 1 = rough
metalness: 0.3, // 0 = dielectric, 1 = metal
map: textureLoader.load('texture.jpg'),
normalMap: textureLoader.load('normal.jpg'),
aoMap: textureLoader.load('ao.jpg'),
roughnessMap: textureLoader.load('roughness.jpg'),
});
const phongMat = new THREE.MeshPhongMaterial({
color: 0x3b82f6,
shininess: 100,
specular: 0x444444,
flatShading: false,
});
const matcapMat = new THREE.MeshMatcapMaterial({
matcap: textureLoader.load('matcap.png'),
});
// ── Mesh (Geometry + Material) ──
const mesh = new THREE.Mesh(box, standardMat);
mesh.position.set(0, 0, 0);
mesh.rotation.x = Math.PI / 4;
mesh.rotation.y = Math.PI / 2;
mesh.scale.set(2, 2, 2);
mesh.castShadow = true;
mesh.receiveShadow = true;
scene.add(mesh);
// ── Groups ──
const group = new THREE.Group();
group.add(mesh);
group.position.y = 5;
scene.add(group);
// ── Edges & Wireframe ──
const edges = new THREE.EdgesGeometry(box);
const edgeMesh = new THREE.LineSegments(
edges,
new THREE.LineBasicMaterial({ color: 0x000000 })
);
scene.add(edgeMesh);| Material | Features |
|---|---|
| MeshBasicMaterial | Unlit, color only |
| MeshLambertMaterial | Lambert lighting (Gouraud) |
| MeshPhongMaterial | Specular highlights |
| MeshStandardMaterial | PBR (roughness/metalness) |
| MeshPhysicalMaterial | PBR + clearcoat, IOR, etc. |
| MeshMatcapMaterial | Matcap texture-based |
| ShaderMaterial | Custom GLSL shaders |
| PointsMaterial | For point cloud rendering |
| Method | Purpose |
|---|---|
| TextureLoader().load() | Load image texture |
| CubeTextureLoader() | Load cubemap (6 faces) |
| CompressedTextureLoader() | Load compressed textures |
| repeat.set(2, 2) | Tile texture |
| wrapS/wrapT | Repeat/WrapClampToEdge |
| encoding | sRGBColorSpace for color textures |
// ── Ambient Light (global illumination) ──
const ambient = new THREE.AmbientLight(0xffffff, 0.4);
scene.add(ambient);
// ── Directional Light (sun-like, parallel rays) ──
const dirLight = new THREE.DirectionalLight(0xffffff, 1);
dirLight.position.set(5, 10, 7);
dirLight.castShadow = true;
dirLight.shadow.mapSize.width = 2048;
dirLight.shadow.mapSize.height = 2048;
dirLight.shadow.camera.near = 0.5;
dirLight.shadow.camera.far = 50;
dirLight.shadow.camera.left = -10;
dirLight.shadow.camera.right = 10;
dirLight.shadow.camera.top = 10;
dirLight.shadow.camera.bottom = -10;
scene.add(dirLight);
// ── Point Light (light bulb, omnidirectional) ──
const pointLight = new THREE.PointLight(0xff6b6b, 1, 20);
pointLight.position.set(-3, 4, 2);
pointLight.castShadow = true;
scene.add(pointLight);
// ── Spot Light (flashlight, cone) ──
const spotLight = new THREE.SpotLight(0xffffff, 1);
spotLight.position.set(0, 10, 0);
spotLight.angle = Math.PI / 6;
spotLight.penumbra = 0.5;
spotLight.decay = 2;
spotLight.distance = 50;
spotLight.castShadow = true;
spotLight.target.position.set(0, 0, 0);
scene.add(spotLight);
scene.add(spotLight.target);
// ── Hemisphere Light (sky + ground) ──
const hemiLight = new THREE.HemisphereLight(
0x87ceeb, // Sky color
0x362d1f, // Ground color
0.5 // Intensity
);
scene.add(hemiLight);
// ── RectArea Light (panel/LED strip) ──
const rectLight = new THREE.RectAreaLight(0xffffff, 10, 10);
rectLight.position.set(0, 5, 5);
rectLight.lookAt(0, 0, 0);
scene.add(rectLight);
// ── Helper (visual light source indicator) ──
const dirLightHelper = new THREE.DirectionalLightHelper(dirLight, 1);
const spotLightHelper = new THREE.SpotLightHelper(spotLight);
scene.add(dirLightHelper, spotLightHelper);| Light | Description | Shadows |
|---|---|---|
| Ambient | Uniform, no direction | No |
| Directional | Parallel rays (sun) | Yes (orthographic) |
| Point | Omnidirectional, decays | Yes (perspective) |
| Spot | Cone-shaped, focus | Yes (perspective) |
| Hemisphere | Sky + ground colors | No |
| RectArea | Surface emission | No (experimental) |
| Property | Default | Description |
|---|---|---|
| mapSize | 512x512 | Shadow map resolution |
| camera.near | 0.5 | Near clip plane |
| camera.far | 500 | Far clip plane |
| bias | -0.0001 | Shadow acne prevention |
| normalBias | 0.02 | Peter-panning prevention |
| radius | 4 | PCF blur radius |
import * as THREE from 'three';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
// ── OrbitControls ──
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.05;
controls.minDistance = 5;
controls.maxDistance = 50;
controls.maxPolarAngle = Math.PI / 2;
// ── Animation Loop with Clock ──
const clock = new THREE.Clock();
function animate() {
requestAnimationFrame(animate);
const elapsed = clock.getElapsedTime();
const delta = clock.getDelta();
// Rotate object
mesh.rotation.y += delta * 0.5;
mesh.rotation.x += delta * 0.3;
// Oscillate position
mesh.position.y = Math.sin(elapsed * 2) * 2;
// Scale pulse
mesh.scale.setScalar(1 + Math.sin(elapsed * 3) * 0.1);
// Follow path (circle)
const angle = elapsed * 0.5;
mesh.position.x = Math.cos(angle) * 5;
mesh.position.z = Math.sin(angle) * 5;
controls.update();
renderer.render(scene, camera);
}
animate();
// ── GSAP Integration ──
// import gsap from 'gsap';
// gsap.to(mesh.position, { x: 5, duration: 2, ease: 'power2.inOut' });
// gsap.to(mesh.rotation, { y: Math.PI * 2, duration: 3, repeat: -1 });
// ── Load GLTF/GLB Model ──
const gltfLoader = new GLTFLoader();
gltfLoader.load(
'/models/character.glb',
(gltf) => {
const model = gltf.scene;
model.position.set(0, 0, 0);
model.traverse((child) => {
if (child.isMesh) {
child.castShadow = true;
child.receiveShadow = true;
}
});
scene.add(model);
},
(error) => console.error('Loading error:', error),
(progress) => {
console.log(Math.round((progress.loaded / progress.total) * 100) + '%');
}
);
// ── Load Texture ──
const textureLoader = new THREE.TextureLoader();
const texture = textureLoader.load('texture.jpg', () => {
renderer.render(scene, camera);
});
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
texture.repeat.set(4, 4);
// ── Environment Map ──
const pmremGenerator = new THREE.PMREMGenerator(renderer);
const envTexture = pmremGenerator.fromScene(
new THREE.RoomEnvironment()
).texture;
scene.environment = envTexture;BufferGeometry (not Geometry), merge static geometries, use texture atlases, minimize draw calls with instanced meshes (InstancedMesh), dispose of unused resources (geometry.dispose(), material.dispose()), and use requestAnimationFrame for the render loop.1) Frustum Culling: Objects outside the camera view are discarded. 2) Occlusion Culling: Objects hidden behind others are skipped. 3) Vertex Processing: Vertices are transformed (model → world → view → clip space), lit (for Phong), and projected. 4) Rasterization: Triangles are converted to fragments (pixels). 5) Fragment Processing: Textures are sampled, colors computed, depth/stencil tested. 6) Framebuffer: Final pixels are written to the screen.
MeshStandardMaterial uses PBR (Physically Based Rendering) with roughness andmetalness properties. It produces more realistic results and is energy-conserving.MeshPhongMaterial uses the older Phong/Lambert model with shininess andspecular properties. It is simpler but less physically accurate. Standard material is recommended for most projects.