如何在 react-three-fiber 中初始化 useFrame() 之外的对象
How to initialize objects outside useFrame() in react-three-fiber
我目前正在使用react-three-fiber制作场景,但我不知道如何将3D物体放置在不同的随机位置。我在 useFrame 中使用了一个 for 循环来获得不同的随机位置,但由于每次都会渲染,粒子将再次移动到随机位置。但我希望这些位置仅在初始化时是随机的,然后移动整个网格。但是如果我在 useframe 之前使用 for 循环,它会给出错误-"Cannot read property 'setMatrixAt' of undefined"。 PS- 我只是想重新创建 -https://threejs.org/examples/?q=postprocessing#webgl_postprocessing
import * as THREE from 'three'
import ReactDOM from 'react-dom'
import React, { useRef, useMemo, useState, useEffect } from 'react'
import { Canvas, useFrame } from 'react-three-fiber'
import Effects from './Effects'
import './styles.css'
const tempObject = new THREE.Object3D()
function Boxes({count}) {
const ref = useRef()
const previous = useRef()
const particles = useMemo(() => {
const temp = []
useFrame(state => {
const time = state.clock.getElapsedTime()
ref.current.rotation.x += 0.00000
ref.current.rotation.y += 0.00000
let i = 0
for (let x = 0; x < count; x++){
const id = i++
tempObject.position.set(Math.random() - 0.5, Math.random() - 0.5, Math.random() - 0.5 ).normalize()
tempObject.position.multiplyScalar( Math.random() * 40 )
tempObject.rotation.set( Math.random() * 2, Math.random() * 2, Math.random() * 2 )
tempObject.updateMatrix()
ref.current.setMatrixAt(id, tempObject.matrix)
}
ref.current.instanceMatrix.needsUpdate = true
})
return (
<instancedMesh ref={ref} args={[null, null, count]} >
<sphereBufferGeometry attach="geometry" args={[1, 4, 4]}/>
<meshPhongMaterial attach="material" color="#ffffff" flatShading ="true"/>
</instancedMesh>
)
}
ReactDOM.render(
<Canvas
gl={{ antialias: false, alpha: false }}
camera={{ position: [0, 0, 400], near: 5, far: 1000 }}
onCreated={({ gl }) => gl.setClearColor('pink')}>
<ambientLight intensity={1.1} color="#222222" />
<directionalLight color="#ffffff" position={[1, 1, 1]} />
<Boxes count={1000}/>
<Effects />
</Canvas>,
document.getElementById('root')
)
我有同样的问题,你的代码看起来不错,问题是当你试图将 instancedMesh 与 ref 绑定时,我不知道为什么不能很好地与旧的反应版本绑定,但我修复了它升级反应和反应-dom 包从 ^16.9.0 到 16.10.2 版本。
我目前正在使用react-three-fiber制作场景,但我不知道如何将3D物体放置在不同的随机位置。我在 useFrame 中使用了一个 for 循环来获得不同的随机位置,但由于每次都会渲染,粒子将再次移动到随机位置。但我希望这些位置仅在初始化时是随机的,然后移动整个网格。但是如果我在 useframe 之前使用 for 循环,它会给出错误-"Cannot read property 'setMatrixAt' of undefined"。 PS- 我只是想重新创建 -https://threejs.org/examples/?q=postprocessing#webgl_postprocessing
import * as THREE from 'three'
import ReactDOM from 'react-dom'
import React, { useRef, useMemo, useState, useEffect } from 'react'
import { Canvas, useFrame } from 'react-three-fiber'
import Effects from './Effects'
import './styles.css'
const tempObject = new THREE.Object3D()
function Boxes({count}) {
const ref = useRef()
const previous = useRef()
const particles = useMemo(() => {
const temp = []
useFrame(state => {
const time = state.clock.getElapsedTime()
ref.current.rotation.x += 0.00000
ref.current.rotation.y += 0.00000
let i = 0
for (let x = 0; x < count; x++){
const id = i++
tempObject.position.set(Math.random() - 0.5, Math.random() - 0.5, Math.random() - 0.5 ).normalize()
tempObject.position.multiplyScalar( Math.random() * 40 )
tempObject.rotation.set( Math.random() * 2, Math.random() * 2, Math.random() * 2 )
tempObject.updateMatrix()
ref.current.setMatrixAt(id, tempObject.matrix)
}
ref.current.instanceMatrix.needsUpdate = true
})
return (
<instancedMesh ref={ref} args={[null, null, count]} >
<sphereBufferGeometry attach="geometry" args={[1, 4, 4]}/>
<meshPhongMaterial attach="material" color="#ffffff" flatShading ="true"/>
</instancedMesh>
)
}
ReactDOM.render(
<Canvas
gl={{ antialias: false, alpha: false }}
camera={{ position: [0, 0, 400], near: 5, far: 1000 }}
onCreated={({ gl }) => gl.setClearColor('pink')}>
<ambientLight intensity={1.1} color="#222222" />
<directionalLight color="#ffffff" position={[1, 1, 1]} />
<Boxes count={1000}/>
<Effects />
</Canvas>,
document.getElementById('root')
)
我有同样的问题,你的代码看起来不错,问题是当你试图将 instancedMesh 与 ref 绑定时,我不知道为什么不能很好地与旧的反应版本绑定,但我修复了它升级反应和反应-dom 包从 ^16.9.0 到 16.10.2 版本。