javascript - 在 React-Three-Fiber 中渲染索引缓冲区几何图形
问题描述
我目前正在尝试从https://threejs.org/examples/?q=buffer#webgl_buffergeometry_indexed在 React-Three-Fiber 环境中获取示例。
我目前在我的代码中看到了几个问题。
首先,特别是在 Chrome 中,我反复收到以下警告:
[.WebGL-0x26d30384f700] GL_INVALID_ENUM: Enum is not currently supported.
此外,我目前看不到任何颜色应用于网格。
这是我到目前为止工作的代码:
import React, { useMemo } from "react";
import { Canvas } from "@react-three/fiber";
import { DoubleSide } from "three";
const App = () => {
const size = 20;
const segments = 10;
const [colors, normals, positions] = useMemo(() => {
const colorsArr = [];
const normalsArr = [];
const positionsArr = [];
const halfSize = size / 2;
const segmentSize = size / segments;
// generate vertices, normals and color data for a simple grid geometry
for (let i = 0; i <= segments; i++) {
const y = i * segmentSize - halfSize;
for (let j = 0; j <= segments; j++) {
const x = j * segmentSize - halfSize;
positionsArr.push(x, -y, 0);
normalsArr.push(0, 0, 1);
const r = x / size + 0.5;
const g = y / size + 0.5;
colorsArr.push(r, g, 1);
}
}
return [colorsArr, normalsArr, positionsArr];
}, []);
const indices = useMemo(() => {
const indicesArr = [];
// generate indices (data for element array buffer)
for (let i = 0; i < segments; i++) {
for (let j = 0; j < segments; j++) {
const a = i * (segments + 1) + (j + 1);
const b = i * (segments + 1) + j;
const c = (i + 1) * (segments + 1) + j;
const d = (i + 1) * (segments + 1) + (j + 1);
// generate two faces (triangles) per iteration
indicesArr.push(a, b, d); // face one
indicesArr.push(b, c, d); // face two
}
}
return indicesArr;
}, []);
return (
<Canvas
camera={{
fov: 27,
near: 1,
far: 3500
}}
position-z={64}
>
<color attach="background" args={["#050505"]} />
<mesh>
<bufferGeometry attach="geometry">
<bufferAttribute
array={indices}
attach="index"
count={indices.length}
itemSize={1}
/>
<bufferAttribute
attachObject={["attributes", "position"]}
count={positions.length / 3}
array={positions}
itemSize={3}
/>
<bufferAttribute
attachObject={["attributes", "color"]}
count={colors.length / 3}
array={colors}
itemSize={3}
/>
<bufferAttribute
attachObject={["attributes", "normal"]}
count={normals.length / 3}
array={normals}
itemSize={3}
/>
</bufferGeometry>
<meshPhongMaterial attach="material" side={DoubleSide} vertexColors />
</mesh>
<hemisphereLight />
</Canvas>
);
};
export default App;
Three.js 的示例代码:https ://github.com/mrdoob/three.js/blob/master/examples/webgl_buffergeometry_indexed.html
解决方案
终于解决了这个问题。主要问题是我需要将位置、颜色和法线数组转换为 Float32Array() 并将索引转换为 Uint32Array()。
因此,例如,在索引数组的情况下,以下内容对我有用:
const indices = useMemo(() => {
const indicesArr = [];
// generate indices (data for element array buffer)
for (let i = 0; i < segments; i++) {
for (let j = 0; j < segments; j++) {
const a = i * (segments + 1) + (j + 1);
const b = i * (segments + 1) + j;
const c = (i + 1) * (segments + 1) + j;
const d = (i + 1) * (segments + 1) + (j + 1);
// generate two faces (triangles) per iteration
indicesArr.push(a, b, d); // face one
indicesArr.push(b, c, d); // face two
}
}
return new Uint32Array(indicesArr);
}, []);