也許你已看過這篇three.js的基礎介紹,也應該了解three.js的匯入架構。如果很麻煩,你可以複製下列程式碼到編輯器中修改。
<!DOCTYPE html>
<html lang="zh-TW">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>基礎版型</title>
<style>
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
width: 100%;
height: 100dvh;
}
</style>
</head>
<body>
<script type="importmap">
{
"imports": {
"three": "https://cdn.jsdelivr.net/npm/three@v0.164.1/build/three.module.js",
"three/addons/": "https://cdn.jsdelivr.net/npm/three@v0.164.1/examples/jsm/"
}
}
</script>
<script type="module">
import * as THREE from "three";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
camera.position.z = 30;
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
const geometry = new THREE.TorusKnotGeometry(5, 2, 100, 100);
const material = new THREE.MeshStandardMaterial({
color: "#ffffff",
metalness: 0.5,
});
const torusKnot = new THREE.Mesh(geometry, material);
scene.add(torusKnot);
const pointLight = new THREE.PointLight("white", 300);
pointLight.position.set(5, 5, 10);
scene.add(pointLight);
const controls = new OrbitControls(camera, renderer.domElement);
controls.enablePan = false;
controls.enableZoom = false;
function animate() {
requestAnimationFrame(animate);
torusKnot.rotation.y += 0.01;
controls.update();
renderer.render(scene, camera);
}
animate();
window.addEventListener("resize", function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
</script>
</body>
</html>
1. 透明背景
想改掉預設的黑色背景,就在 new THREE.WebGLRenderer() 中加入 alpha:true 屬性,場景背景就會變透明,顯現父層元件的背景色。
const renderer = new THREE.WebGLRenderer({ antialias: true, alpha:true });
2. 背景改色
方法1. 更改場景background屬性
在宣告scene後,對background屬性進行修改。
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x87CEEB);
方法2. 更改渲染器設置
在宣告renderer後,使用setClearColor設置顏色。
const renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setClearColor(0x87CEEB);
3. 漸層背景
3-1. 透明背景 + 父層漸層
想製作漸層背景,可以使用第一點提到的『透明背景』。
在new THREE.WebGLRenderer() 中加入 alpha:true 屬性後,更改父層元件的背景CSS。
如果把渲染範圍指定在<body>元件,就更改body背景為漸層色:
<style>
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
body{
/* 漸層背景 */
background: linear-gradient(to right, #c3efb2, #5dd2d5);
}
</style>
3-2. 製做漸層畫布,當成場景背景的材質
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
canvas.width = 1;
canvas.height = 256;
const gradient = context.createLinearGradient(0, 0, 0, 256);
gradient.addColorStop(0, '#87CEEB'); // 天藍
gradient.addColorStop(1, '#FFC0CB'); // 淺粉
// 將漸層設為填充樣式
context.fillStyle = gradient;
context.fillRect(0, 0, 1, 256);
// 將canvas轉換為Three.js材質的對象
const texture = new THREE.CanvasTexture(canvas);
texture.minFilter = THREE.LinearFilter;
scene.background = texture;
4. 環景貼圖(HDR)
4-1. 取得hdri檔案
你可以到poly heven或HDRi Haven,下載免費hdri檔案,但可能有2k解析度的限制。也可以用blender或photoshop自己做(有機會再獨立寫一篇關於HDRI的)。
4-2. 匯入RGBELoader模組
環景貼圖必須使用 RGBELoader 這個外掛模組,把他匯入。
<script type="module">
import * as THREE from "three";
import { RGBELoader } from "three/addons/loaders/RGBELoader.js";
//將場景、相機、渲染、物件、動畫等其餘程式碼添加於此...
//...
</script>
4-3. 建立環景貼圖
使用 JavaScript 的URL構造函數生成HDR圖片的路徑
,並使用 RGBELoader
的load
方法載入此路徑,完成後執行由貼圖紋理(texture)作為參數的回調函數。
const hdrTextureURL= new URL('/src/assets/colorful.hdr', import.meta.url);
const loader = new RGBELoader();
loader.load(hdrTextureURL, function (texture) {
//指定紋理的映射類型
texture.mapping = THREE.EquirectangularReflectionMapping;
//用環景貼圖取代背景
scene.background = texture;
//用環景貼圖的光線來照亮場景
scene.environment = texture;
//受到環景貼圖影響的物件移到callback funtion裡面,例如方塊或扭結...等
//...
})
把物件移進回調函數時,記得改成在外部先定義物件名稱,否則animate()函數可能會找不到物件,就無法執行旋轉動作。