這裡是「Three.js學習日誌」的第4篇,本篇的主旨是透過試做一個Three.js的Hello World案例,來讓讀者對於Three.js有基本的認識,這系列的文章假設讀者看得懂javascript,並且有Canvas 2D Context的相關知識。
前情提要: 昨天因為出了一點小意外,原本該一天處理完的Three.js Hello World篇,寫著寫著就不小心寫到了半夜兩點...,所以這邊為了要符合賽程規定,我決定把昨天超出12點之後撰寫的內容,轉移至今天的篇章,如造成評審不便,深感抱歉!
第5步前的內容可至這裡觀看。
接著馬上又是一個看不懂的專有名詞Mesh。
所謂的Mesh
其實就是3D模型,一個正常的Mesh
會由Geometry
(幾何結構)和Material
(材質)組成。
Geometry
內部紀錄的是構成3D物體的每個表面頂點的座標。Material
則是3D物體表面的圖樣。其實這邊大概就可以聯想到跟
vertex shader
和fragment shader
有關了。
跟前面一樣,Geometry
和Material
其實都有多種類型,這邊因為我們要生成一個方塊,所以選用BoxGeometry
,BoxGeometry.constructor
的前三個參數也就是長
,寬
,高
,而後三個則是xyz軸網格細分數量,網格細分數量會影響一個Mesh到底有多細緻,網格細分數量越大。一個面上的頂點(vertex)就會越多,同時也會吃越多效能。
Material
的部分我們選用MeshStandardMaterial
,這是一種最基本的PBR材質,他可以接收的到光照的變化,而產生不同的顏色,順帶一提,如果環境中沒有光,則會呈現黑色。
延伸閱讀: 什麼是PBR?
最後我們把Geometry
和Material
傳進去Mesh
生成實例,再把Mesh
實例加進去Scene裡面。
import {
Scene,
WebGLRenderer,
BoxGeometry,
PerspectiveCamera,
MeshStandardMaterial,
mesh
} from "https://cdn.skypack.dev/three";
function main() {
...
const geo = new BoxGeometry(1, 1, 1, 10, 10);
const mat = new MeshStandardMaterial({
//這裡可以設置方塊的顏色
color: 0xff0000
});
const mesh = new Mesh(geo,mat);
scene.add(mesh)
}
main();
因為我們在前一步使用的是MeshStandardMaterial
,所以環境中必須要有光,不然攝影機只會照出黑色的方塊。
在這邊我們給Scene加上一盞點光源(PointLight)。
const pl = new PointLight(0xffffff, 0.3);
pl.position.set(3, 3, 3);
scene.add(pl);
接著我們再調整一下攝影機的位置,因為現在攝影機的位置是0,這樣方塊會因為不在近平面/遠平面構成的空間中,而渲染不出來,所以我們稍微拉遠一點攝影機的距離。
camera.position.z = 5;
renderer.render(scene, camera);
燈燈~ 我們的方塊就成功渲染出來啦。
其實就跟2D context
差不多,只要在每一個requestAnimationFrame
的循環重新發動render方法,並且同時改變Mesh
的rotation
屬性就可以。
let time = 0;
const loop = (time) => {
mesh.rotation.y = time / 1000;
renderer.render(scene, camera);
requestAnimationFrame((time) => {
loop(time);
});
};
loop();
在這一篇中,我們只是先用一個最基本的案例來解釋three.js
的渲染流程,但其實Camera
,Geometry
,Material
,...etc. 都還有很多細節需要補充,所以我預計要在後面的天數一點一點地把他們補齊。
一邊跑步一邊看,想說怎麼越講越深入,連unity的案例都出來了,原來我不小心讀起了PBR的外部連結XD。
很有收穫!