1. 程式人生 > 實用技巧 >Three.js 自定義了一個幾何體

Three.js 自定義了一個幾何體

幾何體本質:

立方體幾何體BoxGeometry本質上就是一系列的頂點構成,只是Threejs的APIBoxGeometry把頂點的生成細節封裝了,使用者可以直接使用。

比如一個立方體網格模型,有6個面,每個面至少兩個三角形拼成一個矩形平面,每個三角形三個頂點構成,對於球體網格模型而言,同樣是通過三角形拼出來一個球面,三角形數量越多,網格模型表面越接近於球形。

法向量:

什麼是法向量?三維平面的法線是垂直於該平面的三維向量。一個平面有無數個法向量。

沒有法向量資料,點光源、平行光等帶有方向性的光源不會起作用(樑濤注:可以使用環境光),三角形平面整個渲染效果相對暗淡,而且兩個三角形分界位置沒有稜角感。設定前後對比如下:

法向量計算方法:

1、BA向量的xyz值=A點座標的xyz分別-B點座標的xyz

2、n法向量垂直於BA向量,所以乘積為0

3、n法向量*BA向量=n的xyz分別*BA向量的xyz=0

4、平面任一頂點的法向量=平面的法向量

5、平面存在無數的法向量,取任一值即可

使用three.js自定義立方體:

演示地址

完整程式碼:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
    </head
> <body> <script src="js/three.min.js"></script> <script src="js/OrbitControls.js"></script> <script> //建立場景 var scene = new THREE.Scene(); /** * 相機設定 */ var width = window.innerWidth
-16; //視窗寬度 var height = window.innerHeight-20; //視窗高度 var k = width / height; //視窗寬高比 var s=200; var camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000); //建立相機物件 var camera = new THREE.PerspectiveCamera(75, k, 1, 1000); camera.position.set(100, 200, 100); //設定相機位置 /** * 建立渲染器物件 */ var renderer = new THREE.WebGLRenderer(); renderer.setSize(width, height);//設定渲染區域尺寸 renderer.setClearColor(0xb9d3ff, 1); //設定背景顏色 document.body.appendChild(renderer.domElement); //body元素中插入canvas物件 //點光源 var point = new THREE.PointLight(0xffffff); point.position.set(100, 100, 100); //點光源位置 scene.add(point); //點光源新增到場景中 //宣告一個空幾何體物件 var geometry = new THREE.BufferGeometry(); //型別陣列建立頂點位置position資料 var vertices = new Float32Array([ //第一個面 0, 0, 0, 50, 0, 0, 0, 50, 0, 50, 0, 0, 0, 50, 0, 50, 50, 0, //第二個面 0, 0, 0, 0, 50, 0, 0, 50, 50, 0, 50, 50, 0, 0, 0, 0, 0, 50, //第三個面 50, 0, 0, 50, 50, 0, 50, 50, 50, 50, 0, 0, 50, 0, 50, 50, 50, 50, //第四個面 0, 0, 0, 0, 0, 50, 50, 0, 0, 50, 0, 0, 50, 0, 50, 0, 0, 50, //第五個面 0, 50, 0, 0, 50, 50, 50, 50, 0, 50, 50, 0, 50, 50, 50, 0, 50, 50, //第六個面 0, 0, 50, 50, 0,50, 0, 50, 50, 50, 0, 50, 0, 50, 50, 50, 50, 50, ]); // 建立屬性緩衝區物件 var attribue = new THREE.BufferAttribute(vertices, 3); //3個為一組 // 設定幾何體attributes屬性的位置position屬性 geometry.attributes.position = attribue //設定法向量 var normals = new Float32Array([ //第一個面頂點的法向量 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, //第二個面頂點的法向量 -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, //第三個面頂點的法向量 1,0,0, 1,0,0, 1,0,0, 1,0,0, 1,0,0, 1,0,0, //第四個面頂點的法向量 0,-1,0, 0,-1,0, 0,-1,0, 0,-1,0, 0,-1,0, 0,-1,0, //第五個面頂點的法向量 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, //第四個面頂點的法向量 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ]); // 設定幾何體attributes屬性的位置normal屬性 geometry.attributes.normal = new THREE.BufferAttribute(normals, 3); //3個為一組,表示一個頂點的法向量資料 // 三角面(網格)渲染模式 var material = new THREE.MeshLambertMaterial({ color: 0x0000ff, //三角面顏色 side: THREE.DoubleSide //兩面可見 }); //材質物件 var mesh = new THREE.Mesh(geometry, material); //網格模型物件Mesh scene.add(mesh); // 點渲染模式 var material = new THREE.PointsMaterial({ color: 0xff0000, size: 5.0 //點物件畫素尺寸 }); //材質物件 var points = new THREE.Points(geometry, material); //點模型物件 scene.add(points); //點物件新增到場景中 // 輔助座標系 引數250表示座標系大小,可以根據場景大小去設定 var axisHelper = new THREE.AxisHelper(250); scene.add(axisHelper); //新增幀渲染 function render() { renderer.render(scene, camera); //執行渲染操作 requestAnimationFrame(render); //請求再次執行渲染函式render } render(); var controls = new THREE.OrbitControls(camera, renderer.domElement); //建立滑鼠控制物件 //尺寸響應式 window.addEventListener('resize', () => { //初始化攝像機 camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); //初始化渲染器 renderer.setSize(window.innerWidth, window.innerHeight); }) </script> </body> </html>