Three.js繪制點、線、面


一、綜述

  在計算機世界里,3D世界是由點組成,兩個點能夠組成一條直線,三個不在一條直線上的點就能夠組成一個三角形面,無數三角形面就能夠組成各種形狀的物體,如下圖:

  我們通常把這種網格模型叫做Mesh模型。給物體貼上皮膚,或者專業點就叫做紋理,那么這個物體就活靈活現了。最后無數的物體就組成了我們的3D世界。

二、兩點連成直線

在Three.js中用一個向量來表示點:

var point1 = new THREE.Vecotr3(4,8,9);

另外也可以使用set方法,代碼如下:

var point1 = new THREE.Vector3();
point1.set(4,8,9);

1.畫一條彩色的線代碼

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Three框架</title>
        <script src="js/Three.js"></script>
        <style type="text/css">
            div#canvas-frame {
                border: none;
                cursor: pointer;
                width: 100%;
                height: 600px;
                background-color: #EEEEEE;
            }

        </style>
        <script>
            var renderer;
            function initThree() {
                width = document.getElementById('canvas-frame').clientWidth;
                height = document.getElementById('canvas-frame').clientHeight;
                renderer = new THREE.WebGLRenderer({
                    antialias : true
                });
                renderer.setSize(width, height);
                document.getElementById('canvas-frame').appendChild(renderer.domElement);
                renderer.setClearColor(0xFFFFFF, 1.0);
            }

            var camera;
            function initCamera() {
                camera = new THREE.PerspectiveCamera(45, width / height, 1, 10000);
                camera.position.x = 0;
                camera.position.y = 1000;
                camera.position.z = 0;
                camera.up.x = 0;
                camera.up.y = 0;
                camera.up.z = 1;
                camera.lookAt({
                    x : 0,
                    y : 0,
                    z : 0
                });
            }

            var scene;
            function initScene() {
                scene = new THREE.Scene();
            }

            var light;
            function initLight() {
                light = new THREE.DirectionalLight(0xFF0000, 1.0, 0);
                light.position.set(100, 100, 200);
                scene.add(light);
            }

            var cube;
            function initObject() {

                var geometry = new THREE.Geometry();
                var material = new THREE.LineBasicMaterial( { vertexColors: true } );
                var color1 = new THREE.Color( 0x444444 ), color2 = new THREE.Color( 0xFF0000 );

                // 線的材質可以由2點的顏色決定
                var p1 = new THREE.Vector3( -100, 0, 100 );
                var p2 = new THREE.Vector3(  100, 0, -100 );
                geometry.vertices.push(p1);
                geometry.vertices.push(p2);
                geometry.colors.push( color1, color2 );

                var line = new THREE.Line( geometry, material, THREE.LinePieces );
                scene.add(line);
            }

            function threeStart() {
                initThree();
                initCamera();
                initScene();
                initLight();
                initObject();
                renderer.clear();
                renderer.render(scene, camera);
            }

        </script>
    </head>

    <body onload="threeStart();">
        <div id="canvas-frame"></div>
    </body>
</html>

2.畫線

  兩點確定一條直線,要畫一條直線,思路是:

  • 定義一個幾何體geometry用來存放兩端點的坐標和顏色
  • 定義線條材質
  • 創建線條並加入到場景中

3.代碼解析

定義點的坐標和顏色

var color1 = new THREE.Color( 0x444444 ), color2 = new THREE.Color( 0xFF0000 );
var p1 = new THREE.Vector3( -100, 0, 100 );
var p2 = new THREE.Vector3(  100, 0, -100 );

聲明幾何體並存放點和頂點顏色

var geometry = new THREE.Geometry();
geometry.vertices.push(p1);
geometry.vertices.push(p2);
geometry.colors.push( color1, color2 );

  幾何體里面有一個vertices變量,可以用來存放點。

  geometry中colors表示頂點的顏色,必須材質中vertexColors等於THREE.VertexColors 時,顏色才有效,如果vertexColors等於THREE.NoColors時,顏色就沒有效果了。那么就會去取材質中color的值 。

定義線條材質

var material = new THREE.LineBasicMaterial( { vertexColors: true } );

  使用THREE.LineBasicMaterial類型來定義線條材質,它接受一個集合作為參數,其原型如下:

  LineBasicMaterial( parameters )

  Parameters是一個定義材質外觀的對象,它包含多個屬性來定義材質,這些屬性是:

  • Color:線條的顏色,用16進制來表示,默認的顏色是白色。
  • Linewidth:線條的寬度,默認時候1個單位寬度。
  • Linecap:線條兩端的外觀,默認是圓角端點,當線條較粗的時候才看得出效果,如果線條很細,那么你幾乎看不出效果了。
  • Linejoin:兩個線條的連接點處的外觀,默認是“round”,表示圓角。
  • VertexColors:定義線條材質是否使用頂點顏色,這是一個boolean值。意思是,線條各部分的顏色會根據頂點的顏色來進行插值。
  • Fog:定義材質的顏色是否受全局霧效的影響。

創建線條並加入場景

var line = new THREE.Line( geometry, material, THREE.LinePieces );
scene.add(line);

  第一個參數是幾何體geometry,里面包含了2個頂點和頂點的顏色。第二個參數是線條的材質,或者是線條的屬性,表示線條以哪種方式取色。第三個參數是一組點的連接方式。

  然后,將這條線加入到場景中,代碼如下:

  scene.add(line);

  這樣,場景中就會出現剛才的那條線段了。

4.線條深入理解

  點由THREE.Vector3表示,Threejs中沒有提供單獨畫點的函數,它必須被放到一個THREE.Geometry形狀中,這個結構中包含一個數組vertices,這個vertices就是存放無數的點(THREE.Vector3)的數組。

三、網格面

1.右手坐標系

  Threejs使用的是右手坐標系。x軸正方向向右,y軸正方向向上,z軸由屏幕從里向外。

2.畫坐標平面

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Three框架</title>
        <script src="js/Three.js"></script>
        <style type="text/css">
            div#canvas-frame {
                border: none;
                cursor: pointer;
                width: 100%;
                height: 600px;
                background-color: #EEEEEE;
            }

        </style>
        <script>
            var renderer;
            function initThree() {
                width = document.getElementById('canvas-frame').clientWidth;
                height = document.getElementById('canvas-frame').clientHeight;
                renderer = new THREE.WebGLRenderer({
                    antialias : true
                });
                renderer.setSize(width, height);
                document.getElementById('canvas-frame').appendChild(renderer.domElement);
                renderer.setClearColor(0xFFFFFF, 1.0);
            }

            var camera;
            function initCamera() {
                camera = new THREE.PerspectiveCamera(45, width / height, 1, 10000);
                camera.position.x = 0;
                camera.position.y = 1000;
                camera.position.z = 0;
                camera.up.x = 0;
                camera.up.y = 0;
                camera.up.z = 1;
                camera.lookAt({
                    x : 0,
                    y : 0,
                    z : 0
                });
            }

            var scene;
            function initScene() {
                scene = new THREE.Scene();
            }

            var light;
            function initLight() {
                light = new THREE.DirectionalLight(0xFF0000, 1.0, 0);
                light.position.set(100, 100, 200);
                scene.add(light);
            }

            var cube;
            function initObject() {
                var geometry = new THREE.Geometry();
                geometry.vertices.push( new THREE.Vector3( - 500, 0, 0 ) );
                geometry.vertices.push( new THREE.Vector3( 500, 0, 0 ) );

                for ( var i = 0; i <= 20; i ++ ) {

                    var line = new THREE.Line( geometry, new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.2 } ) );
                    line.position.z = ( i * 50 ) - 500;
                    scene.add( line );

                    var line = new THREE.Line( geometry, new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.2 } ) );
                    line.position.x = ( i * 50 ) - 500;
                    line.rotation.y = 90 * Math.PI / 180;
                    scene.add( line );

                }
            }

            function threeStart() {
                initThree();
                initCamera();
                initScene();
                initLight();
                initObject();
                renderer.clear();
                renderer.render(scene, camera);
            }

        </script>
    </head>

    <body onload="threeStart();">
        <div id="canvas-frame"></div>
    </body>
</html>

3.代碼解析

  定義幾何體並加入兩個點。

var geometry = new THREE.Geometry();
geometry.vertices.push( new THREE.Vector3( - 500, 0, 0 ) );
geometry.vertices.push( new THREE.Vector3( 500, 0, 0 ) );

  這兩個點決定了x軸上的一條線段,將這條線段復制20次,分別平行移動到z軸的不同位置,就能夠形成一組平行的線段。

同理,將p1p2這條線先圍繞y軸旋轉90度,然后再復制20份,平行於z軸移動到不同的位置,也能形成一組平行線。

經過上面的步驟,就能夠得到坐標網格了。代碼如下:

for ( var i = 0; i <-= 20; i ++ ) {
    var line = new THREE.Line( geometry, new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.2 } ) );
    line.position.z = ( i * 50 ) - 500;
    scene.add( line );
var line = new THREE.Line( geometry, new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.2 } ) ); line.position.x = ( i * 50 ) - 500; line.rotation.y = 90 * Math.PI / 180; // 旋轉90度 scene.add( line ); }

4.補充

  相機的position,是相機的位置。如果把人頭比作相機,那么就是人頭的中心的位置。

  up是頭頂的方向。

  lookat是眼睛,看的方向,或者說是眼睛的聚焦點。

  最后要說明的是 up 和lookat這兩個方向必須垂直,無論怎么設置,他們必須互相垂直。不然相機看到的結果無法預知。

  另外,相機沒有朝向的說法,只有lookat,就是它看到的那一個聚焦點,就像眼睛看到的聚焦點一樣。

 

四、出處

剛接觸Three.js,這算是記錄網上找資料學習的筆記,主要來源於WebGL中文網,如有侵權,請聯系我刪除。


免責聲明!

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



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