iT邦幫忙

2022 iThome 鐵人賽

DAY 8
0
Modern Web

Three.js 學習日誌系列 第 8

Day7 - 「就像在玩摺紙一樣」 - 幾何結構Geometry(一)

  • 分享至 

  • xImage
  •  

Day7 - 「就像在玩摺紙一樣」 - 幾何結構Geometry(一)

這裡是「Three.js學習日誌」的第7篇,本篇的主旨是要介紹Geometry的概念,還有一些常用的Geometry子類的使用方法。這系列的文章假設讀者看得懂javascript,並且有Canvas 2D Context的相關知識。

我們在前面有稍微介紹過Geometry(幾何結構)大概是個甚麼樣的概念。

除了BoxGeometry(箱型幾何結構)以外,three.js還內建了很多可以開箱即用的Geometry子類。像是ConeGeometry(圓錐),SphereGeometry(球體)。

BufferGeometry是什麼?

為什麼我們會說BoxGeometry(方塊),ConeGeometry(圓錐),SphereGeometry(球體)這些東西是Geometry子類呢?

那是因為,大多數three.js的內建geometry都是BufferGeometry這個類的延伸。

BufferGeometry是什麼? 其實看到Buffer這個字眼應該就有人聯想到了,他其實就是webgl中用來供給shader attribute取用數值的那個Buffer

所以我們其實也可以像之前在webgl hello world範例中做的一樣,把頂點的座標傳入BufferGeometry,用來生成形狀


這邊我們稍微來點範例

這個範例是打算要在Scene裡面,透過BufferGeometry繪製一系列隨機的三角形

img

  1. 首先先建立BufferGeometry的實例。
//這邊我們忽略掉Scene實例和一些初期渲染環境的設置流程,直接來到展示的重點

const geo = new BufferGeometry();

  1. 先產生一系列隨機的點座標。
...
const vertexNumber = 100; //假設有100個座標
let arr = new Float32Array(vertexNumber * 3); //每個座標都有xyz
arr = arr.map((ele) => {
  return Math.random() * 2 - 1;
});
  1. 利用這些點座標去生成一個BufferAttribute的實例,然後把這個實例轉嫁給我們前面建立好的BufferGeometry實例。
...
const ba = new BufferAttribute(arr, 3);//這邊填3是有點類似stride的概念,也就是每三個算一組
// 
geo.setAttribute("position", ba);

  1. 上材質之後生成Mesh,再來丟進Scene裡面,打完收工。
// 這次我們選用MeshBasicMaterial,這是一種不會受到光源影響的Material,可以很直接地呈現出顏色
  const mat = new MeshBasicMaterial({
    color: new Color("red"),
    transparent: true
  });
  const mesh = new Mesh(geo, mat);
  scene.add(mesh);

Codepen 連結 :點我

BufferGeometry的幾個重要屬性:normal/position/uv

我們剛剛提到了如果要把頂點的座標資料轉嫁給BufferGeometry,我們會需要利用BufferAttribute這個類。

const ba = new BufferAttribute(arr, 3);
geo.setAttribute("position", ba);

仔細一看可以發現我們是把座標資料傳進去BufferGeometry底下一個叫做"position"的屬性去了。

接著打開剛剛範例中的BufferGeometry.attribute來瞧瞧,看看裡面到底都有些甚麼樣的東西~

這邊我們可以看到BufferGeometry.attribute裡面就只有一個"position"這樣的屬性,裡面的值也就是我們剛剛轉嫁進去的頂點座標資料。

img

接著再讓我們來看看之前我們做的three.js Hello World,裡面用到的BoxGeometry,有沒有甚麼不一樣的結果。

img

我們可以發現這邊多出了兩個東西,分別是

  • normal

  • uv

BoxGeometry之所以會有這兩個attribute,原因是因為他本身是一種開箱即用的Geometry

什麼是noraml

normal其實就是我們高中都學過的平面法向量,他的用途是在定義一個多面體的每個三角形面的朝向為何。normal是決定一個3D物件的受光狀況的重要條件之一~

什麼是uv

uv這個詞,有摸過3D建模軟體的人應該都很熟悉。

相信很多人都知道貼圖這個概念。很多的3D物件,從外表上看起來有很多的細節,但是實際上那些都只是一些材質貼圖形成的假象。

img

這個貼了磚塊皮的方塊,只要不從側面看,要看出來是貼皮其實有點難度

而通常我們在3D軟體中,我們會把像上面這樣的材質貼圖,合併為一整張圖片。

img

這時候UV mapping就是一個很重要的概念,他代表一張材質貼圖上面,每一塊小部位,實際是要映射到模型上的"哪個位置"。

而我們在上面"attribute"中看到的"uv attribute"其實就是這樣的概念,他決定了顏色/圖樣附著在模型上的Mapping。

小結

Geometry的內容還沒有結束,我大約預計至少還要再花一天的時間才能寫完預期的內容,明天我們可以來講講一些如何客製Geometry的內容,今天就先到這邊結束。

延伸閱讀


上一篇
Day6 - 事前健身操 - 顏色/動畫循環/群組
下一篇
Day8 - 「面面俱到」 - 幾何結構Geometry(二)
系列文
Three.js 學習日誌31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言