Three.js 入門及簡單專案實作

在這篇文章中,我介紹了如何使用 Three.js 庫來創建和渲染 3D 圖形。我展示了從基本安裝到場景設置,再到加入照明和材料的過程,以及如何進行動畫和交互控制。

Three.js 入門及簡單專案實作
Photo by Luke Jones / Unsplash

Three.js 是一個 JavaScript 庫,用於在瀏覽器中創建和渲染 3D 圖形。以下是使用 Three.js 的一些簡單步驟:

渲染場景
使用 renderer.render() 方法呈現場景。

renderer.render( scene, camera );

添加對象
向場景中添加 3D 對象,如立方體、球體等。

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

創建渲染器
創建渲染器,用於呈現場景中的圖形。

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

創建相機
創建一個相機,用於定義您看到場景的角度。

var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );

創建場景
使用 Three.js 創建場景,其中包含您將添加所有 3D 對象的空間。

var scene = new THREE.Scene();

包括 Three.js 庫
通過將以下代碼放入您的 HTML 頁面中,包括 Three.js 庫:

<script src="https://cdn.jsdelivr.net/npm/three@0.121.0/build/three.js"></script>

一、介紹 Three.js 和 3D 圖形

  1. 什麼是 Three.js
    Three.js 是一個開源的 JavaScript 庫,用於快速和容易地創建交互式 3D 圖形。
  2. Three.js 建立的基本概念
    Three.js 通過場景、相機、物體和照明來建立 3D 圖形,每個元素都可以被自定義和定制以滿足需求。

渲染場景
最後,下面是渲染場景的示例代碼:

function render() {
  requestAnimationFrame( render );
  cube.rotation.x += 0.01;
  cube.rotation.y += 0.01;
  renderer.render( scene, camera );
}
render();

向場景中添加物體
下面是示例代碼,用於向 Three.js 場景中添加立方體物體:

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

Three.js 場景的建立
下面是示例代碼,用於建立 Three.js 場景:

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
camera.position.z = 5;

二、設置 Three.js 環境並創建基本場景

渲染場景
最後,下面是示例代碼,用於渲染 Three.js 場景:

function render() {
  requestAnimationFrame( render );
  renderer.render( scene, camera );
}
render();

建立渲染器
下面是示例代碼,用於建立 Three.js 渲染器:

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

建立相機
下面是示例代碼,用於建立 Three.js 相機:

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

建立場景
下面是示例代碼,用於建立 Three.js 場景:

var scene = new THREE.Scene();

引入 Three.js
在您的 HTML 文件中引入 Three.js 庫,下面是示例代碼:

<script src="https://cdn.jsdelivr.net/npm/three@0.119.1/build/three.js"></script>

三、向場景中添加對象和幾何形狀

調整相機位置
最後,下面是示例代碼,用於調整 Three.js 相機的位置以適應添加的網格:

camera.position.z = 5;

將網格添加到場景中
下面是示例代碼,用於將網格添加到 Three.js 場景中:

scene.add( cube );

建立網格
下面是示例代碼,用於將幾何形狀和材質合併為網格:

var cube = new THREE.Mesh( geometry, material );

建立材質
下面是示例代碼,用於建立 Three.js 的基本材質:

var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );

建立幾何形狀
下面是示例代碼,用於建立 Three.js 的立方體幾何形狀:

var geometry = new THREE.BoxGeometry( 1, 1, 1 );

四、使用材料和紋理添加顏色和細節到物體

呈現更新後的場景
最後,下面是示例代碼,用於呈現更新後的 Three.js 場景:

renderer.render( scene, camera );

更新場景中的物體
下面是示例代碼,用於更新場景中的物體,以使用帶有紋理的新網格:

scene.remove( oldMesh );
scene.add( mesh );

重新創建網格
下面是示例代碼,用於重新創建網格,使用帶有紋理的材料:

var mesh = new THREE.Mesh( geometry, material );

建立材料
下面是示例代碼,用於創建帶有紋理的 Three.js 材料:

var material = new THREE.MeshBasicMaterial( { map: texture } );

建立紋理
下面是示例代碼,用於創建 Three.js 的紋理:

var texture = new THREE.TextureLoader().load( "texture.jpg" );

五、Three.js 場景中的照明和陰影

  1. 了解照明技巧
    Three.js 中的照明可以使場景呈現出立體感。照明可以分為兩種類型:環境照明和平行光。
  2. 陰影
    陰影是 Three.js 中的另一個重要的照明技巧。可以使用投影陰影來創建真實的 3D 場景。可以通過設置 light.castShadow = true 並設置 light.shadow.mapSize 和 light.shadow.

漸變光
漸變光可以使得物體看起來更具深度感。漸變光可以使用 SpotLight 類創建,並設置顏色、位置、光線方向、光照強度和光照距離。

var spotLight = new THREE.SpotLight(0xffffff);
spotLight.position.set(100, 1000, 100);
spotLight.castShadow = true;
scene.add(spotLight);

平行光
平行光是一種向特定方向發射光線的光源。平行光可以使用 DirectionalLight 類創建,並設置顏色和光線方向。

var directionalLight = new THREE.DirectionalLight(0xffffff);
directionalLight.position.set(1, 1, 1).normalize();
scene.add(directionalLight);

環境照明
它是一種非常通用的照明,可以為整個場景呈現光源。環境照明可以使用 AmbientLight 類創建,並設置顏色。

var ambientLight = new THREE.AmbientLight(0xffffff);
scene.add(ambientLight);

六、工作與相機並控制場景中的視圖

  1. 理解相機的概念
    Three.js 中的相機是一種用於觀察場景中物體的工具。它會影響你看到場景中物體的方式。

改變相機的鏡頭
你可以通過改變相機的屬性來控制視野,如視角、近平面和遠平面等。代碼範例:

camera.fov = 120;
camera.near = 0.1;
camera.far = 100;
camera.updateProjectionMatrix();

場景中的視圖
通過將相機作為參數調用 renderer 的 render 方法,你可以從相機的角度呈現場景中的物體。代碼範例:

renderer.render(scene, camera);

控制相機的位置
可以通過調整相機的 position 和 rotation 屬性來控制相機的位置和方向。代碼範例:

camera.position.x = 2;
camera.position.y = 2;
camera.rotation.x = 0.5;

創建相機
你可以創建不同類型的相機,如透視相機、正交相機等。代碼範例:

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

七、Three.js 中的動畫和交互

  1. 介紹動畫
    Three.js 提供了一系列的動畫方法,包括 Tween.js,它允許開發人員輕鬆創建平滑的動畫效果。
  2. 設置 Keyframe 動畫
    開發人員可以使用 KeyframeTrack 對物體的位置、旋轉、大小等屬性進行動畫。
  3. 使用 Morph Targets 動畫
    Morph Targets 是一种在幾何形狀中進行動畫的方法,通過控制不同的頂點位置來創建逼真的動畫效果。
  4. 交互式控制
    Three.js 提供了一系列的交互式控制方法,例如 OrbitControls,它允許開發人員使用滑鼠和鍵盤對場景進行操作。
  5. 結合 HTML 元素
    Three.js 支持將 HTML 元素與 Three.js 場景結合,這樣開發人員就可以在 3D 場景中創建交互式按鈕和表單。
// Keyframe animation example
var mixer = new THREE.AnimationMixer( mesh );
var clip = THREE.AnimationClip.CreateFromMorphTargetSequence( 'run', geometry.morphTargets, 30 );
var action = mixer.clipAction( clip );
action.play();

// Interactive control example
var controls = new THREE.OrbitControls( camera, renderer.domElement );
controls.enableDamping = true;
controls.dampingFactor = 0.25;
controls.enableZoom = false;

// HTML integration example
var button = document.createElement( 'button' );
button.textContent = 'Click me';
button.style.position = 'absolute';
button.style.top = '10px';
button.style.left = '10px';
button.addEventListener( 'click', function () {
alert( 'Button was clicked' );
} );
document.body.appendChild( button );

八、使用高級功能,如粒子系統、後處理和高級着色器

  1. 介紹高級功能
    Three.js 提供了許多高級功能,如粒子系統、後處理和高級着色器等,可以使您的 3D 場景更加生動和有趣。

高級着色器
Three.js 允許你使用自定義的着色器程序,以實現更高級的效果。詳細分成五個重點解釋上面的『Three.js 中使用高級功能,如粒子系統、後處理和高級着色器』並且附上程式碼範例

// 創建一個新的着色器材質
var customMaterial = new THREE.ShaderMaterial({
    uniforms: {
        time: { value: 1.0 },
        resolution: { value: new THREE.Vector2() }
    },
    vertexShader: document.getElementById( 'vertexShader' ).textContent,
    fragmentShader: document.getElementById( 'fragmentShader' ).textContent
});

// 在場景中應用自定義着色器
var sphere = new THREE.Mesh(
    new THREE.SphereGeometry( 5, 32, 32 ),
    customMaterial
);
scene.add( sphere );

// 在渲染循環中更新自定義着色器的時間值
function animate() {
    customMaterial.uniforms.time.value += 0.05;
    renderer.render( scene, camera );
    requestAnimationFrame( animate );
}

後處理
後處理是指在渲染完場景後,對場景的最終結果進行修改的過程。 Three.js 內置了一些常用的後處理效果,如模糊、颜色校正等。

var effectFXAA = new THREE.ShaderPass(THREE.FXAAShader);
effectFXAA.uniforms['resolution'].value.set(1 / window.innerWidth, 1 / window.innerHeight);
composer.addPass(effectFXAA);

var effectBloom = new THREE.BloomPass(0.5);
composer.addPass(effectBloom);

粒子系統
粒子系統可以用來創建火花、煙霧等效果。 Three.js 內置了一些粒子系統,也可以通過自定義來創建粒子系統。

var particleSystem = new THREE.GPUParticleSystem({
  maxParticles: 250000
});
scene.add(particleSystem);

var options = {
  position: new THREE.Vector3(),
  positionRandomness: .3,
  velocity: new THREE.Vector3(),
  velocityRandomness: .5,
  color: 0xaa88ff,
  colorRandomness: .2,
  turbulence: .5,
  lifetime: 2,
  size: 5,
  sizeRandomness: 1
};

for (var i = 0; i < options.maxParticles; i++) {
  particleSystem.spawnParticle(options);
}

在這個範例中,我們創建了一個名為 customMaterial 的新着色器材質,並將其分配給一個球體物體。着色器代碼位於 HTML 頁面的 <script> 標籤中,您可以根據您的需求進行修改。在渲染循環中,我們還更新了着色器的時間值,以便將動畫效果應用到球體上。


九、在 Three.js 中導入和導出 3D 模型

儲存 3D 模型
將導出的 3D 模型儲存下來,可以使用任意的文件儲存方法,如寫入本地文件或上傳到服務器等。

// 導出模型並存為 JSON 文件
var json = scene.toJSON();
var blob = new Blob([json], {type: "application/json"});
var link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = "model.json";
link.click();

// 儲存模型文件
var xhr = new XMLHttpRequest();
xhr.open('POST', 'save

導出 3D 模型
Three.js 支持將場景中的物體導出成多種 3D 模型格式,如 GLTF、OBJ 等,需要使用對應的導出器(如 GLTFExporter、OBJExporter)導出模型。

var exporter = new THREE.GLTFExporter();
exporter.parse(scene, function(gltf) {
  var data = JSON.stringify(gltf, null, 2);
  console.log(data);
});

應用紋理至模型
將紋理對應到模型上的幾何形狀,可以使用 THREE.Mesh 類,再用 add 方法將物體添加到場景中。

var object = new THREE.Mesh(geometry, material);
scene.add(object);

導入紋理圖片
在 Three.js 中,需要先導入紋理圖片,再把它應用到 3D 模型上。

var texture = new THREE.TextureLoader().load("texture.jpg");
var material = new THREE.MeshBasicMaterial({map: texture});
var object = new THREE.Mesh(geometry, material);

導入 3D 模型的格式
Three.js 支持多種 3D 模型格式,如 OBJ、GLTF、FBX 等,需要使用對應的加載器(如 OBJLoader、GLTFLoader、FBXLoader)導入模型。

var loader = new THREE.OBJLoader();
loader.load("model.obj", function(object) {
  scene.add(object);
});

十、有關優化和提高 Three.js 項目性能的技巧和最佳實踐。

適當使用着色器
使用適當的着色器可以提高渲染速度,因為它們允許您更有效地渲染物體。

var material = new THREE.ShaderMaterial({
  uniforms: {
    ...
  },
  vertexShader: `
    ...
  `

適當使用結构
使用結构可以提高渲染速度,因為它們允許您在渲染時對物體進行組織。

var structure = new THREE.Scene();
structure.add(mesh1);
structure.add(mesh2);
...
structure.add(meshN);

適當使用剪切
使用剪切可以提高渲染速度,因為它可以將不在視圖中的物體從渲染流程中排除。

mesh.frustumCulled = true;

使用顯示列表
使用顯示列表可以提高渲染速度,因為它們可以將一組物體組合在一起,以便為其優化渲染。

var displayList = new THREE.DisplayList();
displayList.add(mesh1);
displayList.add(mesh2);
...
displayList.add(meshN);

降低物體數量
降低您的場景中的物體數量,以提高渲染速度。這可以通過合併多個物體來實現,例如,使用綜合物體將多個物體合併為一個物體。

var group = new THREE.Group();
group.add(mesh1);
group.add(mesh2);
...
group.add(meshN);

 

實作專案:Github RepoDemo