大白话react第十八章React 与 WebGL 项目的高级拓展与优化

news/2025/3/13 14:37:15/

大白话react第十八章React 与 WebGL 项目的高级拓展与优化

1. 实现 3D 模型的导入与动画

在之前的基础上,我们可以导入更复杂的 3D 模型,并且让这些模型动起来,就像在游戏里看到的角色和场景一样。这里我们使用 GLTF 格式的模型,它是一种常用的 3D 模型格式,并且 three.js 提供了很好的支持。

// 引入 React 的 useEffect 和 useRef 钩子
import React, { useEffect, useRef } from'react';
// 引入 three.js 用于创建 3D 场景
import * as THREE from 'three';
// 引入 GLTFLoader 用于加载 GLTF 格式的 3D 模型
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';const ModelAnimationComponent = () => {// 创建一个 ref 用于引用存放 3D 场景的 DOM 元素const containerRef = useRef(null);useEffect(() => {// 创建 three.js 的场景const scene = new THREE.Scene();// 创建透视相机,设置视角、宽高比、近裁剪面和远裁剪面const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);// 创建 WebGL 渲染器const renderer = new THREE.WebGLRenderer();// 设置渲染器的大小为窗口大小renderer.setSize(window.innerWidth, window.innerHeight);// 将渲染器的 DOM 元素添加到 ref 对应的 DOM 元素中containerRef.current.appendChild(renderer.domElement);// 创建一个环境光,让场景整体更亮const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);scene.add(ambientLight);// 创建一个点光源,让物体有明暗对比const pointLight = new THREE.PointLight(0xffffff, 1);pointLight.position.set(2, 5, 2);scene.add(pointLight);// 创建一个 GLTF 加载器const loader = new GLTFLoader();// 加载 GLTF 格式的 3D 模型loader.load('path/to/your/model.gltf', (gltf) => {// 获取加载的模型const model = gltf.scene;// 将模型添加到场景中scene.add(model);// 如果模型有动画if (gltf.animations.length > 0) {// 创建一个动画混合器,用于管理动画const mixer = new THREE.AnimationMixer(model);// 获取第一个动画const action = mixer.clipAction(gltf.animations[0]);// 播放动画action.play();// 定义渲染函数const animate = () => {// 请求下一帧动画requestAnimationFrame(animate);// 更新动画混合器mixer.update(0.01);// 渲染场景renderer.render(scene, camera);};// 开始动画循环animate();}});// 设置相机位置camera.position.z = 5;// 组件卸载时清理资源return () => {containerRef.current.removeChild(renderer.domElement);};}, []);return (// 创建一个 div 用于存放 3D 场景<div ref={containerRef} />);
};export default ModelAnimationComponent;
2. 实现多场景切换

在一些大型的 3D 应用中,可能需要多个不同的场景,并且能够在这些场景之间自由切换。我们可以通过管理多个场景对象,根据用户的操作来显示不同的场景。

// 引入 React 的 useEffect、useRef 和 useState 钩子
import React, { useEffect, useRef, useState } from'react';
// 引入 three.js 用于创建 3D 场景
import * as THREE from 'three';const MultiSceneComponent = () => {// 创建一个 ref 用于引用存放 3D 场景的 DOM 元素const containerRef = useRef(null);// 创建一个状态来存储当前显示的场景索引const [currentSceneIndex, setCurrentSceneIndex] = useState(0);useEffect(() => {// 创建两个 three.js 的场景const scenes = [new THREE.Scene(), new THREE.Scene()];// 创建透视相机,设置视角、宽高比、近裁剪面和远裁剪面const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);// 创建 WebGL 渲染器const renderer = new THREE.WebGLRenderer();// 设置渲染器的大小为窗口大小renderer.setSize(window.innerWidth, window.innerHeight);// 将渲染器的 DOM 元素添加到 ref 对应的 DOM 元素中containerRef.current.appendChild(renderer.domElement);// 为第一个场景添加一个立方体const cubeGeometry = new THREE.BoxGeometry(2, 2, 2);const cubeMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 });const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);scenes[0].add(cube);// 为第二个场景添加一个球体const sphereGeometry = new THREE.SphereGeometry(1, 32, 32);const sphereMaterial = new THREE.MeshBasicMaterial({ color: 0x00ff00 });const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);scenes[1].add(sphere);// 设置相机位置camera.position.z = 5;// 定义渲染函数const animate = () => {// 请求下一帧动画requestAnimationFrame(animate);// 获取当前要显示的场景const currentScene = scenes[currentSceneIndex];// 渲染当前场景renderer.render(currentScene, camera);};// 开始动画循环animate();// 组件卸载时清理资源return () => {containerRef.current.removeChild(renderer.domElement);};}, [currentSceneIndex]);return (<div>{/* 创建一个 div 用于存放 3D 场景 */}<div ref={containerRef} />{/* 创建按钮用于切换场景 */}<button onClick={() => setCurrentSceneIndex(0)}>切换到场景 1</button><button onClick={() => setCurrentSceneIndex(1)}>切换到场景 2</button></div>);
};export default MultiSceneComponent;
3. 实现 WebGL 与后端数据交互

有时候我们需要从后端获取数据,然后根据这些数据来更新 3D 场景。这里我们模拟一个从后端获取数据的过程,然后根据数据来改变 3D 物体的属性。

// 引入 React 的 useEffect、useRef 和 useState 钩子
import React, { useEffect, useRef, useState } from'react';
// 引入 three.js 用于创建 3D 场景
import * as THREE from 'three';const DataInteractionComponent = () => {// 创建一个 ref 用于引用存放 3D 场景的 DOM 元素const containerRef = useRef(null);// 创建一个状态来存储从后端获取的数据const [data, setData] = useState(null);useEffect(() => {// 模拟从后端获取数据const fetchData = async () => {try {const response = await fetch('https://example.com/api/data');const jsonData = await response.json();setData(jsonData);} catch (error) {console.error('获取数据失败:', error);}};fetchData();}, []);useEffect(() => {if (data) {// 创建 three.js 的场景const scene = new THREE.Scene();// 创建透视相机,设置视角、宽高比、近裁剪面和远裁剪面const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);// 创建 WebGL 渲染器const renderer = new THREE.WebGLRenderer();// 设置渲染器的大小为窗口大小renderer.setSize(window.innerWidth, window.innerHeight);// 将渲染器的 DOM 元素添加到 ref 对应的 DOM 元素中containerRef.current.appendChild(renderer.domElement);// 根据后端数据创建一个立方体const cubeGeometry = new THREE.BoxGeometry(data.size, data.size, data.size);const cubeMaterial = new THREE.MeshBasicMaterial({ color: data.color });const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);scene.add(cube);// 设置相机位置camera.position.z = 5;// 定义渲染函数const animate = () => {// 请求下一帧动画requestAnimationFrame(animate);// 渲染场景renderer.render(scene, camera);};// 开始动画循环animate();// 组件卸载时清理资源return () => {containerRef.current.removeChild(renderer.domElement);};}}, [data]);return (// 创建一个 div 用于存放 3D 场景<div ref={containerRef} />);
};export default DataInteractionComponent;

通过这些高级拓展和优化,你的 React 与 WebGL 项目会变得更加复杂和强大,能够满足更多的实际需求。

GLTF格式的特点和优势

GLTF 格式的特点和优势介绍

什么是 GLTF 格式

GLTF 就像是一个专门用来装 3D 模型和场景的“盒子”,它能把 3D 世界里的各种东西,像模型的形状、颜色、动画这些信息,有条理地打包起来,方便在不同的地方使用。

特点
1. 轻量化

GLTF 格式很“轻”,就好比一个轻装上阵的运动员。它不会携带一堆没用的东西,只装真正需要的信息。这样在传输的时候,速度就会很快,就像快递送一个很轻的包裹一样。而且它用一种叫 JSON 的格式来记录模型的基本信息,这种格式简单易懂,计算机处理起来也不费劲。

2. 通用性强

不管你用的是电脑、手机,还是其他什么设备,只要这个设备能处理 3D 内容,基本上都能打开 GLTF 格式的文件。就像一把万能钥匙,能开很多不同的“锁”,在各种 3D 软件、游戏引擎里都能使用。

3. 支持动画和材质

GLTF 可以把模型的动画也一起打包进去。想象一下,一个 3D 人物模型,它走路、跑步、挥手这些动作的动画,都能和模型本身放在一个“盒子”里。同时,它还能记录模型的材质信息,比如这个模型看起来是金属的、木头的,还是塑料的,都能清晰地表现出来。

4. 二进制扩展

除了基本的 JSON 格式,GLTF 还有二进制扩展。这就好比在原来的“盒子”外面又加了一个更结实的“外套”,能把一些更复杂、更占空间的数据,像模型的顶点数据,用二进制的方式存储,这样能让文件更小,读取速度也更快。

优势
1. 加载速度快

因为文件轻,所以在网页或者应用里加载 GLTF 格式的 3D 模型时,速度会非常快。用户不用等很长时间,就能看到模型,体验就会很好。

2. 易于编辑和共享

由于它的结构清晰,开发者很容易对 GLTF 文件进行编辑和修改。而且因为通用性强,不同的人之间分享这个格式的文件也很方便,大家都能打开和使用。

3. 跨平台兼容性好

不管是在电脑上的浏览器里,还是在手机的 APP 中,GLTF 格式的模型都能正常显示和使用。这样就可以让更多的人在不同的设备上体验到 3D 内容。

代码示例(使用 Three.js 加载 GLTF 模型)
// 引入 React 的 useEffect 和 useRef 钩子
import React, { useEffect, useRef } from'react';
// 引入 three.js 库,用于创建 3D 场景
import * as THREE from 'three';
// 引入 GLTFLoader 模块,专门用于加载 GLTF 格式的文件
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';// 定义一个 React 组件,用于展示加载的 GLTF 模型
const GLTFModelComponent = () => {// 创建一个 ref 对象,用于引用后续要添加 3D 场景的 DOM 元素const containerRef = useRef(null);useEffect(() => {// 创建一个 three.js 的场景对象,相当于一个 3D 世界的舞台const scene = new THREE.Scene();// 创建一个透视相机,设置视角、宽高比、近裁剪面和远裁剪面// 就像我们用相机拍照一样,确定我们看 3D 场景的视角和范围const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);// 创建一个 WebGL 渲染器,它的作用是把 3D 场景渲染成我们能看到的 2D 画面const renderer = new THREE.WebGLRenderer();// 设置渲染器的大小为窗口的宽度和高度,让场景能占满整个窗口renderer.setSize(window.innerWidth, window.innerHeight);// 将渲染器生成的 DOM 元素添加到之前创建的 ref 对应的 DOM 元素中containerRef.current.appendChild(renderer.domElement);// 创建一个环境光,让整个场景有一个基本的亮度,就像打开房间里的大灯const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);// 将环境光添加到场景中scene.add(ambientLight);// 创建一个点光源,它就像一个手电筒,可以照亮特定的区域const pointLight = new THREE.PointLight(0xffffff, 1);// 设置点光源的位置pointLight.position.set(2, 5, 2);// 将点光源添加到场景中scene.add(pointLight);// 创建一个 GLTFLoader 实例,用于加载 GLTF 文件const loader = new GLTFLoader();// 加载指定路径的 GLTF 文件// 第一个参数是文件的路径,第二个参数是加载成功后的回调函数loader.load('path/to/your/model.gltf', (gltf) => {// 获取加载的 GLTF 文件中的场景对象,也就是模型本身const model = gltf.scene;// 将模型添加到 three.js 的场景中scene.add(model);// 定义一个动画循环函数,用于不断更新和渲染场景const animate = () => {// 请求浏览器在下一次重绘之前调用 animate 函数,实现动画循环requestAnimationFrame(animate);// 渲染场景和相机,把 3D 场景变成我们能看到的画面renderer.render(scene, camera);};// 调用动画循环函数,开始动画animate();});// 设置相机的位置,让相机离场景有一定的距离,能看到整个场景camera.position.z = 5;// 组件卸载时的清理函数return () => {// 从 ref 对应的 DOM 元素中移除渲染器的 DOM 元素containerRef.current.removeChild(renderer.domElement);};}, []);// 返回一个 div 元素,用于承载 3D 场景return (<div ref={containerRef} />);
};// 导出这个组件,方便其他地方使用
export default GLTFModelComponent;

在这个代码示例中,我们使用 React 和 Three.js 来加载一个 GLTF 格式的 3D 模型。首先创建了一个 3D 场景和相机,然后添加了灯光,接着使用 GLTFLoader 加载 GLTF 文件,最后把加载的模型添加到场景中并进行渲染。这样就能在网页上看到加载的 3D 模型啦。

如何将GLTF格式的模型导入到WebGL项目中?

如何将 GLTF 格式的模型导入到 WebGL 项目中

1. 准备工作

在把 GLTF 格式的模型导入到 WebGL 项目之前,你得先有一个 WebGL 项目的基础框架,这里我们用 three.js 这个库,它能让我们更轻松地操作 WebGL。另外,你得准备好一个 GLTF 格式的 3D 模型文件,就好比你要往房子里放一件家具,得先有房子和家具。

2. 安装依赖

如果你还没安装 three.js,可以用下面的命令来安装:

npm install three
3. 编写代码

下面是详细的代码示例,我会逐行加上注释,让你能看明白每一步是干啥的。

// 引入 React 的 useEffect 和 useRef 钩子,useEffect 用于处理副作用,useRef 用于创建一个可变的 ref 对象
import React, { useEffect, useRef } from'react';
// 引入 three.js 库,这是一个强大的 WebGL 抽象库,能让我们更方便地创建 3D 场景
import * as THREE from 'three';
// 引入 GLTFLoader 模块,它专门用于加载 GLTF 格式的模型
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';const GLTFModelComponent = () => {// 创建一个 ref 对象,用于引用后续要渲染 3D 场景的 DOM 元素const containerRef = useRef(null);useEffect(() => {// 创建一个新的 three.js 场景,这就像是一个舞台,所有的 3D 对象都会放在这个舞台上const scene = new THREE.Scene();// 创建一个透视相机,它决定了我们从哪个角度、多大范围去看这个 3D 场景const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);// 创建一个 WebGL 渲染器,它负责把 3D 场景渲染成我们能看到的画面const renderer = new THREE.WebGLRenderer();// 设置渲染器的大小为浏览器窗口的宽度和高度,这样画面就能占满整个窗口renderer.setSize(window.innerWidth, window.innerHeight);// 把渲染器生成的 DOM 元素添加到之前创建的 ref 对应的 DOM 元素中,这样渲染的画面就能显示在网页上了containerRef.current.appendChild(renderer.domElement);// 创建一个环境光,它会均匀地照亮整个场景,让场景不会太暗const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);// 把环境光添加到场景中scene.add(ambientLight);// 创建一个点光源,它就像一个灯泡,能产生有方向的光照,让物体有明暗对比const pointLight = new THREE.PointLight(0xffffff, 1);// 设置点光源的位置pointLight.position.set(2, 5, 2);// 把点光源添加到场景中scene.add(pointLight);// 创建一个 GLTFLoader 实例,用于加载 GLTF 模型const loader = new GLTFLoader();// 调用 loader 的 load 方法来加载 GLTF 模型,这里的 'path/to/your/model.gltf' 要替换成你实际的模型文件路径loader.load('path/to/your/model.gltf', (gltf) => {// 当模型加载成功后,gltf.scene 就是加载好的 3D 模型对象const model = gltf.scene;// 把模型添加到场景中,这样模型就会出现在我们的舞台上了scene.add(model);// 定义一个动画函数,用于实现动画效果const animate = () => {// 请求浏览器在下一次重绘之前调用 animate 函数,实现动画循环requestAnimationFrame(animate);// 这里可以添加模型的动画逻辑,比如让模型旋转,下面的代码让模型绕 y 轴旋转model.rotation.y += 0.01;// 调用渲染器的 render 方法,把场景和相机作为参数传入,渲染出当前的画面renderer.render(scene, camera);};// 调用 animate 函数,开始动画循环animate();}, undefined, (error) => {// 如果加载模型过程中出现错误,打印错误信息console.error('加载模型时出错:', error);});// 设置相机的位置,让相机往后退一点,这样能看到整个场景camera.position.z = 5;// 组件卸载时的清理函数,移除渲染器的 DOM 元素,避免内存泄漏return () => {containerRef.current.removeChild(renderer.domElement);};}, []);return (// 创建一个 div 元素,用于容纳 3D 场景,通过 ref 属性关联到之前创建的 ref 对象<div ref={containerRef} />);
};export default GLTFModelComponent;
4. 代码解释
  • 引入必要的库和模块three.js 是核心库,GLTFLoader 专门用来加载 GLTF 模型。
  • 创建场景、相机和渲染器:场景是 3D 对象的容器,相机决定了我们的视角,渲染器负责把场景渲染成画面。
  • 添加光照:环境光和点光源能让模型看起来更真实,有明暗对比。
  • 加载 GLTF 模型:使用 GLTFLoaderload 方法,传入模型文件路径,加载成功后把模型添加到场景中。
  • 实现动画:通过 requestAnimationFrame 实现动画循环,在循环中更新模型的状态,然后重新渲染画面。
  • 清理工作:组件卸载时,移除渲染器的 DOM 元素,避免内存泄漏。
5. 注意事项
  • 要把 'path/to/your/model.gltf' 替换成你实际的 GLTF 模型文件路径。
  • 如果模型文件有纹理等资源,要确保这些资源的路径也正确。

通过以上步骤,你就能把 GLTF 格式的模型导入到 WebGL 项目中,并且让它动起来啦!

常用的处理GLTF格式的JavaScript库

常用处理 GLTF 格式的 JavaScript 库介绍

在开发使用 GLTF 格式 3D 模型的网页应用时,有几个常用的 JavaScript 库能帮助我们轻松处理这些模型。下面详细介绍这些库以及给出使用示例。

1. three.js
  • 简介:three.js 是一个非常流行的 WebGL 抽象库,它把复杂的 WebGL 操作封装成简单的 API,让开发者能轻松创建和展示 3D 场景,同时也对 GLTF 格式有很好的支持。
  • 代码示例
// 引入 React 的 useEffect 和 useRef 钩子,用于在组件挂载和卸载时执行操作以及引用 DOM 元素
import React, { useEffect, useRef } from'react';
// 引入 three.js 库,用于创建 3D 场景
import * as THREE from 'three';
// 引入 GLTFLoader 模块,专门用于加载 GLTF 格式的模型
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';const ThreeJSGLTFExample = () => {// 创建一个 ref 对象,用于引用存放 3D 场景的 DOM 元素const containerRef = useRef(null);useEffect(() => {// 创建一个 three.js 的场景对象,所有的 3D 元素都会添加到这个场景中const scene = new THREE.Scene();// 创建一个透视相机,设置视角、宽高比、近裁剪面和远裁剪面,模拟人眼的视角const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);// 创建一个 WebGL 渲染器,负责将 3D 场景渲染成 2D 图像显示在网页上const renderer = new THREE.WebGLRenderer();// 设置渲染器的大小为窗口的宽度和高度renderer.setSize(window.innerWidth, window.innerHeight);// 将渲染器的 DOM 元素添加到之前创建的 ref 对应的 DOM 元素中,这样就能在网页上显示场景了containerRef.current.appendChild(renderer.domElement);// 创建一个 GLTF 加载器实例const loader = new GLTFLoader();// 使用加载器加载指定路径的 GLTF 模型文件loader.load('path/to/your/model.gltf', (gltf) => {// 获取加载好的模型的场景对象const model = gltf.scene;// 将模型添加到之前创建的场景中scene.add(model);});// 设置相机的位置,让相机离场景有一定距离,能看到场景中的物体camera.position.z = 5;// 定义一个动画函数,用于不断更新和渲染场景const animate = () => {// 请求浏览器在下一次重绘之前调用 animate 函数,实现动画循环requestAnimationFrame(animate);// 使用渲染器渲染场景和相机,将 3D 场景转换成 2D 图像显示在网页上renderer.render(scene, camera);};// 调用动画函数,开始动画循环animate();// 组件卸载时的清理函数,移除渲染器的 DOM 元素,避免内存泄漏return () => {containerRef.current.removeChild(renderer.domElement);};}, []);return (// 创建一个 div 元素,用于存放 3D 场景,使用 ref 关联到之前创建的 ref 对象<div ref={containerRef} />);
};export default ThreeJSGLTFExample;
2. Babylon.js
  • 简介:Babylon.js 是一个功能强大的 3D 游戏和场景开发引擎,它提供了丰富的工具和功能,能让开发者快速创建出高质量的 3D 应用,对 GLTF 格式的支持也很完善。
  • 代码示例
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><!-- 引入 Babylon.js 的核心库 --><script src="https://cdn.babylonjs.com/babylon.js"></script><!-- 引入 Babylon.js 的加载器扩展库,用于加载 GLTF 模型 --><script src="https://cdn.babylonjs.com/loaders/babylonjs.loaders.min.js"></script><title>Babylon.js GLTF Example</title>
</head><body><!-- 创建一个 canvas 元素,用于显示 3D 场景 --><canvas id="renderCanvas"></canvas><script>javascript">// 获取 canvas 元素const canvas = document.getElementById('renderCanvas');// 创建一个 Babylon.js 的引擎实例,负责管理渲染和更新逻辑const engine = new BABYLON.Engine(canvas, true);// 创建一个函数,用于创建 3D 场景const createScene = function () {// 创建一个新的场景对象const scene = new BABYLON.Scene(engine);// 创建一个自由相机,允许用户在场景中自由移动视角const camera = new BABYLON.FreeCamera('camera1', new BABYLON.Vector3(0, 5, -10), scene);// 设置相机看向场景的原点camera.setTarget(BABYLON.Vector3.Zero());// 让相机控制 canvas 的输入,比如鼠标和键盘操作camera.attachControl(canvas, true);// 创建一个半球光,照亮场景const light = new BABYLON.HemisphericLight('light', new BABYLON.Vector3(0, 1, 0), scene);// 设置光的强度light.intensity = 0.7;// 使用场景的加载器加载指定路径的 GLTF 模型文件BABYLON.SceneLoader.ImportMesh("", "path/to/your/", "model.gltf", scene, function (newMeshes) {// 当模型加载完成后,将第一个网格对象移动到指定位置newMeshes[0].position = new BABYLON.Vector3(0, 0, 0);});return scene;};// 调用创建场景的函数,得到场景对象const scene = createScene();// 监听引擎的渲染循环事件,不断更新和渲染场景engine.runRenderLoop(function () {scene.render();});// 监听窗口大小变化事件,当窗口大小改变时,调整渲染器的大小window.addEventListener('resize', function () {engine.resize();});</script>
</body></html>
3. PlayCanvas
  • 简介:PlayCanvas 是一个基于 WebGL 的开源游戏开发平台,它提供了直观的可视化编辑器和强大的 JavaScript API,对 GLTF 格式的模型加载和处理也很方便。
  • 代码示例
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><!-- 引入 PlayCanvas 的引擎库 --><script src="https://code.playcanvas.com/playcanvas-stable.min.js"></script><title>PlayCanvas GLTF Example</title>
</head><body><!-- 创建一个 canvas 元素,用于显示 3D 场景 --><canvas id="application-canvas"></canvas><script>javascript">// 获取 canvas 元素const canvas = document.getElementById('application-canvas');// 创建一个 PlayCanvas 的应用实例,传入 canvas 元素和配置对象const app = new pc.Application(canvas, {mouse: new pc.Mouse(canvas),touch: 'ontouchstart' in window? new pc.TouchDevice(canvas) : null});// 设置应用的分辨率为自动适应窗口大小app.setCanvasFillMode(pc.FILLMODE_FILL_WINDOW);app.setCanvasResolution(pc.RESOLUTION_AUTO);// 启动应用app.start();// 创建一个实体作为相机,设置其位置和旋转const camera = new pc.Entity('camera');camera.addComponent('camera', {clearColor: new pc.Color(0.1, 0.1, 0.1)});camera.setPosition(0, 0, 5);app.root.addChild(camera);// 创建一个实体作为光照,设置其类型和颜色const light = new pc.Entity('light');light.addComponent('light', {type: 'directional',color: new pc.Color(1, 1, 1),intensity: 1});light.setEulerAngles(45, 30, 0);app.root.addChild(light);// 创建一个资源加载器,用于加载 GLTF 模型const loader = new pc.AssetLoader();// 定义一个资源对象,指定资源的类型为 GLTF 模型const modelAsset = new pc.Asset('model', 'container', {url: 'path/to/your/model.gltf'});// 将资源添加到加载器中loader.add(modelAsset);// 加载资源loader.load(function (err, assets) {if (err) {console.error('加载模型出错:', err);return;}// 获取加载好的模型资源const model = modelAsset.resource.instantiateRenderEntity();// 将模型添加到场景的根实体中app.root.addChild(model);});</script>
</body></html>

这些库都能帮助你轻松处理 GLTF 格式的模型,你可以根据自己的项目需求选择合适的库。

GLTF格式和FBX格式有什么区别?

GLTF 格式和 FBX 格式的区别

1. 整体用途和定位
  • GLTF 格式:这是一种专门为网络传输设计的 3D 格式。就好比是为了在互联网上快速“快递”3D 模型而定制的包装。它的主要目标是让 3D 模型能在网页、游戏、虚拟现实(VR)和增强现实(AR)等场景里高效地加载和显示。
  • FBX 格式:它是一种通用的 3D 交换格式,就像一个大仓库,能把各种 3D 软件里创建的模型、动画、材质等信息都存起来,方便在不同的 3D 软件之间传递和使用。比如说,你在 Maya 里做了个模型,想拿到 3ds Max 里接着做,就可以用 FBX 格式来传输。
2. 文件结构和大小
  • GLTF 格式:它的文件结构比较简单,就像一个精简版的行李包。它把 3D 模型的信息分成几个部分,用 JSON 文件来描述模型的结构、材质、动画等,而模型的几何数据和纹理等可以单独存成二进制文件。这样一来,文件大小就比较小,在网络上传输起来就快多了。
  • FBX 格式:FBX 文件就像一个装满东西的大箱子,它把所有的信息都打包在一起,包括模型的几何形状、骨骼动画、材质纹理、光照信息等等。虽然信息很全面,但文件往往比较大,传输起来就没那么快。
3. 兼容性
  • GLTF 格式:在网络和现代 3D 引擎里的兼容性很好。很多流行的 3D 引擎,像 Three.js、Unity、Unreal Engine 等都对它有很好的支持。而且很多网页浏览器也能直接加载和显示 GLTF 模型,非常适合做网页 3D 展示。
  • FBX 格式:在专业的 3D 建模和动画软件里兼容性很强。像 Maya、3ds Max、Blender 等软件都能很好地导入和导出 FBX 文件。但在网页端的支持就相对没那么好,需要额外的处理才能在网页上显示。
4. 数据存储方式
  • GLTF 格式:它采用了一种分层的存储方式,就像把不同的东西放在不同的抽屉里。JSON 文件负责记录模型的整体结构和配置信息,而二进制文件专门存放模型的顶点数据、索引数据等。纹理文件也可以单独存储,这样可以根据需要灵活加载。
  • FBX 格式:是一种二进制的整体存储方式,就像把所有东西都混在一个大袋子里。虽然这样能保证数据的完整性,但在修改和提取特定数据时就比较麻烦。
5. 代码示例(使用 Three.js 加载 GLTF 和 FBX 模型)
// 引入 React 的 useEffect 和 useRef 钩子
import React, { useEffect, useRef } from'react';
// 引入 three.js 用于创建 3D 场景
import * as THREE from 'three';
// 引入 GLTFLoader 用于加载 GLTF 格式的 3D 模型
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
// 引入 FBXLoader 用于加载 FBX 格式的 3D 模型
import { FBXLoader } from 'three/addons/loaders/FBXLoader.js';const ModelLoadingComponent = () => {// 创建一个 ref 用于引用存放 3D 场景的 DOM 元素const containerRef = useRef(null);useEffect(() => {// 创建 three.js 的场景const scene = new THREE.Scene();// 创建透视相机,设置视角、宽高比、近裁剪面和远裁剪面const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);// 创建 WebGL 渲染器const renderer = new THREE.WebGLRenderer();// 设置渲染器的大小为窗口大小renderer.setSize(window.innerWidth, window.innerHeight);// 将渲染器的 DOM 元素添加到 ref 对应的 DOM 元素中containerRef.current.appendChild(renderer.domElement);// 创建一个环境光,让场景整体更亮const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);scene.add(ambientLight);// 创建一个点光源,让物体有明暗对比const pointLight = new THREE.PointLight(0xffffff, 1);pointLight.position.set(2, 5, 2);scene.add(pointLight);// 设置相机位置camera.position.z = 5;// 加载 GLTF 格式的模型const gltfLoader = new GLTFLoader();gltfLoader.load('path/to/your/model.gltf', (gltf) => {// 获取加载的模型const model = gltf.scene;// 将模型添加到场景中scene.add(model);});// 加载 FBX 格式的模型const fbxLoader = new FBXLoader();fbxLoader.load('path/to/your/model.fbx', (fbx) => {// 将加载的 FBX 模型添加到场景中scene.add(fbx);});// 定义渲染函数const animate = () => {// 请求下一帧动画requestAnimationFrame(animate);// 渲染场景renderer.render(scene, camera);};// 开始动画循环animate();// 组件卸载时清理资源return () => {containerRef.current.removeChild(renderer.domElement);};}, []);return (// 创建一个 div 用于存放 3D 场景<div ref={containerRef} />);
};export default ModelLoadingComponent;

在这个代码示例里,我们用 Three.js 分别加载了 GLTF 和 FBX 格式的 3D 模型。通过对比加载过程和效果,能更直观地感受到这两种格式的特点。


http://www.ppmy.cn/news/1578808.html

相关文章

okhttp源码解析

1、okhttp比httpurlconnection好在哪里 OkHttp 相比于 HttpURLConnection 有以下优势&#xff1a; 功能丰富 支持连接池&#xff1a;OkHttp 通过管理连接池可以复用连接&#xff0c;减少了请求延时。而 HttpURLConnection 每次请求都需要重新建立连接&#xff0c;效率降低。 …

Driver Development Kit(驱动开发服务)

文章目录 一、Driver Development Kit 简介二、外设扩展驱动客户端开发指导一、Driver Development Kit 简介 Driver Development Kit(驱动开发套件)为外设驱动开发者提供高效、安全、丰富的外设扩展驱动开发解决方案C-API,支持外设驱动开发者为消费者带来外设即插即用的极…

【Godot4.4】写入和读取ZIP文件

概述 Godot提供了ZIPPacker类型来读写ZIP压缩包文件。本文是简单的写入和读取文件操作测试笔记。 写入纯文本文件 extends Buttonfunc _ready():write_zip_file("1.zip",func(zip_packer):write_txt_file_to_zippack(zip_packer,"1.txt","hhhhh&qu…

clickhouse源码分析

《ClickHouse源码分析》 当我们谈论数据库时&#xff0c;ClickHouse是一个不容忽视的名字。它是一个用于联机分析处理&#xff08;OLAP&#xff09;的列式数据库管理系统&#xff08;DBMS&#xff09;&#xff0c;以其快速的数据查询能力而闻名。对于想要深入了解这个高效工具…

Hyper-YOLO: When Visual Object Detection Meets Hypergraph Computation

简介&#xff1a; 时间&#xff1a;2025 期刊&#xff1a;TPAMI 作者&#xff1a;Yifan Feng, Jiangang Huang, Shaoyi Du, Shihui Ying, Jun-Hai Yong 摘要&#xff1a; ①Hyper-YOLO引入一种新的目标检测方法&#xff0c;结合超图计算捕捉视觉特征中的复杂高阶相关性 ②…

AI浪潮下嵌入式软件开发如何拥抱AI:VSCODE + MarscodeAI插件+Embedded IDE

一、引言 AI浪潮席卷各个领域&#xff0c;各领域都在探索与AI技术深度融合以创新并提升效率。嵌入式软件开发领域同样面临此机遇与挑战。VSCODE作为流行的开源代码编辑器&#xff0c;与MarscodeAI插件、eide相结合&#xff0c;为嵌入式软件开发的AI融合提供了新思路与方法。 二…

Diffusion-Probabilistic-Models环境配置

1、相关地址 代码地址:https://github.com/Sohl-Dickstein/Diffusion-Probabilistic-Models 论文地址:https://arxiv.org/abs/2006.11239 2、python2.7 环境安装 conda create -n theano python2.7 -y conda activate theano3、包安装 下载合适的版本&#xff0c;也就是201…

简要分析NETLINK_USER参数

NETLINK_USER是Linux Netlink协议族的一个预留类型&#xff0c;允许开发者自定义用户空间与内核空间&#xff08;或用户空间进程间&#xff09;的通信协议。它提供了一种高度灵活的IPC机制&#xff0c;适合于需要高效、结构化、双向通信的场景&#xff0c;尤其是当现有Netlink …