如何用三分钟写一个3D地球云层效果

如何用三分钟写一个3D地球云层效果?

答案是Threejs

在这篇文章中,我们将学习如何用JavaScript和Three.js创建一个带有云层的地球模型。我们将使用Three.js来创建3D场景、模型和动画效果。下面是如何实现这个效果的代码:

引入Three.js

首先,我们需要引入Three.js库。在这个例子中,我们使用了ES6的模块导入方式。

javascript 复制代码
import * as THREE from './three.module.js';

创建地球和云层

定义一个函数createSphereMeshcloud来创建一个带有云层纹理的球体模型。我们使用THREE.TextureLoader加载云层的纹理图片,并将其作为材质的贴图。我们还将材质的透明度设置为0.8,以便看到地球表面的纹理。接下来,我们定义一个函数createSphereMesh来创建一个带有地球纹理的球体模型。我们使用THREE.TextureLoader加载地球的纹理图片,并将其作为材质的贴图。

javascript 复制代码
function createSphereMesh(R) {
  let textureLoader = new THREE.TextureLoader();
  let texture = textureLoader.load('earth.jpg');
  let geometry = new THREE.SphereBufferGeometry(R, 40, 40); 
  let material = new THREE.MeshLambertMaterial({
    map: texture,
  });
  let mesh = new THREE.Mesh(geometry, material); 
  return mesh
}

function createSphereMeshcloud(R) {
  let textureLoader = new THREE.TextureLoader();
  let texture = textureLoader.load('earthclouds1k.png');
  let geometry = new THREE.SphereBufferGeometry(R, 40, 40); 
 
  let material = new THREE.MeshLambertMaterial({
    map: texture,
    transparent: true,
    opacity: 0.8,
  });
  let mesh = new THREE.Mesh(geometry, material); 
  return mesh
}

createSphereMesh()函数中,我们使用THREE.TextureLoader加载了地球的纹理图片,并将其作为材质的贴图。THREE.SphereBufferGeometry则用于创建一个球体模型,参数R为球体的半径,4040分别为水平和垂直方向的细分数,用于控制球体的面数。最后,我们将球体模型和材质对象传递给THREE.Mesh构造函数,来创建一个球体网格模型。

createSphereMeshcloud()函数中,我们使用THREE.TextureLoader加载了云层的纹理图片,并将其作为材质的贴图。我们还将材质的透明度设置为0.8,以便看到地球表面的纹理。其他部分和createSphereMesh()函数类似。

javascript 复制代码
let R = 100;//地球半径
let earth = createSphereMesh(R);// 创建地球mesh

let R2 = 120;//云层半径
let cloud = createSphereMeshcloud(R2);// 创建云层

创建场景

创建一个Three.js场景,将创建好的地球和云层网格模型添加到Three.js场景中。

javascript 复制代码
let scene = new THREE.Scene();
scene.add(earth);
scene.add(cloud);

定义光源

定义了三个光源:两个平行光和一个环境光。这些光源将照亮地球和云层,使其看起来更加逼真。

javascript 复制代码
// 光源设置
// 平行光1
let directionalLight = new THREE.DirectionalLight(0xffffff, 0.6);
directionalLight.position.set(400, 200, 300);
scene.add(directionalLight);
// 平行光2
let directionalLight2 = new THREE.DirectionalLight(0xffffff, 0.6);
directionalLight2.position.set(-400, -200, -300);
scene.add(directionalLight2);
// 环境光
let ambient = new THREE.AmbientLight(0xffffff, 0.6);
scene.add(ambient);

创建相机

创建了一个相机对象,并将其放置在场景中。使用正交投影相机。正交投影相机适合渲染2D图像,因为它不会出现透视效果。

javascript 复制代码
let width = window.innerWidth; //窗口文档显示区的宽度
let height = window.innerHeight; //窗口文档显示区的高度
let k = width / height; 
let s = 150; 
let camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
camera.position.set(100, 0, 100); 
camera.lookAt(0, 0, 0);

在创建好场景和相机之后,我们创建一个Three.js渲染器对象,并将其添加到HTML文档中。并开启了锯齿和背景透明。

javascript 复制代码
// 创建渲染器对象
let renderer = new THREE.WebGLRenderer({
  antialias: true, //开启锯齿
  alpha: true //开启背景透明
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(width, height); //设置渲染区域尺寸
renderer.setClearColor(0xb9d3ff, 0); //设置背景颜色

document.body.appendChild(renderer.domElement);

开启渲染

置了一个渲染循环,使地球和云层可以旋转,并通过渲染器对象将场景和相机渲染到屏幕上。

javascript 复制代码
// 渲染循环
function render() {
  earth.rotateY(-0.004);//地球绕y轴旋转动画
  cloud.rotateY(-0.001);//云层绕y轴旋转动画
  renderer.render(scene, camera); 
  requestAnimationFrame(render); 
}
render();

自适应窗口

最后,我们通过添加一个事件监听器来响应窗口大小的变化,并更新相机和渲染器的尺寸。

javascript 复制代码
window.addEventListener('resize', function() {
  let width = window.innerWidth; //窗口文档显示区的宽度
  let height = window.innerHeight; //窗口文档显示区的高度
  let k = width / height; 
  let s = 150; 
  camera.left = -s * k;
  camera.right = s * k;
  camera.top = s;
  camera.bottom = -s;
  camera.updateProjectionMatrix();
  renderer.setSize(width, height); //设置渲染区域尺寸
})

三分钟时间到,看效果。恩,透明度好像有点小问题,先不管了,抽根烟再说。

相关推荐
安迪小宝几秒前
python基础语法13-装饰器
开发语言·前端·python
鸿蒙场景化示例代码技术工程师21 分钟前
实现文件List拖动鸿蒙示例代码
前端
Rachel_wang27 分钟前
React 使用 i18next 实现国际语言切换翻译
前端
小白探索世界欧耶!~27 分钟前
【踩坑】GitHub Actions 运行的 Linux 环境中,文件名是大小写敏感的
linux·运维·服务器·前端·vue.js·笔记·github
Simon—欧阳31 分钟前
C#异步方法返回Task<T>的同步调用
开发语言·前端·javascript
天生我材必有用_吴用36 分钟前
vue3实战三、Axios封装结合mock数据,vite跨域及环境变量配置 入口
前端
天生我材必有用_吴用37 分钟前
vue3实战二、搭建Vue+ElementPlus项目教程 入口
前端
天生我材必有用_吴用42 分钟前
Vue3实战七、登录认证与退出登录
前端
逆袭的小黄鸭42 分钟前
JavaScript DOM 事件流:从基础传播到高级控制与自定义实践
前端·javascript
H5开发新纪元44 分钟前
基于Ant Design Pro高级表格的企业级代理商管理系统开发实践
前端