iT邦幫忙

2022 iThome 鐵人賽

DAY 13
0
Modern Web

Three.js 學習日誌系列 第 13

Day12 - 「紋理&種類」- Material解密(二)

  • 分享至 

  • xImage
  •  

Day12 - 「紋理&種類」- Material解密(二)

這裡是「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
  })
} 

我們已經知道,如果想要把模型表面填上特定的圖樣,那就是要給予Materialmap這個屬性對應的Texture

但是若打開Three.js官方文件關於MeshStandardMaterial頁面,我們可以發現MeshStandardMaterial除了map以外,還有aoMapdisplacementMapnormalMapalphaMap...等相似的屬性。

這些屬性其實就是我們今天要提的紋理的種類

一般而言,以一個PBR材質的構成來看,常見的紋理通常會有:

  • Normal Map (法線紋理)
  • Height Map (凹凸紋理)
  • Metallic Map (金屬化紋理)
  • Ambient Occulusion Map (環境光遮蔽紋理)
  • Roughness Map (粗糙紋理)
  • Alpha Map (透明度紋理)
  • Color Map (色彩紋理)

除了Color Map (色彩貼圖)就是我們之前用來賦值給map屬性的紋理之外,其餘的6種我們接著會一併作介紹。

Normal Map (法線紋理)

其實看到Normal這個詞應該就不難猜到: 這是一種用來幹麻的東西。

Normal Map其實就跟我們之前提到的Normal attribute是類似的概念。差別就在於:

  • Normal attribute是透過計算頂點法向量去取得每個三角面法向量

  • Normal map則是能用來模擬任何凹凸處光照效果的紋理,就算模型表面沒有實際的凹凸高低變化也可以,說白了它比較像是一種障眼法。

考慮到有些人可能是第一次聽到這個名詞,光看上面的敘述可能還是不太能理解Normal map的用途,所以這邊我準備了2張圖片。

img img

上面左圖是一個普通的方塊,但是四面都貼上了同一張法線紋理

我們可以發現,在某些角度,方塊的表面看起來好像並不如想像中一樣有高低起伏的波紋,反而看起來像一個平面。

這其實就是一種障眼法,透過把特定的區塊加上高亮/陰影,來營造出平面上好像存在著高低差的這種錯覺。

Three.js 中的法線紋理

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
img img

Height Map (凹凸紋理)

Height Map (凹凸紋理)其實和Normal Map是很像的東西,但差別就在於Height Map是真的會去改變一個平面上面,頂點的位置。

Height Map範例 Height Map會實際提高/降低Geometry的頂點位置
img img

凹凸紋理的原理

我們前面其實有提到過,當我們在初始化一個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所帶來的細節就越清楚。

img

Three.js 中的凹凸紋理

使用方法其實和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金屬化紋理主要是用來標記一個平面上具有金屬性質的部位。

img

以上面這張圖來講,左邊是完全沒有加上金屬化紋理的樣子,右邊是金屬化紋理的圖片素材,中間則是把左右兩者合併到一起時的樣子。

金屬化紋理的原理

Metallic Map金屬化紋理的原理其實就在於提升模型指定的區塊的反射率,讓該區域具備能夠大量反射環境光的能力,使得區域自身的顏色變得不那麼明顯。

所以可以注意到像上面的頭盔圖片,在模型特定曲率的邊角,顏色特別接近白色。

Three.js 中的金屬化紋理

注意不是metallicMap,而是metalnessMap

  const tl = new TextureLoader();
  const metallicTexture = tl.load('../img/metallic.png'); 
  
  const mat  = new MeshStandardMaterial({
    
     metalnessMap:metallicTexture
  })

小結

今天我們對於紋理種類的介紹就先到Metallic Map (金屬化紋理)告一段落。

明天我們會繼續補完剩下的紋理種類/images/emoticon/emoticon15.gif

延伸閱讀

-https://www.twblogs.net/a/5c339be9bd9eee35b21cea09


上一篇
Day11 - 「關於紋理」- Material解密(一)
下一篇
Day13 - 「紋理&種類」- Material解密(三)
系列文
Three.js 學習日誌31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言