webgl之Three.js学习 day1构建场景的基本组件

一 、创建场景


1.一个场景要想显示任何东西需要三种类型的组件:

组件

描述

相机 决定哪些东西将要在屏幕上渲染
光源 它们会对材质如何显示,以及生成阴影时材质如何使用产生影响
物体 它们是在相机透视图里主要的渲染对象:方块、球体等

2.创建基本场景

  • 基本场景(相机、物体、光源)
var scene = new THREE.Scene();  //创建场景对象
//创建相机
var camera = new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.1,1000);
camera.position.x = -30;
camera.position.y = 40;
camera.position.z = 30;
camera.lookAt(scene.position);
//创建物体
var planeGeometry = new THREE.PlaneGeometry(60,40,1,1);
var planeMaterial = new THREE.MeshLambertMaterial({color:0xffffff});
var plane = new THREE.Mesh(planeGeometry,planeMaterial);
plane.rotation.x = -0.5 * Math.PI;
plane.position.x = 0;
plane.position.y = 0;
plane.position.z = 0;
scene.add(plane);
//添加环境光
var ambientLight = new THREE.AmbientLight(0x0c0c0c);
scene.add(ambientLight);
//添加点光源
var spotLight = new THREE.SpotLight(0xffffff);
spotLight.position.set(-40, 60, -10);
scene.add(spotLight);

        效果图如下 

webgl之Three.js学习 day1构建场景的基本组件_第1张图片

 

  • 为场景添加控件

addCube(添加方块)

this.addCube = function(){
    var cubeSize = Math.ceil((Math.random()*3));
    var cubeGeometry = new THREE.CubeGeometry(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.numberOfObjects = scene.children.length;
}

注:1.name属性为方块指定了名字,可以用来在场景中查找对象,例如使用Scene.getChildByName(name)函数可直接获取指定           的对象;

       2.Scene.children():获取场景中所有子对象的列表。

removeCube(移除最后一个添加的方块)

this.removeCube = function(){
    var allChildren = scene.children;
    var lastObject = allChildren[allChildren.length-1];
    if(lastObject instanceof THREE.Mesh){
	scene.remove(lastObject);
	this.numberOfObjects = scene.children.length;
    }
}

 render循环渲染场景

var render = function () {
    stats.update();
    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( render );   //周期性渲染
    renderer.render( scene, camera );    
};

注:traverse()函数所传递来的函数会在场景的每一个子对象上调用一次。

效果图如下

webgl之Three.js学习 day1构建场景的基本组件_第2张图片

3.在场景中添加雾化效果

通过fog属性可以为整个场景添加雾化效果,即一个物体离得越远,就越模糊。在Three.js库里打开雾化效果很简单。只要在定义完场景后加上如下一行代码即可:

scene.fog = new THREE.Fog(0xffffff,0.015,100);

        这段代码中我们定义了白色的雾化效果(0xffffff)。后面的两个属性用来调节雾的显示,0.015是near(近处)属性的值,而100设置的是far(远处)属性的值。

        打开雾化后的效果图如下

webgl之Three.js学习 day1构建场景的基本组件_第3张图片

 

4.使用材质覆盖属性

当我们像下面这段代码一样使用overrideMaterial属性即材质覆盖属性时,所有添加到场景中的物体都会使用同样的材质:

scene.overrideMaterial = new THREE.MeshLambertMaterial({color:0xffffff});

5.对场景对象最重要的函数与属性的总结

函数/属性

描述

add(object)        在场景中添加对象。
children        返回一个场景中所有对象的列表,包括相机和光源。
getChildByName(name)        创建对象时,可以通过name属性为它指定一个独一无二的名字。场景对象提供了一个办法,你可以使用该方法根据名字直接返回这个对象。
remove(object)         如果你在场景中引用了一个对象,那么你也可以用这个函数在场景中删除它。
traverse(function)         children属性返回场景中所有子对象的列表。通过traverse()函数,我们同样可以传入一个回调函数访问这些子对象。
fog         通过该属性可以设置场景的雾化效果。
overrideMaterial         通过这个属性,你可以强制场景中的所有物体都使用相同的 材质。

二、使用几何和网格对象


1.几何对象的属性和函数

        在创建几何体时,我们既可以使用Three.js中提供的几何体,也可以通过定义顶点和面,手工创建几何体,可参考以下代码:

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.MeshBasicMaterial({color: 0x000000, wireframe: true}),
  new THREE.MeshLambertMaterial({opacity: 0.6, color: 0x44ff44, transparent: true})
];
var mesh = THREE.SceneUtils.createMultiMaterialObject(geom, materials);    
mesh.castShadow = true;
mesh.children.forEach(function (e) {e.castShadow = true});//为组中所有对象添加阴影

        效果图如下:

webgl之Three.js学习 day1构建场景的基本组件_第4张图片

2.网格对象的函数和属性

        这里,我们先总结一些基本属性和函数

函数/属性

描述

position(位置)         决定该对象相对其父对象的位置。多数情况下,一个对象的父对象是THREE.Scene()对象。
rotation(旋转)         通过这个属性你可以设置对象绕任何一个轴的旋转弧度
scale(比例)         通过这个属性你可以沿着x,y和z轴缩放对象
translateX(amount)(X轴平移)         沿x轴将对象平移指定的距离
translateY(amount)(Y轴平移)         沿y轴将对象平移指定的距离
translateZ(amount)(Z轴平移)         沿z轴将对象平移指定的距离
  • 位置属性(position)

          我们可以用三种方式设置对象的位置

//直接设置坐标
cube.position.x = 10;
cube.position.y = 3;
cube.position.z = 1;
//一次性设置
cube.position.set(10,3,1);
//设置数组
cube.position = new THREE.Vector3(10,3,1);
  • 旋转属性(rotation)

        我们也可以用三种方式旋转对象

//直接设置坐标
cube.rotation.x = 10;
//一次性设置
cube.rotation.set(0.5*Math.PI,0,0);
//设置数组
cube.rotation = new THREE.Vector3(0.5*Math.PI,0,0);
  • 缩放属性(scale)

        我们可以使用下面的方法沿轴缩放物体

cube.scaleX = 1;
cube.scaleY = 1;
cube.scaleZ = 1;
  • 沿轴平移

        使用translate函数可以改变对象的位置,但不是定义将对象放在哪里的绝对位置,而是定义相对偏移量。

三、选择合适的相机


1.透视相机(PersepectiveCamera)

        使用透视相机,使得距离相机越远的方块,被渲染得越小。如下图所示:

webgl之Three.js学习 day1构建场景的基本组件_第5张图片

         THREE.PerspectiveCamera接受如下这些参数:

参数

描述

fov(视场)

       fov表示视场(field of view)。这是从相机位置能够所能够看到的部分场景。

       但是由于普通的计算机显示器不能完全显示我们看到的景象,所以一般会选择一块儿较小的区域。

       推荐默认值:45

aspect(长宽比)

       这是渲染结果输出区的横向长度和纵向长度的比值。

       推荐默认值:window.innerWidth/window.innerHeight

near(近面)

       near属性定义的是Three.js库从距离相机多近的地方开始渲染场景。通常情况下我们会为这个属性设一个很小的值,从而可以渲染从相机位置可以看到的所有物体。

       推荐默认值:0.1

far(远面)

       far属性定义的是相机可以从它所在的位置看多远。如果我们将这个值设得太低,那么场景中的一部分可能就不会被渲染;如果设得太高,在某些情况下会影响渲染的效率。

       推荐默认值:1000

2.正投影相机(OrthographicCamera)

        使用正投影相机,所欲的方块渲染出来的尺寸都一样,如下图所示:

webgl之Three.js学习 day1构建场景的基本组件_第6张图片

         THREE.OrthographicCamera接受如下这些参数:

参数

描述

left(左边界)        在Three.js文档里该属性是可视范围的左边界。
right(右边界)        可视范围的右边界。比这个右侧边界更的对象不会被渲染。
top(上边界)        可被渲染空间的最上面
bottom(下边界)        可被渲染空间的最下面
near(近面)        基于相机所在的位置,从这一点开始渲染场景
far(远面)        基于相机所在的位置,一直渲染到场景中的这一点

 

你可能感兴趣的:(javascript,html5)