以構建一個魔方為例
<div id="cube"></div>
全局變量
camera: null,
scene: null,
renderer: null,
controls: null,
faceA: [1,0,0, 1,0,0, 1,0,0, 1,0,0, 1,0,0, 1,0,0],
faceB: [0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0],
faceC: [0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1],
faceD: [1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0],
faceE: [0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1, 0,1,1],
faceF: [1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,0,1],
faceG: [1,1,1, 1,1,1, 1,1,1, 1,1,1, 1,1,1, 1,1,1],
創(chuàng)建渲染器等內容
this.scene=new THREE.Scene();
//環(huán)境光
const ambient = new THREE.AmbientLight(0xffffff);
//環(huán)境光添加到場景中
this.scene.add(ambient);
const width = window.innerWidth;
// 窗口高度
const height = window.innerHeight;
// 創(chuàng)建相機對象
this.camera = new THREE.PerspectiveCamera( 45, width / height, 0.1, 1000 );
// 設置相機的位置
this.camera.position.set(0,0,300);
// 設置相機的方向(指向場景的方向)
this.camera.lookAt(this.scene.position);
/**
* 創(chuàng)建渲染器的對象
*/
this.renderer = new THREE.WebGLRenderer({antialias: true,logarithmicDepthBuffer:true});
// 設置渲染區(qū)域的尺寸
this.renderer.setSize(width,height);
// 設置背景顏色
this.renderer.setClearColor(0x424142,1);
this.renderer.shadowMap.enabled = true
// 指定元素中插入canvas對象
const webglBox = document.getElementById("cube");
webglBox.appendChild(this.renderer.domElement);
正方體頂點相對位置(基于自身坐標系的位置)
const vertices=new Float32Array([
-10,10,10,10,10,10,10,-10,10,
10,-10,10,-10,-10,10,-10,10,10, // 正面
-10,10,-10,10,10,-10,10,-10,-10,
10,-10,-10,-10,-10,-10,-10,10,-10, // 背面
10,10,10,10,10,-10,10,-10,-10,
10,-10,-10,10,-10,10,10,10,10, //右面
-10,10,10,-10,10,-10,-10,-10,-10,
-10,-10,-10,-10,-10,10,-10,10,10, //左面
-10,10,10,10,10,10,10,10,-10,
10,10,-10,-10,10,-10,-10,10,10, // 頂面
-10,-10,10,10,-10,10,10,-10,-10,
10,-10,-10,-10,-10,-10,-10,-10,10 //地面
])
構建魔方
for (let i = -1; i < 2; i++) {
for (let j = -1; j < 2; j++) {
for (let k = -1; k < 2; k++) {
// 創(chuàng)建幾何體
const geometry=new THREE.BufferGeometry();
geometry.attributes.position=new THREE.BufferAttribute(vertices, 3);
let colorsArr1=[],colorsArr2=[],colorsArr3=[];
// 為不同位置的幾何體的各個面賦予不同的顏色
switch (i) {
case -1: {
colorsArr1 = [...this.faceG, ...this.faceC];
break;
}
case 0: {
colorsArr1 = [...this.faceG, ...this.faceG];
break;
}
case 1: {
colorsArr1 = [...this.faceA, ...this.faceG];
break;
}
}
switch (k) {
case -1: {
colorsArr2 = [...this.faceG, ...this.faceD];
break;
}
case 0: {
colorsArr2 = [...this.faceG, ...this.faceG];
break;
}
case 1: {
colorsArr2 = [...this.faceB, ...this.faceG];
break;
}
}
switch (j) {
case -1: {
colorsArr3 = [...this.faceG, ...this.faceF];
break;
}
case 0: {
colorsArr3 = [...this.faceG, ...this.faceG];
break;
}
case 1: {
colorsArr3 = [...this.faceE, ...this.faceG];
break;
}
}
const colorsArr=[...colorsArr1,...colorsArr2,...colorsArr3];
const colors=new Float32Array(colorsArr);
geometry.attributes.color=new THREE.BufferAttribute(colors,3);
// 創(chuàng)建材質
const material= new THREE.MeshBasicMaterial({
vertexColors: THREE.VertexColors, //以頂點顏色為準
side: THREE.DoubleSide, //兩面可見
});
const mesh=new THREE.Mesh(geometry,material);
mesh.name=i+""+j+""+k
// 正方體的位置(基于世界坐標系)
mesh.position.set(k*23,j*23,i*23);
this.scene.add(mesh);
}
}
}
this.renderer.render(this.scene,this.camera);
重點:
使用BufferGeometry自己手動寫入頂點位置信息構建物體
為同一個面的每一個頂點賦予相同的顏色
使用MeshBasicMaterial創(chuàng)建材質犹撒,并聲明以頂點顏色為準揩局,且兩面可見(保證在某些角度觀察正方體的時候不會出現透視現象)