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

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

相关推荐
Revolution6124 分钟前
React 组件重新渲染时,到底重新执行了什么
前端·react.js·面试
用户2181697049302 小时前
Flutter(四)Dart语法 空安全 运算符 流程控制
前端
许彰午2 小时前
政务督办的分合模式:主办协办的并发审批
前端·javascript·政务
用户69371750013842 小时前
AI时代,程序员该往哪走?
前端·后端
ttwuai2 小时前
GoFrame 后台日志清空失败:无 WHERE 删除为什么被拦住
前端·golang
易筋紫容2 小时前
创建型模式:对象的诞生艺术
开发语言·前端·javascript
半句唐诗3 小时前
我是如何通过 Access Token 成功发布第一个 npm 包的
前端·npm·node.js
程序员黑豆3 小时前
鸿蒙应用开发:@Provider 与 @Consumer 跨组件双向同步详解
前端·harmonyos
paopaokaka_luck3 小时前
基于springboot3+vue3的智能文库平台(AI智能搜索、AI智能汇总、实时在线状态展示、多格式文档预览与富文本编辑、Echarts图形化分析)
前端·网络·spring boot·网络协议·echarts
牧艺3 小时前
cos-design PhotoAlbum:用 CSS 3D 做一个「能翻页」的实体相册
前端·css·交互设计