You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ThreeJS三角形网格创建报错:draw数组越界问题求助

嘿,我来帮你搞定这个Three.js的数组越界问题!你遇到的"draw array attempt to get access out of bound arrays"错误,本质上就是顶点数据和颜色数据的数量没对上,Three.js渲染时找不到对应的数据,就会报越界错误。

先分析你的代码问题

从你贴的代码片段来看:

for (var i = 0, j = 0, k = -halfSize; i <= divisions; i++, k += step) {
  vertices.push(-halfSize, 0, k, halfSize, 0, k);
  vertices.push(k, 0, -halfSize, k, 0, halfSize);
  var colorg = new THREE.Color("rgb(255, 0, 0)");
  colorg.to... // 这里代码没写完,但明显颜色数据没跟顶点对应上
}

你每次循环往vertices里塞了4个顶点(每个顶点3个坐标,也就是12个数值),但颜色部分只创建了一个Color对象,既没把颜色数据按顶点数量添加到颜色数组,也没跟每个顶点/面绑定,这就导致渲染时颜色数组长度不够,直接越界了。

一步步修复方案

1. 让颜色数组和顶点数组严格匹配

首先得明确你用的是顶点颜色还是面颜色:

  • 如果是顶点颜色(每个顶点对应一个颜色):颜色数组的元素数 = 顶点数 × 3(每个颜色的r/g/b值)
  • 如果是面颜色(每个面对应一个颜色):颜色数组的元素数 = 面的数量

下面给你写个完整的示例(以顶点颜色+网格线为例,这应该是你要的效果):

// 先初始化必要的数组和参数
const vertices = [];
const colors = [];
const halfSize = 5; // 你自己的halfSize值
const divisions = 10; // 你自己的分割数
const step = (halfSize * 2) / divisions;

for (let i = 0, k = -halfSize; i <= divisions; i++, k += step) {
  // 第一组线:横向的线,两个顶点
  vertices.push(-halfSize, 0, k);
  vertices.push(halfSize, 0, k);
  // 给这两个顶点加红色
  const red = new THREE.Color("rgb(255, 0, 0)");
  colors.push(red.r, red.g, red.b);
  colors.push(red.r, red.g, red.b);

  // 第二组线:纵向的线,两个顶点
  vertices.push(k, 0, -halfSize);
  vertices.push(k, 0, halfSize);
  // 这里可以根据k(也就是x/y坐标)动态改颜色
  const dynamicColor = new THREE.Color();
  // 比如把k映射成绿色通道的值,k越大绿色越浓
  const greenVal = (k + halfSize) / (halfSize * 2);
  dynamicColor.setRGB(0, greenVal, 0);
  colors.push(dynamicColor.r, dynamicColor.g, dynamicColor.b);
  colors.push(dynamicColor.r, dynamicColor.g, dynamicColor.b);
}

// 把数据赋值给几何体
const geometry = new THREE.BufferGeometry();
geometry.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3));
geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3));

// 材质一定要开启顶点颜色!
const material = new THREE.LineBasicMaterial({ vertexColors: true });
// 用LineSegments来画网格线,比Line更高效
const grid = new THREE.LineSegments(geometry, material);
scene.add(grid);

2. 检查渲染模式是否匹配

如果你是画网格面(比如THREE.Mesh),那顶点数组得是3的倍数(每3个顶点组成一个三角形面),颜色数组也要对应每个面或者每个顶点的数量,不能乱。

3. 动态改颜色的小技巧

如果要根据传入的x/y坐标改颜色,只需要把坐标值映射到0-1的范围(因为Three.js的Color用0-1的数值,不是0-255),比如:

// 假设传入的x坐标是xPos,范围是[-halfSize, halfSize]
const r = (xPos + halfSize) / (halfSize * 2); // 把x映射到0-1
const g = (yPos + halfSize) / (halfSize * 2);
const b = 0.5;
const customColor = new THREE.Color(r, g, b);
额外注意点
  • 如果你用的是旧版的THREE.Geometry(现在已经不推荐了),那得给每个顶点的.color属性赋值,或者给每个面的.color属性赋值,不能直接操作数组。
  • 要是用了索引(geometry.index),一定要确保索引的数值不超过顶点数量-1,不然也会越界。

内容的提问来源于stack exchange,提问作者rockon1

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:35:26