把三维模型放到网站上!

Loading Models 加载模型

通过这两个模块,我们可以加载并创建一个模型组件然后放到我们的场景组件中:

Loading GLTF models

这个页面上的所有模型都是由Sara Vieira创建的,可从任何codesandbox免费下载

有许多类型的3D模型文件类型,在这个页面上,我们将专注于加载三种最常见的类型:GLTFFBXOBJ。所有这些扩展名的文件都将使用useLoader函数,但使用略有不同。

整个部分都假定已经将模型放置在public文件夹中或在应用程序中可以轻松导入它们的地方。

从开放标准和在React Three Fiber中支持性最好以及最推荐的文件类型开始,我们将加载一个.gltf模型。

我们可以先引入两个我们需要的模块:

import { useLoader } from '@react-three/fiber'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
function Scene() {
  const gltf = useLoader(GLTFLoader, '/Poimandres.gltf')
  return <primitive object={gltf.scene} />
}

你可以点击下面这个图片查看codesandbox来看看我给它添加了HDRI背景后的效果:

Loading GLTF models as JSX Components

把GLTF模型数据转换成JSX组件

这里是真正高端的部分,您可以将这些模型转换为React组件,然后像使用任何React组件一样使用它们。

要做到这一点,请获取您的GLTF模型并上传到https://gltf.pmnd.rs/,然后放置您的GLTF文件,之后您应该会看到类似以下的东西:

现在让我们复制代码并将其移动到Model.js文件中:

/*
Auto-generated by: https://github.com/pmndrs/gltfjsx
*/

import React, { useRef } from 'react'
import { useGLTF } from '@react-three/drei'

export default function Model(props) {
  const groupRef = useRef()
  const { nodes, materials } = useGLTF('/Poimandres.gltf')
  return (
    <group ref={groupRef} {...props} dispose={null}>
      <mesh castShadow receiveShadow geometry={nodes.Curve007_1.geometry} material={materials['Material.001']} />
      <mesh castShadow receiveShadow geometry={nodes.Curve007_2.geometry} material={materials['Material.002']} />
    </group>
  )
}

useGLTF.preload('/Poimandres.gltf')

现在,我们可以像导入任何React组件一样导入我们的模型,并在应用程序中使用它:

import { Suspense } from 'react'
import { Canvas } from '@react-three/fiber'
import { Environment } from '@react-three/drei'

import Model from './Model'

export default function App() {
  return (
    <div className="App">
      <Canvas>
        <Suspense fallback={null}>
          <Model />
          <Environment preset="sunset" background />
        </Suspense>
      </Canvas>
    </div>
  )
}

你可以试试这个 codesandbox

Loading OBJ models

接下来,我们将使用useLoader,与three.js的OBJLoader结合使用

import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader'
import { useLoader } from '@react-three/fiber'

利用这些两个模块功能,我们来在场景中实现模型:

function Scene() {
  const obj = useLoader(OBJLoader, '/Poimandres.obj')
  return <primitive object={obj} />
}

这样我们就已经把一个 OBJ 格式的模型展现在我们的页面中了!酷~

你可以试试这个 codesandbox

Loading FBX models

接下来,我们将使用useLoader,与three.js的FBXLoader结合使用

import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader'
import { useLoader } from '@react-three/fiber'

利用这些两个模块功能,我们来在场景中实现模型:

function Scene() {
  const fbx = useLoader(FBXLoader, '/Poimandres.fbx')
  return <primitive object={fbx} />
}

你可以试试这个 codesandbox

Loading FBX models using useFBX

使用 useFBX 来加载 FBX模型

@react-three/drei导出了一个非常有用的hook,用于加载FBX模型,它被称为useFBX,在这种情况下,没有必要从three.js中导入任何内容,因为所有操作都在幕后完成,我们只需将文件的位置传递给useFBX,如下所示:

function Scene() {
  const fbx = useFBX('/Poimandres.fbx')
  return <primitive object={fbx} />
}

你可以试试这个 codesandbox

Showing a loader 显示加载过程

如果您的模型很大并需要一段时间才能加载完成,最好显示一个加载过程,显示已经加载了多少内容,@react-three/drei有提供现成的两个组件,Html和useProgress。

— Html允许您在画布中放置普通的HTML,并像正常的DOM元素一样进行渲染。

— useProgress是一个钩子,提供有关模型加载状态的大量信息。

有了这两个东西,我们可以创建一个非常简单的加载组件,如下所示:

import { Html, useProgress } from '@react-three/drei'

function Loader() {
  const { progress } = useProgress()
  return <Html center>{progress} % loaded</Html>
}

然后,我们可以使用Suspense将我们的模型包装在其中,如下所示:

export default function App() {
  return (
    <Canvas>
      <Suspense fallback={<Loader />}>
        <Model />
      </Suspense>
    </Canvas>
  )
}

这个hook返回的不仅仅是进度,因此您可以在那里做很多事情,以向用户提供有关应用程序加载状态的更多信息。您可以在此codesandbox中尝试所有这些操作: