【问题标题】:Using React-Three-Fiber使用 React-Three-Fiber
【发布时间】:2021-08-20 03:02:12
【问题描述】:

我目前正在使用 React Three Fiber 来简单地渲染太阳和围绕它运行的地球来测试它。但是,在我每次运行开发服务器进行测试时添加代码以将纹理应用于各个球体后,球体无法渲染。我试过寻找有同样问题的人,但没有任何运气。这是我的程序代码。

import React, { useRef, useState } from 'react'
import { Canvas, useFrame, useLoader } from 'react-three-fiber'
import { TextureLoader } from 'three/src/loaders/TextureLoader'
import { useTexture } from "@react-three/drei";

function Sun(props) {
  const [colorMap] = useTexture(['Sun_texture.jpg'])
  const mesh = useRef()
  const [state, setState] = useState({ isHovered: false, isActive: false })
  useFrame((state) => {
    const time = state.clock.getElapsedTime()
    mesh.current.rotation.z = 0
    mesh.current.rotation.x = 0
    mesh.current.rotation.y = time / 5
  })

  return (
    <mesh
      {...props}
      ref={mesh}
      
      scale={[1, 1, 1]}
      onPointerOver={(e) => setState({ ...state, isHovered: true })}
      onPointerOut={(e) => setState({ ...state, isHovered: false })}>
      <sphereGeometry args={[0.5, 100, 100]} map={colorMap} />
      <meshStandardMaterial map={colorMap} transparent={true} emissive={'#444444'} emissiveIntensity={0.3}/>
    </mesh>
  )
}

function Earth(props) {
  const mesh = useRef()
  const [state, setState] = useState({ isHovered: false, isActive: false })
  const [colorMap] = useTexture(['Earth_texture.jpg'])
  useFrame((state) => {
    const time = state.clock.getElapsedTime()
    mesh.current.position.x = 4 * Math.sin(time / 10)
    mesh.current.position.y = 0
    mesh.current.position.z = 4 * Math.cos(time / 10)
    mesh.current.rotation.z = 0
    mesh.current.rotation.x = 0
    mesh.current.rotation.y = time / 2
  })

  return (
    <mesh
      {...props}
      ref={mesh}
      scale={[0.5, 0.5, 0.5]}
      onPointerOver={(e) => setState({ ...state, isHovered: true })}
      onPointerOut={(e) => setState({ ...state, isHovered: false })}>
      <sphereBufferGeometry args={[0.5, 40, 40]} map={colorMap} />
      <meshStandardMaterial map={colorMap} />
    </mesh>
  )
}



export default function App() {
  return (
    <Canvas camera={{position: [0, 2, 8]}}>
      <Sun position={[0, 0, 0]} />
      <Earth position={[3, 0, 0]} />
      <ambientLight intensity={0.01}/>
      <pointLight position={[0, 0, 0]}/>
      
      <spotLight position={[1.5, 0, 0]} distance={4}/>
      <spotLight position={[-1.5, 0, 0]} distance={4}/>
      <spotLight position={[0, 0, -1.5]} distance={4}/>
      <spotLight position={[0, 0, 1.5]} distance={4}/>
      <spotLight position={[0, 1.5, 0]} distance={4}/>
      <spotLight position={[0, -1.5, 0]} distance={4}/>
    </Canvas>
  )
}

特别是纹理部分是问题,但我找不到任何问题。

const [colorMap] = useTexture(['Sun_texture.jpg'])
...
<sphereGeometry args={[0.5, 100, 100]} map={colorMap} />
<meshStandardMaterial map={colorMap} transparent={true} emissive={'#444444'} emissiveIntensity={0.3}/>

【问题讨论】:

    标签: reactjs react-three-fiber


    【解决方案1】:

    您需要将&lt;Earth&gt; 组件放在&lt;Suspense&gt; 中,因为它需要加载纹理,所以这样做的方法是等待它使用suspense 加载。

    你可以指定一个对象在加载时显示

    <suspense fallback={<loadingComponent />} >
    

    所以这会给你类似的东西:

    import React, { useRef, useState, Suspense } from 'react'
    import { Canvas, useFrame, useLoader } from 'react-three-fiber'
    import { TextureLoader } from 'three/src/loaders/TextureLoader'
    import { useTexture } from "@react-three/drei";
    
    function Sun(props) {
      const [colorMap] = useTexture(['Sun_texture.jpg'])
      const mesh = useRef()
      const [state, setState] = useState({ isHovered: false, isActive: false })
      useFrame((state) => {
        const time = state.clock.getElapsedTime()
        mesh.current.rotation.z = 0
        mesh.current.rotation.x = 0
        mesh.current.rotation.y = time / 5
      })
    
      return (
        <mesh
          {...props}
          ref={mesh}
          
          scale={[1, 1, 1]}
          onPointerOver={(e) => setState({ ...state, isHovered: true })}
          onPointerOut={(e) => setState({ ...state, isHovered: false })}>
          <sphereGeometry args={[0.5, 100, 100]} map={colorMap} />
          <meshStandardMaterial map={colorMap} transparent={true} emissive={'#444444'} emissiveIntensity={0.3}/>
        </mesh>
      )
    }
    
    function Earth(props) {
      const mesh = useRef()
      const [state, setState] = useState({ isHovered: false, isActive: false })
      const [colorMap] = useTexture(['Earth_texture.jpg'])
      useFrame((state) => {
        const time = state.clock.getElapsedTime()
        mesh.current.position.x = 4 * Math.sin(time / 10)
        mesh.current.position.y = 0
        mesh.current.position.z = 4 * Math.cos(time / 10)
        mesh.current.rotation.z = 0
        mesh.current.rotation.x = 0
        mesh.current.rotation.y = time / 2
      })
    
      return (
        <mesh
          {...props}
          ref={mesh}
          scale={[0.5, 0.5, 0.5]}
          onPointerOver={(e) => setState({ ...state, isHovered: true })}
          onPointerOut={(e) => setState({ ...state, isHovered: false })}>
          <sphereBufferGeometry args={[0.5, 40, 40]} map={colorMap} />
          <meshStandardMaterial map={colorMap} />
        </mesh>
      )
    }
    
    
    
    export default function App() {
      return (
        <Canvas camera={{position: [0, 2, 8]}}>
          <Sun position={[0, 0, 0]} />
          <Suspense fallback={<Loading />}>
          <Earth position={[3, 0, 0]} />
          </Suspense>
          <ambientLight intensity={0.01}/>
          <pointLight position={[0, 0, 0]}/>
          
          <spotLight position={[1.5, 0, 0]} distance={4}/>
          <spotLight position={[-1.5, 0, 0]} distance={4}/>
          <spotLight position={[0, 0, -1.5]} distance={4}/>
          <spotLight position={[0, 0, 1.5]} distance={4}/>
          <spotLight position={[0, 1.5, 0]} distance={4}/>
          <spotLight position={[0, -1.5, 0]} distance={4}/>
        </Canvas>
      )
    }
    你可以在 codeSandbox 上找到关于 react-three-fiber 的很酷的东西和示例。

    https://codesandbox.io/search?refinementList%5Bnpm_dependencies.dependency%5D%5B0%5D=%40react-three%2Ffiber&page=1&configure%5BhitsPerPage%5D=12&query=

    如果您需要更高的精度,请告诉我。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-31
      • 2019-10-27
      • 2022-01-25
      • 1970-01-01
      • 2021-12-23
      • 2021-05-13
      • 2020-01-20
      • 2022-11-30
      相关资源
      最近更新 更多