# 使用Three.js实现炫酷的赛博朋克风格3D数字地球大屏 🌐
![banner](./images/banner.gif)
> 声明:本文涉及图文和模型素材仅用于个人学习、研究和欣赏,请勿二次修改、非法传播、转载、出版、商用、及进行其他获利行为。
## 背景
![role](./images/role.png)
近期工作有涉及到数字大屏的需求,于是利用业余时间,结合 `Three.js` 和 [CSS实现赛博朋克2077风格视觉效果](https://juejin.cn/post/6972759988632551460) 实现炫酷 `3D` 数字地球大屏页面。页面使用 `React + Three.js + Echarts + stylus` 技术栈,本文涉及到的主要知识点包括:`THREE.Spherical` 球体坐标系的应用、`Shader` 结合 `TWEEN` 实现飞线和冲击波动画效果、`dat.GUI` 调试工具库的使用、`clip-path` 创建不规则图形、`Echarts` 的基本使用方法、`radial-gradient` 创建雷达图形及动画、`GlitchPass` 添加故障风格后期、`Raycaster` 网格点击事件等。
## 效果
如下图 `👇` 所示,页面主要头部、两侧卡片、底部仪表盘以及主体 `3D` 地球 `🌐` 构成,地球外围有 `飞线` 动画和 `冲击波` 动画效果 `🌠` ,通过 `🖱` 鼠标可以旋转和放大地球。点击第一张卡片的 `START` `⬜` 按钮会给页面添加故障风格后期 `⚡`,**双击**地球会弹出随机提示语弹窗。
![scale](./images/scale.gif)
* `💻` 本页面仅适配 `PC` 端,大屏访问效果更佳。
* `👁🗨` 在线预览地址1:<https://3d-eosin.vercel.app/#/earthDigital>
* `👁🗨` 在线预览地址2:<https://dragonir.github.io/3d/#/earthDigital>
## 实现
### `📦` 资源引入
引入开发必备的资源,其中除了基础的 `React` 和样式表之外,`dat.gui` 用于动态控制页面参数,其他剩余的主要分为两部分:**Three.js**相关, `OrbitControls` 用于镜头轨道控制、`TWEEN` 用于补间动画控制、`mergeBufferGeometries` 用户合并模型、`EffectComposer` `RenderPass` `GlitchPass` 用于生成后期故障效果动画、 `lineFragmentShader` 是飞线的 `Shader`、**Echarts**相关按需引入需要的组件,最后使用 `echarts.use` 使其生效。
```js
import './index.styl';
import React from 'react';
import * as dat from 'dat.gui';
// three.js 相关
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { TWEEN } from 'three/examples/jsm/libs/tween.module.min.js';
import { mergeBufferGeometries } from 'three/examples/jsm/utils/BufferGeometryUtils';
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js';
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js';
import { GlitchPass } from 'three/examples/jsm/postprocessing/GlitchPass.js';
import lineFragmentShader from '@/containers/EarthDigital/shaders/line/fragment.glsl';
// echarts 相关
import * as echarts from 'echarts/core';
import { BarChart /*...*/ } from 'echarts/charts';
import { GridComponent /*...*/ } from 'echarts/components';
import { LabelLayout /*...*/ } from 'echarts/features';
import { CanvasRenderer } from 'echarts/renderers';
echarts.use([BarChart, GridComponent, /* ...*/ ]);
```
### `📃` 页面结构
页面主要结构如以下代码所示,`.webgl` 用于渲染 `3D` 数字地球;`.header` 是页面顶部,里面包括**时间**、**日期**、**星际坐标**、`Cyberpunk 2077 Logo`、本人 `Github` 仓库地址等;`.aside` 是左右两侧的图表展示区域;`.footer` 是底部的仪表盘,展示一些雷达动画和文本信息;如果仔细观察,可以看出背景有**噪点**效果,`.bg` 就是用于生成噪点背景效果。
```js
<div className='earth_digital'>
<canvas className='webgl'></canvas>
<header className='hud header'>
<header></header>
<aside className='hud aside left'></aside>
<aside className='hud aside right'></aside>
<footer className='hud footer'></footer>
<section className="bg"></section>
</div>
```
### `🔩` 场景初始化
定义一些全局变量和参数,初始化**场景**、**相机**、**镜头轨道控制器**、**页面缩放监听**、添加页面**重绘更新动画**等进行场景初始化。
```js
const renderer = new THREE.WebGLRenderer({
canvas: document.querySelector('canvas.webgl'),
antialias: true,
alpha: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
// 创建场景
const scene = new THREE.Scene();
// 创建相机
const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, .01, 50);
camera.position.set(0, 0, 15.5);
// 添加镜头轨道控制器
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.enablePan = false;
// 页面缩放监听并重新更新场景和相机
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}, false);
// 页面重绘动画
renderer.setAnimationLoop( _ => {
TWEEN.update();
earth.rotation.y += 0.001;
renderer.render(scene, camera);
});
```
### `🌐` 创建点状地球
具体思路是使用 `THREE.Spherical` 创建一个球体坐标系 `〽`,然后创建 `10000` 个平面网格圆点,将它们的空间坐标转换成球坐标,并使用 `mergeBufferGeometries` 将它们合并为一个网格。然后使用一张如下图所示的地图图片作为材质,在 `shader` 中根据材质图片的颜色分布调整圆点的大小和透明度,根据传入的参数调整圆点的颜色和大小比例。然后创建一个球体 `SphereGeometry`,使用生成的着色器材质,并将它添加到场景中。到此,一个点状地球 `🌐` 模型就完成了,具体实现如下。
![step_0](./images/earth.jpg)
```js
// 创建球类坐标
let sph = new THREE.Spherical();
let dummyObj = new THREE.Object3D();
let p = new THREE.Vector3();
let geoms = [], rad = 5, r = 0;
let dlong = Math.PI * (3 - Math.sqrt(5));
let dz = 2 / counter;
let long = 0;
let z = 1 - dz / 2;
let params = {
colors: { base: '#f9f002', gradInner: '#8ae66e', gradOuter: '#03c03c' },
reset: () => { controls.reset() }
}
let uniforms = {
impacts: { value: impacts },
// 陆地色块大小
maxSize: { value: .04 },
// 海洋色块大小
minSize: { value: .025 },
// 冲击波高度
waveHeight: { value: .1 },
// 冲击波范围
scaling: { value: 1 },
// 冲击波径向渐变内侧颜色
gradInner: { value: new THREE.Color(params.colors.gradInner) },
// 冲击波径向渐变外侧颜色
gradOuter: { value: new THREE.Color(params.colors.gradOuter) }
}
// 创建10000个平面圆点网格并将其定位到球坐标
for (let i = 0; i < 10000; i++) {
r = Math.sqrt(1 - z * z);
p.set( Math.cos(long) * r, z, -Math.sin(long) * r).multiplyScalar(rad);
z = z - dz;
long = long + dlong;
sph.setFromVector3(p);
dummyObj.lookAt(p);
dummyObj.updateMatrix();
let g = new THREE.PlaneGeometry(1, 1);
g.applyMatrix4(dummyObj.matrix);
g.translate(p.x, p.y, p.z);
let centers = [p.x, p.y, p.z, p.x, p.y, p.z, p.x, p.y, p.z, p.x, p.y, p.z];
let uv = new THREE.Vector2((sph.theta + Math.PI) / (Math.PI * 2), 1. - sph.phi / Math.PI);
let uvs = [uv.x, uv.y, uv.x, uv.y, uv.x, uv.y, uv.x, uv.y];
g.setAttribute('center', new THREE.Float32BufferAttribute(centers, 3));
g.setAttribute('baseUv', new THREE.Float32BufferAttribute(uvs, 2));
geoms.push(g);
}
// 将多个网格合并为一个网格
let g = mergeBufferGeometries(geoms);
let m = new THREE.MeshBasicMaterial({
color: new THREE.Color(params.colors.base),
onBeforeCompile: shader => {
shader.uniforms.impacts = uniforms.impacts;
shader.uniforms.maxSize = uniforms.maxSize;
shader.uniforms.minSize = uniforms.minSize;
shader.uniforms.waveHeight = uniform
没有合适的资源?快使用搜索试试~ 我知道了~
Three.js 3D项目(源码+项目说明)(包含冰墩墩、数字城市、3D人像等一些3D趣味演示页面).zip
共493个文件
png:168个
js:121个
jpg:31个
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 113 浏览量
2024-03-09
22:02:09
上传
评论 1
收藏 179.04MB ZIP 举报
温馨提示
【资源说明】 1、该资源包括项目的全部源码,下载可以直接使用! 2、本项目适合作为计算机、数学、电子信息等专业的课程设计、期末大作业和毕设项目,作为参考资料学习借鉴。 3、本资源作为“参考资料”如果需要实现其他功能,需要能看懂代码,并且热爱钻研,自行调试。 Three.js 3D项目(源码+项目说明)(包含冰墩墩、数字城市、3D人像、车模展示、塞尔达传说等一些3D趣味演示页面).zipThree.js 3D项目(源码+项目说明)(包含冰墩墩、数字城市、3D人像等一些3D趣味演示页面).zipThree.js 3D项目(源码+项目说明)(包含冰墩墩、数字城市、3D人像等一些3D趣味演示页面).zipThree.js 3D项目(源码+项目说明)(包含冰墩墩、数字城市、3D人像等一些3D趣味演示页面).zipThree.js 3D项目(源码+项目说明)(包含冰墩墩、数字城市、3D人像等一些3D趣味演示页面).zipThree.js 3D项目(源码+项目说明)(包含冰墩墩、数字城市、3D人像等一些3D趣味演示页面).zip
资源推荐
资源详情
资源评论
收起资源包目录
Three.js 3D项目(源码+项目说明)(包含冰墩墩、数字城市、3D人像等一些3D趣味演示页面).zip (493个子文件)
logo.awebp 4KB
index.css 5KB
index.css 4KB
App.css 1KB
index.css 1KB
sheep.css 1KB
index.css 1KB
index.css 1KB
mine.css 971B
index.css 967B
_index.css 944B
index.css 921B
index.css 389B
index.css 175B
index.css 108B
Head_03.ctm 357KB
Head_01.ctm 355KB
Head_02.ctm 355KB
EyeRightCurved.ctm 56KB
EyeRight.ctm 55KB
LensRight.ctm 33KB
city.fbx 47.42MB
land.fbx 13.43MB
city.fbx 4.21MB
link.fbx 2.57MB
meta.fbx 1021KB
text.fbx 739KB
text.fbx 670KB
cropland.fbx 635KB
earth.fbx 276KB
dm.fbx 38KB
move.gif 5.55MB
preview.gif 5.48MB
banner.gif 5.19MB
banner.gif 5.1MB
banner.gif 4.39MB
banner.gif 3.87MB
preview.gif 3.8MB
banner.gif 3.73MB
banner.gif 3.72MB
preview.gif 3.35MB
scale.gif 2.9MB
banner.gif 2.85MB
preview_1.gif 2.83MB
step_points.gif 2.72MB
step_sea.gif 2.6MB
preview_3.gif 2.51MB
banner.gif 2.07MB
banner.gif 1.9MB
complete.gif 1.7MB
step_sky.gif 1.68MB
preview_2.gif 1.61MB
banner.gif 1.44MB
rick_and_morty.gif 1.13MB
gravity.gif 144KB
.gitignore 333B
land.glb 26.31MB
plant_cell.glb 9.4MB
animal_cell.glb 5.06MB
bingdwendwen.glb 3.24MB
rickAndMorty.glb 1.98MB
island.glb 1.66MB
flag.glb 1.12MB
Miku.glb 983KB
xuerongrong.glb 862KB
heart.glb 688KB
kas.glb 683KB
land.glb 581KB
logo.glb 402KB
Shelter.glb 251KB
astronaut.glb 235KB
model.glb 235KB
heart.glb 178KB
Fox.glb 159KB
flamingo.glb 76KB
windStroke1Model.glb 5KB
windStroke2Model.glb 2KB
entranceModel.glb 1KB
earth.glb 1KB
bakedFloorLightModel.glb 1024B
bakedFloorShadowModel.glb 984B
fragment.glsl 8KB
fragment.glsl 4KB
fragment.glsl 4KB
vertexHeart.glsl 2KB
vertex.glsl 1KB
fragment.glsl 978B
fragment.glsl 796B
fragment.glsl 549B
vertex.glsl 522B
fragment.glsl 235B
fragment.glsl 234B
vertex.glsl 210B
vertex.glsl 169B
fragment.glsl 130B
vertex.glsl 125B
vertex.glsl 125B
vertex.glsl 119B
vertex.glsl 97B
fragment.glsl 75B
共 493 条
- 1
- 2
- 3
- 4
- 5
资源评论
土豆片片
- 粉丝: 1562
- 资源: 5642
下载权益
C知道特权
VIP文章
课程特权
开通VIP
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功