当前位置: 首页 > news >正文

Three.js实战:从零搭建一个3D旋转地球(附完整代码)

Three.js实战:从零搭建3D旋转地球全流程解析

1. 项目准备与环境搭建

在开始构建3D旋转地球之前,我们需要确保开发环境准备就绪。Three.js作为WebGL的高级封装库,让3D图形开发变得触手可及。以下是基础环境配置步骤:

  1. 创建项目结构

    mkdir 3d-earth && cd 3d-earth npm init -y
  2. 安装核心依赖

    npm install three three-orbitcontrols
  3. HTML基础模板

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>3D Earth</title> <style> body { margin: 0; overflow: hidden; } canvas { display: block; } </style> </head> <body> <script src="src/main.js" type="module"></script> </body> </html>

提示:现代浏览器已原生支持ES模块,使用type="module"可以直接导入npm包

2. 核心场景构建

2.1 初始化三大件

每个Three.js应用都始于三个核心对象的创建:

import * as THREE from 'three'; import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'; // 初始化场景 const scene = new THREE.Scene(); scene.background = new THREE.Color(0x000814); // 透视相机配置 const camera = new THREE.PerspectiveCamera( 75, // 视场角 window.innerWidth / window.innerHeight, // 宽高比 0.1, // 近裁面 1000 // 远裁面 ); camera.position.z = 5; // WebGL渲染器 const renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(window.innerWidth, window.innerHeight); renderer.setPixelRatio(window.devicePixelRatio); document.body.appendChild(renderer.domElement); // 添加轨道控制器 const controls = new OrbitControls(camera, renderer.domElement); controls.enableDamping = true;

2.2 光照系统配置

真实的地球渲染需要精心设计的光照方案:

光源类型参数配置作用
环境光new THREE.AmbientLight(0x404040)基础照明
平行光new THREE.DirectionalLight(0xffffff, 1)模拟太阳光
点光源new THREE.PointLight(0xffffff, 0.5, 100)补充光照
// 创建光源组 const ambientLight = new THREE.AmbientLight(0x333333); scene.add(ambientLight); const directionalLight = new THREE.DirectionalLight(0xffffff, 1); directionalLight.position.set(5, 3, 5); scene.add(directionalLight);

3. 地球模型创建

3.1 几何体与材质

地球模型由球体几何体和多层材质组成:

// 创建球体几何体 const geometry = new THREE.SphereGeometry(2, 64, 64); // 加载地球纹理 const textureLoader = new THREE.TextureLoader(); const earthTexture = textureLoader.load('assets/earth_map.jpg'); const bumpMap = textureLoader.load('assets/earth_bump.jpg'); const specularMap = textureLoader.load('assets/earth_specular.jpg'); // 创建标准材质 const material = new THREE.MeshPhongMaterial({ map: earthTexture, bumpMap: bumpMap, bumpScale: 0.05, specularMap: specularMap, specular: new THREE.Color('grey'), shininess: 5 }); const earth = new THREE.Mesh(geometry, material); scene.add(earth);

3.2 大气层效果

通过缩放球体并应用特殊材质实现大气散射效果:

// 大气层几何体 const atmosphereGeometry = new THREE.SphereGeometry(2.1, 64, 64); const atmosphereMaterial = new THREE.ShaderMaterial({ vertexShader: ` varying vec3 vNormal; void main() { vNormal = normalize(normalMatrix * normal); gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); } `, fragmentShader: ` varying vec3 vNormal; void main() { float intensity = pow(0.7 - dot(vNormal, vec3(0.0, 0.0, 1.0)), 2.0); gl_FragColor = vec4(0.3, 0.6, 1.0, 1.0) * intensity; } `, blending: THREE.AdditiveBlending, side: THREE.BackSide, transparent: true }); const atmosphere = new THREE.Mesh(atmosphereGeometry, atmosphereMaterial); earth.add(atmosphere);

4. 动画与交互实现

4.1 自转动画控制

通过requestAnimationFrame实现平滑的地球自转:

function animate() { requestAnimationFrame(animate); // 地球自转 earth.rotation.y += 0.001; // 更新阻尼控制器 controls.update(); renderer.render(scene, camera); } animate();

4.2 响应式处理

确保场景适应不同屏幕尺寸:

window.addEventListener('resize', () => { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); });

5. 进阶效果增强

5.1 星空背景

使用粒子系统创建浩瀚星空:

// 创建星空几何体 const starGeometry = new THREE.BufferGeometry(); const starMaterial = new THREE.PointsMaterial({ color: 0xffffff, size: 0.02, transparent: true, opacity: 0.8 }); // 生成随机星点 const starVertices = []; for (let i = 0; i < 5000; i++) { const x = (Math.random() - 0.5) * 2000; const y = (Math.random() - 0.5) * 2000; const z = (Math.random() - 0.5) * 2000; starVertices.push(x, y, z); } starGeometry.setAttribute( 'position', new THREE.Float32BufferAttribute(starVertices, 3) ); const stars = new THREE.Points(starGeometry, starMaterial); scene.add(stars);

5.2 云层效果

叠加透明云层纹理增强真实感:

const cloudGeometry = new THREE.SphereGeometry(2.05, 64, 64); const cloudTexture = textureLoader.load('assets/earth_clouds.jpg'); const cloudMaterial = new THREE.MeshPhongMaterial({ map: cloudTexture, transparent: true, opacity: 0.3 }); const clouds = new THREE.Mesh(cloudGeometry, cloudMaterial); earth.add(clouds); // 云层以不同速度旋转 function animate() { // ... clouds.rotation.y += 0.0005; }

6. 性能优化技巧

实现高质量3D效果的同时需要关注性能表现:

  • 纹理压缩:使用512x512或1024x1024的压缩纹理

  • 几何体优化:合理设置球体的分段数(widthSegments/heightSegments)

  • 渲染策略

    renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)); renderer.outputEncoding = THREE.sRGBEncoding;
  • 按需渲染:当页面不可见时暂停渲染

    document.addEventListener('visibilitychange', () => { if (document.hidden) { cancelAnimationFrame(animationId); } else { animate(); } });

7. 项目扩展方向

完成基础地球模型后,可以考虑以下增强功能:

  1. 国家边界高亮:使用额外纹理标记特定区域
  2. 实时天气数据:通过API动态展示云层和风暴
  3. 昼夜变化:根据真实时间计算光照角度
  4. 城市光点:在夜间显示主要城市灯光
  5. 飞行航线:添加动态的弧线表示主要航线
// 示例:添加动态航线 const createFlightPath = (start, end) => { const curve = new THREE.QuadraticBezierCurve3( start, new THREE.Vector3( (start.x + end.x) / 2, Math.max(start.y, end.y) + 0.5, (start.z + end.z) / 2 ), end ); const points = curve.getPoints(50); const geometry = new THREE.BufferGeometry().setFromPoints(points); const material = new THREE.LineBasicMaterial({ color: 0x00ffff }); return new THREE.Line(geometry, material); };

在实现这些高级功能时,建议使用Three.js的后期处理通道(EffectComposer)来添加辉光、色彩校正等效果,这将显著提升视觉表现力。

http://www.jsqmd.com/news/547033/

相关文章:

  • 2026年包塑金属软管白皮书:电缆防水接头、不锈钢接头、不锈钢电缆接头、不锈钢金属软管、包塑金属软管接头、塑料穿线管选择指南 - 优质品牌商家
  • 2026氧化锆珠应用白皮书精细化工定制研磨方案解析:超细研磨氧化锆珠、超细研磨陶瓷珠、通用型陶瓷研磨珠、锂电专用氧化锆珠选择指南 - 优质品牌商家
  • 嵌入式轻量级事件调度库timer设计与实践
  • 新手福音:用快马AI生成图文指南,轻松搞定正版开发环境搭建
  • OpenClaw+nanobot自动化写作:5个高效内容处理技巧
  • DxWrapper:Windows 10/11上经典游戏兼容性的终极解决方案
  • 企业级Docker容器Windows环境RDP安全配置实战指南
  • 从WeNet到ONNX:手把手教你用Sherpa-onnx部署自定义语音识别模型(避坑指南)
  • 如何解决Beat Saber版本管理难题?BSManager让多版本并行不再复杂
  • 2026年比较好的悬浮电动伸缩门公司选择指南 - 品牌宣传支持者
  • 2026年普通程序员转型大模型应用开发保姆级教程——从入门到精通
  • STC15单片机驱动LCD1602,除了Hello World还能玩出什么花样?
  • 裂缝里的黑科技:COMSOL玩转二氧化碳驱油
  • OpenRocket:免费开源的模型火箭设计与飞行仿真终极指南
  • 告别龟速!WSL2 + ESP-IDF 打造小智AI固件极速编译流水线
  • 精准拓客下半场:号码核验行业的痛点破解与技术赋能,氪迹科技技术服务,法人股东号码核验筛选系统,阶梯式价格
  • 现在Java求职一片唱衰,2026真的是都不招人了吗?
  • 实战:基于react与快马ai,开发媲美typora的可嵌入markdown编辑器组件
  • OpenClaw操作审计系统:百川2-13B任务日志分析与可视化
  • 电机设计就像玩拼图,参数之间总在较劲。今天咱们用有限元+Matlab扒一扒参数敏感度的底裤,带点代码实操更带劲
  • 60个AI大模型核心概念:PM也能听懂的工作场景指南
  • 2026宜宾整装公司推荐榜:性价比比较高的装饰公司、本地装修公司、本地装饰公司、装修公司口碑排行、附近装修公司选择指南 - 优质品牌商家
  • 终极指南:用qmcdump轻松破解QQ音乐加密格式,实现音乐文件自由转换
  • OpenClaw批量处理:Qwen3-VL:30B多任务队列管理
  • 终极指南:如何使用uesave轻松编辑Unreal Engine游戏存档
  • 枚举 接口 抽象类
  • 高效音乐资源获取:Soundcloud Music Downloader全功能解析
  • 钦州可靠海鲜美食攻略品牌丰江食坊详解:钦州出名饭店/钦州去哪吃海鲜便宜/钦州去哪吃海鲜好吃/钦州吃海鲜的地方/钦州必吃美食清单/选择指南 - 优质品牌商家
  • OpenClaw任务监控技巧:百川2-13B-4bits模型执行日志分析实战
  • OpenClaw扩展实践:Qwen3.5-9B控制树莓派GPIO设备