实现效果 【three.js|threejs学习第一天--3D地月环绕实战案例】
部分代码 index.html
:
Document - 锐客网
>
* {
margin: 0;
padding: 0;
}canvas {
background-image: url(imgs/star.jpg);
background-size: cover;
}.label {
color: #fff;
font-size: 16px;
}
type="module">
import * as THREE from '../libs/build/three.module.js'
import {OrbitControls} from '../libs/jsm/controls/OrbitControls.js'
import {CSS2DRenderer,CSS2DObject} from '../libs/jsm/renderers/CSS2DRenderer.js'// 声明全局变量
let camera,scene,renderer,labelRenderer;
let moon,earth;
let clock = new THREE.Clock()
// 实例化纹理加载器
const textureLoader = new THREE.TextureLoader()function init(){
// 地球和月球的半径大小
const EARTH_RADIUS = 2.5
const MOON_RADIUS = 0.27
// 实例化相机
camera = new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.1,200)
camera.position.set(10,5,20)// 实例化场景
scene = new THREE.Scene()
// 创建聚光灯光源以及添加光源
const dirLight = new THREE.SpotLight(0xffffff)
dirLight.position.set(0,0,10)
dirLight.intensity = 2
dirLight.castShadow = true
scene.add(dirLight)// 添加环境光
const aLight = new THREE.AmbientLight(0xffffff)
aLight.intensity = 0.3// 设置光的亮度
scene.add(aLight)// 创建月球
const moonGeometry = new THREE.SphereGeometry(MOON_RADIUS,16,16)
const moonMaterial = new THREE.MeshPhongMaterial({
map:textureLoader.load('textures/planets/moon_1024.jpg')
})
moon = new THREE.Mesh(moonGeometry,moonMaterial)
moon.receiveShadow = true
moon.castShadow = true
scene.add(moon)const moonDiv = document.createElement('div')
moonDiv.className = 'label'
moonDiv.textContent = 'moon'
const moonLabel = new CSS2DObject(moonDiv)moonLabel.position.set(0,MOON_RADIUS+0.5,0)
moon.add(moonLabel)// 创建地球
const earthGeometry = new THREE.SphereGeometry(EARTH_RADIUS,16,16)
const earthMaterial = new THREE.MeshPhongMaterial({
// 镜面反射调低一点
shininess:5,
map:textureLoader.load('textures/planets/earth_atmos_2048.jpg'),
specularMap:textureLoader.load('textures/planets/earth_specular_2048.jpg'),// 设置纹理
normalMap:textureLoader.load('textures/planets/earth_normal_2048.jpg')
})earth = new THREE.Mesh(earthGeometry,earthMaterial)
earth.receiveShadow = true
earth.castShadow = true
scene.add(earth)const earthDiv = document.createElement('div')
earthDiv.className = 'label'
earthDiv.textContent = 'Earth'
const earthLabel = new CSS2DObject(earthDiv)earthLabel.position.set(0,EARTH_RADIUS+0.5,0)
earth.add(earthLabel)// 创建渲染器
renderer = new THREE.WebGLRenderer({
alpha:true
})
renderer.setPixelRatio(window.devicePixelRatio)// 像素比和屏幕的的像素比一致
renderer.setSize(window.innerWidth,window.innerHeight)
// 渲染阴影
renderer.shadowMap.enabled = true
document.body.appendChild(renderer.domElement)// 标签渲染器
labelRenderer = new CSS2DRenderer()
labelRenderer.setSize(window.innerWidth,window.innerHeight)
labelRenderer.domElement.style.position = 'absolute'
labelRenderer.domElement.style.top = '0px'
document.body.appendChild(labelRenderer.domElement)// 绑定控制器和摄像头,以及场景
const controls = new OrbitControls(camera,renderer.domElement)
}
var oldtime = 0
function animate(){
const elapsed = clock.getElapsedTime()
moon.position.set(Math.sin(elapsed)*5,0,Math.cos(elapsed)*5)// 地球自转
var axis = new THREE.Vector3(0,1,0)
earth.rotateOnAxis(axis,(elapsed-oldtime)*Math.PI/10)
renderer.render(scene,camera)
labelRenderer.render(scene,camera)
oldtime = elapsed
requestAnimationFrame(animate)}init()
animate()// 调整尺寸
window.onresize = function(){
camera.aspect = window.innerWidth/window.innerHeight
camera.updateProjectionMatrix()
renderer.setSize(window.innerWidth,Window.innerHeight)
}
推荐阅读
- three.js|Three.js - 模拟太阳、地球、月亮的运动(十一)
- 前端|【中秋快乐】如何用three.js实现我的太空遐想3D网页
- Unity学习笔记|Unity学习笔记--实现UI元素跟随3D物体
- QT|采用QT进行OpenGL开发(三)着色器编程
- ROS进阶教程|【ROS进阶篇】第九讲 基于Rviz和Arbotix控制的机器人模型运动
- 使用Three.js实现炫酷的赛博朋克风格3D数字地球大屏
- 图像处理|摄像机标定和 3D 重构
- 3D|Unity3D入门笔记01
- 开发者|奥比中光成功登陆科创板,董事长黄源浩致辞(打造最好的3D“慧眼”,看懂世界,照亮未来)