如何用三分钟写一个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); //设置渲染区域尺寸
})

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

相关推荐
IT_陈寒4 分钟前
Python 3.12 的这5个新特性,让我的代码性能提升了40%!
前端·人工智能·后端
方安乐21 分钟前
vite+vue+js项目使用ts报错
前端·javascript·vue.js
韩立233323 分钟前
Vue 3.5 升级指南
前端·vue.js
子兮曰30 分钟前
🚀别再乱写package.json了!这些隐藏技巧让项目管理效率提升300%
前端·javascript·npm
我叫汪枫36 分钟前
Spring Boot图片验证码功能实现详解 - 从零开始到完美运行
java·前端·javascript·css·算法·html
小桥风满袖39 分钟前
极简三分钟ES6 - ES8中async,await
前端·javascript
一直在学习的小白~1 小时前
node_modules 明明写进 .gitignore,却还是被 push/commit 的情况
前端·javascript·vue.js
前端小超超2 小时前
如何配置capacitor 打包的ios app固定竖屏展示?
前端·ios·web app
nightunderblackcat2 小时前
新手向:从零理解LTP中文文本处理
前端·javascript·easyui
kyle~2 小时前
python---PyInstaller(将Python脚本打包为可执行文件)
开发语言·前端·python·qt