Three.js - 打開Web 3D世界的大門

文章目錄

    • 前言
    • 一、Three.js 的起源與背景
    • 二、Three.js 的特點
    • 三、Three.js 的核心組件詳解
    • 四、實際應用案例
    • 結語


前言

Three.js 是一個基于JavaScript的庫,它極大地簡化了使用WebGL創建3D圖形的過程。通過封裝復雜的WebGL API,Three.js為開發者提供了一個更加友好和高效的開發環境,使得即使是對3D編程不太熟悉的開發者也能夠快速上手,并創造出令人印象深刻的交互式3D內容。


一、Three.js 的起源與背景

Three.js 是由一位西班牙的開發者 Ricardo Cabello(又名 Mr.doob)于2010年發起的項目。其初衷是為了簡化WebGL(Web Graphics Library)的使用難度,因為直接使用WebGL進行3D渲染需要大量的代碼編寫,并且API相對復雜。Three.js通過封裝WebGL的功能,提供了一個更加友好、易于使用的接口,使得更多的開發者可以快速上手并創造出令人驚艷的3D內容。

二、Three.js 的特點

  • 易用性:Three.js 提供了豐富的文檔和支持,擁有龐大的社區,對于初學者來說是一個很好的入門選擇。
  • 跨平臺兼容性:由于它是基于WebGL構建的,因此可以在任何支持HTML5和WebGL的瀏覽器上運行,無需安裝額外的插件。
  • 廣泛的適用性:無論是游戲開發、虛擬現實應用還是數據可視化,Three.js都能提供強有力的支持。
  • 性能優化:隨著版本迭代,Three.js不斷改進性能,確保即使是在處理復雜場景時也能保持流暢。

三、Three.js 的核心組件詳解

場景(Scene)

場景是所有3D對象、光源和其他元素的容器。在Three.js中,我們首先需要創建一個場景對象,然后將其他組件添加到這個場景中。

const scene = new THREE.Scene();

相機(Camera)

相機決定了用戶從哪個視角觀看場景。Three.js提供了多種類型的相機,如透視相機(PerspectiveCamera),它模仿人眼的視覺效果,適合大多數應用場景;還有正交相機(OrthographicCamera),它用于創建技術圖紙或UI元素等不需要透視效果的內容。

const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5;

渲染器(Renderer)

渲染器負責將場景中的內容繪制到HTML頁面上的canvas元素中。Three.js支持多種渲染器,但最常用的是WebGLRenderer,因為它提供了最好的性能和兼容性。

const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

物體(Object)

物體是由幾何形狀(Geometry)和材質(Material)組成的3D模型。Three.js內置了許多常見的幾何形狀,比如球體、立方體、圓柱體等,并且可以通過自定義幾何體來實現更復雜的設計。

const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);

動畫與交互

Three.js不僅限于靜態圖像,還支持動畫和用戶交互。你可以使用requestAnimationFrame循環更新場景,或者監聽鼠標事件來響應用戶的操作。

function animate() {requestAnimationFrame(animate);// 更新物體的位置或旋轉等屬性cube.rotation.x += 0.01;cube.rotation.y += 0.01;renderer.render(scene, camera);
}
animate();

四、實際應用案例

案例1:旋轉的立方體

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>Simple FPS Game</title><style>body {margin: 0;}canvas {display: block;}</style>
</head><body><script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script><script>// 創建場景var scene = new THREE.Scene();// 創建相機var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);camera.position.z = 5;// 創建渲染器var renderer = new THREE.WebGLRenderer();renderer.setSize(window.innerWidth, window.innerHeight);document.body.appendChild(renderer.domElement);// 創建一個立方體幾何體var geometry = new THREE.BoxGeometry();// 創建一個材質var material = new THREE.MeshBasicMaterial({ color: 0x00ff00, wireframe: true });// 創建一個網格(幾何體 + 材質)var cube = new THREE.Mesh(geometry, material);scene.add(cube);// 渲染函數function animate() {requestAnimationFrame(animate);// 旋轉立方體cube.rotation.x += 0.01;cube.rotation.y += 0.01;renderer.render(scene, camera);}// 開始動畫循環animate();// 處理窗口大小調整window.addEventListener('resize', function () {var width = window.innerWidth;var height = window.innerHeight;renderer.setSize(width, height);camera.aspect = width / height;camera.updateProjectionMatrix();});</script>
</body></html>

案例2:軌道運動動畫

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>Simple FPS Game</title><style>body {margin: 0;}canvas {display: block;}</style>
</head><body><script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script><script>// 初始化場景、相機和渲染器var scene = new THREE.Scene();var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);var renderer = new THREE.WebGLRenderer({ antialias: true });renderer.setSize(window.innerWidth, window.innerHeight);document.body.appendChild(renderer.domElement);// 創建球體并設置初始位置function createOrbitingSphere(radius, distance, speed) {var geometry = new THREE.SphereGeometry(radius, 32, 32);var material = new THREE.MeshBasicMaterial({ color: Math.random() * 0xffffff });var sphere = new THREE.Mesh(geometry, material);sphere.position.x = distance;sphere.distance = distance;sphere.angle = 0;sphere.speed = speed;scene.add(sphere);return sphere;}var spheres = [];for (var i = 0; i < 10; i++) {spheres.push(createOrbitingSphere(0.5 + Math.random(), 5 + i * 2, 0.005 + Math.random() * 0.01));}camera.position.z = 20;function animate() {requestAnimationFrame(animate);spheres.forEach(function (sphere) {sphere.angle += sphere.speed;sphere.position.x = Math.cos(sphere.angle) * sphere.distance;sphere.position.y = Math.sin(sphere.angle) * sphere.distance;});renderer.render(scene, camera);}animate();// 窗口調整事件處理window.addEventListener('resize', function () {var width = window.innerWidth;var height = window.innerHeight;renderer.setSize(width, height);camera.aspect = width / height;camera.updateProjectionMatrix();});</script>
</body></html>

案例3:隨機生成的粒子系統

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>Simple FPS Game</title><style>body {margin: 0;}canvas {display: block;}</style>
</head><body><script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script><script>var scene = new THREE.Scene();var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);var renderer = new THREE.WebGLRenderer({ antialias: true });renderer.setSize(window.innerWidth, window.innerHeight);document.body.appendChild(renderer.domElement);camera.position.z = 50;var particlesCount = 5000;var particlesGeometry = new THREE.BufferGeometry();var particlesPositions = new Float32Array(particlesCount * 3);for (var i = 0; i < particlesCount * 3; i++) {particlesPositions[i] = (Math.random() - 0.5) * 100;}particlesGeometry.setAttribute('position', new THREE.BufferAttribute(particlesPositions, 3));var particlesMaterial = new THREE.PointsMaterial({ color: 0x00ff00 });var particles = new THREE.Points(particlesGeometry, particlesMaterial);scene.add(particles);function animateParticles() {var positions = particles.geometry.attributes.position.array;for (var i = 0; i < positions.length; i += 3) {positions[i + 1] -= 0.1;if (positions[i + 1] < -50) {positions[i + 1] = 50;}}particles.geometry.attributes.position.needsUpdate = true;}function animate() {requestAnimationFrame(animate);animateParticles();renderer.render(scene, camera);}animate();// 窗口調整事件處理window.addEventListener('resize', function () {var width = window.innerWidth;var height = window.innerHeight;renderer.setSize(width, height);camera.aspect = width / height;camera.updateProjectionMatrix();});</script>
</body></html>

結語

Three.js作為Web 3D開發的強大工具,正在不斷推動著網絡技術的發展邊界。無論是創建沉浸式的用戶體驗、教育工具,還是進行復雜的數據可視化,Three.js都展現出了其獨特的價值。隨著社區的不斷壯大和技術的進步,Three.js的應用前景無疑將更加廣闊。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/65388.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/65388.shtml
英文地址,請注明出處:http://en.pswp.cn/web/65388.shtml

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

相關文章

恒壓恒流原邊反饋控制芯片 CRE6289F

CRE6289F 系列產品是一款內置高壓 MOS 功率開關管的高性能多模式原邊控制的開關電源芯片。較少的外圍元器件、較低的系統成本設計出高性能的交直流轉換開關電源。CRE6289F 系列產品提供了極為全面和性能優異的智能化保護功能&#xff0c;包括逐周期過流保護、軟啟動、芯片過溫保…

開源 AI 智能名片 2+1 鏈動模式商城小程序在商業營銷中的心理博弈與策略應用

摘要&#xff1a;在當今競爭激烈的商業環境中&#xff0c;理解消費者心理對營銷成敗起著關鍵作用。本文聚焦于消費者 “占便宜” 心理&#xff0c;深入探討開源 AI 智能名片 21 鏈動模式商城小程序如何利用這一心理&#xff0c;在 “雙十一”“雙十二” 等購物熱潮背景下&#…

01 數據分析介紹及工具準備

數據分析介紹及工具準備 一、工具準備二、下載和使用Anaconda三、jupyter notebook常用快捷鍵 一、工具準備 數據科學庫 NumPy&#xff0c;SciPy&#xff0c;Pandas&#xff0c;Scikit-Learn 數據可視化庫 Matplotlib&#xff0c;Seaborn 編譯器 Jupyter Notebook 數據科…

opencv攝像頭標定程序實現

攝像頭標定是計算機視覺中的一個重要步驟&#xff0c;用于確定攝像頭的內參&#xff08;如焦距、主點、畸變系數等&#xff09;和外參&#xff08;如旋轉矩陣和平移向量&#xff09;。OpenCV 提供了方便的工具來進行攝像頭標定。下面分別給出 C 和 Python 的實現。 1. C 實現…

后端Java開發:第十三天

第十三天&#xff1a;繼承 - 面向對象的核心概念 歡迎來到第十三天的學習&#xff01;今天&#xff0c;我們將深入探討 Java 中的 繼承&#xff08;Inheritance&#xff09;&#xff0c;這是面向對象編程的四大基本特性之一。繼承是指一個類&#xff08;子類&#xff09;通過繼…

java項目之網上租貿系統源碼(springboot+mysql+vue)

風定落花生&#xff0c;歌聲逐流水&#xff0c;大家好我是風歌&#xff0c;混跡在java圈的辛苦碼農。今天要和大家聊的是一款基于springboot的網上租貿系統。項目源碼以及部署相關請聯系風歌&#xff0c;文末附上聯系信息 。 項目簡介&#xff1a; 基于Spring Boot的網上租貿…

協方差矩陣

協方差矩陣是一個對稱矩陣&#xff0c;用來描述多個隨機變量之間的協方差關系。協方差反映了兩個隨機變量如何共同變化的趨勢&#xff0c;協方差矩陣將這種關系擴展到了多維數據。 1. 定義 假設有一個 n 維隨機向量 &#xff0c;協方差矩陣 Σ 定義為&#xff1a; 其中&#…

spring boot controller放到那一層

在 Spring Boot 應用程序中&#xff0c;Controller 層通常被放置在應用程序的 表示層&#xff08;Presentation Layer&#xff09; 或 用戶界面層&#xff08;UI Layer&#xff09; 中。Controller 層的主要職責是處理用戶的 HTTP 請求&#xff0c;并將請求轉發給服務層進行業務…

計算機網絡之---局域網

什么叫局域網 局域網&#xff08;LAN&#xff0c;Local Area Network&#xff09; 是指在一個相對較小的區域內&#xff0c;如家庭、辦公室、學校、企業等&#xff0c;連接多個計算機和設備的網絡。局域網的特點是覆蓋范圍小、傳輸速度快、構建成本較低。 局域網的主要特點&…

Spring Boot + Jasypt 實現application.yml 屬性加密的快速示例

Jasypt(Java Simplified Encryption)是一個專為Java應用程序設計的開源加密庫,旨在簡化加密和解密流程,保護敏感數據如密碼、API密鑰等。 jasypt-spring-boot-starter允許開發者在Spring Boot應用中輕松地實現加密和解密功能。 本篇介紹使用 jasypt-spring-boot-starter 以…

HarmonyOS開發:傳參方式

一、父子組件傳參 1、父傳子&#xff08;Prop方式&#xff09; 父組件代碼 Entry Component struct ParentComponent {State parentMessage: string Hello from Parent;build() {Column() {ChildComponent({ message: this.parentMessage });}} } 子組件代碼 Component s…

deepin系統下開放指定端口

一、安裝ufw 若已安裝則跳過 sudo apt-get install ufw二、查看防火墻狀態 sudo ufw status三、打開防火墻 sudo ufw enable四、開放端口 sudo ufw allow 6654/tcp五、windows下測試遠程端口 telnet 192.168.1.22 6654六、關閉防火墻 sudo ufw disable附上ufw的全部命令…

微信小程序中使用 TypeScript 定義組件時,Component 函數確實需要多個類型參數

在微信小程序中使用 TypeScript 定義組件時&#xff0c;Component 函數確實需要多個類型參數&#xff0c;而不僅僅是一個。這些參數包括&#xff1a; Properties&#xff1a;組件的屬性&#xff08;props&#xff09;類型。 Data&#xff1a;組件的內部數據類型。 Methods&am…

我在廣州學 Mysql 系列——與索引相關的練習題

??大家好&#xff0c;我是練小杰&#xff0c;今天星期二啦&#xff0c;還有三天就是星期五了&#xff0c;為了美好生活奮斗吧朋友們&#xff01; 本文將學習MYSQL中數據表內容的索引相關練習題目~~ 復習&#xff1a;&#x1f449;【索引詳解】 數據庫專欄&#x1f449;【數據…

通過 route 或 ip route 管理Linux主機路由

目錄 一&#xff1a;route 使用說明1、查看路由信息2、刪除指定路由3、增加指定路由 二&#xff1a;ip route 使用說明1、查看主機路由2、新增主機路由3、刪除主機路由 通過route 或者ip route修改Linux主機路由后屬于臨時生效&#xff0c;系統重啟后就恢復默認值了&#xff0c…

SASS 簡化代碼開發的基本方法

概要 本文以一個按鈕開發的實例&#xff0c;介紹如何使用SASS來簡化CSS代碼開發的。 代碼和實現 我們希望通過CSS開發下面的代碼樣式&#xff0c;從樣式來看&#xff0c;每個按鈕的基本樣式相同&#xff0c;就是顏色不同。 如果按照傳統的方式開發&#xff0c;需要開發btn &…

我用Ai學Android Jetpack Compose之Button

答案來自 通義千問&#xff0c;代碼同樣需要到Android Studio里實踐&#xff0c;才能學會。完整工程代碼見文末。 我要學Button&#xff0c;麻煩介紹一下 當然可以&#xff01;Button 是 Jetpack Compose 中用于創建可點擊按鈕的 Composable 函數。它提供了豐富的配置選項來定…

flutter 專題三十六 Flutter動態化框架Thresh

一、前言 移動端技術棧自誕生以來&#xff0c;其雙端開發成本和發布效率一直廣受詬病。為了解決這些問題&#xff0c;前端跨端技術一直在不斷嘗試&#xff0c;希望能一次開發、多端運行并且能做到快速發布。期間經歷了多個技術發展階段。 第一階段&#xff1a;以H5為代表&…

NodeJs 箭頭函數:`()=>{}` 和 `()=>()` 的區別與使用場景

在 JavaScript 中&#xff0c;箭頭函數&#xff08;Arrow Function&#xff09;是一種簡潔的函數寫法&#xff0c;它不僅可以減少代碼量&#xff0c;還能避免 this 綁定的問題。然而&#xff0c;箭頭函數有兩種常見的寫法&#xff1a;()>{} 和 ()>()。這兩種寫法雖然看起…

緩存-Redis-緩存更新策略-主動更新策略-Cache Aside Pattern(全面 易理解)

**Cache-Aside Pattern&#xff08;旁路緩存模式&#xff09;**是一種廣泛應用于緩存管理的設計模式&#xff0c;尤其在使用 Redis 作為緩存層時尤為常見。該模式通過在應用程序與緩存之間引入一個旁路&#xff0c;確保數據的一致性和高效性。本文將在之前討論的 Redis 主動更新…