使用R3F或drei加载模型及动画

762 阅读2分钟

加载模型

加载模型方法1:从R3F引入useLoader

从three中的examples中引入GLTFLoader

路径是相对于public文件下的index出发的

  const model = useLoader(GLTFLoader, "./hambergur1148.glb");

将模型添加到场景中并缩放:

      <primitive object={model.scene} scale={0.01} />
添加draco类型的模型,draco模型比较小

将dracoLoader添加到GLTFLoader:在useLoader的第三个参数,是一个函数,函数的参数就是loader,即为GLTFLoader

  const model = useLoader(GLTFLoader, "./hambergur-draco.glb", (loader) => {
    const dracoLoader = new DRACOLoader();
    dracoLoader.setDecoderPath("./draco/");
    loader.setDRACOLoader(dracoLoader);
  });

加载模型方法2:用drei加载GLTF模型

export function Hambergur() {
  const model = useGLTF("./hambergur1148.glb");
  return <primitive object={model.scene} scale={0.35} />;
}
      <Suspense fallback={<PlaceHolder position-y={0.5} scale={[2, 3, 2]} />}>
        <Hambergur />
      </Suspense>

用drei加载draco模型也是用useGLTF

懒加载

问题:大模型会出现一开始是白屏,等待几秒模型下载后才出现

解决方法:懒加载

懒加载概念:当模型准备好就加入场景,在模型没有加载好之前就先展示其他东西,而不会出现白屏。懒加载用于加载大模型时的性能优化。

包裹模型组件。


 <Suspense
//在模型还没下载下来之前展示fallback中的内容           
        fallback={
          <mesh position-y={0.5} scale={[2, 3, 2]}>
            <boxGeometry args={[1, 1, 1, 2, 2, 2]} />
            <meshBasicMaterial wireframe color="red" />
          </mesh>
        }
      >
        <Model />
      </Suspense>

预加载

预先加载所有模型

可以用useGLTF函数上的preload方法


// 当这行代码所在的Model.js被加载 ./hambergur1148.glb"这个模型就会开始下载
useGLTF.preload("./hambergur1148.glb");

克隆

要100个汉堡包,使用drei中的Clone

这也可以优化性能,因为它只加载一个文件,然后把它应用到多个mesh

import { Clone, useGLTF } from "@react-three/drei";
​
export function Hambergur() {
  const model = useGLTF("./hambergur1148.glb");
  return (
    <>
      <Clone object={model.scene} scale={0.35} position-x={4} />
      <Clone object={model.scene} scale={0.35} position-x={-4} />
    </>
  );
}

在线改变模型的细节并生成代码

gltf.pmnd.rs

这个网站可以将模型转为组件, 组件分为模型的各个部分。可以调整模型并生成对应的代码

如果模型在我们项目的public文件下,就可以直接拷贝代码,如果需要下载模型,就选择export中的download zip

修改模型阴影:圆曲面会有阴影线,在方向光中设置:


​
      <directionalLight
        castShadow
        position={[1, 2, 3]}
        // 调整曲面的阴影线
        shadow-normalBias={0.04}
       //../>

加载模型动画

基本使用

使用drei的 useAnimations

github中

gtlf-Sample-Models 库中有模型
 import { useGLTF, useAnimations } from "@react-three/drei";
 
 const animations = useAnimations(fox.animations, fox.scene);
​
  //   在第一次渲染的时候还没有加载好动画,所以要在useEffect中调用动画
  useEffect(() => {
    const action = animations.actions.Run;
    action.play();
  }, []);

动画过渡

跑步2到3秒后开始走路,中间有过渡

​
    window.setTimeout(() => {
      animations.actions.Walk.play();
      //   从Run过渡到Walk,用1s,调用crossFadeFrom
      animations.actions.Walk.crossFadeFrom(animations.actions.Run, 1);
    }, 2000)

控制动画,让狐狸走或跑或搜寻

要使用Leva的useControls

​
  const { animationName } = useControls({
    animationName: {
      options: animations.names,
    },
  });
  
    //   在第一次渲染的时候还没有加载好动画,所以要在useEffect中调用动画
  //   在第一次渲染的时候还没有加载好动画,所以要在useEffect中调用动画
  useEffect(() => {
    const action = animations.actions[animationName];
    // reset()让动画重新开始,这样从最后的Run选项切换到第一个选项就不会卡住
    action.reset().fadeIn(0.5).play();
​
    return () => {
      // 这个函数会在animationName改变的时候被调用,可以拿到上一个action
      action.fadeOut(0.5);
    };
 
  }, [animationName]);

渐渐消失fadeOut