第二篇:Three.js核心三要素:場景、相機、渲染器

第二篇:Three.js核心三要素:場景、相機、渲染器

引言

在Three.js的世界里,場景(Scene)、相機(Camera)和渲染器(Renderer)構成了最基礎的"鐵三角"。它們如同導演、攝像機和放映機,共同決定了3D內容的呈現方式。本篇將深入解析這三個核心組件,并通過Vue3實戰案例展示它們的協同工作。


在這里插入圖片描述

1. 場景(Scene):3D世界的容器
1.1 場景的本質

場景是Three.js的頂級容器,所有3D對象(網格、燈光、相機)都需要加入場景才能被渲染。可以將其理解為:

  • 3D對象的舞臺
  • 空間坐標系的管理者
  • 場景圖(Scene Graph)的根節點
// 創建場景
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x87CEEB); // 設置天空藍背景
1.2 場景層級管理

Three.js使用樹狀結構管理對象:

Scene
Camera
Mesh1
Group
Mesh2
Mesh3

實戰:使用Group組織對象

<script setup>
import { ref, onMounted } from 'vue';
import * as THREE from 'three';const scene = new THREE.Scene();// 創建汽車組
const carGroup = new THREE.Group();
scene.add(carGroup);// 車身
const bodyGeo = new THREE.BoxGeometry(2, 0.5, 1);
const bodyMat = new THREE.MeshBasicMaterial({ color: 0xff0000 });
const body = new THREE.Mesh(bodyGeo, bodyMat);
carGroup.add(body);// 車輪
const wheelGeo = new THREE.CylinderGeometry(0.3, 0.3, 0.2, 16);
wheelGeo.rotateZ(Math.PI/2); // 旋轉90度使其立起
const wheelMat = new THREE.MeshBasicMaterial({ color: 0x333333 });const wheel1 = new THREE.Mesh(wheelGeo, wheelMat);
wheel1.position.set(0.7, -0.3, 0.5);
carGroup.add(wheel1);const wheel2 = wheel1.clone();
wheel2.position.z = -0.5;
carGroup.add(wheel2);// 移動整個汽車組
carGroup.position.x = -3;
</script>

關鍵點Group允許將多個對象作為單一實體操作,大幅簡化復雜對象的變換控制。


2. 相機(Camera):觀察世界的眼睛
2.1 透視相機(PerspectiveCamera)

模擬人眼視角,近大遠小效果:

const camera = new THREE.PerspectiveCamera(75, // 視野角度(FOV)window.innerWidth / window.innerHeight, // 寬高比0.1, // 近裁剪面(near)1000 // 遠裁剪面(far)
);
camera.position.set(0, 2, 5); // 設置相機位置
2.2 正交相機(OrthographicCamera)

平行投影,無透視變形:

const aspect = window.innerWidth / window.innerHeight;
const camera = new THREE.OrthographicCamera(-5 * aspect, // left5 * aspect,  // right5,           // top-5,          // bottom0.1,         // near100          // far
);
2.3 相機類型對比
特性透視相機正交相機
投影方式錐形投影平行投影
適用場景真實感場景技術圖紙/2.5D游戲
尺寸感知近大遠小保持物體原尺寸
參數復雜度簡單(4參數)復雜(6參數)
典型應用第一人稱游戲CAD查看器

3. 渲染器(Renderer):將3D轉為2D
3.1 渲染器核心配置
<script setup>
import { ref, onMounted, onUnmounted } from 'vue';const canvasRef = ref(null);onMounted(() => {const renderer = new THREE.WebGLRenderer({canvas: canvasRef.value,antialias: true, // 開啟抗鋸齒alpha: true,     // 允許透明背景powerPreference: "high-performance" // 高性能模式});// 設置像素比和尺寸renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));renderer.setSize(window.innerWidth, window.innerHeight);// 開啟陰影renderer.shadowMap.enabled = true;renderer.shadowMap.type = THREE.PCFSoftShadowMap; // 柔和陰影
});
</script>
3.2 響應式窗口處理
// Vue3中使用@vueuse/core監聽窗口變化
import { useWindowSize } from '@vueuse/core';const { width, height } = useWindowSize();watch([width, height], () => {camera.aspect = width.value / height.value;camera.updateProjectionMatrix(); // 必須更新相機renderer.setSize(width.value, height.value);
});

4. 綜合實戰:多相機切換系統
4.1 項目結構
src/├── components/│    ├── CameraSystem.vue   // 相機系統組件│    └── SceneObjects.vue   // 場景對象組件└── App.vue
4.2 相機切換核心代碼
<!-- CameraSystem.vue -->
<script setup>
import { ref } from 'vue';// 相機枚舉類型
const CameraType = {PERSPECTIVE: 0,ORTHOGRAPHIC: 1
};const currentCamera = ref(CameraType.PERSPECTIVE);
const cameras = {[CameraType.PERSPECTIVE]: createPerspectiveCamera(),[CameraType.ORTHOGRAPHIC]: createOrthographicCamera()
};function createPerspectiveCamera() {const camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);camera.position.set(0, 2, 5);return camera;
}function createOrthographicCamera() {const aspect = window.innerWidth / window.innerHeight;const camera = new THREE.OrthographicCamera(-5*aspect, 5*aspect, 5, -5, 0.1, 100);camera.position.set(0, 2, 5);camera.lookAt(0, 0, 0);return camera;
}function toggleCamera() {currentCamera.value = currentCamera.value === CameraType.PERSPECTIVE ? CameraType.ORTHOGRAPHIC : CameraType.PERSPECTIVE;
}
</script><template><button @click="toggleCamera" class="camera-toggle">{{ currentCamera === CameraType.PERSPECTIVE ? '正交視圖' : '透視視圖' }}</button>
</template>
4.3 渲染循環適配多相機
// 在渲染循環中使用當前相機
function animate() {requestAnimationFrame(animate);// 獲取當前激活的相機const activeCamera = cameras[currentCamera.value];// 旋轉場景物體scene.traverse(obj => {if (obj.isMesh) obj.rotation.y += 0.01;});renderer.render(scene, activeCamera);
}
4.4 相機切換效果對比

5. 高級技巧:相機控制器
5.1 引入OrbitControls
npm install three-orbitcontrols
<script setup>
import { OrbitControls } from 'three-orbitcontrols';onMounted(() => {const controls = new OrbitControls(camera, renderer.domElement);// 配置控制器參數controls.enableDamping = true; // 啟用阻尼效果controls.dampingFactor = 0.05; // 阻尼系數controls.autoRotate = true;    // 自動旋轉controls.autoRotateSpeed = 1.0;// 在渲染循環中更新控制器function animate() {requestAnimationFrame(animate);controls.update(); // 必須每幀更新renderer.render(scene, camera);}
});
</script>
5.2 控制器限制設置
// 限制垂直旋轉角度
controls.minPolarAngle = Math.PI / 6; // 30度
controls.maxPolarAngle = Math.PI / 2; // 90度// 禁用平移
controls.enablePan = false;// 縮放限制
controls.minDistance = 3;
controls.maxDistance = 15;

6. 常見問題解答

Q1:物體在場景中不可見怎么辦?

  1. 檢查物體是否添加到場景 scene.add(mesh)
  2. 確認相機位置是否在物體前方
  3. 驗證物體是否在相機裁剪范圍內

Q2:如何實現畫布透明背景?

const renderer = new THREE.WebGLRenderer({alpha: true, // 開啟透明度premultipliedAlpha: false // 避免顏色預乘
});
scene.background = null; // 清除場景背景

Q3:為什么正交相機看到的物體是扁平的?

  • 調整正交相機參數范圍:
// 正確設置左右上下參數的比例關系
const aspect = window.innerWidth / window.innerHeight;
const height = 10;
const width = height * aspect;const camera = new THREE.OrthographicCamera(-width/2, width/2, // left, rightheight/2, -height/2, // top, bottom1, 1000
);

7. 總結

通過本篇學習,你已掌握:

  1. 場景的層級管理技巧(使用Group組織對象)
  2. 透視相機與正交相機的核心區別及適用場景
  3. 渲染器的關鍵配置項(抗鋸齒/陰影/響應式)
  4. Vue3中實現多相機切換系統
  5. 使用OrbitControls實現交互控制

核心原理:Three.js的渲染流程本質上是將場景中的3D對象,通過相機的視角轉換,最終由渲染器投影到2D畫布上的過程。


下一篇預告

第三篇:幾何體入門:內置幾何體全解析
你將學習:

  • 12種基礎幾何體的創建與參數調整
  • 幾何體頂點(Vertex)與面(Face)的底層原理
  • 動態生成參數化幾何體(如可調節分段數的球體)
  • 幾何體性能優化技巧(BufferGeometry詳解)
  • Vue3實現幾何體參數實時調節面板

準備好探索Three.js的幾何世界了嗎?讓我們從最簡單的立方體開始,逐步揭開3D建模的神秘面紗!

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

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

相關文章

RagFlow本地源碼部署(非Docker)

參考官方文檔做個總結 1. 提前安裝好uv pipx install uv pre-commit2. 下載源碼&#xff1a; git clone https://github.com/infiniflow/ragflow.git cd ragflow/ uv sync --python 3.10 --all-extras # install RAGFlow dependent python modules uv run download_deps.py …

[免費]基于Python的招聘職位信息推薦系統(獵聘網數據分析與可視化)(Django+requests庫)【論文+源碼+SQL腳本】

大家好&#xff0c;我是python222_小鋒老師&#xff0c;看到一個不錯的基于Python的招聘職位信息推薦系統(獵聘網數據分析與可視化)(Djangorequests庫)&#xff0c;分享下哈。 項目視頻演示 【免費】基于Python的招聘職位信息推薦系統(獵聘網數據分析與可視化)(Django爬蟲) P…

國產化PDF處理控件Spire.PDF教程:Java 提取 PDF 圖片,高質量提取與圖片過濾技巧

在處理包含圖片的 PDF 文件時&#xff0c;例如掃描文檔、產品手冊或宣傳資料&#xff0c;我們經常需要將其中的圖像提取出來&#xff0c;用于保存、識別或再加工。E-iceblue旗下Spire系列產品&#xff0c;是文檔處理領域的佼佼者&#xff0c;支持國產化信創。本文將介紹如何使用…

Cesium 快速入門(七)材質詳解

Cesium 快速入門&#xff08;七&#xff09;材質詳解 看過的知識不等于學會。唯有用心總結、系統記錄&#xff0c;并通過溫故知新反復實踐&#xff0c;才能真正掌握一二 作為一名摸爬滾打三年的前端開發&#xff0c;開源社區給了我飯碗&#xff0c;我也將所學的知識體系回饋給大…

C++:結構體(Structure)

目錄 第一性原理出發&#xff1a;我們要解決什么問題&#xff1f; 定義結構體&#xff08;Defining Structures&#xff09; 問題&#xff1a;名字太長怎么辦&#xff1f; 如何定義結構體變量&#xff1f; 結構體的大小&#xff08;Size of Structures&#xff09; 初始化…

化學結構式解讀指南:從基礎認知到InDraw智能識別

中文名稱&#xff1a;3-[2-(二甲基氨基)乙基]-1H-吲哚英文名稱&#xff1a;3-[2-(dimethylamino)ethyl]-1H-indole分子式: C12H16N2分子量: 188.2740這是什么結構式&#xff1f;怎么繪制呢&#xff1f;可以用InDraw里的AI圖像識別這個結構式&#xff0c;也可以手動繪圖&#xf…

如何使用一臺電腦adb調試多個Android設備

目錄 一、臨時斷開其中一個設備連接 二、指定調試設備 總結 當我們使用Android調試工具調試多個設備&#xff0c;例如一開始使用adb連接了一臺Android真機進行調試&#xff0c;此時又在Android studio中打開了一個模擬機&#xff0c;此時我們在adb命令窗口中使用adb命令的…

ChatGPT的下一站:從“答案引擎”到“思維教練”

摘要&#xff1a;我們正處在一個“萬物皆可ChatGPT”的時代&#xff0c;但當它淪為最高效的“代碼搬運工”和“作業速成器”時&#xff0c;我們得到的究竟是效率的提升還是思維的退化&#xff1f;本文深入探討一個引人深思的概念——“導師模式”的AI。它不再直接提供答案&…

SpringBoot集成Flyway

SpringBoot集成Flyway_springboot flyway-CSDN博客 Flyway 本質上是一個開源的數據庫遷移工具&#xff0c;它能夠以自動化、可重復且可靠的方式管理數據庫的變更。無論是小型項目還是大型企業級應用&#xff0c;Flyway 都能助力開發者輕松應對數據庫架構的演進。它支持多種數據…

【實時Linux實戰系列】實時圖像處理應用開發

在當今快速發展的技術領域&#xff0c;實時圖像處理應用在眾多領域發揮著至關重要的作用。從自動駕駛汽車、工業自動化檢測到醫療影像診斷&#xff0c;實時圖像處理技術的應用場景無處不在。通過在實時Linux系統中開發圖像處理應用&#xff0c;開發者能夠充分利用Linux的穩定性…

Caterpillar Fungus Optimizer, CFO

核心算法解析1. 算法框架與初始化class EnhancedCFO: def __init__(self, objective_func, dim10, pop_size30, max_iter200, lb-10, ub10):??改進點??&#xff1a;針對傳統優化算法后期易停滯的問題&#xff0c;結合了精英策略、多樣性控制和自適應參數??關鍵特性??&a…

c++設計模式編程練習

一、運用觀察者模式原理編寫鳥類模型運行結果&#xff1a;二、運用簡單工廠模式編寫打怪掉裝備模型運行結果

FastMCP本地構建Server和Clinet交互

1. MCP Server介紹 MCP Server 是實現模型上下文協議&#xff08;MCP&#xff09;的服務器&#xff0c;旨在為 AI 模型提供一個標準化接口&#xff0c;連接外部數據源和工具&#xff0c;例如文件系統、數據庫或 API。 相比之下&#xff0c;在MCP出現前&#xff0c;AI調用工具…

工業企業與清潔生產匹配數據庫(1998-2015年)

1484工業企業與清潔生產匹配數據庫&#xff08;1998-2015年&#xff09;“清潔生產”近年發文趨勢及主題分布數據來源中華人民共和國生態環境部以及中國工業企業數據庫&#xff0c;由數據皮皮俠團隊整理時間跨度1998-2015年數據范圍各工業企業數據指標參考文獻孫博文,鄭世林.環…

第13屆藍橋杯C++青少組中/高級組選拔賽2022年1月22日真題

第13屆藍橋杯C青少組中/高級組選拔賽2022年1月22日真題 更多內容請查看網站&#xff1a;【試卷中心 -----> 藍橋杯----> C ----> 選拔賽】 網站鏈接 青少年軟件編程歷年真題模擬題實時更新 編程題 第 1 題 比大小 題目描述&#xff1a; 給出兩個不同的整數&#…

從0到1學PHP(七):PHP 與 HTML 表單:實現數據交互

目錄一、表單的創建與提交方式1.1 HTML 表單的基本結構1.2 GET 和 POST 提交方式的區別及適用場景二、表單數據的接收與處理2.1 使用\$_GET、\$_POST 超全局變量獲取表單數據2.2 對接收的數據進行驗證三、表單安全處理3.1 防止 XSS 攻擊的方法3.2 防止 CSRF 攻擊的措施一、表單…

Docker compose和Docker-compose的區別

Docker Compose 的兩個命令形式 docker compose&#xff08;空格連接&#xff09;與 docker-compose&#xff08;短橫線連接&#xff09;核心區別如下&#xff1a;一、技術本質docker-compose&#xff08;短橫線&#xff09;獨立可執行文件&#xff1a;早期實現方式&#xff0c…

自定心深凹槽參數檢測裝置及檢測方法 - 激光頻率梳 3D 輪廓檢測

一、引言在機械零件深凹槽檢測中&#xff0c;傳統方法常因定心不準導致檢測誤差。如平臺推表檢測時零件基準面與測量平臺難以精準對齊&#xff0c;三坐標測量需人工找正&#xff0c;效率低且誤差大。激光頻率梳 3D 輪廓檢測雖精度高&#xff0c;但缺乏自定心機制會影響深凹槽軸…

C語言---結構體(格式、用法、嵌套、初始化)、共用體、枚舉類型、typedef類型

目錄 結構體與共用體 1、結構體(struct) (1) 格式與用法 (2) 結構體允許嵌套 (3) 結構體成員初始化 (4) 指針替換變量 (5) 求結構體在內存空間所占字節 2、共用體(union) (1) 格式與概念 (2) 應用 3、枚舉類型(enum) (1) 格式與概念 (2) 應用 4、typedef 類型 結構體與共用…

輻射源定位方法簡述

文章目錄 前言 一、按照信息建模分類 1.1.時間參數 1.1.1.到達時間&#xff08;TOA, Time of Arrival&#xff09;定位 1.1.2.到達時間差&#xff08;TDOA, Time Difference of Arrival&#xff09;定位 1.2.角度參數 1.2.1.到達角度&#xff08;AOA, Angle of Arrival&a…