這裡是「Three.js學習日誌」的第12篇,本篇的主旨是要介紹紋理的種類,這系列的文章假設讀者看得懂javascript,並且有Canvas 2D Context的相關知識。
我們在上一回提到了如何在Three.js
使用Texture
(紋理),而我們今天是要來講講Texture
(紋理)的種類。
async function main() {
const someTexture1 = await getTexture("https://picsum.photos/id/237/200/300");
const mat = new MeshStandardMaterial({
map:someTexture1
})
}
我們已經知道,如果想要把模型表面填上特定的圖樣,那就是要給予Material
的map
這個屬性對應的Texture
。
但是若打開Three.js
官方文件關於MeshStandardMaterial
的頁面,我們可以發現MeshStandardMaterial
除了map
以外,還有aoMap
,displacementMap
,normalMap
,alphaMap
...等相似的屬性。
這些屬性其實就是我們今天要提的紋理的種類。
一般而言,以一個PBR材質的構成來看,常見的紋理通常會有:
除了Color Map (色彩貼圖)就是我們之前用來賦值給map
屬性的紋理之外,其餘的6種我們接著會一併作介紹。
其實看到Normal
這個詞應該就不難猜到: 這是一種用來幹麻的東西。
Normal Map其實就跟我們之前提到的Normal attribute
是類似的概念。差別就在於:
Normal attribute
是透過計算頂點法向量去取得每個三角面的法向量。
Normal map
則是能用來模擬任何凹凸處光照效果的紋理,就算模型表面沒有實際的凹凸高低變化也可以,說白了它比較像是一種障眼法。
考慮到有些人可能是第一次聽到這個名詞,光看上面的敘述可能還是不太能理解Normal map
的用途,所以這邊我準備了2張圖片。
上面左圖是一個普通的方塊,但是四面都貼上了同一張法線紋理。
我們可以發現,在某些角度,方塊的表面看起來好像並不如想像中一樣有高低起伏的波紋,反而看起來像一個平面。
這其實就是一種障眼法,透過把特定的區塊加上高亮/陰影,來營造出平面上好像存在著高低差的這種錯覺。
在Three.js
中要怎麼給3D模型加上法線紋理?
其實就跟
Color Map
差不多
const tl = new TextureLoader();
const normalTexture = tl.load('../img/normal.png');
const mat = new MeshStandardMaterial({
normalMap:normalTexture
})
法線紋理的圖片格式最好不要採用jpg
,因為法線紋理的圖片通常有大量的純色/漸層色區塊,使用jpg
可能會導致破壞性壓縮的問題,而使得貼圖看起來有瑕疵。
以PNG 儲存的Normal Map |
以JPG 儲存的Normal Map |
---|---|
Height Map (凹凸紋理)其實和Normal Map是很像的東西,但差別就在於Height Map是真的會去改變一個平面上面,頂點的位置。
Height Map範例 | Height Map會實際提高/降低Geometry 的頂點位置 |
---|---|
我們前面其實有提到過,當我們在初始化一個BoxGeometry
的實例時,其實可以傳入第4
/5
/6
個參數。
const geo = new BoxGeometry(1,1,1,100,100,100)
這邊第4
/5
/6
個參數代表的是Segments,意思也就是把平面分割成多少部分。
分割線和分割線的交會處會形成新的頂點,而Height Map就是透過變更這些Segments頂點,來達到Geometry
的變形。
也就是說,Segments數量越高,Height Map所帶來的細節就越清楚。
使用方法其實和Normal Map大同小異。
要注意在three.js中height map的屬性是被命名為
displacementMap
,而不是heightMap
const tl = new TextureLoader();
const heightTexture = tl.load('../img/height.png');
const mat = new MeshStandardMaterial({
displacementMap:heightTexture
})
Metallic Map金屬化紋理主要是用來標記一個平面上具有金屬性質的部位。
以上面這張圖來講,左邊是完全沒有加上金屬化紋理的樣子,右邊是金屬化紋理的圖片素材,中間則是把左右兩者合併到一起時的樣子。
Metallic Map金屬化紋理的原理其實就在於提升模型指定的區塊的反射率,讓該區域具備能夠大量反射環境光的能力,使得區域自身的顏色變得不那麼明顯。
所以可以注意到像上面的頭盔圖片,在模型特定曲率的邊角,顏色特別接近白色。
注意不是metallicMap
,而是metalnessMap
。
const tl = new TextureLoader();
const metallicTexture = tl.load('../img/metallic.png');
const mat = new MeshStandardMaterial({
metalnessMap:metallicTexture
})
今天我們對於紋理種類的介紹就先到Metallic Map (金屬化紋理)告一段落。
明天我們會繼續補完剩下的紋理種類。
-https://www.twblogs.net/a/5c339be9bd9eee35b21cea09