Documentation

Three.js

Three.js is a powerful, lightweight, cross-browser JavaScript library/API used to create and display animated 3D computer graphics on a Web browser. These graphics can be interactive and can be created, in part, with the help of the WebGL API.

Three.js

Scene

  • The 3D scene where all the objects, lights, and cameras are added and rendered
const scene = new THREE.Scene();

Camera

  • Defines the virtual camera used to view the scene
const camera = new THREE.PerspectiveCamera(
  75,
  window.innerWidth / window.innerHeight,
  0.1,
  1000,
);

Renderer

  • Provides the rendering capabilities using WebGL
  • The options { antialias: true, alpha: true } enable antialias and support for transparency
const renderer = new THREE.WebGLRenderer({
  antialias: true,
  alpha: true,
  canvas: document.querySelector("canvas"),
});

renderer.setSize(window.innerWidth, window.innerHeight);

renderer.setPixelRatio(devicePixelRatio);

Resize Handler

  • Used to handle window resizing
window.addEventListener("resize", onWindowResize, false);

function onWindowResize() {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
}

Animation Loop

  • Creates a loop that repeatedly renders the scene
function animate() {
  requestAnimationFrame(animate);
  renderer.render(scene, camera);
}
animate();

Mesh

  • Combines the geometry and material to create a mesh object
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshBasicMaterial({ color: 0xffff00 });
const mesh = new THREE.Mesh(geometry, material);

GLTF Loader

  • Load 3D models in the glTF format
const loader = new THREE.GLTFLoader();

Texture Loader

  • Load textures from image files
const textures = [
  "https://picsum.photos/id/1/200/300",
  "https://picsum.photos/id/2/200/300",
].map((url) =>
  new THREE.TextureLoader().load(url, (texture) => {
    // Onload callback, do something
  }),
);

ShaderMaterial

  • Custom shaders to be used
  • The vertexShader and fragmentShader variables define the GLSL code
const uniforms = {
  uTime: { value: 1.0 },
};

const vertexShader = `
varying vec2 vUv;
varying vec3 vNormal;
varying vec3 vPosition;
uniform float uTime;

void main() {
    vUv = uv;
    vNormal = normal;
    vPosition = position;

    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
`;
const fragmentShader = `
varying vec2 vUv;
varying vec3 vNormal;
varying vec3 vPosition;
uniform float uTime;

void main() {
    gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
}
`;

const material = new THREE.ShaderMaterial({
  uniforms: uniforms,
  vertexShader: vertexShader,
  fragmentShader: fragmentShader,
});

Mouse Events

  • Picking objects and performing intersection tests
const raycaster = new THREE.Raycaster();

window.addEventListener("mousemove", onMouseMove, false);

function onMouseMove(event) {
  const mouse = new THREE.Vector2(
    (event.clientX / window.innerWidth) * 2 - 1,
    -(event.clientY / window.innerHeight) * 2 + 1,
  );

  raycaster.setFromCamera(mouse, camera);

  const intersects = raycaster.intersectObjects(scene.children, true);

  if (intersects.length > 0) {
    // Object is being hovered
  } else {
    // No object is being hovered
  }
}

Instance Mesh

  • Creates an InstancedMesh with 125 instances arranged in a grid pattern
const dummy = new THREE.Object3D();
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshBasicMaterial({ color: 0xffff00 });
const count = 125;
const instancedMesh = new THREE.InstancedMesh(geometry, material, count);

function generateNode(num: number) {
  const temp = [];
  const gap = 5;

  for (let i = 0; i < num; i++) {
    for (let j = 0; j < num; j++) {
      for (let k = 0; k < num; k++) {
        temp.push({ x: gap * i, y: gap * j, z: gap * k });
      }
    }
  }
  return temp;
}

const nodes = generateNode(5);

for (let i = 0; i < nodes.length; i++) {
  const { x, y, z } = nodes[i];
  dummy.position.set(x, y, z);
  dummy.updateMatrix();
  instancedMesh.setMatrixAt(i, dummy.matrix);
  instancedMesh.instanceMatrix.needsUpdate = true;
}