在javascript中使用Three.js设计并且实现3D场景是一个很有意思的事情,因为在浏览器中就能够渲染出3D场景,非常简单和轻便。接下来就总结以下我学习Three.js过程中的心得。
1 建立基本场景
在Three.js中有三要素:场景、摄像机和渲染器,只有以上三者结合才能渲染出可见的内容。当然在这之前你需要先下载Three.js文件,直接百度搜索Three.js到官网下载即可,下载完成之后新建一个html文件并且引入Three.js即可。一个最基本的使用Three.js的html文件应该是这样子的:
-
<!DOCTYPE html>
-
<html>
-
<head>
-
<title>Wonanut 3D
</title>
-
<style type="text/css">
-
body {
margin:
0; }
-
canvas {
width:
100%;
height:
100%; }
-
</style>
-
</head>
-
<body>
-
<script type="text/javascript" src="js/three.js">
</script>
-
<script type="text/javascript">
-
// 场景
-
var scene =
new
THREE.
Scene();
-
-
// 摄像机
-
var camera =
new
THREE.
PerspectiveCamera(
75,
window.
innerWidth /
window.
innerHeight,
0.1,
1000);
-
camera.
position.
z =
5;
-
-
// 渲染器
-
var renderer =
new
THREE.
WebGLRenderer();
-
renderer.
setSize(
window.
innerWidth,
window.
innerHeight );
-
document.
body.
appendChild( renderer.
domElement );
-
// 渲染器 end
-
-
// 物体
-
var geometry =
new
THREE.
BoxGeometry(
1,
1,
1);
-
var material =
new
THREE.
MeshBasicMaterial( {
color:
0x00ff00} );
-
var cube =
new
THREE.
Mesh( geometry, material );
-
scene.
add( cube );
-
// 物体 end
-
-
</script>
-
</body>
-
</html>
我们打开浏览器看一下:
哦天哪,发生了什么,浏览器上黑乎乎一片什么都没有啊。
别急,这是因为我们只是设置了三要素,但并没有渲染,只有使用渲染器scene和camera进行渲染之后才能看到内容,在scene.add( cube ); 后面添加一句:
renderer.render(scene, camera);
再试试效果如何:
快看,现在屏幕中出现了一个正方形,这正是我们所期待的!
但是,我们使用的Three.js不应该是三维场景吗,为什么现在只有平面效果?不急,接下来我们使用requestAnimationFrame让画面动起来!
2 让画面动起来
将上一步中最后一句代码:
renderer.render(scene, camera);
替换为:
-
// 动画
-
function
animate(
) {
-
-
cube.
rotation.
x +=
0.01;
-
cube.
rotation.
y +=
0.01;
-
renderer.
render( scene, camera );
-
-
requestAnimationFrame( animate );
-
}
-
animate();
再到浏览器看看效果,如果没有什么问题的话,现在你所看到的画面应该是一个旋转的立方体:
不过我对这个效果还是不满意,它看起来像是一个 正方体,但缺少了阴影灯光效果,接下来我们添加灯光效果。
3 添加光效
使用点光源THREE.SpotLight,代码如下:
-
// 光源
-
var spotLight =
new
THREE.
SpotLight(
0xffffff );
-
spotLight.
position.
set( -
40,
60, -
10 );
-
scene.
add( spotLight );
-
// 光源 end
同时将cube的材质从MeshBasicMaterial换为MeshLamberMaterial,因为最基本的MeshBasicMaterial材质对光源不会有任何反应。
-
// 物体
-
var geometry =
new
THREE.
BoxGeometry(
1,
1,
1);
-
var material =
new
THREE.
MeshLambertMaterial( {
color:
0x00ff00} );
-
var cube =
new
THREE.
Mesh( geometry, material );
-
scene.
add( cube );
-
// 物体 end
4 添加阴影效果
为了渲染阴影效果,需要对代码做如下修改:
-
renderer.
setClearColor(
new
THREE.
Color(
0x000000,
1.0));
-
renderer.
shadowMap.
enabled =
true;
同时要给立方体设置投射阴影:
cube.castShadow = true;
设置地面接受阴影:
plane.receiveShadow = true;
设置spotLight投射阴影:
spotLight.castShadow = true;
为了添加阴影效果,我们需要设置一个平面来接受阴影,因此重新创建一个场景,源码如下:
-
<!DOCTYPE html>
-
<html>
-
<head>
-
<title>Wonanut 3D
</title>
-
<style type="text/css">
-
body {
margin:
0; }
-
canvas {
width:
100%;
height:
100%; }
-
</style>
-
</head>
-
<body>
-
<script type="text/javascript" src="js/three.js">
</script>
-
<script type="text/javascript" src="js/stats.js">
</script>
-
<script type="text/javascript">
-
场景-----------------------
-
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 renderer =
new
THREE.
WebGLRenderer();
-
renderer.
setSize(
window.
innerWidth,
window.
innerHeight );
-
document.
body.
appendChild( renderer.
domElement );
-
-
// 设置渲染器渲染阴影效果
-
renderer.
setClearColor(
new
THREE.
Color(
0x000000));
-
renderer.
setSize(
window.
innerWidth,
window.
innerHeight);
-
renderer.
shadowMap.
enabled =
true;
-
渲染器 end----------------
-
-
坐标轴--------------------
-
var axes =
new
THREE.
AxesHelper(
20);
-
scene.
add(axes);
-
-------------------------
-
-
平面---------------------
-
var planeGeometry =
new
THREE.
PlaneGeometry(
60,
20,
1,
1);
-
var planeMaterial =
new
THREE.
MeshLambertMaterial({
color:
0xcccccc});
-
var plane =
new
THREE.
Mesh(planeGeometry, planeMaterial);
-
plane.
rotation.
x = -
0.5 *
Math.
PI;
-
plane.
position.
x =
15
-
plane.
position.
y =
0
-
plane.
position.
z =
0
-
scene.
add(plane);
-
-
// 设置投影
-
plane.
receiveShadow =
true;
-
--------------------------
-
-
物体----------------------
-
var geometry =
new
THREE.
BoxGeometry(
4,
4,
4);
-
var material =
new
THREE.
MeshLambertMaterial( {
color:
0x00ff00} );
-
var cube =
new
THREE.
Mesh( geometry, material );
-
cube.
position.
x =
0;
-
cube.
position.
y =
2;
-
cube.
position.
z =
0;
-
-
// 设置投影
-
cube.
castShadow =
true;
-
scene.
add( cube );
-
物体 end ------------------
-
-
光源-----------------------
-
var spotLight =
new
THREE.
SpotLight(
0xffffff );
-
spotLight.
position.
set( -
40,
60, -
10 );
-
scene.
add( spotLight );
-
-
// 设置投影
-
spotLight.
castShadow =
true;
-
光源 end -------------------
-
-
状态监视器-------------------
-
var stats =
new
Stats();
-
stats.
showPanel(
0 );
-
document.
body.
appendChild( stats.
dom );
-
状态监视器 end --------------
-
-
renderer.
render( scene, camera );
-
-
</script>
-
</body>
-
</html>
渲染结果如下图:
阴影是有了,但总觉得阴影不太对劲,比较模糊。通过查阅资料,我找到了答案:
光源的位置一定要距离合适,否则容易引起阴影模糊粗糙的像打马赛克一样
所以嘛,这个东西还是要自己去调的(其实具体原因我也不清楚,反正我没调好)
</article>