three.js顶点篇
目錄
- 基礎篇
- 頂點是什么
- 頂點幾何體和geometry.attributes.position
- 頂點顏色geometry.attributes.color
- 頂點法向量geometry.attributes.normal
- 頂點復用geometry.index
基礎篇
閱讀頂點篇之前如果沒有學習基礎篇請先移步,方便了解學習環境:three.js基礎篇
頂點是什么
基礎篇中我們學會了網絡模型mesh,網絡模型基礎包括了集合體Geometry和材質material。
其中幾何體中我們可以很容易的使用BoxGeometry或者SphereGeometry創建柱狀幾何體或者球形幾何體。
這些幾何體其實都是通過頂點這個概念創建的,只不過它們在內部封裝好了。
頂點幾何體和geometry.attributes.position
面、線、點有效的幾何體表達名為BufferGeometry
const geometry = new THREE.BufferGeometry()當然它不像BoxGeometry或者SphereGeometry傳遞尺寸等參數就形成了幾何體,它麻煩一些。
想要使用它我們得先借助js的內置對象Float32Array,32位浮點數對象生成一份矩陣數據。
const vertices = new Float32Array([0, 0, 0, 50, 0, 0, 0, 100, 0, 0, 0, 10, 0, 0, 100, 50, 0, 10, ]);這份數據有什么用呢?
我們可以把它賦值給幾何體屬性值上的位置position。
當然還得使用到three能夠搭配這份數據的方法BufferAttribute。
后面的3表示前面的數據3個為一組,一組3個數字分別代表一個點的xyz軸值,也就是這個模型總共包括了6個點。
geometry.attributes.position = new THREE.BufferAttribute(vertices, 3)我們先不加材質,渲染一下試試啥樣。
順便復習一下基礎篇生成網絡模型再把模型加進場景的代碼。
const mesh = new THREE.Mesh(geometry)scene.add(mesh)
會發現渲染出這幾個點包圍的圖形,要明白最少三個點才可以包圍出一個面。
我們如果旋轉一下模型,往上轉到底部,會發現這個面只有一個面能看見,背面看不見。
這是因為得在相應的材質上加上屬性。
加上一個簡單著色材質MeshBasicMaterial重新構建網絡模型
注意這個材質不受光照影響,所以你現在可以看見顏色,等到后面介紹法向量時你可能會產生為啥現在可以看見光照的疑惑,這里已經先解釋了。
const material = new THREE.MeshBasicMaterial({color: 0x0000ff, //三角面顏色side: THREE.DoubleSide //兩面可見})const mesh = new THREE.Mesh(geometry,material)scene.add(mesh)
現在有顏色了而且可以看見背面。
頂點顏色geometry.attributes.color
創建幾何體時我們使用到了geometry.attributes.position,它可以設置頂點的位置,同理我們還可以設置頂點的顏色。
同樣也是以定點為單位設置,借助Float32Array。
同樣是3個數一組,不過這次的3個數代表的是3原色,一組三原色構成一個點的顏色,取值范圍0-1。
const colors = new Float32Array([1, 0, 0, //頂點1顏色0, 1, 0, //頂點2顏色0, 0, 1, //頂點3顏色1, 1, 0, //頂點4顏色0, 1, 1, //頂點5顏色1, 0, 1, //頂點6顏色]);geometry.attributes.color = new THREE.BufferAttribute(colors, 3)為了先理解頂點著色,我們還得改改材質和模型。
我們用點材質PointsMaterial代替簡單材質,再使用Points模型代替mesh網絡模型。
const material = new THREE.PointsMaterial({vertexColors: THREE.VertexColors, size: 10.0})const points = new THREE.Points(geometry, material)scene.add(points)
可以看見六個點分別著上對應的顏色。
我們可以不換材質,換回網絡模型。
const mesh = new THREE.Mesh(geometry, material)scene.add(mesh)
我們會發現當頂點顏色不同時,在頂點形成面的過程中會出現漸變,兩個頂點形成線時會自動在中間自動插入過渡色,看起來就是漸變了。
頂點法向量geometry.attributes.normal
這個是法向量與光照有關,我們先把頂點著色改成全藍。
之前用的MeshBasicMaterial不受光照影響看不出特別,隨便換個MeshPhongMaterial材質好了。
去掉頂點著色,給材質顏色上個藍色。
挪動一下下面兩個點讓兩個面重合。
然后順便加上環境光和點光源。
const vertices = new Float32Array([0, 0, 0,50, 0, 0,0, 100, 0,0, 0, 0,0, 0, 100,50, 0, 0,]);geometry.attributes.position = new THREE.BufferAttribute(vertices, 3)const material = new THREE.MeshPhongMaterial({color: 0x0000ff,side: THREE.DoubleSide})const mesh = new THREE.Mesh(geometry, material)scene.add(mesh)//環境光const ambient = new THREE.AmbientLight(0x444444);scene.add(ambient);// 點光源const point = new THREE.PointLight(0xffffff);point.position.set(200, 400, 300); //點光源位置scene.add(point); //點光源添加到場景中會發現烏漆嘛黑,沒有光照效果,顏色都看不見,我們明明加上了光源為什么沒有效果呢。
因為用BufferGeometry的話,如果需要用普通材質,想要看到光照效果,必須設置頂點法向量。
設置時沿著三個點順時針構成面的這面也就是我們看見的正面,讓法向量從它們的反面穿過來,這樣子正面將會作為光照到的外面。
聽不懂就算了直接設置看效果,設置的屬性換成normal,這次的三個數代表一個法向量,不知道法向量先學習數學。
const normals = new Float32Array([0, 0, 1, //頂點1法向量0, 0, 1, //頂點2法向量0, 0, 1, //頂點3法向量0, 1, 0, //頂點4法向量0, 1, 0, //頂點5法向量0, 1, 0, //頂點6法向量]);geometry.attributes.normal = new THREE.BufferAttribute(normals, 3)
設置完就看見了,有棱角,有光照,我們分析一下法向量在哪里。
六個頂點的法向量是這樣的,不明白原理知道怎么設置就行了。
頂點復用geometry.index
就在上面的例子,當兩個三角形粘連的時候,每個三角形有兩個頂點是重復了的。
因此我們沒必要寫出6個頂點,只要4個就可以表示同樣的內容了。
把重復的頂點刪除,再刪除對應的法向量。
const vertices = new Float32Array([0, 0, 0,50, 0, 0,0, 100, 0,// 0, 0, 0,0, 0, 100,// 50, 0, 0,]);geometry.attributes.position = new THREE.BufferAttribute(vertices, 3)const normals = new Float32Array([0, 0, 1, //頂點1法向量0, 0, 1, //頂點2法向量0, 0, 1, //頂點3法向量// 0, 1, 0, //頂點4法向量0, 1, 0, //頂點5法向量// 0, 1, 0, //頂點6法向量]);geometry.attributes.normal = new THREE.BufferAttribute(normals, 3)然后就是使用我們的geometry.index來表明如何復用頂點。
根據頂點的數量選擇類型數組Uint8Array、Uint16Array、Uint32Array。對于頂點索引而言選擇整型類型數組,對于非索引的頂點數據,需要使用浮點類型數組Float32Array等。
這里的每個數字代表的是哪個頂點,我們上方設置了4個頂點,計數同數組從0開始,0、1、2三個頂點構成一個三角形,0,3,1三個頂點構成一個三角形。
const indexes = new Uint16Array([0, 1, 2,0, 3, 1,])geometry.index = new THREE.BufferAttribute(indexes, 1)
能夠顯示出六個頂點要的效果,不過感覺連接處有一些粘連,所以可能還是得復用需要組合成一個形狀的頂點才好,比如兩個三角形拼成一個矩形,為了方便學習就就這么做了,可以自行嘗試多加一個頂點在某個面上讓三角形成為矩形。
總結
以上是生活随笔為你收集整理的three.js顶点篇的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: GNN图神经网络
- 下一篇: cesium获取坐标及高程