ThreeJS?入門如何渲染出第一個(gè)3D圖形
什么是ThreeJS?
Three.js 是一個(gè)用于在Web瀏覽器上創(chuàng)建和顯示交互式 3D 圖形的 JavaScript 庫(kù)。簡(jiǎn)化了在 Web 上創(chuàng)建基于 WebGL 的 3D 圖形的過(guò)程。WebGL 是一種在 Web 瀏覽器中實(shí)現(xiàn)硬件加速的 3D 圖形渲染的技術(shù)。Three.js 通過(guò)封裝復(fù)雜的WebGL API,提供了一個(gè)更簡(jiǎn)單的接口,使得我們能夠輕松地在瀏覽器中創(chuàng)建 3D 場(chǎng)景、模型、動(dòng)畫和交互效果。
渲染一個(gè) 3D 圖形需要哪些步驟?
要渲染第一個(gè) 3D 圖形,需要以下幾個(gè)步驟:
- 創(chuàng)建場(chǎng)景 scene,使用 THREE.Scene 進(jìn)行創(chuàng)建。
- 創(chuàng)建相機(jī) camera,使用 THREE.PerspectiveCamera 進(jìn)行創(chuàng)建。
- 創(chuàng)建渲染對(duì)象(以立方體為例),并添加到場(chǎng)景 scene 中。
- 創(chuàng)建渲染器 renderer,并進(jìn)行場(chǎng)景渲染,使用THREE.WebGLRenderer 進(jìn)行創(chuàng)建。調(diào)用渲染器 render 函數(shù)將場(chǎng)景 scene 和相機(jī) camera 作為參數(shù)進(jìn)行渲染。
// 插入一個(gè)跳轉(zhuǎn)地址,方便查看完整代碼
創(chuàng)建場(chǎng)景
在 Three.js 中,使用 THREE.Scene 來(lái)創(chuàng)建 scene(場(chǎng)景),scene包含了所有 3D 對(duì)象、光源和相機(jī)的容器。它是構(gòu)建和組織 3D 場(chǎng)景的基礎(chǔ)。
場(chǎng)景(THREE.Scene)類代表了一個(gè)虛擬的 3D 空間,其中可以包含各種對(duì)象,例如幾何體、模型、燈光等。通過(guò)將對(duì)象添加到場(chǎng)景中,可以在渲染過(guò)程中將它們呈現(xiàn)到屏幕上。
創(chuàng)建一個(gè)簡(jiǎn)單的場(chǎng)景:
import * as THREE from 'three'; const scene = new THREE.Scene();
實(shí)例化后的 scene 對(duì)象提供一些列的API來(lái)對(duì)其中的 3D 對(duì)象進(jìn)行管理,如: scene.add(object: Object3D)
、scene.remove(object: Object3D)
, scene.traverse(callback: Function)
。還提供對(duì) scene 進(jìn)行設(shè)置和操作的 API 本文暫時(shí)未使用到 scene 中其他的API,后續(xù)單獨(dú)寫篇文章進(jìn)行介紹。
創(chuàng)建相機(jī)
在 Three.js 中,camera(相機(jī))是用于定義場(chǎng)景中的視角和觀察位置的對(duì)象。相機(jī)確定了渲染器如何將場(chǎng)景中的 3D 對(duì)象投影到屏幕上,決定了觀察者在場(chǎng)景中看到的內(nèi)容。使用相機(jī)來(lái)控制觀察者在場(chǎng)景中的位置和視角。在 openGL 中相機(jī)的位置固定在(0,0,0)位置,所有的相機(jī)移動(dòng)實(shí)際都是對(duì)場(chǎng)景中的所有對(duì)象進(jìn)行矩陣變換。
Three.js 提供了多種類型的相機(jī),常用的是透視相機(jī)(THREE.PerspectiveCamera)和正交相機(jī)(THREE.OrthographicCamera)。
- 透視相機(jī)(THREE.PerspectiveCamera)使用透視投影,模擬了人眼的視覺(jué)效果。它具有視場(chǎng)角(FOV)、縱橫比、近剪裁面和遠(yuǎn)剪裁面等屬性。視場(chǎng)角決定了場(chǎng)景在相機(jī)前方可見(jiàn)的范圍,縱橫比定義了視圖的寬高比,近剪裁面和遠(yuǎn)剪裁面則定義了相機(jī)的可見(jiàn)范圍。
- 正交相機(jī)(THREE.OrthographicCamera)使用正交投影,產(chǎn)生了一個(gè)沒(méi)有透視效果的平行投影。它具有左、右、上、下、近、遠(yuǎn)等屬性,用于定義可見(jiàn)區(qū)域的范圍。
本文使用透視相機(jī)創(chuàng)建一個(gè)實(shí)例:
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
參數(shù)主要如下,THREE.PerspectiveCamera(fov, aspect, near, far)
- fov: 視場(chǎng)角,表示相機(jī)的視角張度,單位是度。
- aspect: 縱橫比,表示渲染區(qū)域的寬高比。
- near: 近剪裁面的距離,表示相機(jī)能夠看到的最近距離,在近剪裁面之前的3D對(duì)象會(huì)被裁剪掉。
- far: 遠(yuǎn)剪裁面,表示相機(jī)能夠看到的最遠(yuǎn)距離。在此之后的對(duì)象也會(huì)被裁剪掉。
不用擔(dān)心,后續(xù)會(huì)專門寫篇文章進(jìn)行詳細(xì)介紹兩相機(jī)之間的區(qū)別,什么是近剪裁面、遠(yuǎn)剪裁面以及其距離怎么算的。
創(chuàng)建渲染對(duì)象(立方體為)
創(chuàng)建一個(gè)正立方體:
// 創(chuàng)建綠色的立方體 // 創(chuàng)建立方體幾何體 const geometry = new THREE.BoxGeometry(1,1,1); // 實(shí)例化基礎(chǔ)的材質(zhì),顏色設(shè)置為綠色, rgb 每?jī)蓚€(gè)十六進(jìn)制單位分別表示一個(gè)基礎(chǔ)元色。 const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 }); // 生成一個(gè)立方體網(wǎng)格對(duì)象,傳入幾何體對(duì)象和顏色材質(zhì)對(duì)象 const cube = new THREE.Mesh(geometry, material); // 將立方體網(wǎng)格對(duì)象添加到場(chǎng)景中 scene.add(cube);
這里涉及到三個(gè)新的基類分別是 THREE.BoxGeometry
、 THREE.MeshBasicMaterial
、 THREE.Mesh
- THREE.BoxGeometry 立方幾何體,用于創(chuàng)建長(zhǎng)方體或者立方體。 ThreeJS 提供 8 種 Shape 類用于創(chuàng)建基本幾何體和自定義形狀。還提供一些可以擴(kuò)展的基類,我們可以在這個(gè)基類的基礎(chǔ)上進(jìn)行其他封裝。openGL 提供的圖元實(shí)際很基礎(chǔ)(點(diǎn),線,線環(huán),線帶,三角形,三角扇,三角帶,四邊形),ThreeJS 進(jìn)行的大量封裝使得我們更好進(jìn)行形狀生成。(^_^)以后再開(kāi)篇進(jìn)行詳細(xì)介紹。
- MeshBasicMaterial 基礎(chǔ)材質(zhì),不受光照影響,只顯示顏色。ThreeJS 一共提供了 7 種常用材質(zhì)對(duì)象以及特殊的幾種材質(zhì)比如:粒子材質(zhì)等。
- Mesh 網(wǎng)格對(duì)象,用于將幾何體與材質(zhì)結(jié)合起來(lái)。ThreeJS 提供 6 種網(wǎng)格對(duì)象支持不同的使用場(chǎng)景。
創(chuàng)建渲染器將 scene 渲染出來(lái)
創(chuàng)建一個(gè) WebGLRenderer 渲染器渲染scene:
// 創(chuàng)建一個(gè) webgl 渲染器 const renderer = new THREE.WebGLRenderer(); // 設(shè)置渲染器的 size renderer.setSize(window.innerWidth, window.innerHeight); // 綁定輸出位置 document.body.appendChild(renderer.domElement); // 將 scene 渲染出來(lái) renderer.render(scene, camera);
渲染器是 ThreeJS 的核心組件,將 scene 場(chǎng)景中的三維對(duì)象渲染到屏幕上。ThreeJS 提供了三類常用的渲染器 WebGLRenderer
、 CanvasRenderer
、SVGRenderer
。預(yù)計(jì)未來(lái)可能會(huì)支持 WebGPURenderer
現(xiàn)在 Chrome 已經(jīng)支持 WebGPU 了并且性能比 Webgl 更好一些(反正隔壁 babyIcon 已經(jīng)支持了^v^)。
渲染器主要行為大體如下:
- 創(chuàng)建渲染上下文
- 設(shè)置渲染參數(shù)
- 渲染 scene
- 輸出渲染結(jié)果到載體(通常都是canvas)
至此已經(jīng)能渲染一個(gè)立方體了,接下來(lái)補(bǔ)充一丟丟代碼讓立方體渲染起來(lái)。
const rotateBox = () => { // 創(chuàng)建 scene 場(chǎng)景 const scene = new THREE.Scene(); // 創(chuàng)建相機(jī) const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); // 設(shè)置相機(jī)的z位置為5 ,位置:(0,0,5) camera.position.z = 5; // 創(chuàng)建綠色立方體 const geometry = new THREE.BoxGeometry(1, 1, 1); const material = new THREE.MeshBasicMaterial({ color: 0x00ffa1 }); const cube = new THREE.Mesh(geometry, material); scene.add(cube); // 創(chuàng)建渲染器 const renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // 讓立方體渲染起來(lái) function animate() { requestAnimationFrame(animate); cube.rotation.x += 0.01; cube.rotation.y += 0.01; renderer.render(scene, camera); } animate(); };
完整代碼(我在 react 中運(yùn)行),方便對(duì)每篇文章的 demo 進(jìn)行管理以及ui交互。代碼也可以復(fù)制到到 HTML 中執(zhí)行額外添加一行 threejs庫(kù)的引入即可:
import React, { useEffect } from 'react'; import * as THREE from 'three'; export default function OneDay() { const rotateBox = () => { // 創(chuàng)建 scene 場(chǎng)景 const scene = new THREE.Scene(); // 創(chuàng)建相機(jī) const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); // 設(shè)置相機(jī)的z位置為5 ,位置:(0,0,5) camera.position.z = 5; // 創(chuàng)建綠色立方體 const geometry = new THREE.BoxGeometry(1, 1, 1); const material = new THREE.MeshBasicMaterial({ color: 0x00ffa1 }); const cube = new THREE.Mesh(geometry, material); scene.add(cube); // 創(chuàng)建渲染器 const renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // 讓立方體渲染起來(lái) function animate() { requestAnimationFrame(animate); cube.rotation.x += 0.01; cube.rotation.y += 0.01; renderer.render(scene, camera); } animate(); }; useEffect(() => { rotateBox(); }, []); return <div id="container"></div> }
以上就是ThreeJS 入門如何渲染出第一個(gè)3D圖形的詳細(xì)內(nèi)容,更多關(guān)于ThreeJS渲染3D圖形的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
TypeScript數(shù)據(jù)結(jié)構(gòu)之隊(duì)列結(jié)構(gòu)Queue教程示例
這篇文章主要為大家介紹了TypeScript數(shù)據(jù)結(jié)構(gòu)之隊(duì)列結(jié)構(gòu)Queue教程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02TypeScript開(kāi)發(fā)HapiJS應(yīng)用詳解
這篇文章主要為大家介紹了TypeScript開(kāi)發(fā)HapiJS應(yīng)用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08前端算法之TypeScript包含min函數(shù)的棧實(shí)例詳解
這篇文章主要為大家介紹了前端算法之TypeScript包含min函數(shù)的棧實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09微信小程序?qū)崿F(xiàn)圖片自適應(yīng)(支持多圖)
這篇文章主要介紹了微信小程序如何實(shí)現(xiàn)圖片自適應(yīng)的相關(guān)資料,文中介紹的方法同樣適應(yīng)于多圖,有需要的朋友可以參考借鑒,下面來(lái)一起看看吧。2017-01-01TypeScript數(shù)據(jù)結(jié)構(gòu)棧結(jié)構(gòu)Stack教程示例
這篇文章主要為大家介紹了TypeScript數(shù)據(jù)結(jié)構(gòu)棧結(jié)構(gòu)Stack教程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02TypeScript判斷對(duì)稱的二叉樹(shù)方案詳解
這篇文章主要為大家介紹了TypeScript判斷對(duì)稱的二叉樹(shù)方案實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09數(shù)據(jù)結(jié)構(gòu)Typescript之哈希表實(shí)現(xiàn)詳解
這篇文章主要為大家介紹了數(shù)據(jù)結(jié)構(gòu)Typescript之哈希表實(shí)現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01TypeScript?泛型接口具體使用實(shí)戰(zhàn)
這篇文章主要為大家介紹了TypeScript?泛型接口具體使用實(shí)戰(zhàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-07-07