最近在b站上找了个three.js视频学习了一下,照着模仿了一下地月旋转,模仿的过程中发现textureLoader加载图片实际是异步进行,不知道是three.js的版本问题还是别的什么原因,我按照视频上的代码实现发现图片加载不上,没办法只能用回调方式,有过相关经历的3d大牛可以指点一下。(看的视频是老XXX的three.js教学,b站直接能搜到)
最终效果:
首先新建一个简单的web项目,目录如下,其中相关图片和three.js在网上下就行:
css文件:
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
canvas {
background: url(../img/starbg1.jpg);
background-size: cover;
}
html文件:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<link rel="stylesheet" type="text/css" href="css/index.css"/>
</head>
<body>
<div id="webgl-output"></div>
<script type="text/javascript" src="js/three.min.js">
</script>
<script type="text/javascript" src="js/OrbitControls.js">
</script>
<script type="text/javascript" src="js/index.js">
</script>
</body>
</html>
js文件:
function init() {
let earth,moon;
let textureLoader = new THREE.TextureLoader();
let scene = new THREE.Scene()
let camera = new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.1,200)
camera.position.x = 0;
camera.position.y = 2
camera.position.z = 20
let renderer = new THREE.WebGLRenderer({
alpha: 1
})
renderer.shadowMap.enabled = true;
renderer.setSize(window.innerWidth,window.innerHeight)
let spotLight = new THREE.SpotLight(0xffffff)
spotLight.position.set(20,10,40)
spotLight.castShadow = true;
scene.add(spotLight)
renderer.render(scene,camera)
textureLoader.load('./img/earth.jpg',
(texture)=> {
let earthGeometry = new THREE.SphereGeometry(2,16,16)
let earthMaterial = new THREE.MeshPhongMaterial({
map: texture
})
earth = new THREE.Mesh(earthGeometry,earthMaterial)
earth.receiveShadow = true;
scene.add(earth)
}
)
textureLoader.load('./img/moon.jpg',
(texture)=> {
let moonGeometry = new THREE.SphereGeometry(0.8,16,16)
let moonMaterial = new THREE.MeshPhongMaterial({
map: texture
})
moon = new THREE.Mesh(moonGeometry,moonMaterial)
moon.position.set(0,0,10)
moon.castShadow = true;
scene.add(moon)
}
)
camera.lookAt(scene.position)
document.getElementById('webgl-output').appendChild(renderer.domElement);
let earthAxis = new THREE.Vector3(0,1,0);
let clock = new THREE.Clock()
function animate() {
let elapsed = clock.getElapsedTime()
if(earth) {
earth.rotateOnAxis(earthAxis,0.01)
}
if(moon) {
moon.position.set(Math.cos(elapsed) * 10,0,Math.sin(elapsed)* 10)
}
renderer.render(scene,camera)
requestAnimationFrame(animate)
}
animate()
}
window.onload = init