大白話react第十八章React 與 WebGL 項目的高級拓展與優化

大白話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>// 獲取 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>// 獲取 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.pswp.cn/diannao/73139.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/73139.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/73139.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

有關Java中的多線程

學習目標 ● 掌握線程相關概念 ● 掌握線程的基本使用 ● 掌握線程池的使用 ● 了解解決線程安全方式 1.為什么要學習線程? ● 從1946年2月14日世界上第一臺計算機在美國賓夕法尼亞大學誕生到今天&#xff0c;計算和處理的模式早已從單用戶單任務的串行模式發展到了多用戶多…

Spring Boot集成EasyExcel

1. 初始化Spring Boot項目 首先&#xff0c;使用Spring Initializr&#xff08;https://start.spring.io/&#xff09;生成一個基本的Spring Boot項目。選擇以下依賴項&#xff1a; Spring WebLombok (用于減少樣板代碼)SLF4J (用于日志記錄) 2. 添加依賴 在你的pom.xml文件…

(2025|ICLR|廈大華為,LoSA,基于表示互信息的動態層級稀疏率,基于重構誤差的秩分配)LLM 的動態低秩稀疏自適應

Dynamic Low-Rank Sparse Adaptation for Large Language Models 目錄 1. 引言 1.1 關鍵詞 2. 方法 2.1 預備知識 2.2 層級稀疏率確定 2.3 稀疏感知的秩分配 2.4 動態稀疏與適配 3. 實驗 3.1 實驗設置 3.2 語言建模 3.3 零樣本任務 3.4 N:M 稀疏性 3.5 消融實驗 …

p5.js:sound(音樂)可視化,動畫顯示音頻高低變化

本文通過4個案例介紹了使用 p5.js 進行音樂可視化的實踐&#xff0c;包括將音頻振幅轉化為圖形、生成波形圖。 承上一篇&#xff1a;vite&#xff1a;初學 p5.js demo 畫圓圈 cd p5-demo copy .\node_modules\p5\lib\p5.min.js . copy .\node_modules\p5\lib\addons\p5.soun…

linux 進程和計劃管理

查看進程 在Linux系統中&#xff0c;有多個命令可以用來查看進程 以下是一些常用的命令&#xff1a; ps命令&#xff1a;用于查看當前系統中的進程狀態。 基本用法&#xff1a;ps -ef&#xff0c;該命令會以完整格式顯示所有進程的詳細信息&#xff0c;包括用戶ID、進程ID、父…

DeepSeek 多模態大模型 Janus-Pro 本地部署教程

下載模型倉庫 git clone https://github.com/deepseek-ai/Janus.git 國內下載倉庫失敗時&#xff0c;可以使用以下代理&#xff1a; git clone https://github.moeyy.xyz/https://github.com/deepseek-ai/Janus.git 準備 Conda 3.12 虛擬環境 conda create --name deepseek7B p…

Qt開源控件庫(qt-material-widgets)的編譯及使用

項目簡介 qt-material-widgets是一個基于 Qt 小部件的 Material Design 規范實現。 項目地址 項目地址&#xff1a;qt-material-widgets 本地構建環境 Win11 家庭中文版 VS2019 Qt5.15.2 (MSVC2019) 本地構建流程 克隆后的目錄結構如圖&#xff1a; 直接使用Qt Crea…

ARM 嵌入式處理器內核與架構深度剖析(2): ARM 處理器架構剖析

目錄 一、ARM處理器架構剖析 1.1. 指令集架構&#xff08;ISA&#xff09; 1.2. 寄存器集 1.3. 存儲模型 1.4. 異常模型 二、架構設計精要 2.1 處理器模式與特權分級 2.2 寄存器銀行化技術 2.3 指令集演化 三、微架構核心技術 3.1 流水線創新 3.2 內存子系統 3.3 …

Flutter 按鈕組件 TextButton 詳解

目錄 1. 引言 2. TextButton 的基本用法 3. 主要屬性 4. 自定義按鈕樣式 4.1 修改文本顏色 4.2 添加背景色 4.3 修改按鈕形狀和邊距 4.4 樣式定制 5. 高級應用技巧 5.1 圖標文本組合 5.2 主題統一配置 5.3 動態交互 6. 性能優化與注意事項 6.1 點擊區域優化 6.…

std::ranges::views::split, lazy_split, std::ranges::split_view, lazy_split_view

std::ranges::views::split, std::ranges::split_view C20 中引入的用于分割范圍&#xff08;range&#xff09;的組件&#xff0c;允許將輸入范圍按特定分隔符或條件分割成多個子范圍。以下是詳細說明和示例&#xff1a; 基本概念 1. 功能 分割范圍&#xff1a;將輸入范圍&…

c++ constraints與concepts使用筆記

c constraints與concepts使用筆記 1. 模板參數缺乏約束的問題2. Concepts 基本概念3. Concept 的定義與使用4. requires 表達式詳解5. requires 從句 vs requires 表達式完整示例&#xff1a;約束矩陣運算 1. 模板參數缺乏約束的問題 問題分析&#xff1a; 傳統模板參數沒有語…

Qt | 屏幕截圖實現

01 全局截屏控件 1. 鼠標右鍵彈出菜單。 2. 支持全局截屏。 3. 支持局部截屏。 4. 支持截圖區域拖動。 5. 支持圖片另存為。 演示 點擊按鈕即可截圖 源碼: 通過網盤分享的文件:screenwidget屏幕截圖 鏈接: https://pan.baidu.com/s/1PZfQlUXNIoZKEfEtLNV2jQ?pwd=5jsg 提…

2.angular指令

初級使用可以查看視頻 參考手冊 注意 像ng-class,ng-value,ng-href等這些&#xff0c;很多都可以直接用class“{{}}” 原生寫&#xff0c;為啥還出這些指令&#xff0c;是因為原生的比如剛一進頁面就先出現表達式了&#xff0c;瀏覽器走到這里的時候才去解析&#xff0c;給用戶…

CTFshow 【WEB入門】信息搜集 【VIP限免】 web1-web17

CTFshow 【 WEB入門】、【VIP限免】 web1 ----源碼泄露 首先第一步&#xff0c;看源代碼 web2----前臺JS繞過 簡單點擊查看不了源代碼&#xff0c;可以強制查看 比如 Ctrl Shift ICtrl U或者在url前加一個view-source: view-source:http://79999ca1-7403-46da-b25b-7ba9…

java 手搓一個http工具類請求傳body

import java.io.*; import java.net.HttpURLConnection; import java.net.URL; import java.nio.charset.StandardCharsets;public class HttpUtil {/*** JSON請求發起*/public static String httpJsonRequest(String requestUrl, String requestJson) {String responseJson &…

Spring boot3-WebClient遠程調用非阻塞、響應式HTTP客戶端

來吧&#xff0c;會用就行具體理論不討論 1、首先pom.xml引入webflux依賴 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId> </dependency> 別問為什么因為是響應式....…

寫了一個二叉樹構造函數和畫圖函數,方便debug

代碼 class TreeNode(object):def __init__(self, val, leftNone, rightNone):self.val valself.left leftself.right rightdef construct_tree(nodes):if not nodes:return Noneroot TreeNode(nodes[0])queue [root]index 1while index < len(nodes):node queue.p…

QT:串口上位機

創建工程 布局UI界面 設置名稱 設置數據 設置波特率 波特率默認9600 設置數據位 數據位默認8 設置停止位 設置校驗位 調整串口設置、接收設置、發送設置為Group Box 修改配置 QT core gui serialport 代碼詳解 mianwindow.h 首先在mianwindow.h當中定義一個串口指…

【Pandas】pandas Series asof

Pandas2.2 Series Time Series-related 方法描述Series.asfreq(freq[, method, how, …])用于將時間序列數據轉換為指定的頻率Series.asof(where[, subset])用于返回時間序列中指定索引位置的最近一個非缺失值 pandas.Series.asof pandas.Series.asof 方法用于返回時間序列…

沉浸式CSS學習路徑

好的!我將以魔法學院成長故事為框架,為您設計一套沉浸式CSS學習路徑。以下是敘事化學習提綱: 第一卷:像素學徒的覺醒 章節1:被封印的魔法書 發現HTML的"素顏"本質,通過<!DOCTYPE html>解除網頁封印用style標簽打開CSS魔法書,學會給文字穿上color斗篷和…