咱们在这片文章里不会上来就告诉你
Three.js
里面有什么方法,都该怎么去使用;咱们想让你先尝试去使用Three.js
,经过这个小例子但愿能够勾引发你的兴趣;而后咱们会在后面的学习中慢慢的深刻Three.js
的学习;慢慢来嘛,欲速则不达。javascript
编辑器
推荐使用WebStrom
或者Atom
或者SublimeText
jquery
Three.js
咱们学习Three.js
固然要用到three.js
,获取的途径有两种;一种是直接在github上的Three.js克隆下载,另外一种方法是使用learning-threejs上的给你准备好的学习资料。我选择的是第二种方法,由于那里面还包含了许多咱们将使用到的库。git
Web服务器
在刚开始的学习中,咱们可能只会在一个页面上书写咱们的代码;可是随着学习的深刻,咱们可能会加载许多的材料,这时候就须要服务器来帮忙了。固然搭建一个本地的服务器也是十分容易的。若是你使用的编辑器是WebStrom的话,那么就不须要搭建本地服务器了;由于经过WebStrom打开的页面就是在WebStrom建立的服务器中运行的。angularjs
引入文件库github
<script src="libs/three.js"></script> <script src="libs/jquery-1.9.0.js"></script> <script src="libs/stats.js"></script> <script src="libs/dat.gui.js"></script>
注意,咱们上面引入的库在文件夹learning-threejs
里面都有的。服务器
书写CSS和HTML代码app
body { margin: 0; overflow: hidden; }
这些样式文件是为了防止里面内容的溢出,去除了body
的外边距。dom
<div id="container"></div>
添加存放Three.js
渲染内容的容器。
添加场景,相机,渲染器
// 添加场景 var scene = new THREE.Scene(); // 添加相机 var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000); // 添加渲染器 var renderer = new THREE.WebGLRenderer();
场景就至关于一个画板,相机至关于你的眼睛,渲染器至关于一支画笔;这些是个人理解,若是你对这些概念不是很清楚的话,那也不要紧;学习Three.js
还有很长的路要走,随着学习的深刻,相信你会有本身的理解。
设置场景大小,背景颜色
// 设置场景的大小 renderer.setSize(window.innerWidth, window.innerHeight); // 设置场景的背景颜色 第一个参数是一个表示颜色的字符串或者16进制的数字 renderer.setClearColor(0x000000);
将场景元素添加到页面,渲染场景
// 选取页面中的容器,将咱们的场景元素添加进去 $('#container').append(renderer.domElement); // 渲染器渲染咱们的场景 renderer.render(scene, camera);
效果图以下:
虽然看着十分简单,可是这是咱们开始下面内容的基础,继续前进吧。
添加一个坐标轴
// 新建坐标轴 var axis = new THREE.AxisHelper(20); // 在场景中添加坐标轴 scene.add(axis); /* 在设置了相机的位置以后才能够看到坐标轴 */ // 设置相机的x坐标位置 camera.position.x = -30; // 设置相机的y坐标位置 camera.position.y = 40; // 设置相机的z坐标的位置 camera.position.z = 30; // 设置相机的焦点 camera.lookAt(scene.position);
效果图以下:
图二,添加了坐标轴的场景。
添加一个平面
// 建立平面的骨架 var planeGeometry = new THREE.PlaneBufferGeometry(60, 30, 1, 1); // 建立平面的材料 var planeMaterial = new THREE.MeshBasicMaterial({color: '#aaaaaa'}); // 合成平面 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);
效果图以下:
图三,添加了坐标轴的场景。
添加一个立方体和一个球体
// 建立立方体骨架 var cubeGeometry = new THREE.BoxGeometry(4, 4, 4); // 建立立方体材料 var cubeMaterial = new THREE.MeshBasicMaterial({color: 'yellow', wireframe: true}); // 合成立方体 var cube = new THREE.Mesh(cubeGeometry, cubeMaterial); // 设置立方体位置 cube.position.x = -8; cube.position.y = 4; cube.position.z = 0; // 在场景中添加立方体 scene.add(cube); // 建立并在场景中添加球体 var sphereGeometry = new THREE.SphereGeometry(4, 20, 20); var sphereMaterial = new THREE.MeshBasicMaterial({color: 'red', wireframe: true}); var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial); sphere.position.x = 20; sphere.position.y = 10; sphere.position.z = 0; scene.add(sphere);
效果图以下:
图四,添加了坐标轴的场景。
在场景中添加灯光
// 建立灯光 var spotLight = new THREE.SpotLight(0xffffff); // 设置灯光位置 spotLight.position.set(-40, 60, -10); // 在场景中添加灯光 scene.add(spotLight);
添加灯光以后,你会发现页面并无什么变化;那是由于咱们在场景中添加的物体的材料是不会对光源产生任何反应的,因此咱们要改动一些东西,以下所示:
/* 将构建物体的材料改变 */ //var planeMaterial = new THREE.MeshBasicMaterial({color: '#aaaaaa'}); var planeMaterial = new THREE.MeshLambertMaterial({color: '#aaaaaa'}); //var cubeMaterial = new THREE.MeshBasicMaterial({color: 'yellow', wireframe: true}); var cubeMaterial = new THREE.MeshLambertMaterial({color: 'yellow', wireframe: true}); //var sphereMaterial = new THREE.MeshBasicMaterial({color: 'red', wireframe: true}); var sphereMaterial = new THREE.MeshLambertMaterial({color: 'red', wireframe: true}); /* 设置渲染器容许阴影映射 */ renderer.shadowMapEnabled = true; /* 设置哪些物体投射阴影,那些物体接受阴影 */ plane.receiveShadow = true; cube.castShadow = true; sphere.castShadow = true; spotLight.castShadow = true;
效果图以下:
图五,添加了阴影映射的场景。
添加监测动画运行帧数的辅助库
var stats = initStats(); renderScene(); // 重复渲染场景 function renderScene() { // 更新 stats.update(); // 使用requestAnimationFrame代替setInterval requestAnimationFrame(renderScene); // 渲染场景 renderer.render(scene, camera); } // 初始化监测动画运行频帧库stats function initStats() { var stats = new Stats(); stats.setMode(0); stats.domElement.style.position = 'absolute'; stats.domElement.style.left = '0px'; stats.domElement.style.top = '0px'; // 在页面上面添加一个div,id为stats $('#stats').append(stats.domElement); return stats; }
为立方体和球体添加动画
var stats = initStats(); var step = 0; renderScene(); // 重复渲染场景 function renderScene() { // 更新 stats.update(); // 立方体的旋转 cube.rotation.x += 0.02; cube.rotation.y += 0.02; cube.rotation.z += 0.02; // 球体的弹跳 step += 0.03; sphere.position.x = 20 + (10 * Math.cos(step)); sphere.position.y = 0 + (10 * Math.sin(step)); // 使用requestAnimationFrame代替setInterval requestAnimationFrame(renderScene); // 渲染场景 renderer.render(scene, camera); } // 初始化监测动画运行频帧库stats function initStats() { var stats = new Stats(); stats.setMode(0); stats.domElement.style.position = 'absolute'; stats.domElement.style.left = '0px'; stats.domElement.style.top = '0px'; // 在页面上面添加一个div,id为stats $('#stats').append(stats.domElement); return stats; }
效果图以下:
图六,添加了动画以及监测动画运行频帧场景。
使用dat.GUI简化测试
// 定义咱们使用到的测试变量 var controls = new function() { this.rotationSpeed = 0.02; this.bouncingSpeed = 0.03; }; var gui = new dat.GUI(); gui.add(controls, 'rotationSpeed', 0, 1); gui.add(controls, 'bouncingSpeed', 0, 1); // 使用上面的变量替换咱们的固定数据 // 立方体的旋转 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 = 0 + (10 * Math.sin(step));
效果图以下:
图七,最终造成的场景。
最终的javascript代码部分
$(function() { var controls = new function() { this.rotationSpeed = 0.02; this.bouncingSpeed = 0.03; }; var gui = new dat.GUI(); gui.add(controls, 'rotationSpeed', 0, 1); gui.add(controls, 'bouncingSpeed', 0, 1); // 添加场景 var scene = new THREE.Scene(); // 添加相机 var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000); // 添加渲染器 var renderer = new THREE.WebGLRenderer(); // 设置场景的大小 renderer.setSize(window.innerWidth, window.innerHeight); // 设置场景的背景颜色 renderer.setClearColor(0x000000); // 设置渲染器容许阴影映射 renderer.shadowMapEnabled = true; // 新建坐标轴 var axis = new THREE.AxisHelper(20); // 在场景中添加坐标轴 scene.add(axis); // 建立平面的骨架 var planeGeometry = new THREE.PlaneBufferGeometry(60, 30, 1, 1); // 建立平面的材料 // var planeMaterial = new THREE.MeshBasicMaterial({color: '#aaaaaa'}); var planeMaterial = new THREE.MeshLambertMaterial({color: '#aaaaaa'}); // 合成平面 var plane = new THREE.Mesh(planeGeometry, planeMaterial); plane.receiveShadow = true; // 设置平面的旋转角度 plane.rotation.x = -0.5 * Math.PI; // 设置平面的位置 plane.position.x = 15; plane.position.y = 0; plane.position.z = 0; // 在场景中添加平面 scene.add(plane); // 建立立方体骨架 var cubeGeometry = new THREE.BoxGeometry(4, 4, 4); // 建立立方体材料 // var cubeMaterial = new THREE.MeshBasicMaterial({color: 'yellow', wireframe: true}); var cubeMaterial = new THREE.MeshLambertMaterial({color: 'yellow', wireframe: true}); // 合成立方体 var cube = new THREE.Mesh(cubeGeometry, cubeMaterial); cube.castShadow = true; // 设置立方体位置 cube.position.x = -8; cube.position.y = 4; cube.position.z = 0; // 在场景中添加立方体 scene.add(cube); // 建立并在场景中添加球体 var sphereGeometry = new THREE.SphereGeometry(4, 20, 20); // var sphereMaterial = new THREE.MeshBasicMaterial({color: 'red', wireframe: true}); var sphereMaterial = new THREE.MeshLambertMaterial({color: 'red', wireframe: true}); var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial); sphere.castShadow = true; sphere.position.x = 20; sphere.position.y = 10; sphere.position.z = 0; scene.add(sphere); // 建立灯光 var spotLight = new THREE.SpotLight(0xffffff); // 设置灯光位置 spotLight.position.set(-40, 60, -10); spotLight.castShadow = true; // 在场景中添加灯光 scene.add(spotLight); // 设置相机的x坐标位置 camera.position.x = -30; // 设置相机的y坐标位置 camera.position.y = 40; // 设置相机的z坐标的位置 camera.position.z = 30; // 设置相机的焦点 camera.lookAt(scene.position); // 选取页面中的容器,将咱们的场景元素添加进去 $('#container').append(renderer.domElement); var stats = initStats(); var step = 0; renderScene(); // 重复渲染场景 function renderScene() { // 更新 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 = 0 + (10 * Math.sin(step)); // 使用requestAnimationFrame代替setInterval requestAnimationFrame(renderScene); // 渲染场景 renderer.render(scene, camera); } // 初始化监测动画运行频帧库stats function initStats() { var stats = new Stats(); stats.setMode(0); stats.domElement.style.position = 'absolute'; stats.domElement.style.left = '0px'; stats.domElement.style.top = '0px'; // 在页面上面添加一个div,id为stats $('#stats').append(stats.domElement); return stats; } })
若是文中有什么不足欢迎你们指出,咱们一块儿进步。
这一系列文章大都参考了《Learning Three.js》