Atlaslog
Atlaslog / three.js / Tutorial / Geometry and buffers
three.js · Tutorial

Geometry and buffers

Quick answer

This tutorial treats BufferGeometry as the real building block behind built-in shapes. It generates a 64 by 64 grid terrain with position, uv and index attributes, calls computeVertexNormals, and writes elevation-derived vertex colors for a MeshStandardMaterial with vertexColors enabled. It also updates an existing position attribute using DynamicDrawUsage, needsUpdate and a rebuilt bounding sphere. Readers can construct and edit custom terrain meshes efficiently.

Last verified 2026-11-03 · three.js 0.160.0 · Cite this page
Key points
Example
const cols = 64;
const rows = 64;
const step = 20;                 // 每个格 20 米

const positions = [];
const uvs = [];
const indices = [];

function heightAt(x, z) {
  return 18 * Math.sin(x * 0.015) * Math.cos(z * 0.02) + 40;
}

for (let r = 0; r <= rows; r++) {
  for (let c = 0; c <= cols; c++) {
    const x = c * step;
    const z = r * step;
    positions.push(x, heightAt(x, z), z);
    uvs.push(c / cols, r / rows);
  }
}

for (let r = 0; r < rows; r++) {
  for (let c = 0; c < cols; c++) {
    const a = r * (cols + 1) + c;
    const b = a + 1;
    const d = a + cols + 1;
    const e = d + 1;
    indices.push(a, d, b, b, d, e);
  }
}

const geometry = new THREE.BufferGeometry();
geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3));
geometry.setAttribute('uv', new THREE.Float32BufferAttribute(uvs, 2));
geometry.setIndex(indices);
geometry.computeVertexNormals();
const pos = geometry.attributes.position;
const colors = new Float32Array(pos.count * 3);

const low = new THREE.Color('#1f5fd0');
const mid = new THREE.Color('#f0a020');
const high = new THREE.Color('#d0453a');

for (let i = 0; i < pos.count; i++) {
  const h = pos.getY(i);
  const t = THREE.MathUtils.clamp((h - 20) / 50, 0, 1);

  const color = t < 0.5
    ? low.clone().lerp(mid, t * 2)
    : mid.clone().lerp(high, (t - 0.5) * 2);

  colors[i * 3] = color.r;
  colors[i * 3 + 1] = color.g;
  colors[i * 3 + 2] = color.b;
}

geometry.setAttribute('color', new THREE.BufferAttribute(colors, 3));

const terrain = new THREE.Mesh(geometry, new THREE.MeshStandardMaterial({
  vertexColors: true,
  roughness: 0.95,
  metalness: 0.0
}));
Notes
Runnable examplesChinese originalAll Tutorials
English edition written for Atlaslog. Code is taken from the original Chinese page and runs unchanged.
Cite this page

Atlaslog (2026). Geometry and buffers. https://www.jingweizhi.com/en/three/tutorials/geometry.html (accessed 2026-11-03).