Building a Basic 3D Scene with Primitive Shapes in Three.js
A Three.js environment acts as a container for all 3D elements, including objects, lighting, and cameras. Initialize a new environment using the THREE.Scene() constructor.
const environment = new THREE.Scene();
Renderer Setup
The renderer handles the drawing of the 3D scene onto a canvas. Use THREE.WebGLRenderer() to create the instance. Configure its size to match the viewport and append the canvas element to the dcoument body.
function setupRenderer() {
const canvasRenderer = new THREE.WebGLRenderer({ antialias: true });
canvasRenderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(canvasRenderer.domElement);
return canvasRenderer;
}
Camera Configuration
A PerspectiveCamera mimics human vision. Define the field of view (FOV), aspect ratio, and clippign planes (near and far) to determine what is visible.
function setupCamera() {
const perspectiveCam = new THREE.PerspectiveCamera(
60,
window.innerWidth / window.innerHeight,
0.1,
1000
);
perspectiveCam.position.set(0, 10, 200);
return perspectiveCam;
}
Materials
A standard material that colors the mesh based on its face normals can be created using MeshNormalMaterial.
const normalMat = new THREE.MeshNormalMaterial();
Primitive Geometry Definitions
Cube Generates a box shape using width, height, and depth parameters.
const cubeMesh = new THREE.Mesh(
new THREE.BoxGeometry(10, 10, 10, 1, 1, 1),
normalMat
);
cubeMesh.position.set(-60, 30, 0);
environment.add(cubeMesh);
Circle Creates a flat disc or polygon based on radius and segment count.
const discMesh = new THREE.Mesh(
new THREE.CircleGeometry(8, 64),
normalMat
);
discMesh.position.set(-20, 30, 0);
environment.add(discMesh);
Cone Constructs a cone shape defined by the bottom radius, height, and radial segments.
const coneMesh = new THREE.Mesh(
new THREE.ConeGeometry(6, 25, 32),
normalMat
);
coneMesh.position.set(25, 30, 0);
environment.add(coneMesh);
Cylinder Generates a cylinder with distinct top and bottom radii.
const tubeMesh = new THREE.Mesh(
new THREE.CylinderGeometry(5, 5, 25, 32),
normalMat
);
tubeMesh.position.set(65, 30, 0);
environment.add(tubeMesh);
Sphere Creates a spherical object using radius and width/height segments.
const globeMesh = new THREE.Mesh(
new THREE.SphereGeometry(7, 32, 32),
normalMat
);
globeMesh.position.set(-40, -25, 0);
environment.add(globeMesh);
Plane Defines a two-dimensional flat surface.
const flatMesh = new THREE.Mesh(
new THREE.PlaneGeometry(10, 10),
normalMat
);
flatMesh.position.set(0, -25, 0);
environment.add(flatMesh);
Torus Generates a donut-shaped geometry defined by radius, tube thickness, and segments.
const ringMesh = new THREE.Mesh(
new THREE.TorusGeometry(12, 4, 16, 100),
normalMat
);
ringMesh.position.set(40, -25, 0);
environment.add(ringMesh);
Animation Loop
The animation cycle uses requestAnimationFrame to continuously update the scene. The rotation angle increments based on a control flag, applying the transformation to all meshes.
let angle = 0;
let isSpinning = true;
function renderLoop() {
requestAnimationFrame(renderLoop);
if (isSpinning) {
angle += 0.02;
cubeMesh.rotation.set(angle, angle, angle);
discMesh.rotation.set(angle, angle, angle);
coneMesh.rotation.set(angle, angle, angle);
tubeMesh.rotation.set(angle, angle, angle);
globeMesh.rotation.set(angle, angle, angle);
flatMesh.rotation.set(angle, angle, angle);
ringMesh.rotation.set(angle, angle, angle);
}
performanceStats.update();
canvasRenderer.render(environment, perspectiveCam);
}
Debugging Utilities
Initialize a performance monitor (Stats.js) to display FPS and a GUI (dat.GUI) to toggle the rotation state interactive.
function initPerformanceMonitor() {
performanceStats = new Stats();
document.body.appendChild(performanceStats.dom);
}
function initControlPanel() {
const settings = { spin: true };
const guiInterface = new dat.GUI();
guiInterface.add(settings, 'spin')
.name('Toggle Spin')
.onChange((value) => {
isSpinning = value;
});
}