Three.js開發指南---使用構建three.js的基本組件(第二章)

.gui本章的主要內容javascript

  1 場景中使用哪些組件html

  2 幾何圖形和材質如何關聯java

  3 正投影相機和透視相機的區別數組

一,Three所須要的基本元素瀏覽器

  場景scene:一個容器,用來保存並跟蹤全部咱們想渲染的物體app

  相機camera:場景scene中保存了全部咱們想要渲染的物體,可是這些物體哪些是但願被看到的,由相機來決定,即相機決定了哪些東西將要在屏幕上渲染,場景渲染的時候會自動將camera添加進去dom

  光源:光源會對物體如何顯示,以及生成陰影時物體如何使用產生影響ide

  渲染器render:負責計算指定相機角度下,瀏覽器中場景的樣子,有給予wenbGL的渲染器,有基於Canvas的渲染器,還有基於SVG的渲染器函數

  物體:相機的主要渲染對象,Three自帶的最基本的物體有球體,平面,座標軸,方塊等ui

  

二,場景

   2.1   場景是渲染過程當中全部物體,光源和相機的容器

  2.2    下面是場景最常常用到的屬性和方法

屬性/方法 描述
add(object) 向場景中添加對象
children屬性 返回一個場景中全部對象的列表,包括相機和光源
getChildByName(name) 經過對象的name屬性來獲取該對象
remove(object) 刪除該場景中的某個對象
traverse(function(object){}) 遍歷場景中的全部對象
fog 設置場景的霧化效果(一個物體離相機越遠,就越模糊)
overrideMaterial 經過這個屬性,能夠強制場景中的全部物體使用相同的材質
var scene = new THREE.Scene();//生成一個場景
scene.add(物體);//向該場景中添加物體
scene.add(光源);//向該場景中添加光源
scene.remove(某個物體/某個光源);//移除掉該場景中的某個物體或者某個光源
scene.children();//獲取場景中的全部子對象列表
scene.getChildByName(name屬性);//根據name屬性獲取到場景中的某一個對象
scene.children.length;//獲取子對象的數量
scene.traverse(function(e){console.log("遍歷場景中的的每個子對象e:",e)});
scene.fog=new THREE.Fog(0xffffff,0.015,100);//設置場景的霧化效果
scene.overrideMaterial=new THREE.MeshLambertMaterial({color:0xffffff});//設置該場景中的全部物體的材質

 demo,使用dat.gui圖形界面增長立方體,刪除立方體,以及計算立方體的個數,以及場景霧化(一個物體離得越遠,就越模糊)

<!DOCTYPE html>

<html>

<head>
    <title>1</title>
    <script type="text/javascript" src="three.js"></script>
    <script type="text/javascript" src="dat.gui.js"></script>
    <script type="text/javascript" src="AsciiEffect.js"></script>
    <style>
        body {
            /* set margin to 0 and overflow to hidden, to go fullscreen */
            margin: 0;
            overflow: hidden;
        }
    </style>
</head>
<body>

<!-- Div which will hold the Output -->
<div id="WebGL-output">
</div>

<!-- Javascript code that runs our Three.js examples -->
<script type="text/javascript">
//var scene
   function init() {
        var scene=new THREE.Scene();//生成一個場景
        //生成一個相機
        var camera=new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.1,1000);//視場,長寬比,近面,遠面
        camera.position.x=-20;
        camera.position.y=40;
        camera.position.z=30;
        camera.lookAt(scene.position);
        //生成一個渲染器
        var render=new THREE.WebGLRenderer();
        render.setClearColorHex(0xEEEEEE);
        render.setSize(window.innerWidth,window.innerHeight);
        render.shadowMapEnabled=true;//容許陰影映射,渲染陰影須要大量的資源,所以咱們須要告訴渲染器咱們須要陰影
        
        
        //生成一個座標軸,輔助線
        var axes=new THREE.AxisHelper(20);
        //生成一個平面
        var planeGeometry=new THREE.PlaneGeometry(60,20,10,10);//平面
        //生成一個材質
        var planeMaterial=new THREE.MeshLambertMaterial({color:0xffffff});
        //生成一個網格,將平面和材質放在一個網格中,組合在一塊兒,組成一個物體
        var plane=new THREE.Mesh(planeGeometry,planeMaterial);
        plane.rotation.x=-0.5*Math.PI;//將平面沿着x軸進行旋轉
        plane.position.x=0;
        plane.position.y=0;
        plane.position.z=0;
        plane.receiveShadow=true;//平面進行接受陰影
        
        var cubeGeometry=new THREE.CubeGeometry(10,10,10);
        var planeMaterial1=new THREE.MeshLambertMaterial({color:0xff0000});
        /*var cube=new THREE.Mesh(cubeGeometry,planeMaterial1);
        //plane1.rotation.x=-0.5*Math.PI;//將平面沿着x軸進行旋轉
        cube.position.x=-4;
        cube.position.y=3;
        cube.position.z=0;
        cube.castShadow=true;//須要陰影,方塊進行投射陰影*/
        
        
        var spotLight=new THREE.SpotLight(0xffffff);
        spotLight.position.set(-40,60,-10);
        spotLight.castShadow=true;
        //將相機,渲染器,座標軸,平面都追加到場景中,而後對場景和相機進行渲染
        scene.add(camera);
        scene.add(render);
        scene.add(axes);
        scene.add(plane);
        //scene.add(cube);
        scene.add(spotLight);
        //var effect=new THREE.AsciiEffect(render);
        ///effect.setSize(window.innerWidth,window.innerHeight);
        document.getElementById("WebGL-output").append(render.domElement);
        
        
        
        var controls=new function(){
            this.rotationSpeed=0.02;
            this.numberofObject=scene.children.length;
            this.addCube=function(){
                var cubeSize=Math.ceil(Math.random()*3);
                var cubeGeometry=new THREE.BoxGeometry(cubeSize,cubeSize,cubeSize);
                var cubeMaterial=new THREE.MeshLambertMaterial({color:Math.random()*0xffffff});
                var cube=new THREE.Mesh(cubeGeometry,cubeMaterial);
                cube.castShadow=true;
                cube.name="cube-"+scene.children.length;
                cube.position.x=-30+Math.round(Math.random()*planeGeometry.parameters.width);
                cube.position.y=Math.round(Math.random()*5);
                cube.position.z=-20+Math.round(Math.random()*planeGeometry.parameters.height);
                scene.add(cube);
                this.numberofObject=scene.children.length;
            };
            this.removeCube=function(){
                var allChildren=scene.children;
                var lastChild=allChildren[allChildren.length-1];
                if(lastChild instanceof THREE.Mesh){
                    scene.remove(lastChild);
                    this.numberofObject=scene.children.length;
                }
            };
        };
        var gui=new dat.GUI();
        gui.add(controls,"rotationSpeed",0,0.5);
        gui.add(controls,"addCube"); gui.add(controls,"removeCube");
        gui.add(controls,"numberofObject").listen();;
        function renderScene(){
            scene.traverse(function (e) { if (e instanceof THREE.Mesh && e != plane) { e.rotation.x += controls.rotationSpeed; e.rotation.y += controls.rotationSpeed; e.rotation.z += controls.rotationSpeed; } });
            requestAnimationFrame(renderScene);
            render.render(scene, camera);
        }
     scene.fog=new THREE.Fog(0xffffff,0.015,100);//霧化 renderScene(); } window.onload
= init; </script> </body> </html>

 

 

 

 

 

三 使用幾何和網格對象

  3.1 幾何體對象Geometry

  Geometry對象基本上是三維空間中的點集,以及將這些點集連接起來的面組成

    例如:一個方塊有8個角,每一個角的座標又是x,y,z的一個組合,這8個點稱之爲定點

        一個方塊有6個側面,每一個面有兩個三角面片構成,至於咱們是使用四邊形來定義一個面仍是使用兩個三角形來構建一個面,

        如何取捨,基本上在建模的時候是使用四邊形,由於它比三角形更容易加強和加強,可是對於渲染和遊戲引擎來講,使用三角形則更容易,由於任意一個形狀均可以渲染成多個三角形

var vertices = [
            new THREE.Vector3(1,3,1),
            new THREE.Vector3(1,3,-1),
            new THREE.Vector3(1,-1,1),
            new THREE.Vector3(1,-1,-1),
            new THREE.Vector3(-1,3,-1),
            new THREE.Vector3(-1,3,1),
            new THREE.Vector3(-1,-1,-1),
            new THREE.Vector3(-1,-1,1)
        ];
        var faces=[
            new THREE.Face3(0,2,1),
            new THREE.Face3(2,3,1),
            new THREE.Face3(4,6,5),
            new THREE.Face3(6,7,5),
            new THREE.Face3(4,5,1),
            new THREE.Face3(5,0,1),
            new THREE.Face3(7,6,2),
            new THREE.Face3(6,3,2),
            new THREE.Face3(5,7,0),
            new THREE.Face3(7,2,0),
            new THREE.Face3(1,3,4),
            new THREE.Face3(3,6,4)
        ]
        var geom=new THREE.Geometry();
        geom.vertices=vertices;
        geom.faces=faces;
        geom.computeCentroids();
/*

computeCentroids這個函數是算geometry中每個面的重心,不管在平面座標系仍是空間座標系中,重心能夠求座標的平均值來獲得,如A點(X1,Y1,Z1),B點(X2,Y2,Z2)和C點(X3,Y3,Z3),他們造成的三角面的中心是:

 
 

重心的橫座標:(X1+X2+X3)/3

 
 

重心的縱座標:(Y1+Y2+Y3)/3

 
 

重心的豎座標:(z1+z2+z3)/3

*/
        geom.mergeVertices();

 

    

 

下面的demo的功能

  1 使用頂點和麪來構建本身的幾何體,

  2 用它來建立網格,

  3 改變頂點,來改變幾何體的形狀,

  4 geometry的clone方法對上面定義的物體進行復制,而後賦予不一樣的材質,造成一個新的網格對象

      須要注意的點:

  1 three.js假設一個網格幾何體在其生命週期內是不會改變,咱們能夠設置verticeNeedUpdate的值爲true,當頂點的值發生改變的時候,就會被更新,

    另外咱們還須要調用computeFaceNormals方法從新計算側面,從而完成整個模型的更新

  2 咱們上面使用幾何體材質的時候,使用代碼語句是new Mesh(幾何體,材質),在下面的demo中,咱們使用的是var mesh=THREE.SceneUtils.createMultiMaterialObject(geom,materials);

  咱們使用的不是單一的材質對幾何體進行關聯,而是使用的材質數組,即多個材質。由於除了一個能夠對光作出反應的材質外,咱們還想使用一個線框,能夠具體看到頂點和麪的位置,

  使用多種材質關聯一個幾何體的話,就須要使用函數THREE.SceneUtils.createMultiMaterialObject(geom,materials),在這個函數中,不是生成一個Mesh的實例,而是爲每一個你指定的材質都建立一個實例,而後將這些實例存放在一個組裏,

  咱們可使用mesh.children.forEach(function(e){})來遍歷每一個網格實例

<!DOCTYPE html>

<html>

<head>
    <title>1</title>
    <script type="text/javascript" src="three.js"></script>
    <script type="text/javascript" src="dat.gui.js"></script>
    <script type="text/javascript" src="AsciiEffect.js"></script>
    <style>
        body {
            /* set margin to 0 and overflow to hidden, to go fullscreen */
            margin: 0;
            overflow: hidden;
        }
    </style>
</head>
<body>

<!-- Div which will hold the Output -->
<div id="WebGL-output">
</div>

<!-- Javascript code that runs our Three.js examples -->
<script type="text/javascript">
//var scene
   function init() {
        var scene=new THREE.Scene();//生成一個場景
        
        //生成一個相機
        var camera=new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.1,1000);//視場,長寬比,近面,遠面
        camera.position.x=-20;
        camera.position.y=40;
        camera.position.z=30;
        camera.lookAt(scene.position);
        
        //生成一個渲染器
        var render=new THREE.WebGLRenderer();
        render.setClearColorHex(0xEEEEEE);
        render.setSize(window.innerWidth,window.innerHeight);
        render.shadowMapEnabled=true;//容許陰影映射,渲染陰影須要大量的資源,所以咱們須要告訴渲染器咱們須要陰影
        
        
    
        //生成一個平面
        var planeGeometry=new THREE.PlaneGeometry(60,20,10,10);//平面
        //生成一個材質
        var planeMaterial=new THREE.MeshLambertMaterial({color:0xffffff});
        //生成一個網格,將平面和材質放在一個網格中,組合在一塊兒,組成一個物體
        var plane=new THREE.Mesh(planeGeometry,planeMaterial);
        plane.rotation.x=-0.5*Math.PI;//將平面沿着x軸進行旋轉
        plane.position.x=0;
        plane.position.y=0;
        plane.position.z=0;
        plane.receiveShadow=true;//平面進行接受陰影
        
        
        //生成一個光源
        var spotLight=new THREE.SpotLight(0xffffff);
        spotLight.position.set(-40,60,-10);
        spotLight.castShadow=true;
        
        //生成點和麪
        var vertices=[
            new THREE.Vector3(1,3,1),
            new THREE.Vector3(1,3,1),
            new THREE.Vector3(1,-1,1),
            new THREE.Vector3(1,-1,-1),
            new THREE.Vector3(-1,3,-1),
            new THREE.Vector3(-1,3,1),
            new THREE.Vector3(-1,-1,-1),
            new THREE.Vector3(-1,-1,1)
        ];
//生成面的參數是頂點集合裏面的序列號
var faces=[ new THREE.Face3(0,2,1), new THREE.Face3(2,3,1), new THREE.Face3(4,6,5), new THREE.Face3(6,7,5), new THREE.Face3(4,5,1), new THREE.Face3(5,0,1), new THREE.Face3(7,6,2), new THREE.Face3(6,3,2), new THREE.Face3(5,7,0), new THREE.Face3(7,2,0), new THREE.Face3(1,3,4), new THREE.Face3(3,6,4) ]; //使用上面生成的點和麪構建咱們本身的幾何體
      //computeFaceNormal函數對幾何體的各個側面進行計算,以完成對整個模型的構建

var geom=new THREE.Geometry(); geom.vertices=vertices; geom.faces=faces; geom.computeFaceNormals(); //生成材質 var materials=[ new THREE.MeshLambertMaterial({opacity:0.6,color:0x44ff44,transparent:true}), new THREE.MeshBasicMaterial({color:0x000000,wireframe:true}) ] //將上面自定義的幾何體與材質關聯起來,一個幾何體和多個材質進行關聯,使用的是方法THREE.SceneUtils.createMultiMaterialObject var mesh=THREE.SceneUtils.createMultiMaterialObject(geom,materials); mesh.children.forEach(function(e){ e.castShadow=true; }); //增長gui圖形操做界面,
//初始化8個頂點的初始值

function addControl(x,y,z){ var controls=new function(){ this.x=x; this.y=y; this.z=z; } return controls; } var controlPoints=[]; controlPoints.push(addControl(3,5,3)); controlPoints.push(addControl(3,5,0)); controlPoints.push(addControl(3,0,3)); controlPoints.push(addControl(3,0,0)); controlPoints.push(addControl(0,5,0)); controlPoints.push(addControl(0,5,3)); controlPoints.push(addControl(0,0,0)); controlPoints.push(addControl(0,0,3)); //增長gui圖形操做界面,gui設置摺疊菜單 var gui=new dat.GUI(); for(var i=0;i<8;i++){ var f1=gui.addFolder("vertices"+(i+1)); f1.add(controlPoints[i],'x',-10,10); f1.add(controlPoints[i],'y',-10,10); f1.add(controlPoints[i],'z',-10,10); }
        gui.add(new function(){ this.clone=function(){ var cloneGeometry=mesh.children[0].geometry.clone();//這裏的mesh是一個網格集合,裏面的子元素都是網格,網格對象又有幾何體和材質對象,這裏複製的只是網格對象的幾何體 var mesh2=THREE.SceneUtils.createMultiMaterialObject(cloneGeometry,materials); mesh2.children.forEach(function(e){ e.castShadow=true; }); mesh2.translateX(5); mesh2.translateY(5); scene.add(mesh2); } },"clone"); 

function renderScene(){ var vertices=[]; for(var i=0;i<8;i++){ vertices.push(new THREE.Vector3(controlPoints[i].x, controlPoints[i].y, controlPoints[i].z)); }
//因爲three.js假設一個幾何體在其生命週期是不會改變的,
//因此這裏咱們要動態改變幾何體的形狀,須要在渲染網格對象的時候,
//設置幾何體的屬性verticesNeedUpdate能夠刷新,
//而後再對側面進行計算computeFaceNormal,以完成對幾何體的重構
mesh.children.forEach(
function(e){ e.geometry.vertices=vertices; e.geometry.verticesNeedUpdate=true; e.geometry.computeFaceNormals() }); requestAnimationFrame(renderScene); render.render(scene, camera); } scene.add(camera); scene.add(spotLight); scene.add(plane); scene.add(mesh); scene.add(render); document.getElementById("WebGL-output").append(render.domElement); renderScene(); } window.onload = init; </script> </body> </html>

 

   3.2 網格mesh

  建立一個網格,須要一個幾何體和一個或者多個材質,

  上面的demo中,咱們已經建立了一個長方體geom,下面咱們來建立兩個材質

  var materials = [
            new THREE.MeshLambertMaterial({opacity: 0.6, color: 0x44ff44, transparent: true}),//朗伯材質,是一種能夠對光源作出反應的材質,能夠用來建立暗淡的材質
            new THREE.MeshBasicMaterial({color: 0x000000, wireframe: true})
//這種材質是一種很是簡單的材質,不考慮光照影響,使用這種材質網格會被渲染成一些簡單的平面多邊形,wireframe的值設置爲true,能夠將材質渲染成線框,對調試有力
        ];

 

  建立網格的函數:THREE.SceneUtils.createMultiMaterialObject(幾何體,材質)

 var mesh = THREE.SceneUtils.createMultiMaterialObject(geom, materials);
//注意這裏使用的不是THREE.mesh方法,而是createMultiMaterialObject,該方法爲每一個你指定的材質(這裏是兩種不一樣的材質),都建立一個網格,即建立了兩個網格,一個是簡單材質,不考慮光照影響,一個是對暗淡光照有反應

  而後咱們將上面生成的網格添加到場景中,並經過position(位置),rotation(旋轉),scale(比例),translateX/Y/Z(x/y/z軸的平移)來改變其位置和展現的效果

  mesh.translateX(5);
  mesh.translateZ(5);
  mesh.name = "clone";
  scene.remove(scene.getChildByName("clone"));
  scene.add(mesh);

position屬性是針對該對象的父對象而言,而父對象通常是指場景,上面的demo中,咱們使用createMultiMaterialObject方法實際上是建立了一個多材質對象,即不是一個單純的網格對象,而是一個對象組,每一個網格都有兩個如出一轍的幾何體,可是這兩個幾何體的材質不一樣,咱們能夠經過position或者上面別的屬性,對其中一個的位置進行改變,這樣就能夠看到兩個獨立的對象了

<!DOCTYPE html>

<html>

<head>
    <title>1</title>
    <script type="text/javascript" src="three.js"></script>
    <script type="text/javascript" src="dat.gui.js"></script>
    <script type="text/javascript" src="AsciiEffect.js"></script>
    <style>
        body {
            /* set margin to 0 and overflow to hidden, to go fullscreen */
            margin: 0;
            overflow: hidden;
        }
    </style>
</head>
<body>

<!-- Div which will hold the Output -->
<div id="WebGL-output">
</div>

<!-- Javascript code that runs our Three.js examples -->
<script type="text/javascript">
//var scene
   function init() {
        var scene=new THREE.Scene();//生成一個場景
        
        //生成一個相機
        var camera=new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.1,1000);//視場,長寬比,近面,遠面
        camera.position.x=-20;
        camera.position.y=40;
        camera.position.z=30;
        camera.lookAt(scene.position);
        
        //生成一個渲染器
        var render=new THREE.WebGLRenderer();
        render.setClearColorHex(0xEEEEEE);
        render.setSize(window.innerWidth,window.innerHeight);
        render.shadowMapEnabled=true;//容許陰影映射,渲染陰影須要大量的資源,所以咱們須要告訴渲染器咱們須要陰影
        
        
    
        //生成一個平面
        var planeGeometry=new THREE.PlaneGeometry(60,20,10,10);//平面
        //生成一個材質
        var planeMaterial=new THREE.MeshLambertMaterial({color:0xffffff});
        //生成一個網格,將平面和材質放在一個網格中,組合在一塊兒,組成一個物體
        var plane=new THREE.Mesh(planeGeometry,planeMaterial);
        plane.rotation.x=-0.5*Math.PI;//將平面沿着x軸進行旋轉
        plane.position.x=0;
        plane.position.y=0;
        plane.position.z=0;
        plane.receiveShadow=true;//平面進行接受陰影
        
        
        //生成一個光源
        var spotLight=new THREE.SpotLight(0xffffff);
        spotLight.position.set(-40,60,-10);
        spotLight.castShadow=true;
        
        //生成點和麪
        var vertices=[
            new THREE.Vector3(1,3,1),
            new THREE.Vector3(1,3,1),
            new THREE.Vector3(1,-1,1),
            new THREE.Vector3(1,-1,-1),
            new THREE.Vector3(-1,3,-1),
            new THREE.Vector3(-1,3,1),
            new THREE.Vector3(-1,-1,-1),
            new THREE.Vector3(-1,-1,1)
        ];
        var faces=[
            new THREE.Face3(0,2,1),
            new THREE.Face3(2,3,1),
            new THREE.Face3(4,6,5),
            new THREE.Face3(6,7,5),
            new THREE.Face3(4,5,1),
            new THREE.Face3(5,0,1),
            new THREE.Face3(7,6,2),
            new THREE.Face3(6,3,2),
            new THREE.Face3(5,7,0),
            new THREE.Face3(7,2,0),
            new THREE.Face3(1,3,4),
            new THREE.Face3(3,6,4)
            
        ];
        
        //使用上面生成的點和麪構建咱們本身的幾何體
        var geom=new THREE.Geometry();
        geom.vertices=vertices;
        geom.faces=faces;
        geom.computeFaceNormals();
        
        //生成材質
        var materials=[
            new THREE.MeshLambertMaterial({opacity:0.6,color:0x44ff44,transparent:true}),
            new THREE.MeshBasicMaterial({color:0x000000,wireframe:true})
        ]
        
        //將自定義的幾何體與材質關聯起來
        var mesh=THREE.SceneUtils.createMultiMaterialObject(geom,materials);
        mesh.children.forEach(function(e){
            e.castShadow=true;
        });
        
        
        
        
        
        
        //增長gui圖形操做界面
        function addControl(x,y,z){
            //設置8個頂點最初的值
            //設置網格對象初始的值
            var controls=new function(){
                this.x=x;
                this.y=y;
                this.z=z;
                this.scaleX=1; this.scaleY=1; this.scaleZ=1; this.positionX=1; this.positionY=1; this.positionZ=1; this.rotationX=1; this.rotationY=1; this.rotationZ=1; this.translateX=1; this.translateY=1; this.translateZ=1;
            }
            return controls;
        }
        var controlPoints=[];
        controlPoints.push(addControl(3,5,3));
        controlPoints.push(addControl(3,5,0));
        controlPoints.push(addControl(3,0,3));
        controlPoints.push(addControl(3,0,0));
        controlPoints.push(addControl(0,5,0));
        controlPoints.push(addControl(0,5,3));
        controlPoints.push(addControl(0,0,0));
        controlPoints.push(addControl(0,0,3));
        
        var gui=new dat.GUI();
        for(var i=0;i<8;i++){
            var f1=gui.addFolder("vertices"+(i+1));
            //在渲染的時候,使用是controlPoints的x,y,z的值
            f1.add(controlPoints[i],'x',-10,10);
            f1.add(controlPoints[i],'y',-10,10);
            f1.add(controlPoints[i],'z',-10,10);
        }
        
        var proControls=addControl();//獲取gui圖形界面的初始值,
        //當這些值發生改變的時候,都放置在proControls中,
        //在後面渲染的時候,直接取proControls裏面的值就能夠了
        var f2=gui.addFolder("scale"); f2.add(proControls,'scaleX',0,2); f2.add(proControls,'scaleY',0,2); f2.add(proControls,'scaleZ',0,2); var f3=gui.addFolder("position"); f3.add(proControls,'positionX',-10,10); f3.add(proControls,'positionY',-10,10); f3.add(proControls,'positionZ',-10,10); var f4=gui.addFolder("rotation"); f4.add(proControls,'rotationX',-10,10); f4.add(proControls,'rotationY',-10,10); f4.add(proControls,'rotationZ',-10,10); var f5=gui.addFolder("translate"); f5.add(proControls,'translateX',-10,10); f5.add(proControls,'translateY',-10,10); f5.add(proControls,'translateZ',-10,10);
        
        
        gui.add(new function(){
            this.clone=function(){
                var cloneGeometry=mesh.children[0].geometry.clone();
                var mesh2=THREE.SceneUtils.createMultiMaterialObject(cloneGeometry,materials);
                mesh2.children.forEach(function(e){
                    e.castShadow=true;
                });
                mesh2.translateX(5);
                mesh2.translateY(5);
                scene.add(mesh2);
            }
        },"clone");
        
        
        
        function renderScene(){
            var vertices=[];
            for(var i=0;i<8;i++){
                vertices.push(new THREE.Vector3(controlPoints[i].x, controlPoints[i].y, controlPoints[i].z));
                
            }
            mesh.children.forEach(function(e){
                e.geometry.vertices=vertices;
                e.geometry.verticesNeedUpdate=true;
                e.geometry.computeFaceNormals();
                //在渲染的時候,取proControls裏面的值對網格對象的屬性進行設置,若是隻針對網格組裏面的某個具體網格對象進行屬性操做,將這一塊的代碼註釋,將下面註釋的代碼註銷註釋便可
e.scale.set(proControls.scaleX,proControls.scaleY,proControls.scaleZ); e.position.set(proControls.positionX,proControls.positionY,proControls.positionZ); e.rotation.set(proControls.rotationX,proControls.rotationY,proControls.rotationZ); e.translateX(proControls.translateX); e.translateY(proControls.translateY); e.translateZ(proControls.translateZ); }); /*mesh.children[0].scale.set(proControls.scaleX,proControls.scaleY,proControls.scaleZ);
            mesh.children[0].position.set(proControls.positionX,proControls.positionY,proControls.positionZ);
            mesh.children[0].rotation.set(proControls.rotationX,proControls.rotationY,proControls.rotationZ);
            mesh.children[0].translateX(proControls.translateX);
            mesh.children[0].translateY(proControls.translateY);
            mesh.children[0].translateZ(proControls.translateZ);*/

requestAnimationFrame(renderScene); render.render(scene, camera); } scene.add(camera); scene.add(spotLight); scene.add(plane); scene.add(mesh); scene.add(render); document.getElementById(
"WebGL-output").append(render.domElement); renderScene(); } window.onload = init; </script> </body> </html>

 

 

因爲這裏的網格對象是一個網格組,因此能夠只針對該網格組合裏某個具體的網格對象進行操做

 

 三    相機

  3.1    three.js有兩種相機:正投影相機和透視相機

  3.2    透視圖

    下面是一個透視圖,也就是最天然的視圖,正以下圖所示,距離視角(相機)越遠的物體,被渲染的越小

 

 

var camera=new THREE.PerspectiveCamera(視場,長寬比,近面,遠面); //生成一個透視相機,設置該透視相機的視場,長寬比,近面,遠面 camera.position.x=120; camera.position.y=60; camera.position.z=180; //設置該相機的位置 camera.lookAt(scene.position); //設置相機的聚焦位置,通常狀況下爲場景的中心,即scene.position,也能夠設置其餘的座標(x,y,z)

 

  3.3    正投影相機:全部的方塊渲染出來的尺寸都同樣,對象和相機之間的距離不會影響渲染的效果

 

var camera=new THREE.OrthographicCamera(左邊界,右邊界,上邊界,下邊界,近面,遠面); //生成一個透視相機,設置該透視相機的視場,長寬比,近面,遠面 camera.position.x=120; camera.position.y=60; camera.position.z=180; //設置該相機的位置 camera.lookAt(scene.position); //設置相機的聚焦位置,通常狀況下爲場景的中心,即scene.position,也能夠設置其餘的座標(x,y,z)
<!DOCTYPE html>

<html>

<head>
    <title>1</title>
    <script type="text/javascript" src="three.js"></script>
    <script type="text/javascript" src="dat.gui.js"></script>
    <script type="text/javascript" src="AsciiEffect.js"></script>
    <style>
        body {
            /* set margin to 0 and overflow to hidden, to go fullscreen */
            margin: 0;
            overflow: hidden;
        }
    </style>
</head>
<body>

<!-- Div which will hold the Output -->
<div id="WebGL-output">
</div>

<!-- Javascript code that runs our Three.js examples -->
<script type="text/javascript">
//var scene
   function init() {
        var scene=new THREE.Scene();//生成一個場景
        
        //生成一個相機
        //var camera=new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.1,1000);//視場,長寬比,近面,遠面
        var camera=new THREE.OrthographicCamera(window.innerWidth/-16,window.innerWidth/16,window.innerHeight/16,window.innerHeight/-16);
        camera.position.x=-20;
        camera.position.y=40;
        camera.position.z=30;
        camera.lookAt(scene.position);
        
        //生成一個渲染器
        var render=new THREE.WebGLRenderer();
        render.setClearColorHex(0xEEEEEE);
        render.setSize(window.innerWidth,window.innerHeight);
        render.shadowMapEnabled=true;//容許陰影映射,渲染陰影須要大量的資源,所以咱們須要告訴渲染器咱們須要陰影
        
        
    
        //生成一個平面
        var planeGeometry=new THREE.PlaneGeometry(60,20,10,10);//平面
        //生成一個材質
        var planeMaterial=new THREE.MeshLambertMaterial({color:0xffffff});
        //生成一個網格,將平面和材質放在一個網格中,組合在一塊兒,組成一個物體
        var plane=new THREE.Mesh(planeGeometry,planeMaterial);
        //plane.rotation.x=-0.5*Math.PI;//將平面沿着x軸進行旋轉
        plane.position.x=0;
        plane.position.y=0;
        plane.position.z=0;
        plane.receiveShadow=true;//平面進行接受陰影
        
        
        //生成一個光源
        var spotLight=new THREE.SpotLight(0xffffff);
        spotLight.position.set(-40,60,-10);
        spotLight.castShadow=true;
        
        //生成點和麪
        var vertices=[
            new THREE.Vector3(1,3,1),
            new THREE.Vector3(1,3,1),
            new THREE.Vector3(1,-1,1),
            new THREE.Vector3(1,-1,-1),
            new THREE.Vector3(-1,3,-1),
            new THREE.Vector3(-1,3,1),
            new THREE.Vector3(-1,-1,-1),
            new THREE.Vector3(-1,-1,1)
        ];
        var faces=[
            new THREE.Face3(0,2,1),
            new THREE.Face3(2,3,1),
            new THREE.Face3(4,6,5),
            new THREE.Face3(6,7,5),
            new THREE.Face3(4,5,1),
            new THREE.Face3(5,0,1),
            new THREE.Face3(7,6,2),
            new THREE.Face3(6,3,2),
            new THREE.Face3(5,7,0),
            new THREE.Face3(7,2,0),
            new THREE.Face3(1,3,4),
            new THREE.Face3(3,6,4)
            
        ];
        for(var i=0;i<10;i++){
            for(var j=0;j<10;j++){
                //使用上面生成的點和麪構建咱們本身的幾何體
                var geom=new THREE.Geometry();
                geom.vertices=vertices;
                geom.faces=faces;
                geom.computeFaceNormals();
                
                //生成材質
                var materials=[
                    new THREE.MeshLambertMaterial({opacity:0.6,color:0x44ff44,transparent:true}),
                    new THREE.MeshBasicMaterial({color:0x000000,wireframe:true})
                ]
                
                //將自定義的幾何體與材質關聯起來
                var mesh=THREE.SceneUtils.createMultiMaterialObject(geom,materials);
                mesh.children.forEach(function(e){
                    e.castShadow=true;
                });
                mesh.position.set(i*4,2,j*4);
                scene.add(mesh);
            }
            
        }
        
        var lookAtGeo=new THREE.SphereGeometry(2);
        var lookAtMesh=new THREE.Mesh(lookAtGeo,new THREE.MeshLambertMaterial({opacity:0.6,color:"red",transparent:true}));
        
        
        var controls=new function(){
            this.cameraType="perspective";
            this.switchCamera=function(){
                if(camera instanceof THREE.PerspectiveCamera){
                    camera = new THREE.OrthographicCamera(window.innerWidth / -16, window.innerWidth / 16, window.innerHeight / 16, window.innerHeight / -16, -200, 500);
                    this.cameraType="orthographic";
                    camera.position.x = 30;
                    camera.position.y = 20;
                    camera.position.z = 10;
                }else{
                    camera=new THREE.PerspectiveCamera(90,window.innerWidth/window.innerHeight,0.1,1000);//視場,長寬比,近面,遠面
                    camera.position.x = 80;
                    camera.position.y = 20;
                    camera.position.z = 30;
                    this.cameraType="perspective";
                }
                

                camera.lookAt(scene.position);
            }
        }
        
        
        //增長gui圖形操做界面
        var gui=new dat.GUI();
        
        gui.add(controls,"switchCamera");
        gui.add(controls,"cameraType").listen();
        var step=0;
        function renderScene(){
            var vertices=[];
            step+=0.02;
            if(camera instanceof THREE.Camera){
                var x=10+(10*Math.sin(step));
                camera.lookAt(new THREE.Vector3(x,10,0));
                lookAtMesh.position.copy(new THREE.Vector3(x,10,0))
            }
            requestAnimationFrame(renderScene);
            render.render(scene, camera);
        }
        scene.add(lookAtMesh);
        scene.add(camera);
        scene.add(spotLight);
        //scene.add(plane);
        scene.add(mesh);
        scene.add(lookAtMesh);
        scene.add(render);
        document.getElementById("WebGL-output").append(render.domElement);        
        renderScene();
        
    }
    
    window.onload = init;

</script>
</body>
</html>
相關文章
相關標籤/搜索