索引 · Index · ▶ 在线运行案例
案例合集: 三维可视化功能案例(threehub.cn)
开源仓库github地址: https://github.com/z2586300277/three-cesium-examples
**400个案例代码: ** 网盘链接

你将学到什么
- 索引绘制 vs 非索引绘制 的区别
geometry.index如何用 4 个顶点拼出 2 个三角形- 同一 Geometry 可同时用于 Points、Line、Mesh
效果说明
同一组顶点数据,同时以 黄色点、红色线、蓝色面 三种方式渲染,展示 WebGL 不同 图元模式(points / lines / triangles)。
核心概念
非索引 vs 索引
| 方式 | 顶点数(矩形) | 说明 |
|---|---|---|
| 非索引 | 6(每三角独立 3 顶点) | 网格 案例 |
| 索引 | 4 顶点 + 6 索引值 | 顶点可复用,节省内存 |
// 4 个唯一顶点
const vertices = new Float32Array([
0, 0, 0, // 索引 0
50, 0, 0, // 索引 1
50, 0, 50, // 索引 2
0, 0, 50, // 索引 3
]);
// 索引表:每 3 个索引构成一个三角形
const indexes = new Uint16Array([
0, 1, 2, // 三角面 1
0, 3, 2, // 三角面 2
]);
geometry.index = new THREE.BufferAttribute(indexes, 1);
geometry.attributes.position = new THREE.BufferAttribute(vertices, 3);
同一 Geometry,三种 Object
| Object | Material | 渲染模式 |
|---|---|---|
Points |
PointsMaterial |
GL_POINTS |
Line |
LineBasicMaterial |
GL_LINE_STRIP 等 |
Mesh |
MeshBasicMaterial |
GL_TRIANGLES |
实现步骤
- 定义 4 顶点 + 6 索引
- 分别创建 Points、Line、Mesh 加入 scene
- OrbitControls 交互
代码要点
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
const scene = new THREE.Scene();
// 网格模型Mesh其实就一个一个三角形(面)拼接构成
const geometry = new THREE.BufferGeometry();
const vertices = new Float32Array([
0, 0, 0,
50, 0, 0,
50, 0, 50,
// 0, 0, 0,
0, 0, 50,
// 50, 0, 50,
]);
// 下面索引值对应顶点位置数据中的顶点坐标
// 第 0、1、2这三个点构成一个三角形
// 第 0、3、2这三个点构成一个三角形
const indexes = new Uint16Array([
0, 1, 2, 0, 3, 2,
])
geometry.index = new THREE.BufferAttribute(indexes, 1);
geometry.attributes.position = new THREE.BufferAttribute(vertices, 3);
// 点渲染模式
const material2 = new THREE.PointsMaterial({
color: 0xffff00,
size: 10.0 //点对象像素尺寸
});
const points = new THREE.Points(geometry, material2); //点模型对象
scene.add(points);
// 线材质对象
const material1 = new THREE.LineBasicMaterial({
color: 0xff0000 //线条颜色
});
// 创建线模型对象
const line = new THREE.Line(geometry, material1);
scene.add(line);
// 网格
const material = new THREE.MeshBasicMaterial({
color: 0x0000ff,
side: THREE.DoubleSide,
});
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
// AxesHelper
const axesHelper = new THREE.AxesHelper(150);
scene.add(axesHelper);
// 相机
const camera = new THREE.PerspectiveCamera(); //相机
camera.position.set(200, 200, 200); //相机位置
camera.lookAt(0, 0, 0); //相机观察位置
// 渲染器
const renderer = new THREE.WebGLRenderer(); // 创建渲染器
const box = document.getElementById('box');
renderer.setSize(box.clientWidth, box.clientHeight); //渲染区域
renderer.render(scene, camera); //执行渲染
box.appendChild(renderer.domElement);;
const controls = new OrbitControls(camera, renderer.domElement);
controls.addEventListener('change', function () {
renderer.render(scene, camera);
});
完整源码:GitHub
小结
- 本文提供 索引 完整 Three.js 源码与在线 Demo,建议先运行案例再改 uniform/参数做二次实验
- 更多 Three.js 实战案例见 three-cesium-examples 合集 与 GitHub 开源仓库