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>

頂點索引復用頂點數據

通過頂點索引組織網格模型三角形的繪制,因為矩形的兩個三角形有兩個頂點位置重復,所以頂點位置數據、頂點法向量數據可以復用。立方體只需要定義8個頂點。

             //聲明一個空幾何體對象
            var geometry = new THREE.BufferGeometry();
            //類型數組創建頂點位置position數據
            var vertices = new Float32Array([
              //第一個面
              0, 0, 0, 
              50, 0, 0,
              50, 50, 0,
              0, 50, 0,
              0, 0, 50,
              50, 0, 50,
              50, 50, 50,
              0, 50, 50, 
            ]);
            // 創建屬性緩沖區對象
            var attribue = new THREE.BufferAttribute(vertices, 3); //3個為一組
            // 設置幾何體attributes屬性的位置position屬性
            geometry.attributes.position = attribue
            
            //設置法向量
            var normals = new Float32Array([
             //第一個頂點的法向量
              0, 1, 0, 
              0, 1, 0, 
              0, 1, 0,
              0, 1, 0, 
              0, 1, 0, 
              0, 1, 0, 
              0, 1, 0,
              0, 1, 0,
            ]);
            // 設置幾何體attributes屬性的位置normal屬性
            geometry.attributes.normal = new THREE.BufferAttribute(normals, 3); //3個為一組,表示一個頂點的法向量數據
            
            // Uint16Array類型數組創建頂點索引
            var indexes = new Uint16Array([
              // 0對應第1個頂點位置數據、第1個頂點法向量數據
              // 1對應第2個頂點位置數據、第2個頂點法向量數據
              // 索引值3個為一組,表示一個三角形的3個頂點
              0,1,2,
              0,2,3,
              2,3,6,
              3,6,7,
              1,2,5,
              2,5,6,
              0,3,4,
              3,4,7,
              1,4,5,
              0,1,4,
              4,5,7,
              5,6,7
            ])
            // 索引數據賦值給幾何體的index屬性
            geometry.index = new THREE.BufferAttribute(indexes, 1); //1個為一組

創建頂點索引數組的時候,可以根據頂點的數量選擇類型數組Uint8ArrayUint16Array(數據無符號16位整型Uint32Array。對於頂點索引而言選擇整型類型數組,對於非索引的頂點數據,需要使用浮點類型數組Float32Array等。

 

Face3對象定義Geometry的三角形面

幾何體Geometry的三角面屬性geometry.faces和緩沖類型幾何體BufferGeometry頂點索引屬性BufferGeometry.index類似都是頂點位置數據的索引值,用來組織網格模型三角形的繪制。

threejs提供了Face3對象構建三角形,通過Face3構建一個三角形,不要設置頂點位置坐標數據,只需要通過數組索引值從geometry.vertices數組中獲得頂點位置坐標數據。

 //聲明一個幾何體對象Geometry
            var geometry = new THREE.Geometry();
            //類型數組創建頂點位置position數據
            var p1 = new THREE.Vector3(0, 0, 0); //頂點1坐標
            var p2 = new THREE.Vector3(50, 0, 0); //頂點2坐標
            var p3 = new THREE.Vector3(50, 50, 0); //頂點3坐標
            var p4 = new THREE.Vector3(0, 50, 0); //頂點4坐標
            
            var p5 = new THREE.Vector3(0, 0, 50); //頂點5坐標
            var p6 = new THREE.Vector3(50, 0, 50); //頂點6坐標
            var p7 = new THREE.Vector3(50, 50, 50); //頂點7坐標
            var p8 = new THREE.Vector3(0, 50, 50); //頂點8坐標
            //頂點坐標添加到geometry對象
            geometry.vertices.push(p1, p2, p3,p4,p5,p6,p7,p8);

            // Face3構造函數創建一個三角面
            var face1 = new THREE.Face3(0,1,2);
            var face2 = new THREE.Face3(0,2,3);
            var face3 = new THREE.Face3(2,3,6);
            var face4 = new THREE.Face3(3,6,7);
            var face5 = new THREE.Face3(1,2,5);
            var face6 = new THREE.Face3(2,5,6);
            var face7 = new THREE.Face3(0,3,4);
            var face8 = new THREE.Face3(3,4,7);
            var face9 = new THREE.Face3(1,4,5);
            var face10 = new THREE.Face3(0,1,4);
            var face11 = new THREE.Face3(4,5,7);
            var face12 = new THREE.Face3(5,6,7);
            
            // 設置三角面法向量
            face3.normal=new THREE.Vector3(0, 0, 1);
            
            // 設置三角面face1三個頂點的顏色
            face1.color = new THREE.Color(0xff00ff);
            
            //三角面face1、face2添加到幾何體中
            geometry.faces.push(face1,face2,face3,face4,face5,face6,face7,face8,face9,face10,face11,face12);
            
            //縮放
            geometry.scale(0.5, 1.5, 1.5);

總結:

BufferGeometry總結

 

 

Geometry總結

 

幾何體縮放、平移、旋轉屬性

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM