需求:实现3d地球与卫星绕地飞行,实时运动
1 准备
- 创建场景
let scene = new THREE.Scene();
// scene.background = new THREE.Color( 0xa0a0a0 );
this.scene = scene;
- 创建相机
//canvas将要渲染的位置大小
let areaSize = this.areaSize;
//渲染区域
let camera = new THREE.PerspectiveCamera(60, areaSize.width / areaSize.height, 0.1, 10000)
//设置相机位置
camera.position.set(50, -10, 200)
//设置相机方向
camera.lookAt(0, 0, 0)
this.camera = camera;
this.scene.add(this.camera);
- 创建网络模型
//==============地球===============
//this.map.earthRadius为显示地球的半径
let geometry = new THREE.SphereGeometry( this.map.earthRadius, 64, 32);
let earthImgSrc = require('@/assets/img/home/home3dMapBackground.png');
//材质
let earthMater = new THREE.MeshPhongMaterial({
map: new THREE.TextureLoader().load(earthImgSrc),
transparent:true,
depthWrite:false,
});
//网络模型对象 -- 地球
let meshMaterial = new THREE.Mesh(geometry,earthMater);
//地球模型
this.meshMaterial = meshMaterial;
//添加到场景中
this.scene.add(meshMaterial);
//==============卫星轨迹===============
// 轨迹圆环图片
let sadImgSrc = require('@/assets/img/control/satellite.png');
//循环卫星 假设有3颗卫星
for(let i=0; i<3; i++){
let satelliteSize = 12,satelliteRadius=0,rotation={x:0,y:0,z:0},speed=0;
if(i==0){
satelliteRadius = 80;
rotation.x = -Math.PI * 0.35;
rotation.y = Math.PI * 0.25;
rotation.z = 0;
speed = 0.004;
}else if(i==1){
satelliteRadius =100;
rotation.x = -Math.PI * 0.35;
rotation.y = -Math.PI * 0.2;
rotation.z = 0;
speed = 0.005;
}else{
satelliteRadius = 86;
rotation.x = -Math.PI * 0.25;
rotation.y = Math.PI * 0.15;
rotation.z = 0;
speed = 0.003;
}
//卫星中心
let earthGeometry = new THREE.SphereGeometry(0,0,0);
//材质
let earthMater = new THREE.MeshPhongMaterial({
color:0xa0a0a0,
});
let centerMesh = new THREE.Mesh(earthGeometry,earthMater);
//卫星圆环
let circleGeometry = new THREE.RingGeometry(satelliteRadius, satelliteRadius + 0.3, 100, 1);
//材质
let circleMater = new THREE.MeshBasicMaterial({
color:0xffffff,
side: THREE.DoubleSide
})
//网络模型对象 -- 卫星圆环
let track = new THREE.Mesh(circleGeometry,circleMater);
//卫星图片
let satellite = new THREE.Sprite(new THREE.SpriteMaterial({
map: new THREE.TextureLoader().load(sadImgSrc),
blending: THREE.AdditiveBlending
}));
//卫星大小
satellite.scale.x = satellite.scale.y = satellite.scale.z = 12;
//卫星旋转半径
satellite.position.set(satelliteRadius, 0, 0);
//3d模型
let pivotPoint = new THREE.Object3D();
pivotPoint.add(satellite);
pivotPoint.add(track);
//卫星中心模型添加卫星对象
centerMesh.add(pivotPoint);
centerMesh.rotation.set(rotation.x, rotation.y, rotation.z);
//添加到场景中
this.scene.add(centerMesh);
//添加卫星
this.satellites.push({satellite:centerMesh, speed:speed, address:rotation});
}
- 创建控制器
let controls = new OrbitControls(this.camera, this.renderer.domElement);
controls.enableDamping = true; //开启衰弱
controls.maxZoom = Infinity;
controls.minDistance = 75; //设置最小可缩放
this.controls = controls;
- 创建渲染器
letelement = document.getElementById("home3dMap");
//创建渲染器
let renderer = new THREE.WebGLRenderer({
antialias:true, //开启抗锯齿
alpha:true,
})
let areaSize = this.areaSize;
renderer.setSize(areaSize.width,areaSize.height) //设置渲染区域尺寸
renderer.shadowMap.enabled = true; //显示阴影
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
renderer.setClearColor(0x3f3f3f, 0); //设置背景颜色
this.renderer = renderer;
element.appendChild(this.renderer.domElement)
6 渲染文章来源:https://www.toymoban.com/news/detail-628610.html
this.controls.update(); //控制阻尼器
//地球自传
this.meshMaterial.rotation.y += 0.0015;
this.renderer.render(this.scene, this.camera);
//卫星轨迹转动
for(let i=0; i<this.map.circleLonLat.length; i++){
this.map.circleLonLat[i].rotation.y += 0.0015;
}
requestAnimationFrame(this.animate.bind(this));
完整代码
<template>
<div class="home3dMap" id="home3dMap">
</div>
</template>
<script>
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
export default {
name:"home3dMap",
data(){
return {
scene:null, //场景
camera:null, //相机
meshMaterial:null, //网络模型
controls:null, //控制器
renderer:null, //渲染器
satellites:[], //卫星(数组)
}
},
components:{},
created(){
},
beforeDestroy(){
},
mounted(){
//初始化
this.init();
},
methods:{
init(){
this.createScene(); //创建场景
this.createLight(); //创建光源
this.createCamera(); //创建相机
this.createMesh(); //创建几何体
this.createRender(); //创建渲染器
this.createControls(); //创建轨道控制器
this.animate();
},
//创建场景
createScene(){
let scene = new THREE.Scene();
// scene.background = new THREE.Color( 0xa0a0a0 );
this.scene = scene;
},
//创建光源
createLight(){
// 环境光
const ambientLight = new THREE.AmbientLight(0xcccccc, 2)
this.scene.add(ambientLight)
// 平行光
let directionalLight = new THREE.DirectionalLight(0xffffff, 0.2)
directionalLight.position.set(1, 0.2, 0).normalize()
// 平行光2
let directionalLight2 = new THREE.DirectionalLight(0xff2ffff, 0.2)
directionalLight2.position.set(1, 0.2, 0.1).normalize()
this.scene.add(directionalLight)
this.scene.add(directionalLight2)
// 半球光
let hemiLight = new THREE.HemisphereLight(0xffffff, 0x444444, 0.2)
hemiLight.position.set(5, 50, 0)
// this.scene.add(hemiLight)
// 平行光3
let directionalLight3 = new THREE.DirectionalLight(0xffffff, 0)
// directionalLight3.position.set(1, 50, -2)
// 开启阴影
directionalLight3.castShadow = true
// 设置光边界
// directionalLight3.shadow.camera.top = 18
// directionalLight3.shadow.camera.bottom = -10
// directionalLight3.shadow.camera.left = -52
// directionalLight3.shadow.camera.right = 12
this.scene.add(directionalLight3)
},
//创建相机
createCamera(){
//渲染区域 宽高为 960/685
let camera = new THREE.PerspectiveCamera(60, 960 / 685, 1, 10000)
//设置相机位置
camera.position.set(50, -10, 200)
//设置相机方向
camera.lookAt(0, 0, 0)
this.camera = camera;
this.scene.add(this.camera);
},
//创建几何体
createMesh(){
//地球
let geometry = new THREE.SphereGeometry( 70, 32, 16);
let earthImgSrc = require('@/assets/img/home/home3dMapBackground.png');
//材质
let earthMater = new THREE.MeshPhongMaterial({
map: new THREE.TextureLoader().load(earthImgSrc),
transparent:true,
depthWrite:false,
});
//网络模型对象 -- 地球
let meshMaterial = new THREE.Mesh(geometry,earthMater);
//地球模型
this.meshMaterial = meshMaterial;
//添加到场景中
this.scene.add(meshMaterial);
//添加圆环
this.initSatellite(meshMaterial);
},
//添加圆环
initSatellite(meshMaterial){
//返回一个卫星和轨道的组合体
// satelliteSize/卫星大小 satelliteRadius/卫星旋转半径 rotation /组合体的旋转方向 speed/卫星运动速度
// 圆环图片
let sadImgSrc = require('@/assets/img/control/satellite.png');
//循环卫星 假设有3颗卫星
for(let i=0; i<3; i++){
let satelliteSize = 12,satelliteRadius=0,rotation={x:0,y:0,z:0},speed=0;
if(i==0){
satelliteRadius = 80;
rotation.x = -Math.PI * 0.35;
rotation.y = Math.PI * 0.25;
rotation.z = 0;
speed = 0.004;
}else if(i==1){
satelliteRadius =100;
rotation.x = -Math.PI * 0.35;
rotation.y = -Math.PI * 0.2;
rotation.z = 0;
speed = 0.005;
}else{
satelliteRadius = 86;
rotation.x = -Math.PI * 0.25;
rotation.y = Math.PI * 0.15;
rotation.z = 0;
speed = 0.003;
}
//卫星中心
let earthGeometry = new THREE.SphereGeometry(0,0,0);
//材质
let earthMater = new THREE.MeshPhongMaterial({
color:0xa0a0a0,
});
let centerMesh = new THREE.Mesh(earthGeometry,earthMater);
//卫星圆环
let circleGeometry = new THREE.RingGeometry(satelliteRadius, satelliteRadius + 0.3, 100, 1);
//材质
let circleMater = new THREE.MeshBasicMaterial({
color:0xffffff,
side: THREE.DoubleSide
})
//网络模型对象 -- 卫星圆环
let track = new THREE.Mesh(circleGeometry,circleMater);
let satellite = new THREE.Sprite(new THREE.SpriteMaterial({
map: new THREE.TextureLoader().load(sadImgSrc),
blending: THREE.AdditiveBlending
}));
//卫星大小
satellite.scale.x = satellite.scale.y = satellite.scale.z = 12;
//卫星旋转半径
satellite.position.set(satelliteRadius, 0, 0);
let pivotPoint = new THREE.Object3D();
pivotPoint.add(satellite);
pivotPoint.add(track);
//卫星中心模型添加卫星对象
centerMesh.add(pivotPoint);
centerMesh.rotation.set(rotation.x, rotation.y, rotation.z);
//添加到场景中
this.scene.add(centerMesh);
//添加卫星
this.satellites.push({satellite:centerMesh, speed:speed, address:rotation});
}
},
//发光的星星
generateSprite(color){
let canvas = document.createElement('canvas');
canvas.width = 16;
canvas.height = 16;
let context = canvas.getContext('2d');
let gradient = context.createRadialGradient(canvas.width / 2, canvas.height / 2, 0, canvas.width / 2, canvas.height / 2, canvas.width / 2);
gradient.addColorStop(0, 'rgba(' + color + ',1)');
gradient.addColorStop(0.2, 'rgba(' + color + ',1)');
gradient.addColorStop(0.4, 'rgba(' + color + ',.6)');
gradient.addColorStop(1, 'rgba(0,0,0,0)');
context.fillStyle = gradient;
context.fillRect(0, 0, canvas.width, canvas.height);
return canvas;
},
//创建渲染器
createRender(){
let element = document.getElementById("home3dMap");
//创建渲染器
let renderer = new THREE.WebGLRenderer({antialias:true, alpha:true})
renderer.setSize(960,685) //设置渲染区域尺寸
renderer.shadowMap.enabled = true; //显示阴影
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
renderer.setClearColor(0x3f3f3f, 0); //设置背景颜色
this.renderer = renderer;
element.appendChild(this.renderer.domElement)
},
//创建轨道控制器
createControls(){
let controls = new OrbitControls(this.camera, this.renderer.domElement);
controls.enableDamping = true;
controls.maxZoom = Infinity;
this.controls = controls;
},
//循环
animate(){
this.controls.update(); //控制阻尼器
//地球自传
this.meshMaterial.rotation.y += 0.0015;
this.renderer.render(this.scene, this.camera);
for(let i=0; i<this.satellites.length; i++){
this.satellites[i].satellite.rotation.z -= this.satellites[i].speed;
}
requestAnimationFrame(this.animate.bind(this));
},
},
}
</script>
<style>
.home3dMap{
width:100%;
height:100%;
}
</style>
文章来源地址https://www.toymoban.com/news/detail-628610.html
到了这里,关于3d 地球与卫星绕地飞行的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!