项目演示 https://5mfivemeter.github.io/THREE/chapter03.html
项目截图

源码地址 https://github.com/5mFiveMeter/5mFiveMeter.github.io/blob/master/THREE/chapter03.html
源码展示
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
html,body{margin: 0;padding: 0;overflow: hidden;}
</style>
<script src="three.js"></script>
<script src="stats.js"></script>
<script src="dat.gui.js"></script>
</head>
<body>
<div id="Stats-output"></div>
<div id="WebGL-output"></div>
<script>
function init(){
var stats = initStats();
//场景/相机/渲染器
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.1,1000);
camera.position.set(-50,50,50);
camera.lookAt(scene.position);
var renderer = new THREE.WebGLRenderer();
renderer.setClearColor(new THREE.Color(0xEEEEEE));
renderer.setSize(window.innerWidth,window.innerHeight);
renderer.shadowMap.enabled = true;
//底部 纹理加载
var textureGrass = new THREE.TextureLoader().load("./assit/textures/grasslight-big.jpg");
textureGrass.wrapS = THREE.RepeatWrapping;
textureGrass.wrapT = THREE.RepeatWrapping;
textureGrass.repeat.set(5, 5);
var planeGeometry = new THREE.PlaneGeometry(1000,1000,20,20);
var planeMeterial = new THREE.MeshPhongMaterial({map:textureGrass});
var plane = new THREE.Mesh(planeGeometry,planeMeterial);
plane.rotation.x = -0.5*Math.PI;
plane.position.set(15,0,0);
plane.receiveShadow = true;
scene.add(plane);
//放入一个块
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;
cube.position.set(-4,3,0);
scene.add(cube);
//放入一个球
var sphereGeometry = new THREE.SphereGeometry(4,20,20);
var sphereMaterial = new THREE.MeshLambertMaterial({color:0x77777ff});
var sphere = new THREE.Mesh(sphereGeometry,sphereMaterial);
sphere.position.set(20,0,2);
sphere.castShadow = true;
scene.add(sphere);
//环境光
var ambientColor = "#957a7a";
var AmbientLight = new THREE.AmbientLight(ambientColor);
scene.add(AmbientLight);
//聚光灯
var spotLight = new THREE.SpotLight(0xffffff);
spotLight.position.set(-40,60,-10);
spotLight.castShadow = true;
spotLight.intensity=0.2;
spotLight.visible=false;
scene.add(spotLight);
//漂浮的点光源
var pointColor = "#ccffcc";
var pointLight = new THREE.PointLight(pointColor);
pointLight.distance=100;
pointLight.castShadow = true;
scene.add(pointLight);
var sphereLightGeometry = new THREE.SphereGeometry(0.5);
var sphereLightMaterial = new THREE.MeshBasicMaterial({color:0xac6c25});
var sphereLightMesh = new THREE.Mesh(sphereLightGeometry,sphereLightMaterial);
sphereLightMesh.castShadow = true;
sphereLightMesh.position = new THREE.Vector3(3,0,3);
scene.add(sphereLightMesh);
scene.add(spotLight);
//将渲染器放入dom
document.getElementById("WebGL-output").appendChild(renderer.domElement);
//--------------------------------
var step = 0;
var invert = 1;
var phase = 0;
var controls = {
rotationSpeed:0.02,
bouncingSpeed:0.03,
ambientColor:ambientColor,
disableSpotlight:true,
intensity:2,
distance:100
};
var gui = new dat.GUI();
gui.addColor(controls,"ambientColor").onChange(function(color){
AmbientLight.color = new THREE.Color(color);
});
gui.add(controls,"disableSpotlight").onChange(function(bln){
spotLight.visible = !bln;
});
gui.add(controls,"intensity",0,5).onChange(function(intensity){
pointLight.intensity = intensity;
});
gui.add(controls,"distance",0,200).onChange(function(dist){
pointLight.distance = dist;
});
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 = 2 + ( 10 * Math.abs(Math.sin(step)));
//点光源移动
if (phase > 2 * Math.PI) {
invert = invert * -1;
phase -= 2 * Math.PI;
} else {
phase += controls.rotationSpeed;
}
sphereLightMesh.position.z = +(7 * (Math.sin(phase)));
sphereLightMesh.position.x = +(14 * (Math.cos(phase)));
sphereLightMesh.position.y = 5;
if (invert < 0) {
var pivot = 14;
sphereLightMesh.position.x = (invert * (sphereLightMesh.position.x - pivot)) + pivot;
}
pointLight.position.copy(sphereLightMesh.position);
requestAnimationFrame(renderScene);
renderer.render(scene,camera);
}
function initStats(){
var stats = new Stats();
stats.setMode(0);
stats.domElement.style.position = "absolute";
stats.domElement.style.left = "0";
stats.domElement.style.top = "0";
document.getElementById("Stats-output").appendChild(stats.domElement);
return stats;
}
window.addEventListener("resize",function(){
camera.aspect = window.innerWidth/window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth,window.innerHeight);
})
}
window.onload = init;
</script>
</body>
</html>
原文:https://www.cnblogs.com/fivemeter/p/12118343.html