您的位置:首页 > Web前端 > JavaScript

丰富你的第一个Three.js场景

2017-11-25 23:24 495 查看
上一篇文章中我们创建了我们的第一个Three.js场景,并在场景中加入了坐标系、平面、立方体和球体,在这篇文章中我们将进一步丰富我们的场景,向其中加入光源产生阴影、加入动画并添加控制器、最后加入两个在Three.js常用的插件。

我们采用的是CanvasRenderer渲染器,但在这篇文章之前发现它对聚光光源的支持上存在问题、同样的代码只是换了一个渲染器整个场景就变成黑色,可能是Three.js的一个小bug吧,而且它渲染出来的物体是存在很明显的线条,建议采用更为友好WebGl渲染器。

1、准备需要的Js文件

stats.js:https://github.com/mrdoob/three.js/tree/dev/examples/js/libs

dat.gui:https://github.com/mrdoob/three.js/tree/dev/examples/js/libs

2、向场景中加入聚光灯光源

上一节中我们为平面、立方体和球体都添加了表面材质MeshBasicMaterial材料,它是一种非光敏材料,渲染后物体的颜色始终为该材质的颜色,而不会由于光照产生明暗、阴影效果,本节中我们采用的是MeshPhongMaterial材质,没有光源的情况显示是黑色的,在光源下才会展现,即可以理解为天黑了看不见,Phong是镜面反射材料,类似于金属材质,关于Three.js的三种材质将会在后续中介绍。

......
var planeMaterial = new THREE.MeshPhongMaterial({color: 0xffffff});
......
var cubeMaterial = new THREE.MeshPhongMaterial({color: 0xff0000});
......
var sphereMateial = new THREE.MeshPhongMaterial({color: 0x7777ff});
......


向场景中加入聚光灯光源SpotLight,类似于手电筒,存在一定的角度并朝固定的方向照射。

var spotLight = new THREE.SpotLight(0xffffff);
spotLight.position.set(-40, 60, -10);
scene.add(spotLight);


3、为场景中物体添加阴影效果

由于阴影的渲染是要消耗大量资源的,所以Three.js默认是关闭阴影功能的,需要我们手动添加属性

(一)渲染器开启支持

renderer.shadowMapEnabled = true;
Three.js版本比较多吧,代码中也没有明显的版本标识,最新的版本已经将阴影属性改为renderer.shadowMap.enable,但是最新的版本阴影效果存在特别明显的锯齿效果,所以我使用了老版本,后面应该会修复。

(二)光源开启支持

spotLight.castShadow = true;


(三)接收平面开启支持

plane.receiveShadow = true;


(四)物体开启支持

cube.castShadow = true;
......
sphere.castShadow = true;
此时你看到的场景是这样的:


3、为立方体cube加入动画

我们采用requestAnimationFrame进行动画渲染,在此之前一般都是采用定时器的方法进行HTML的动画控制,但是定时器不会根据浏览器实时渲染情况进行调节,而且定时器是一直存在的,requestAnimationFrame完美的解决了这两个问题,它是和浏览器当前绑定的,即只有在渲染完当前一帧才会去渲染下一帧,而且在HTML最小化的时候是不会继续执行的,基本用法如下:

function renderSence() {
// Control Cube
cube.rotation.x += 0.02;
cube.rotation.y += 0.02;
cube.rotation.z += 0.02;

requestAnimationFrame(renderSence);
renderer.render(scene, camera);
console.log("Here");
}
为了方便动画渲染需要重新定义一个渲染函数renderSence,直接在自执行函数的最后调用该函数即可。requestAnimationFrame的使用可以抽象为递归函数,即在函数里面再次调用,在这里加入了Cube控制,每次渲染给立方体的角度添加0.02的角度,这样的效果就是立方体在场景中不停的旋转。为了查看requestAnimationFrame是否调用成功,可以在里面加入一段日志打印查看效果。

4、为球体加入动画

function renderSence() {
// Control Cube
cube.rotation.x += 0.02;
cube.rotation.y += 0.02;
cube.rotation.z += 0.02;
// Control Sphere
step += 0.04;
sphere.position.x = 20 + (10 * ( Math.cos(step) ));
sphere.position.y = 2 + (10 * Math.abs( Math.sin(step) ));
// Render With RequestAnimationFrame
requestAnimationFrame(renderSence);
renderer.render(scene, camera);
console.log("Here");
}

此时重新打开你的场景,你会看到立方体在不停的旋转、球体在按照既定路线跳跃,场景已经开始丰富起来啦!



5、加入JavaScript性能监视器Stats.js

Stats包含两个参数,每秒渲染次数FPS及每次渲染所需内存,使用它可以实时监控你的Three.js项目的运行情况,使用也是非常简单,首先给它准备个容器盒子

<div id="Stats-Output">

</div>
之后实例化一个对象并为它添加样式,最后在requestAnimationFrame中调用更新函数updata()。
var stats = initStats();
......
function initStats() {
var stats = new Stats();
stats.setMode(0);
stats.domElement.style.position = 'absolute';
stats.domElement.style.left = '0px';
stats.domElement.style.top = '0px';
document.getElementById("Stats-Output").appendChild(stats.domElement);
return stats;
}
function renderSence() {
......
stats.update();
......
}
此时可以看到上面动图中左上角的效果,点击可以查看每帧率内存占用情况。

6、添加动画控制器dat.gui.js,可以用来控制物体动画的变化值,即可以让立方体旋转变快变慢、球体运动速度加快减慢

var controls = new function () {
this.rotationSpeed = 0.02;
this.bouncingSpeed = 0.03;
};

var gui = new dat.GUI();
gui.add(controls, 'rotationSpeed', 0, 0.5);
gui.add(controls, 'bouncingSpeed', 0, 0.5);

function renderSence() {
// Control Cube
cube.rotation.x += controls.rotationSpeed;
cube.rotation.y += controls.rotationSpeed;
cube.rotation.z += controls.rotationSpeed;
// Control Sphere
step += controls.bouncingSpeed;
sphere.position.x = 20 + (10 * ( Math.cos(step) ));
sphere.position.y = 2 + (10 * Math.abs( Math.sin(step) ));
// Render With RequestAnimationFrame
requestAnimationFrame(renderSence);
renderer.render(scene, camera);
stats.update();
console.log("Here");
}
新建一个构造器函数controls,定义需要传递的参数rotationSpeed与bouncingSpeed,之后实例化dat.GUI对象,传递的参数分别为构造器函数、参数(对应构造器内部参数)、最小值、最大值,之后在requestAnimationFrame中将原来的静态变量改为controls的参数,这样就可以通过鼠标调节动画的属性啦!

后面我会持续更新有关Three.js的内容,如果觉得本文对您有帮助,请点击‘顶’支持一下

您的支持是我写作最大的动力,谢谢。

QQ:1193238879

微信:lizhaoting12
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: