- 在three.js项目里,创建一个场景,添加一些需要渲染的场景(带有材质的图形)。
- 材质定义了物体的样子,每种材质对光源的反应不一样。
- 渲染阴影开销非常大,并且需要渲染器、每一个物体,以及每一个光源上打开。
- 通过修改场景中物体的position、rotation属性,可以轻松实现动画。
- 通过辅助库,可以轻松的统计控件(Stats)和定制控件(dat.GUI)。
点击查看【codepen】
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>My New Pen!</title>
<!-- <script src="https://cdn.bootcss.com/stats.js/r17/Stats.js"></script> -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/89/three.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/dat-gui/0.7.3/dat.gui.js"></script>
</head>
<body>
<div id="webgl-output"></div>
<div id="stats-output"></div>
<script>
$(function() {
init();
var gui = new dat.GUI();
gui.add(controls, 'rotationSpeed', 0, 0.5);
gui.add(controls, 'bouncingSpeed', 0, 0.5);
});
// 增加界面控制
var controls = new function() {
this.rotationSpeed = 0.02;
this.bouncingSpeed = 0.03;
}
function init() {
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
var renderer = new THREE.WebGLRenderer();
renderer.setClearColor(new THREE.Color(0xeeeeee), 1);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
var axes = new THREE.AxesHelper(20);
scene.add(axes);
// 地板
var planeGeometry = new THREE.PlaneGeometry(60, 20, 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;
plane.receiveShadow = true;
scene.add(plane);
// 球体
var sphereGeometry = new THREE.SphereGeometry(4, 20, 20);
var sphereMaterial = new THREE.MeshLambertMaterial({ color: 0x7777ff, wireframe: true });
var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
sphere.position.x = 20;
sphere.position.y = 4;
sphere.position.z = 2;
sphere.castShadow = true;
scene.add(sphere);
//创建一个立方体
var cubeGeometry = new THREE.BoxGeometry(4, 4, 4);
//将线框(wireframe)属性设置为true,这样物体就不会被渲染为实物物体
var cubeMaterial = new THREE.MeshLambertMaterial({ color: 0xff0000 });
var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
cube.castShadow = true;
//设置立方体的位置
cube.position.x = -4;
cube.position.y = 3;
cube.position.z = 0;
//将立方体添加到场景中
scene.add(cube);
// 添加光源
var spotLight = new THREE.SpotLight(0xffffff);
spotLight.position.set(-40, 60, -10);
spotLight.castShadow = true;
scene.add(spotLight);
camera.position.x = -30;
camera.position.y = 40;
camera.position.z = 30;
camera.lookAt(scene.position);
$('#webgl-output').append(renderer.domElement);
renderScene();
var step = 0;
function renderScene() {
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在特定时间间隔重新渲染场景
requestAnimationFrame(renderScene);
// 渲染场景
renderer.render(scene, camera);
}
}
</script>
</body>
</html>