THREE.JS场景基本组件(一)

时间:2022-03-19 05:14:12

scene是物体的容器,three.JS绘制的物体对象都会放置在场景之中;相机决定了在场景中如何查看物体,能看到什么物体;光源决定了能看到物体,物体可以产生阴影等;物体就是利用three.JS创建的各种对象,如球体,立方体等等。

下面会建立一个基本的框架,在此基础上,会做一些基本的功能:添加一个立方体,删除添加的立方体,轴辅助,箭头辅助,边辅助,网格辅助。

各种需要的库需要自己去下载,都是免费的:three.js;jquery-1.9.0.js;controlKit.js;stats.js;dat.GUI.js

1.建立基本框架,书写HTML代码,添加必要的库引用;代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>基本场景组件</title>
<!--需要的基本JS库-->
<script src="jquery19.js"></script>
<script src="three.js"></script>
<script src ="stats.js"></script>
<script src = "dat.gui.js"></script>
<script src = "controlKit.js"></script>
<!--给body加入一个样式,边框为0(零,不显示边框);滚动条隐藏-->
<style type="text/css">
body{
margin: 0;
overflow: hidden;
}

</style>
</head>
<body>
<!--建立一个DIV,WebGL渲染的基本物体会在此处输出-->
<div id="WebGL-output">
</div>

<!--构建一个DIV,显示一个FPS监测组件-->
<div id = "Stats-output">
</div>
</body>
</html>

2.添加jquery代码(JavaScript):添加一个匿名的jQuery函数,所有的threejs操作都会在该函数中进行。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>基本场景组件</title>
<!--需要的基本JS库-->
<script src="jquery19.js"></script>
<script src="three.js"></script>
<script src ="stats.js"></script>
<script src = "dat.gui.js"></script>
<script src = "controlKit.js"></script>
<!--给body加入一个样式,边框为0(零,不显示边框);滚动条隐藏-->
<style type="text/css">
body{
margin: 0;
overflow: hidden;
}

</style>
</head>
<body>
<!--建立一个DIV,WebGL渲染的基本物体会在此处输出-->
<div id="WebGL-output">
</div>

<!--构建一个DIV,显示一个FPS监测组件-->
<div id = "Stats-output">
</div>
<!--第2步 一个匿名函数-->
<script type="text/javascript">
//匿名函数定义
$(function () {

});
</script>

</body>
</html>

3.添加场景定义:

 var scene = new THREE.Scene();

添加完之后如下:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>基本场景组件</title>
<!--需要的基本JS库-->
<script src="jquery19.js"></script>
<script src="three.js"></script>
<script src ="stats.js"></script>
<script src = "dat.gui.js"></script>
<script src = "controlKit.js"></script>
<!--给body加入一个样式,边框为0(零,不显示边框);滚动条隐藏-->
<style type="text/css">
body{
margin: 0;
overflow: hidden;
}

</style>
</head>
<body>
<!--建立一个DIV,WebGL渲染的基本物体会在此处输出-->
<div id="WebGL-output">
</div>

<!--构建一个DIV,显示一个FPS监测组件-->
<div id = "Stats-output">
</div>
<!--第2步 一个匿名函数-->
<script type="text/javascript">
//匿名函数定义
$(function () {
//添加场景定义
var scene = new THREE.Scene();
});
</script>

</body>
</html>

4.添加相机:PerspectiveCamera( fov, aspect, near, far );透视相机

fov — 相机视锥体垂直视角
aspect — 相机视锥体宽高比
near — 相机视锥体近裁剪面
far — 相机视锥体远裁剪面。

var camera = new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.1,1000);

5.添加渲染器,设置渲染范围,渲染背景色;

          //添加渲染器,还有其他种类的渲染器
var renderer = new THREE.WebGLRenderer();
//渲染背景色
renderer.setClearColor(0xEEEFFF);
//渲染尺寸
renderer.setSize(window.innerWidth,window.innerHeight);
//渲染出阴影,默认是不渲染出阴影的。
renderer.shadowMapEnabled = true;

6.添加一个平面:

       //增加一个平面,平面尺寸(60,40)
var planeGeometry = new THREE.PlaneGeometry(60,40);
//平面材质,基本材质是渲染不出阴影的,下面的材质可以,仅仅指定颜色
var planeMaterial = new THREE.MeshLambertMaterial({color:0xff00dd});
//以给定的尺寸和材质构建一个平面
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;
//平面接受阴影,其他物体产生的阴影会投射的该平面上
plane.receiveShadow = true;
//平面加入场景
scene.add(plane);

7.加入2种光源:一种是环境光,一种是聚光灯

       // 添加一种光源:环境光
var ambientLight = new THREE.AmbientLight(0x0c0c0c);
//环境光加入场景
scene.add(ambientLight);


//添加聚光灯光源
var spotLight = new THREE.SpotLight(0xffffff);
//指定聚光灯的位置
spotLight.position.set(-40,60,-10);
//指定聚光灯产生阴影,就是说物体由于该光源的照射而产生阴影
spotLight.castShadow = true;
//聚光灯加入场景
scene.add(spotLight);

8.dat.GUI.js的使用-添加一些辅助功能,包含辅助箭头,辅助轴,辅助网格,边辅助;

8.1 建立一个变量controls,用来添加在dat.GUI中进行控制的各种功能,辅助功能都会在此基础上进行添加:

var controls = new  function(){
};

8.2 加入箭头辅助:箭头辅助在three.JS中用 ArrowHelper来添加,在上面的代码中添加:

var controls = new function(){
//开始添加 箭头辅助代码
this.addArrow = function () {
//确定箭头的方向,分别为XYZ坐标轴平行
var Xdir = new THREE.Vector3(1,0,0);
var Ydir = new THREE.Vector3(0,1,0);
var Zdir = new THREE.Vector3(0,0,1);

//确定原点,箭头长度,和箭头颜色,三个箭头同一设置
var origin = new THREE.Vector3(0,0,0);
var length = 10;
var color = 0xffff00;


//建立三个方向上箭头辅助
var YarrowHelper = new THREE.ArrowHelper(Ydir,origin,length,color);
var ZarrowHelper = new THREE.ArrowHelper(Zdir,origin,length,color);
var XarrowHelper = new THREE.ArrowHelper(Xdir,origin,length,color);
//把箭头辅助加入 场景
scene.add(YarrowHelper);
scene.add(ZarrowHelper);
scene.add(XarrowHelper);
};
};

把添加的箭头辅助功能加入dat.GUI
构建一个dat.GUI的实例

var  gui = new  dat.GUI();

把controls对象中定义的AddArrow加入gui:

gui.add(controls,‘AddArrow’);

这样控制面板上,显示AddArrow字符串,单击AddArrow字符串时,会执行上面controls对象中定义的那个函数,在页面添加三个坐标方向的箭头辅助。

8.3加入轴辅助:在three.JS使用AxisHelper来建立
同样在controls对象中添加如下代码:

   this.addAxis = function () {
var Axes = new THREE.AxisHelper(50);
scene.add(Axes);
};

加入gui:

 gui.add(controls,'addAxis');

8.4 加入网格辅助:利用three.JS中的GridHelper();
在controls对象中添加:

  this.网格辅助 = function () {
var grid = new THREE.GridHelper(10,5);
scene.add(grid);
};

加入gui

gui.add(controls,‘网格辅助’);

9.指定相机的位置,视点;


camera.position.x = -30;
camera.position.y = 40;
camera.position.z = 30;
camera.lookAt(scene.position);

10.进行场景渲染:

   function renderScene() {
plane.rotation.set((controls.planeRotation)*(Math.PI),0,0);
box.rotation.set((controls.planeRotation)*(Math.PI),0,0);
requestAnimationFrame(renderScene);
renderer.render(scene,camera);
}
$("#WebGL-output").append(renderer.domElement);
renderScene();

最后代码如下:还有一些别的功能,可以尝试修改进行观察:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>基本场景组件</title>
<!--需要的基本JS库-->
<script src="jquery19.js"></script>
<script src="three.js"></script>
<script src ="stats.js"></script>
<script src = "dat.gui.js"></script>
<script src = "controlKit.js"></script>
<!--给body加入一个样式,边框为0(零,不显示边框);滚动条隐藏-->
<style type="text/css">
body{
margin: 0;
overflow: hidden;
}
</style>
</head>
<body>
<!--建立一个DIV,WebGL渲染的基本物体会在此处输出-->
<div id="WebGL-output">

</div>

<!--构建一个DIV,显示一个FPS监测组件-->
<div id = "Stats-output">

</div>


<script type="text/javascript">
//匿名函数定义开始,所有的THREE.JS操作都在该函数中进行
$(function () {
//定义场景
var scene = new THREE.Scene();
//添加雾化效果
scene.fog = new THREE.Fog(0xffffff,0.015,100);
//添加一个透视相机
var camera = new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.1,1000);
//添加渲染器,还有其他种类的渲染器
var renderer = new THREE.WebGLRenderer();
//渲染背景色
renderer.setClearColor(0xEEEFFF);
//渲染尺寸
renderer.setSize(window.innerWidth,window.innerHeight);
//渲染出阴影,默认是不渲染出阴影的。
renderer.shadowMapEnabled = true;

//增加一个平面,平面尺寸(60,40)
var planeGeometry = new THREE.PlaneGeometry(60,40,15,10);
//平面材质,基本材质是渲染不出阴影的,下面的材质可以,仅仅指定颜色
var planeMaterial = new THREE.MeshLambertMaterial({color:0xff00dd,wireframe:true});
//以给定的尺寸和材质构建一个平面
var plane = new THREE.Mesh(planeGeometry,planeMaterial);
//指定平面的旋转角度,方便观察
plane.rotation.x = -0.5 * Math.PI;
// plane.rotation.x = (controls.平面旋转) * Math.PI;
//平面的位置
plane.position.x = 0;
plane.position.y = 0;
plane.position.z = 0;
//平面接受阴影,其他物体产生的阴影会投射的该平面上
plane.receiveShadow = true;
//平面加入场景
scene.add(plane);



var boxGeo = new THREE.BoxGeometry(10,10,10,2,2,2);
var boxMaterial = new THREE.MeshBasicMaterial({color:0xff0000});
var box = new THREE.Mesh(boxGeo,boxMaterial);

scene.add(box);

// 添加一种光源:环境光
var ambientLight = new THREE.AmbientLight(0x0c0c0c);
//环境光加入场景
scene.add(ambientLight);


//添加聚光灯光源
var spotLight = new THREE.SpotLight(0xffffff);
//指定聚光灯的位置
spotLight.position.set(-40,60,-10);
//指定聚光灯产生阴影,就是说物体由于该光源的照射而产生阴影
spotLight.castShadow = true;
//聚光灯加入场景
scene.add(spotLight);

<!--dat.GUI库的使用,构建一个简单的页面控制组件-->
var controls = new function () {
//如果不再添加范围控制,就是一个输入框
this.message = 10;
//一个复选框
this.box = false;
//一个类似下拉列表的组件
this.LEAD ='P';
//添加一个立方体
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-数字
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.removeCube = function () {
var allChildren = scene.children;
var lastCube = allChildren[allChildren.length-1];
if(lastCube instanceof THREE.Mesh)
{
scene.remove(lastCube);
}
};

this.addArrow = function () {
var Xdir = new THREE.Vector3(1,0,0);
var Ydir = new THREE.Vector3(0,1,0);
var Zdir = new THREE.Vector3(0,0,1);


var origin = new THREE.Vector3(0,0,0);
var length = 10;
var color = 0xffff00;



var YarrowHelper = new THREE.ArrowHelper(Ydir,origin,length,color);
var ZarrowHelper = new THREE.ArrowHelper(Zdir,origin,length,color);
var XarrowHelper = new THREE.ArrowHelper(Xdir,origin,length,color);

scene.add(YarrowHelper);
scene.add(ZarrowHelper);
scene.add(XarrowHelper);
};

this.addAxis = function () {
var Axes = new THREE.AxisHelper(50);
//Axes.position.x =10;
//Axes.position.y = 10;
// Axes.position.z = 10;
scene.add(Axes);
};

this.HelperEdge = function () {
var boxGeo = new THREE.BoxGeometry(10,10,10,2,2,2);
var boxMaterial = new THREE.MeshBasicMaterial({color:0xff0000});
var box = new THREE.Mesh(boxGeo,boxMaterial);
box.position.set(10,5,-10);
var Edges = new THREE.EdgesHelper(box,0x00ff00);

scene.add(box);
scene.add(Edges)



};

this.VertexHelper = function () {
var geometry = new THREE.BoxGeometry( 20, 20, 20, 2, 2, 2 );
var material = new THREE.MeshBasicMaterial( { color: 0xff0000 } );
var object = new THREE.Mesh( geometry, material );

var edges = new THREE.VertexNormalsHelper( object, 2, 0x00ff00, 1 );

scene.add( object );
scene.add( edges );
};

this.网格辅助 = function () {
var grid = new THREE.GridHelper(10,5);
scene.add(grid);
};

this.planeRotation = -1;

this.ptShow = function () {





alert("xxx");

}



};
var gui = new dat.GUI();
gui.add(controls,'message').min(10).max(1000);
gui.add(controls,'box');
gui.add(controls,'addCube');
gui.add(controls,'removeCube');
gui.add(controls,'addArrow');
gui.add(controls,'addAxis');
gui.add(controls,'HelperEdge');
gui.add(controls,'VertexHelper');
gui.add(controls,'ptShow');
gui.add(controls,'网格辅助');
gui.add(controls,'planeRotation',-1,1);
gui.add(controls,'LEAD',['P','Y','X','Z','N','K']);







camera.position.x = -30;
camera.position.y = 40;
camera.position.z = 30;
camera.lookAt(scene.position);

function renderScene() {
plane.rotation.set((controls.planeRotation)*(Math.PI),0,0);
box.rotation.set((controls.planeRotation)*(Math.PI),0,0);
requestAnimationFrame(renderScene);
renderer.render(scene,camera);
}
$("#WebGL-output").append(renderer.domElement);
renderScene();
});
</script>

</body>
</html>

部分效果:
THREE.JS场景基本组件(一)