這個問題我想了蠻久但還是想不太出來 = =
我一開始想的做法還蠻簡單,就是單純的用coneGeometry 去做出來一個正四面體
但是寫到最後才發覺 cone實際只有兩個面 = =... 所以沒辦法讓四個面填入不同的材質實例
有人知道要怎麼做嗎?
參考
BufferGeometry.groups
Split the geometry into groups, each of which will be rendered in a separate WebGL draw call. This allows an array of materials to be used with the bufferGeometry.
const geometry = new THREE.TetrahedronGeometry();
for (let i = 0; i < 4; ++i) {
geometry.addGroup(
i * 3, //start : Integer, 從第幾個點開始
3, //count : Integer, 每 3 個點為一組
i //materialIndex : Integer, 使用第幾個 material
const materials = [
new THREE.MeshPhysicalMaterial({ color: 0xff0000 }),
new THREE.MeshPhysicalMaterial({ color: 0x00ff00 }),
new THREE.MeshPhysicalMaterial({ color: 0x0000ff }),
new THREE.MeshPhysicalMaterial({ color: 0xffff00 }),
// .Mesh 的第二個參數可以是陣列,geometry 需要用 addGroup 分群
const tetrahedron = new THREE.Mesh(geometry, materials);
scene.add(tetrahedron);
主要是因為three.js 的tetra geo 的頂點似乎不止四個, 實際console geometry.attribute.position.array出來發現有出來發現座標有12 組, 也就是長度36 的陣列
(下列這行是錯誤的描述, 20220329更正)
如果單純的用for loop去 iterate, 會出現頂點抓錯的狀況
謝謝分享,我稍微整理一下:
關於 36 個數值的問題,是因為一個面有 3 個點,而每個點要有 3 數值(對應到 x,y,z),所以合計 4面 * 3(點/面) * 3(數值/點) = 36 個數值。
因為使用者貼圖時,想要的圖片的座標映射方式不同,所以直接照他預設的方式去貼,圖片會變形。解決方式是自己設定一下 uv 的值。
PolyhedronGeometry 預設的貼圖方式,可以想像成:
1. 在 PolyhedronGeometry 外有一個大的球體
2. Texture 類似世界地圖那樣貼到這個球體上(y軸為南北極,赤道在xz平面上)
3. 當從原點往某頂點 P 作一條射線,會與球體相交於點 P',此時把 P 的 uv 設定為 P' 的uv。
const geometry = new THREE.TetrahedronGeometry(2, 0)
const position = geometry.attributes.position.clone();
const material = new THREE.MeshBasicMaterial({
vertexColors: THREE.FaceColors,
const colors = [];
const color = new THREE.Color();
for ( let i = 0; i < position.count; i ++ ) {
const z = Math.random() * 0.2;
position.setZ( i, z );
const s = z * 5; // values in the range [0,1]
color.setHSL( s, s, s );
colors.push( color.r, color.g, color.b );
geometry.addAttribute( 'color', new THREE.Float32BufferAttribute( colors, 3 ) );
const tetrahedron = new THREE.Mesh(geometry, material)
scene.add(tetrahedron)
沒想到解法是像 淺水員 回答的這麼簡單