Vanilla的三个JS与三纤维代码之间的差异,无法弄清楚什么是不同的
以下代码工作得很好,并使用设置的所有属性(即颜色、uvs、法线和顶点)渲染几何图形。
import * as THREE from "three";
const { useEffect } = require("react");
function main() {
const canvas = document.querySelector('#c');
const renderer = new THREE.WebGLRenderer({canvas});
const fov = 150;
const aspect = 2;
const near = 0.1;
const far = 100;
const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
camera.position.z = 5;
const scene = new THREE.Scene();
const color = 0xFFFFFF;
const intensity = 1;
const light = new THREE.DirectionalLight(color, intensity);
light.position.set(-1, 2, 4);
scene.add(light);
const positions = [...somepoints];
const normals = [...somepoints];
const uvs = [...somepoints];
const colours = [...somepoints];
const geometry = new THREE.BufferGeometry();
const positionNumComponents = 3;
const normalNumComponents = 3;
const uvNumComponents = 2;
const colorComp = 4;
geometry.setAttribute(
'position',
new THREE.BufferAttribute(new Float32Array(positions), positionNumComponents));
geometry.setAttribute(
'normal',
new THREE.BufferAttribute(new Float32Array(normals), normalNumComponents));
geometry.setAttribute(
'uv',
new THREE.BufferAttribute(new Float32Array(uvs), uvNumComponents));
geometry.setAttribute(
'color',
new THREE.BufferAttribute(new Float32Array(colours), colorComp));
const material = new THREE.MeshPhongMaterial({color: 0x88FF88});
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
function render(time) {
renderer.render(scene, camera);
}
requestAnimationFrame(render);
}
const App = () => {
useEffect(() => {
main();
});
return (
<canvas id="c"></canvas>
)
}
export default App;
但是,如果我尝试使用 React 组件运行它,它不会显示任何内容,并且出现以下错误 235 [.WebGL-0x38089eaa00] GL_INVALID_OPERATION: Vertex buffer is not big enough for the draw call
:
I认为问题可能出在 requestAnimationFrame 上,但在上面的代码中它甚至没有对场景的对象执行任何计算。它只是调用 renderer.render 来反应三纤维,对吧?
import { Canvas } from '@react-three/fiber'
import * as THREE from "three";
const App = () => {
const positions = [...somepoints];
const normals = [...somepoints];
const uvs = [...somepoints];
const colours = [...somepoints];
return (
<Canvas>
<perspectiveCamera
fov={150}
aspect={2}
position={[0,0,5]}
near={0.1}
far={100}
/>
<directionalLight
color={0xFFFFFF}
intensity={1.5}
position={[-1, 2, 4]}
/>
<mesh>
<bufferGeometry attach="geometry">
<bufferAttribute
attachObject={["attributes", "position"]}
count={positions.length / 3}
itemSize={3}
array={positions}
normalized={true}
/>
<bufferAttribute
attachObject={["attributes", "normal"]}
count={normals.length / 3}
itemSize={3}
array={normals}
normalized={true}
/>
<bufferAttribute
attachObject={["attributes", "color"]}
count={colours.length / 4}
itemSize={4}
array={colours}
normalized={true}
/>
<bufferAttribute
attachObject={["attributes", "uv"]}
count={uvs.length / 2}
itemSize={2}
array={uvs}
normalized={true}
/>
</bufferGeometry>
<meshPhongMaterial attach="material" color={0x88FF88} />
</mesh>
</Canvas>
)
};
export default App;
任何帮助将不胜感激!谢谢你!
编辑: 这里的问题在于反应代码。由于缓冲区属性要求所有数组均为 new Float32Array([...somepoints])
。将位置、uv、法线和颜色更改为 float32 数组类型后,一切正常。
Following code works just fine and renders the geometry with all the attributes set i.e. color, uvs, normal and vertices.
import * as THREE from "three";
const { useEffect } = require("react");
function main() {
const canvas = document.querySelector('#c');
const renderer = new THREE.WebGLRenderer({canvas});
const fov = 150;
const aspect = 2;
const near = 0.1;
const far = 100;
const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
camera.position.z = 5;
const scene = new THREE.Scene();
const color = 0xFFFFFF;
const intensity = 1;
const light = new THREE.DirectionalLight(color, intensity);
light.position.set(-1, 2, 4);
scene.add(light);
const positions = [...somepoints];
const normals = [...somepoints];
const uvs = [...somepoints];
const colours = [...somepoints];
const geometry = new THREE.BufferGeometry();
const positionNumComponents = 3;
const normalNumComponents = 3;
const uvNumComponents = 2;
const colorComp = 4;
geometry.setAttribute(
'position',
new THREE.BufferAttribute(new Float32Array(positions), positionNumComponents));
geometry.setAttribute(
'normal',
new THREE.BufferAttribute(new Float32Array(normals), normalNumComponents));
geometry.setAttribute(
'uv',
new THREE.BufferAttribute(new Float32Array(uvs), uvNumComponents));
geometry.setAttribute(
'color',
new THREE.BufferAttribute(new Float32Array(colours), colorComp));
const material = new THREE.MeshPhongMaterial({color: 0x88FF88});
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
function render(time) {
renderer.render(scene, camera);
}
requestAnimationFrame(render);
}
const App = () => {
useEffect(() => {
main();
});
return (
<canvas id="c"></canvas>
)
}
export default App;
However if I try to run it using react components it doesn't show anything and I get the following error 235 [.WebGL-0x38089eaa00] GL_INVALID_OPERATION: Vertex buffer is not big enough for the draw call
:
I think that the problem might be with requestAnimationFrame but in above code it doesn't even perform any computation on the scene's object. It just calls renderer.render which react three fiber takes care off, right?
import { Canvas } from '@react-three/fiber'
import * as THREE from "three";
const App = () => {
const positions = [...somepoints];
const normals = [...somepoints];
const uvs = [...somepoints];
const colours = [...somepoints];
return (
<Canvas>
<perspectiveCamera
fov={150}
aspect={2}
position={[0,0,5]}
near={0.1}
far={100}
/>
<directionalLight
color={0xFFFFFF}
intensity={1.5}
position={[-1, 2, 4]}
/>
<mesh>
<bufferGeometry attach="geometry">
<bufferAttribute
attachObject={["attributes", "position"]}
count={positions.length / 3}
itemSize={3}
array={positions}
normalized={true}
/>
<bufferAttribute
attachObject={["attributes", "normal"]}
count={normals.length / 3}
itemSize={3}
array={normals}
normalized={true}
/>
<bufferAttribute
attachObject={["attributes", "color"]}
count={colours.length / 4}
itemSize={4}
array={colours}
normalized={true}
/>
<bufferAttribute
attachObject={["attributes", "uv"]}
count={uvs.length / 2}
itemSize={2}
array={uvs}
normalized={true}
/>
</bufferGeometry>
<meshPhongMaterial attach="material" color={0x88FF88} />
</mesh>
</Canvas>
)
};
export default App;
Any Help will be greatly appreciated! Thank you!
EDIT:
The issue here was with the react code. As buffer attributes requires all the arrays to be new Float32Array([...somepoints])
. After changing positions, uvs, normal and colours to float32 array type everything worked fine.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论