react fiber加载gltf文件:3d模型


前言

本文将从threejs引入3d模型讲起,到react fiber引入3d模型结束。


一、threejs引入3d模型(html版本)

1. 完整代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>3D人像</title>

</head>

<body>
    <script src="../libs/build/three.min.js"></script>
    <script src="../libs/jsm/loaders/GLTFLoader.js"></script>
    <script src="../libs/jsm/controls/OrbitControls.js"></script>
    <script src="../libs/jsm/Clock.js"></script>

    <script>
        // import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
        let scene, camera, renderer, controls;
        var root;

        function initScene() {
    
    
            //场景
            scene = new THREE.Scene();

            // 创建一个纹理图片加载器加载图片
            var textureLoader = new THREE.TextureLoader();
            // 加载背景图片
            var texture = textureLoader.load('../images/background.jpg');
            // 纹理对象Texture赋值给场景对象的背景属性.background
            scene.background = texture;

        }

        function initCamera() {
    
    
            //相机
            camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 200);
            camera.position.set(0, 15, 50);
        }

        function initRenderer() {
    
    
            //渲染器
            renderer = new THREE.WebGLRenderer({
    
     antiallias: true });
            //设置渲染区域尺寸
            renderer.setSize(window.innerWidth, window.innerHeight);
            document.body.appendChild(renderer.domElement);
        }


        function initHilght() {
    
    
            //环境光
            hilght = new THREE.AmbientLight(0x404040, 10);
            scene.add(hilght);
        }

        function initPeople() {
    
    
            //导入3D模型
            let loader = new THREE.GLTFLoader();
            loader.load(
                '../models/herbalist/scene.gltf',
                function (gltf) {
    
    
                    root = gltf.scene;

                    //模型大小
                    root.scale.set(0.5, 0.5, 0.5);
                    //初始位置
                    root.translateX(-10);
                    scene.add(root);

                    renderer.render(scene, camera);
                });
        }

        //渲染
        function render() {
    
    
            renderer.render(scene, camera);//执行渲染操作

            requestAnimationFrame(render);//请求再次执行渲染函数render
            
            
        }


        function initControl() {
    
    
            controls = new THREE.OrbitControls(camera, renderer.domElement)
            //监听控制器的鼠标事件,执行渲染内容
            controls.addEvemtListener('change', () => {
    
    
                renderer.render(scene, camera)
            })
        }

        function initLine() {
    
    
            var geometry = new THREE.BufferGeometry(); //声明一个几何体对象Geometry
            //参数:0, 0圆弧坐标原点x,y  100:圆弧半径    0, 2 * Math.PI:圆弧起始角度
            var arc = new THREE.ArcCurve(0, 20, 15, 10, 1 * Math.PI);
            //getPoints是基类Curve的方法,返回一个vector2对象作为元素组成的数组
            var points = arc.getPoints(50);//分段数50,返回51个顶点
            // setFromPoints方法从points中提取数据改变几何体的顶点属性vertices
            geometry.setFromPoints(points);
            //材质对象
            var material = new THREE.LineBasicMaterial({
    
    
                color: 0xffffff
            });
            //线条模型对象
            var line = new THREE.Line(geometry, material);
            scene.add(line); //线条对象添加到场景中
        }


        function init() {
    
    
            initScene();
            initCamera();
            initRenderer();

            initPeople();
            initLine();
            initHilght();
            render();
           
        }


        init();

    </script>

</body>

</html>

2. 代码详解

首先参考threejs官方文档中,引入3d模型的内容:

关键代码:

  1. 引入js文件
<script src="../libs/jsm/loaders/GLTFLoader.js"></script>
  1. 按格式引入gltf文件
function initPeople() {
    
    
            //导入3D模型
            let loader = new THREE.GLTFLoader();
            loader.load(
                '../models/herbalist/scene.gltf',
                function (gltf) {
    
    
                    root = gltf.scene;

                    //模型大小
                    root.scale.set(0.5, 0.5, 0.5);
                    //初始位置
                    root.translateX(-10);
                    scene.add(root);

                    renderer.render(scene, camera);
                });
        }

二、react fiber引入3d模型(react fiber版本)

1.代码详解

查看drei官方文档
如图所示,是useGLTF的用法/语法:
在这里插入图片描述

1.1 引入3d模型的资源

注意:

  1. 引入资源必须放在public文件夹下,否则会引入失败。(报错如图)
    在这里插入图片描述

问题一:为什么“资源必须放在public文件夹下”?

引入知识点:

在React中有个Public文件夹可以放静态资源,但是在src目录中同样有个assets文件夹,这个同样也是放静态资源的,这个就很困惑了,为何放置静态资源的地方会有两个?

原因如下:

两者区别就在于是否会被webpack所处理。

  1. Public文件夹放静态资源

如果您将文件放入该public文件夹,webpack 将不会处理它,在你打包的时候,会将public文件夹直接复制一份到你构建出来的文件夹中。
好处:把一些不会改动的静态文件放到public中,可以:

  • 减少文件构建时间,减少构建文件的大小
  • 避免首页白屏时间过长
  1. src目录中assets文件夹放静态资源

资源会被webpack编译,比如图片,如果你的图片小于你在webpack中的loader下设置的limit大小(可配置),它会被编译成base64,从而在实际项目中减少http请求,放置在src/assets目录有以下几点好处:

  • 脚本和样式表被缩小并捆绑在一起以避免额外的网络请求。
  • 缺少文件会导致编译错误,而不是用户的404错误。
  • 结果文件名包含内容哈希,因此您无需担心浏览器缓存旧版本。

问题二:引入 public 文件夹下的图片显示不出来?

注意!!该问题仅限于解决图片加载问题。

  • 出现错误如图:无法加载public下的图片文件
    在这里插入图片描述
  • 解决办法:
  • 在node_module文件夹下找到react-script/config/webpack.config.js,找到相应代码注释掉,然后重新启动项目,问题解决。(可以ctrl+f查找ModuleScopePlugin 相关的代码)
const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');

new ModuleScopePlugin(paths.appSrc, [
          paths.appPackageJson,
          reactRefreshOverlayEntry,
        ]),

问题三:无法加载 public 文件夹下的3D模型?

报错如图所示:models文件夹在public下,但是引用public下的models文件夹,3d模型引入失败,如图一,路径不存在,却可以引入成功(该问题仍未解决)
在这里插入图片描述
在这里插入图片描述
引入3d模型的完整代码:

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


export function Man(){
    
    
    const gltf = useLoader(GLTFLoader,'../../models/table_scene/girl/scene.gltf');
   
    return(
        <>     
        <primitive
            object={
    
    gltf.scene}
            position={
    
    [3,18,0]}
            rotation={
    
    [Math.PI/2, 0, 0]}
            scale={
    
    3}
        />
        </>
    );
}

1.2 需要引入的js文件

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

1.3 使用3d模型

在需要使用3d模型的js文件中,用标签形式引用。
例如:我将3d模型建在man.jsx文件中的function Man()函数中,引用时,
第一步:import { Man } from "../table/man"
第二步:

  <Canvas>
                    {
    
    /* 3d模型放置 */}
                 <Table position={
    
    [0, 0, 0]} />
                 <Man />
  <Canvas/>


猜你喜欢

转载自blog.csdn.net/JingYan_Chan/article/details/126058916
今日推荐