[新手淺談] Three.js 的解題技巧:入門及簡單專案實作,手把手帶你兩分鐘做出可放上履歷的專案
在這篇文章中,我介紹了如何使用 Three.js 庫來創建和渲染 3D 圖形。我展示了從基本安裝到場景設置,再到加入照明和材料的過程,以及如何進行動畫和交互控制。
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 圖形
- 什麼是 Three.js
Three.js 是一個開源的 JavaScript 庫,用於快速和容易地創建交互式 3D 圖形。 - 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 場景中的照明和陰影
- 了解照明技巧
Three.js 中的照明可以使場景呈現出立體感。照明可以分為兩種類型:環境照明和平行光。 - 陰影
陰影是 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);
六、工作與相機並控制場景中的視圖
- 理解相機的概念
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 中的動畫和交互
- 介紹動畫
Three.js 提供了一系列的動畫方法,包括 Tween.js,它允許開發人員輕鬆創建平滑的動畫效果。 - 設置 Keyframe 動畫
開發人員可以使用 KeyframeTrack 對物體的位置、旋轉、大小等屬性進行動畫。 - 使用 Morph Targets 動畫
Morph Targets 是一种在幾何形狀中進行動畫的方法,通過控制不同的頂點位置來創建逼真的動畫效果。 - 交互式控制
Three.js 提供了一系列的交互式控制方法,例如 OrbitControls,它允許開發人員使用滑鼠和鍵盤對場景進行操作。 - 結合 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 );
八、使用高級功能,如粒子系統、後處理和高級着色器
- 介紹高級功能
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 Repo|Demo