# https://threejs.org/
# https://zh.wikipedia.org/wiki/Three.js
雖說從 WebGL API 以 Bottom-Up 方式著手才能徹底了解 WebFGL 3D 繪圖的精隨, 但那太費時間, 我覺得從較高階的 Three.js 以 Top-Down 方式來學才是快速上手之道.
Three.js 為 Ricardo Cabello 於 2012 年發布之 3D Javascript 函式庫開源專案, 它是基於 WebGL 的物件導向框架, 不需要像以前那樣依賴外部 Plug in 即可進行 3D 繪圖, 並可使用 GPU 加速. 其原始碼與教學文件寄存於 GitHub, 自發布以來經過多位貢獻者持續改進, 目前穩定版本為 r83 :
# https://github.com/mrdoob/three.js/
關於 Three.js 的發展摘要如下 :
- 前身是 Ricardo Cabello 以 ActionScript 實作的場景演示.
- Ricardo Cabello 於 2009 年移植到 Javascript.
- 2010 年首次發布於 GitHub.
- Paul Brunt 為 Three.js 添加渲染功能.
- Cabello 開發了 CanvasRenderer 與 SVGRenderer 等 API.
- Branislav Ulicny 貢獻了素材, 著色器, 後處理, 以及渲染能力之強化.
- Three.js 在所有支持 WebGL 1.0 的瀏覽器皆可運行.
- Three.js 以最寬鬆的 MIT 授權開源.
# http://threejs.org/build/three.min.js
然後在網頁中連結此 js 檔即可 :
<script src="js/three.min.js"></script>
也可以使用 Google API 提供的各版本的 CDN (r84, r83, r82, r81, r80, r79, r78, r77, r76, r75, r74, r73, r72, r71, r70, r69, r68, r67) :
<script src="https://ajax.googleapis.com/ajax/libs/threejs/r84/three.min.js"></script>
另外, cdnjs 網站上也有提供各版本 Three.js CDN 的服務, 參考 :
# https://cdnjs.com/libraries/three.js/
選擇所要版本後底下就會出現 three.min.js 的 CDN 超連結, 將其複製到網頁中 Script 標籤的 src 屬性即可.
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r83/three.min.js"></script>
基本網頁架構如下 :
使用本地 three.min.js
使用 Google API CDN 上的 three.min.js
使用 CDN.JS 的 three.min.js
這樣就可以開始用 three.js 撰寫 WebGL 3D 網頁繪圖程式了. 但在那之前須對 Three.js 的 3D 繪圖架構, 術語, 以及概念有個基本了解才行, 摘要如下 :
- 場景 (Scene) :
場景是一個容器, 用來放置曲面 (Mesh), 光源 (Light) 與相機 (Camera) 等 3D 繪製元素. 繪製器 (Renderer) 就根據這些元素進行繪製. - 相機 (Camera) :
相機是觀察點, 也就是觀察者眼睛的視角投影, 要將 3D 物件呈現在 2D 平面上需要透過相機的投影. 投影有兩種模式 :
(1). 透視投影 : 使用四稜錐建模將 3D 物件投影到 2D 平面, 有立體感.
(2). 正交投影 : 模擬長焦鏡頭拍攝相片方式將 3D 投影至 2D, 無立體感.
透視投影與人類視覺最類似, 有景深空間立體感, 但大小會被扭曲; 正交投影則建立 3D 物件的 2D 幾何圖形, 提供無扭曲的投影視圖, 以便精確縮放與放置. 一般 3D 繪圖流程是先以正交投影來建立場景, 得到精確之製圖與建模, 然後用透視投影來繪製輸出. Three.js 提供 PerspectiveCamera 類別與 OrthographicCamera 類別來實現透視與正交投影相機功能. - 繪製器 (Renderer) :
繪製器是用來繪製 3D 圖形的畫布, 也就是 HTML5 中的 Canvas 元素. Three.js 提供兩種繪製器 :
(1). WebGLRenderer :
使用 WebGLRenderingContext 實現 GPU 加速之 2D/3D 繪圖
(2). CanvasRenderer (目前已被移除) :
使用 CanvasRenderingContext2D 實現 2D 繪圖
在特定情況下 CanvasRenderer 可用 2D 環境模擬出 3D 效果, 但與材質或光源有關的 3D 功能無法模擬, 故 3D 繪圖還是以 WebGLRenderer 為主. 若瀏覽器不支援 WebGLRenderer, 那也只好用 CanvasGLRenderer 來模擬.
- 建立場景 :
使用 new THREE.scene() - 建立曲面圖形物件 (mesh) :
使用 new THREE.mesh(geometr, material)
呼叫場景物件的 add() 方法將曲面物件加入場景中
曲面就是 3D 空間中的物體, 由幾何形狀或模型 (geometry) 與材質 (material) 組成. 其中 geometry 由三個屬性定義 :
(1). vertices : 頂點清單
(2). faces : 面
(3). faceVertexUv : 紋理座標 - 建立相機 :
使用 new THREE.PerspectiveCamera()
相機建立後會自動加入場景中, 不須呼叫 add() - 建立繪製器 :
使用 new THREE.WebGLRenderer() 建立繪製器物件 (canvas 元素)
將繪製器物件加入網頁的 DOM 結構中
呼叫繪製器物件的 render(scene, camera) 方法繪製指定場景與相機
# https://zh.wikipedia.org/wiki/Three.js
測試 1 : 移動中的 3D 立方體 [原始碼]
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
body {
background-color: #ffffff;
margin: 0;
overflow: hidden;
}
</style>
<script src="js/three.min.js"></script>
</head>
<body>
<script>
//宣告全域變數
var scene, camera, renderer;
var geometry, material, mesh;
init(); //呼叫起始設定函數
animate(); //呼叫動畫函數
//定義起始設定函數
function init() {
//1.建立場景
scene=new THREE.Scene();
//2.建立曲面圖形物件
geometry=new THREE.BoxGeometry(500, 500, 500); //建立幾何形狀
material=new THREE.MeshBasicMaterial({ //建立材質
color: 0xff0000,
wireframe: true});
mesh=new THREE.Mesh(geometry, material); //以幾何形狀與材質建立曲面
scene.add(mesh); //曲面圖形物件加入場景中
//3.建立相機
camera=new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 1, 10000);
camera.position.z=1000;
//4.建立繪圖器
renderer=new THREE.WebGLRenderer({antialias:true}); //建立 WebGL 繪圖器
renderer.setClearColor("#ffffff"); //設定背景色為白色
renderer.setSize(window.innerWidth, window.innerHeight); //設定畫布為瀏覽器大小
document.body.appendChild(renderer.domElement); //將畫布加入瀏覽器 DOM 中
}
//定義動畫函數
function animate() {
requestAnimationFrame(animate);
mesh.rotation.x += 0.01;
mesh.rotation.y += 0.02;
renderer.render(scene, camera);
}
</script>
</body>
</html>
此例 Three.js 我改用 Google API 提供的 CDN 服務, 執行結果如下 :
此立方體實際上是不斷旋轉移動的.
下面範例改寫自 "Game Development with Three.js (Packt, 2013)" 第一章範例, 此程式使用了 CanvasRenderer, 新版 Three.js 已不支援, 需使用較舊的版本, 參考 :
# https://mrdoob.com/projects/htmleditor/
測試 2 : 轉動的 3D 球體 [原始碼]
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
body {
background-color: #ffffff;
margin: 0;
overflow: hidden;
}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r59/three.min.js"></script>
</head>
<body>
<script>
var scene, camera, renderer;
var geometry, material, mesh;
init();
animate();
function init() {
scene=new THREE.Scene();
geometry=new THREE.IcosahedronGeometry(200, 1);
material=new THREE.MeshBasicMaterial({
color: 0x000000,
wireframe: true,
wireframeLinewidth: 2});
mesh=new THREE.Mesh(geometry, material);
scene.add(mesh);
camera=new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.z=500;
renderer=new THREE.WebGLRenderer({antialias:true});
renderer.setClearColor("#ffffff");
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
}
function animate() {
requestAnimationFrame(animate);
mesh.rotation.x=Date.now() * 0.00005;
mesh.rotation.y=Date.now() * 0.0001;
renderer.render(scene, camera);
}
</script>
</body>
</html>
執行結果如下 :
參考 :
# [Da13] Three.js API 簡介
# Three.js 101 : Hello World! (Part 1)
2019-01-07 補充 :
由於所有主流瀏覽器均已支援 WebGLRenderer, 因此 Three.js 已經將 CanvasRenderer 移除了, 如果要執行含有此繪圖器的程式, 可在 r59 或之前版本的 Three.min.js 上執行.
2020-09-15 補充 :
今天在接案網站上看到有人徵 three.js 案子, 想起我好像曾經玩過 (可惡的失憶), 於是就複習了一下, 順便找到下面不錯的教學 :
# 3D 網站開發入門筆記_Three.js 入門
這個好玩, 我有空會再回來玩的.
沒有留言 :
張貼留言