一个简单的场景
- 准备
a. 准备HTML页面
b. 引入Three.js
c. 添加Dom容器
2. 渲染三维对象
a. 创建场景
new THREE.Scene()
b. 创建相机
new THREE.PerspectiveCamera(45, window.innerWidth /window.innerHeight, 0.1, 1000);
c. 创建渲染器
new THREE.WebGLRenderer()
d. 创建一个立方体
new THREE.BoxGeometry(4, 4, 4)
e. 创建一种材质
new THREE.MeshBasicMaterial({color: 0xcccccc})
f. 物体和材质构成一个Mesh(网格对象)
new THREE.Mesh(planeGeometry, planeMaterial)
g. 将Mesh加入场景
scene.add(cube)
h. 配置相机的位置
camera.position.x =-30
i. 配置相机的朝向
camera.lookAt(scene.position)
j. 将渲染器的输出添加到页面中
document.getElementById(“webgl”).appendChild(renderer.domElement)
k. 渲染三维场景
renderer.render(scene, camera)
<!DOCTYPE html><html> <head> <script src="../libs/three.js"></script> <style> body { margin: 0; overflow: hidden; } </style> </head> <body> <div id="webgl"></div> <script> function init() { // 创建场景 // create a scene, that will hold all our elements such as objects, cameras and lights. var scene = new THREE.Scene(); // 创建相机 // create a camera, which defines where we're looking var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000); // 创建渲染器 // create a render and set the size var renderer = new THREE.WebGLRenderer(); renderer.setClearColor(new THREE.Color(0xEEEEEE)); renderer.setSize(window.innerWidth, window.innerHeight); // 创建坐标系 // show axes in the screen var axes = new THREE.AxisHelper(20); // scene.add(axes); // 创建场地 // create the ground plane var planeGeometry = new THREE.PlaneGeometry(60, 20); // 创建材料 var planeMaterial = new THREE.MeshBasicMaterial({color: 0xcccccc}); // 合成物体 var plane = new THREE.Mesh(planeGeometry, planeMaterial); // 位置、旋转 // rotate and position the plane plane.rotation.x = -0.5 * Math.PI; plane.position.x = 15; plane.position.y = 0; plane.position.z = 0; // add the plane to the scene scene.add(plane); // 创建立方体 // create a cube var cubeGeometry = new THREE.BoxGeometry(4, 4, 4); var cubeMaterial = new THREE.MeshBasicMaterial({color: 0xff0000, wireframe: true}); var cube = new THREE.Mesh(cubeGeometry, cubeMaterial); // position the cube cube.position.x = -4; cube.position.y = 3; cube.position.z = 0; // add the cube to the scene scene.add(cube); // 创建球体 // create a sphere var sphereGeometry = new THREE.SphereGeometry(4, 20, 20); var sphereMaterial = new THREE.MeshBasicMaterial({color: 0x7777ff, wireframe: true}); var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial); // position the sphere sphere.position.x = 20; sphere.position.y = 4; sphere.position.z = 2; // add the sphere to the scene scene.add(sphere); // position and point the camera to the center of the scene camera.position.x = -30; camera.position.y = 40; camera.position.z = 30; camera.lookAt(scene.position); // add the output of the renderer to the html element // 把渲染器绘制的Dom加到页面中 document.getElementById("webgl").appendChild(renderer.domElement); // render the scene renderer.render(scene, camera); } window.onload = init ; </script> </body></html>
加一个光源
- 添加能够产生阴影的光源
spotLight = new THREE.SpotLight(0xffffff)
2. 打开光源的阴影
spotLight.castShadow =true
3. 将光源加入场景
scene.add(spotLight)
4. 创建一个能够反应光源的材质
new THREE.MeshLambertMaterial({color: 0xffffff})
5. 使此Mesh可以投射阴影
plane.receiveShadow =true
<!DOCTYPE html><html> <head> <title>Example 01.03 - Materials and light</title> <script type="text/javascript" src="../libs/three.js"></script> <script type="text/javascript" src="../libs/stats.js"></script> <script type="text/javascript" src="../libs/dat.gui.js"></script> <style> body { /* set margin to 0 and overflow to hidden, to go fullscreen */ margin: 0; overflow: hidden; } </style> </head> <body> <!-- Div which will hold the Output --> <div id="WebGL-output"> </div> <!-- Javascript code that runs our Three.libs examples --> <script type="text/javascript"> // once everything is loaded, we run our Three.libs stuff. function init() { // create a scene, that will hold all our elements such as objects, cameras and lights. var scene = new THREE.Scene(); // create a camera, which defines where we're looking at. var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000); // create a render and set the size var renderer = new THREE.WebGLRenderer(); renderer.setClearColor(new THREE.Color(0xEEEEEE, 1.0)); renderer.setSize(window.innerWidth, window.innerHeight); renderer.shadowMapEnabled = true; // create the ground plane var planeGeometry = new THREE.PlaneGeometry(60, 20); // (MeshLambertMaterial/MeshPhongMaterial) var planeMaterial = new THREE.MeshLambertMaterial({color: 0xffffff}); var plane = new THREE.Mesh(planeGeometry, planeMaterial); // plane.receiveShadow = true; // rotate and position the plane plane.rotation.x = -0.5 * Math.PI; plane.position.x = 15; plane.position.y = 0; plane.position.z = 0; // add the plane to the scene scene.add(plane); // create a cube var cubeGeometry = new THREE.BoxGeometry(4, 4, 4); var cubeMaterial = new THREE.MeshLambertMaterial({color: 0xff0000}); var cube = new THREE.Mesh(cubeGeometry, cubeMaterial); cube.castShadow = true; // position the cube cube.position.x = -4; cube.position.y = 3; cube.position.z = 0; // add the cube to the scene 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); // position the sphere sphere.position.x = 20; sphere.position.y = 4; sphere.position.z = 2; sphere.castShadow = true; // add the sphere to the scene scene.add(sphere); // position and point the camera to the center of the scene camera.position.x = -30; camera.position.y = 40; camera.position.z = 30; camera.lookAt(scene.position); // add spotlight for the shadows var spotLight = new THREE.SpotLight(0xffffff); spotLight.position.set(-40, 60, -10); spotLight.castShadow = true; scene.add(spotLight); // add the output of the renderer to the html element document.getElementById("WebGL-output").appendChild(renderer.domElement); // call the render function renderer.render(scene, camera); } window.onload = init; </script> </body></html>
让场景动起来
- 引入动画检测
stats.js
2. 初始化动画检测统计对象
new Stats()
3. 配置检测每秒传输帧数
stats.setMode(0)
4. 将输出加入页面
document.getElementById(“Stats-output”).appendChild(stats.domElement)
创建动画场景方法
renderScene()
a. 更新统计对象
stats.update()
b. Mesh的动作
cube.rotation.x += 0.02
c. 渲染场景
renderer.render(scene, camera)
d. 循环渲染
requestAnimationFrame(renderScene)
6. 启动动画
renderScene()
<!DOCTYPE html><html> <head> <title>Example 01.04 - Materials, light and animation</title> <script type="text/javascript" src="../libs/three.js"></script> <!-- --> <script type="text/javascript" src="../libs/stats.js"></script> <style> body { /* set margin to 0 and overflow to hidden, to go fullscreen */ margin: 0; overflow: hidden; } </style> </head> <body> <div id="Stats-output"> </div> <!-- Div which will hold the Output --> <div id="WebGL-output"> </div> <!-- Javascript code that runs our Three.js examples --> <script type="text/javascript"> // once everything is loaded, we run our Three.js stuff. function init() { var stats = initStats(); // create a scene, that will hold all our elements such as objects, cameras and lights. var scene = new THREE.Scene(); // create a camera, which defines where we're looking at. var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000); // create a render and set the size var renderer = new THREE.WebGLRenderer(); renderer.setClearColor(new THREE.Color(0xEEEEEE, 1.0)); renderer.setSize(window.innerWidth, window.innerHeight); renderer.shadowMapEnabled = true; // create the ground plane 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; // rotate and position the plane plane.rotation.x = -0.5 * Math.PI; plane.position.x = 15; plane.position.y = 0; plane.position.z = 0; // add the plane to the scene scene.add(plane); // create a cube var cubeGeometry = new THREE.BoxGeometry(4, 4, 4); var cubeMaterial = new THREE.MeshLambertMaterial({color: 0xff0000}); var cube = new THREE.Mesh(cubeGeometry, cubeMaterial); cube.castShadow = true; // position the cube cube.position.x = -4; cube.position.y = 3; cube.position.z = 0; // add the cube to the scene 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); // position the sphere sphere.position.x = 20; sphere.position.y = 0; sphere.position.z = 2; sphere.castShadow = true; // add the sphere to the scene scene.add(sphere); // position and point the camera to the center of the scene camera.position.x = -30; camera.position.y = 40; camera.position.z = 30; camera.lookAt(scene.position); // add subtle ambient lighting var ambientLight = new THREE.AmbientLight(0x0c0c0c); scene.add(ambientLight); // add spotlight for the shadows var spotLight = new THREE.SpotLight(0xffffff); spotLight.position.set(-40, 60, -10); spotLight.castShadow = true; scene.add(spotLight); // add the output of the renderer to the html element document.getElementById("WebGL-output").appendChild(renderer.domElement); // call the render function var step = 0; // renderScene(); function renderScene() { stats.update(); // rotate the cube around its axes cube.rotation.x += 0.02; cube.rotation.y += 0.02; cube.rotation.z += 0.02; // bounce the sphere up and down step += 0.04; sphere.position.x = 20 + ( 10 * (Math.cos(step))); sphere.position.y = 2 + ( 10 * Math.abs(Math.sin(step))); // // render using requestAnimationFrame requestAnimationFrame(renderScene); renderer.render(scene, camera); } // function initStats() { var stats = new Stats(); stats.setMode(0); // 0: fps, 1: ms // Align top-left stats.domElement.style.position = 'absolute'; stats.domElement.style.left = '0px'; stats.domElement.style.top = '0px'; document.getElementById("Stats-output").appendChild(stats.domElement); return stats; } } window.onload = init; </script> </body></html>
添加控制器
- 引入图形交互插件
dat.gui.js
2. 创建控制对象
new function () {
this.rotationSpeed = 0.02;
this.bouncingSpeed = 0.03;
}
3. 初始化GUI
new dat.GUI()
4. 设置属性和取值范围
gui.add(controls, ‘rotationSpeed’, 0, 0.5)
5. 在动画中引用属性
cube.rotation.x += controls.rotationSpeed
<!DOCTYPE html><html> <head> <title>Example 01.05 - Control gui</title> <script type="text/javascript" src="../libs/three.js"></script> <script type="text/javascript" src="../libs/stats.js"></script> <script type="text/javascript" src="../libs/dat.gui.js"></script> <style> body { /* set margin to 0 and overflow to hidden, to go fullscreen */ margin: 0; overflow: hidden; } </style> </head> <body> <div id="Stats-output"> </div> <!-- Div which will hold the Output --> <div id="WebGL-output"> </div> <!-- Javascript code that runs our Three.js examples --> <script type="text/javascript"> function init() { var stats = initStats(); // create a scene, that will hold all our elements such as objects, cameras and lights. var scene = new THREE.Scene(); // create a camera, which defines where we're looking at. var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000); // create a render and set the size var renderer = new THREE.WebGLRenderer(); renderer.setClearColor(new THREE.Color(0xEEEEEE, 1.0)); renderer.setSize(window.innerWidth, window.innerHeight); renderer.shadowMapEnabled = true; // create the ground plane 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; // rotate and position the plane plane.rotation.x = -0.5 * Math.PI; plane.position.x = 15; plane.position.y = 0; plane.position.z = 0; // add the plane to the scene scene.add(plane); // create a cube var cubeGeometry = new THREE.BoxGeometry(4, 4, 4); var cubeMaterial = new THREE.MeshLambertMaterial({color: 0xff0000}); var cube = new THREE.Mesh(cubeGeometry, cubeMaterial); cube.castShadow = true; // position the cube cube.position.x = -4; cube.position.y = 3; cube.position.z = 0; // add the cube to the scene 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); // position the sphere sphere.position.x = 20; sphere.position.y = 0; sphere.position.z = 2; sphere.castShadow = true; // add the sphere to the scene scene.add(sphere); // position and point the camera to the center of the scene camera.position.x = -30; camera.position.y = 40; camera.position.z = 30; camera.lookAt(scene.position); // add subtle ambient lighting var ambientLight = new THREE.AmbientLight(0x0c0c0c); scene.add(ambientLight); // add spotlight for the shadows var spotLight = new THREE.SpotLight(0xffffff); spotLight.position.set(-40, 60, -10); spotLight.castShadow = true; scene.add(spotLight); // add the output of the renderer to the html element document.getElementById("WebGL-output").appendChild(renderer.domElement); // call the render function 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); render(); function render() { stats.update(); // rotate the cube around its axes // cube.rotation.x += controls.rotationSpeed; cube.rotation.y += controls.rotationSpeed; cube.rotation.z += controls.rotationSpeed; // bounce the sphere up and down step += controls.bouncingSpeed; sphere.position.x = 20 + ( 10 * (Math.cos(step))); sphere.position.y = 2 + ( 10 * Math.abs(Math.sin(step))); // render using requestAnimationFrame requestAnimationFrame(render); renderer.render(scene, camera); } function initStats() { var stats = new Stats(); stats.setMode(0); // 0: fps, 1: ms // Align top-left stats.domElement.style.position = 'absolute'; stats.domElement.style.left = '0px'; stats.domElement.style.top = '0px'; document.getElementById("Stats-output").appendChild(stats.domElement); return stats; } } window.onload = init; </script> </body></html>
自适应浏览器
- 添加监听
window.addEventListener(‘resize’, onResize, false)
2. 重置相机长宽比
camera.aspect= window.innerWidth /window.innerHeight
3. 更新相机
camera.updateProjectionMatrix()
4. 更新渲染器尺寸
renderer.setSize(window.innerWidth, window.innerHeight)
<!DOCTYPE html><html> <head> <title>Example 01.06 - Screen size change</title> <script type="text/javascript" src="../libs/three.js"></script> <script type="text/javascript" src="../libs/stats.js"></script> <script type="text/javascript" src="../libs/dat.gui.js"></script> <style> body { /* set margin to 0 and overflow to hidden, to go fullscreen */ margin: 0; overflow: hidden; } </style> </head> <body> <div id="Stats-output"> </div> <!-- Div which will hold the Output --> <div id="WebGL-output"> </div> <!-- Javascript code that runs our Three.js examples --> <script type="text/javascript"> var camera; var scene; var renderer; // once everything is loaded, we run our Three.js stuff. function init() { var stats = initStats(); // create a scene, that will hold all our elements such as objects, cameras and lights. scene = new THREE.Scene(); // create a camera, which defines where we're looking at. camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000); // create a render and set the size renderer = new THREE.WebGLRenderer(); renderer.setClearColor(new THREE.Color(0xEEEEEE, 1.0)); renderer.setSize(window.innerWidth, window.innerHeight); renderer.shadowMapEnabled = true; // create the ground plane 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; // rotate and position the plane plane.rotation.x = -0.5 * Math.PI; plane.position.x = 15; plane.position.y = 0; plane.position.z = 0; // add the plane to the scene scene.add(plane); // create a cube var cubeGeometry = new THREE.BoxGeometry(4, 4, 4); var cubeMaterial = new THREE.MeshLambertMaterial({color: 0xff0000}); var cube = new THREE.Mesh(cubeGeometry, cubeMaterial); cube.castShadow = true; // position the cube cube.position.x = -4; cube.position.y = 3; cube.position.z = 0; // add the cube to the scene 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); // position the sphere sphere.position.x = 20; sphere.position.y = 0; sphere.position.z = 2; sphere.castShadow = true; // add the sphere to the scene scene.add(sphere); // position and point the camera to the center of the scene camera.position.x = -30; camera.position.y = 40; camera.position.z = 30; camera.lookAt(scene.position); // add subtle ambient lighting var ambientLight = new THREE.AmbientLight(0x0c0c0c); scene.add(ambientLight); // add spotlight for the shadows var spotLight = new THREE.SpotLight(0xffffff); spotLight.position.set(-40, 60, -10); spotLight.castShadow = true; scene.add(spotLight); // add the output of the renderer to the html element document.getElementById("WebGL-output").appendChild(renderer.domElement); // call the render function 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); render(); function render() { stats.update(); // rotate the cube around its axes cube.rotation.x += controls.rotationSpeed; cube.rotation.y += controls.rotationSpeed; cube.rotation.z += controls.rotationSpeed; // bounce the sphere up and down step += controls.bouncingSpeed; sphere.position.x = 20 + ( 10 * (Math.cos(step))); sphere.position.y = 2 + ( 10 * Math.abs(Math.sin(step))); // render using requestAnimationFrame requestAnimationFrame(render); renderer.render(scene, camera); } function initStats() { var stats = new Stats(); stats.setMode(0); // 0: fps, 1: ms // Align top-left 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 onResize() { // camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); } window.onload = init; // listen to the resize events window.addEventListener('resize', onResize, false); </script> </body></html>