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>
相关文章
相关标签/搜索