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
相关产品推荐
相关产品推荐

