创建一个Threejs案例,必不可少的要素有场景、相机、渲染器、光源。
基本步骤
1、性能监听 initStats();
var stats = initStats();
2、创建场景Scene
var scene = new THREE.Scene();
3、创建相机,透视投影相机 PerspectiveCamera
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
第一个参数是可视角度,第二个参数是实际窗口的纵横比,第三个参数是近处裁面距离,第四个参数是远处裁面距离。
4、创建渲染器,WebGLRenderer,使用WebGL绘制场景,利用GPU硬件加速提高渲染性能,渲染器背景色、范围大小、是否显示阴影的设置。
var renderer = new THREE.WebGLRenderer();
renderer.setClearColor(new THREE.Color(0x000000)); //背景色
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true; // 显示阴影
6、创建一个平面,包括几何体、材质,把几何体、材质添加到网格中,同时设置平面接受阴影。
var planeGeometry = new THREE.PlaneGeometry(60, 20, 1, 1);
var planeMaterial = new THREE.MeshLambertMaterial({ color: 0xffffff });
var plane = new THREE.Mesh(planeGeometry, planeMaterial);
plane.receiveShadow = true;
7、平面位置设置
plane.rotation.x = -0.5 * Math.PI;
plane.position.x = 15;
plane.position.y = 0;
plane.position.z = 0;
8、把平面添加到场景中
scene.add(plane);
9、设置相机的位置,并把镜头指向场景中心
camera.position.x = -30;
camera.position.y = 40;
camera.position.z = 30;
camera.lookAt(scene.position);
10、设置环境光、聚光,并添加到场景中
var ambientLight = new THREE.AmbientLight(0x353535); // 环境光
scene.add(ambientLight);
var spotLight = new THREE.SpotLight(0xffffff); // 聚光
spotLight.position.set(-10, 20, -5);
spotLight.castShadow = true;
scene.add(spotLight);
11、把渲染器挂载到页面上,场景、相机作为参数传给render。
document.getElementById("webgl-output").appendChild(renderer.domElement);
renderer.render(scene, camera);
至此,一个渲染器渲染出了一个带有一个平面、环境光、聚光的场景。以上也是一般建立一个Three.js场景并渲染出来的基本过程。
把物体添加到场景中
现在还要做的是在场景中添加两个物体,立方体和球体。物体需要在相机定位之前添加到场景中。
// 创建立方体
var cubeGeometry = new THREE.BoxGeometry(4, 4, 4); // 几何体
var cubeMaterial = new THREE.MeshLambertMaterial({ color: 0xff0000 }); // 材质
var cube = new THREE.Mesh(cubeGeometry, cubeMaterial); // 网格
cube.position.x = -4;
cube.position.y = 3;
cube.position.z = 0;
cube.castShadow = true;
// 添加立方体到场景中
scene.add(cube);
// 创建球体
var sphereGeometry = new THREE.SphereGeometry(4, 20, 20);
var sphereMaterial = new THREE.MeshLambertMaterial({ color: 0x7777ff });
var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
sphere.position.x = 20;
sphere.position.y = 0;
sphere.position.z = 2;
sphere.castShadow = true;
// 添加球体到场景中
scene.add(sphere);
至此,能够在平面上看到两个带有阴影的静止的物体。
让物体动起来
如果需要把物体做一个动画处理,需要使用到requestAnimationFrame(render)这个函数,参数也是一个函数,这个参数函数用来对物体的旋转、物体位置进行设置。把requestAnimationFrame(render)这个函数放到参数函数render里面调用,实现动画效果。另外还要把之前写过的renderer.render(scene, camera);这个渲染语句剪切放到里面。
具体实现。
function render () {
stats.update();
// 立方体能同时围绕x、y、z轴旋转
cube.rotation.x += 0.02;
cube.rotation.y += 0.02;
cube.rotation.z += 0.02;
step += 0.04;
// 球体在x轴方向来回移动,同时在y轴方向做曲线运动
sphere.position.x = 20 + (10 * (Math.cos(step)));
sphere.position.y = 2 + (10 * Math.abs(Math.sin(step)));
requestAnimationFrame(render);
renderer.render(scene, camera);
}
控制物体改变的速度
如图中所示,物体能够按照一定的幅度自动进行旋转、跳动,如果想要控制物体的旋转、跳动幅度,可以使用threejs库中的控件。具体可以这样做。
在第11步骤的后面,紧接着写上
var step = 0;
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);
var trackballControls = initTrackballControls(camera, renderer);
var clock = new THREE.Clock();
render函数里的内容,调整如下
function render () {
trackballControls.update(clock.getDelta());
stats.update();
cube.rotation.x += controls.rotationSpeed;
cube.rotation.y += controls.rotationSpeed;
cube.rotation.z += controls.rotationSpeed;
step += controls.bouncingSpeed;
sphere.position.x = 20 + (10 * (Math.cos(step)));
sphere.position.y = 2 + (10 * Math.abs(Math.sin(step)));
requestAnimationFrame(render);
renderer.render(scene, camera);
}
render();
在浏览器中,调控右上角的控件,可以改变球体的跳动速度或者立方体的旋转速度。
添加坐标轴
如果想要查看坐标轴,可以把坐标轴添加到场景中。
var axesHelper = new THREE.AxesHelper( 150 );
scene.add( axesHelper );
坐标轴如下,红色为x轴,绿色为y轴,蓝色为z轴。
xyz <====> rgb
即时监听窗口变化即时渲染窗口大小
如果改变窗口大小,会发现渲染器的渲染有点问题,比如缩小页面又放大页面之后,没能及时监听到窗口大小的变化,从而渲染不全整个页面。
解决方法是写一个监听函数。
function onResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
然后在最开始,进行监听。
window.addEventListener('resize', onResize, false);
// 接着的是性能监听...
// ...
参考
Three.js开发指南:基于WebGL和HTML5在网页上渲染3D图形和动画(原书第3版), (美)乔斯·德克森
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。