Three.js 粒子地球教程
粒子地球 ·Points Earth· ▶ 在线运行案例案例合集三维可视化功能案例threehub.cn开源仓库github地址https://github.com/z2586300277/three-cesium-examples400个案例代码:网盘链接你将学到什么ShaderMaterial 自定义着色器实现核心视觉效果OrbitControls 相机轨道交互THREE.Points 粒子点渲染requestAnimationFrame渲染循环与resize自适应效果说明本案例演示粒子地球效果基于 WebGL 实现「粒子地球」可视化效果附完整可运行源码核心用到 ShaderMaterial、OrbitControls、THREE.Points。建议先打开文首在线案例查看动态画面再对照下方源码逐步理解。核心概念Scene / Camera / WebGLRenderer构成最小渲染闭环大场景可开logarithmicDepthBuffer缓解 Z-fighting。ShaderMaterial通过uniforms 自定义 GLSL 控制逐像素/逐点效果透明粒子常配合depthTest: false。OrbitControls提供轨道旋转/缩放开启enableDamping后需在 animate 中controls.update()。THREE.Points将每个顶点渲染为可控大小的粒子可用自定义 attribute如u_index驱动片元/顶点动画。实现步骤搭建 Scene、PerspectiveCamera、WebGLRenderer挂载 canvas 并处理resize定义 uniforms / onBeforeCompile 或 ShaderMaterial编写 GLSL 与材质参数创建 OrbitControls及 Raycaster 等交互控件若源码包含在requestAnimationFrame循环中更新状态并 renderCesium 为viewer.render或自动渲染代码要点import * as THREE from three;import { OrbitControls } from three/addons/controls/OrbitControls.js; import { GUI } from three/addons/libs/lil-gui.module.min.js;let gui new GUI(); // 初始化场景、相机和渲染器 const gl { clearColor: #332148, shadows: false, alpha: false, outputColorSpace: THREE.SRGBColorSpace, };const scene new THREE.Scene(); const camera new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 100 );const renderer new THREE.WebGLRenderer({ alpha: gl.alpha }); renderer.setClearColor(gl.clearColor); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement);const controls new OrbitControls(camera, renderer.domElement); controls.target.set(0, 0, 0); controls.update(); // 设置相机位置 camera.position.z 2; // Shaders const vertexShader uniform float size; uniform sampler2D elevTexture; uniform sampler2D alphaTexture; uniform float uTime; uniform float uWaveHeight; uniform float uWaveSpeed;varying vec2 vUv; varying float vVisible; varying float vAlpha; varying float vElevation; // Function to generate fBm with vec3 input float random(vec3 st) { return fract(sin(dot(st.xyz, vec3(12.9898,78.233,45.164))) * 43758.5453123); }float noise(vec3 st) { vec3 i floor(st); vec3 f fract(st);// Eight corners in 3D of a tile float a random(i); float b random(i vec3(1.0, 0.0, 0.0)); float c random(i vec3(0.0, 1.0, 0.0)); float d random(i vec3(1.0, 1.0, 0.0)); float e random(i vec3(0.0, 0.0, 1.0)); float f1 random(i vec3(1.0, 0.0, 1.0)); float g random(i vec3(0.0, 1.0, 1.0)); float h random(i vec3(1.0, 1.0, 1.0));vec3 u ff(3.0 - 2.0 * f);return mix(mix(mix(a, b, u.x), mix(c, d, u.x), u.y), mix(mix(e, f1, u.x), mix(g, h, u.x), u.y), u.z); }float fbm(vec3 st) { float value 0.0; float amplitude 0.5;for (int i 0; i 5; i) { value amplitude * noise(st); st * 2.0; amplitude * 0.5; } return value; }void main() { vUv uv; float alphaLand 1.0 - texture2D(alphaTexture, vUv).r; vAlpha alphaLand; vec3 newPosition position;if(alphaLand 0.5) { // Sea // fBm for wave-like displacement float waveHeight uWaveHeight; // Adjust wave height as needed float waveSpeed uWaveSpeed; // Adjust wave speed as needed float displacement (fbm(newPosition5.0 uTimewaveSpeed)2.0 - 1.0)waveHeight; vElevation displacement; newPosition normal * displacement ; }vec4 mvPosition modelViewMatrix * vec4( newPosition, 1.0 ); float elv texture2D(elevTexture, vUv).r; vec3 vNormal normalMatrix * normal; vVisible step(0.0, dot( -normalize(mvPosition.xyz), normalize(vNormal))); mvPosition.z 0.45 * elv;// 求出 mvPosition 距离相机的距离 float dist length(mvPosition.xyz); // 根据距离调整 size float pointSize size * (1.0 - dist / 10.0); gl_PointSize max(pointSize, 1.0); gl_PointSize pointSize; gl_Position projectionMatrix * mvPosition; }; // 将pointsEarth.vert的内容粘贴在这里 const fragmentShader uniform sampler2D colorTexture; // uniform sampler2D alphaTexture; uniform sampler2D earthTexture; uniform sampler2D starTexture;varying vec2 vUv; varying float vVisible; varying float vAlpha; varying float vElevation;void main() { if (floor(vVisible 0.1) 0.0) discard; vec2 coord gl_PointCoord; float alpha texture2D(starTexture, coord).a; // 根据 alpha 值来裁剪形状 if (alpha 0.1) discard;// float alphaLand 1.0 - texture2D(alphaTexture, vUv).r; vec3 color texture2D(colorTexture, vUv).rgb; vec3 earth texture2D(earthTexture, vUv).rgb; color mix(color, earth, 0.65); if( vAlpha 0.5 ) { gl_FragColor vec4(color, vAlpha); }else { // 对于海洋部分根据 vElevation 调整颜色 float elevationEffect clamp(vElevation*30.0, -1.0, 1.0); // 将 vElevation 限制在 [-1, 1] 范围内 vec3 deep_sea_blue vec3(0.004, 0.227, 0.388); vec3 adjustedColor mix(deep_sea_blue, earth1.75, (elevationEffect 1.0)0.5); // 根据 vElevation 调整颜色 gl_FragColor vec4(adjustedColor, 1.0-vAlpha); } }; // 将pointsEarth.frag的内容粘贴在这里const params { color: #17c5a9, pointSize: 4.0, };const wireframeMaterial { color: params.color, wireframe: true, transparent: true, opacity: 0.2, };const textures { earthMap: new THREE.TextureLoader().load(FILE_HOST threeExamples/shader/earth1.jpg), starSprite: new THREE.TextureLoader().load(FILE_HOST threeExamples/particle/particleEarth/circle.png), colorMap: new THREE.TextureLoader().load(FILE_HOST threeExamples/particle/particleEarth/04_rainbow1k.jpg), elevMap: new THREE.TextureLoader().load(FILE_HOST threeExamples/particle/particleEarth/01_earthbump1k.jpg), alphaMap: new THREE.TextureLoader().load(FILE_HOST threeExamples/particle/particleEarth/02_earthspec1k.jpg), };const pointsShader { uniforms: { size: { type: f, value: params.pointSize }, uTime: { type: f, value: 0.0 }, uWaveHeight: { type: f, value: 0.075 }, uWaveSpeed: { type: f, value: 0.2 }, colorTexture: { type: t, value: textures.colorMap }, elevTexture: { type: t, value: textures.elevMap }, alphaTexture: { type: t, value: textures.alphaMap }, earthTexture: { type: t, value: textures.earthMap }, starTexture: { type: t, value: textures.starSprite }, }, vertexShader: vertexShader, fragmentShader: fragmentShader, transparent: true, side: THREE.FrontSide, };const group new THREE.Group(); const wireframeMaterialRef new THREE.MeshBasicMaterial(wireframeMaterial); const pointsMaterial new THREE.ShaderMaterial(pointsShader);const geometry new THREE.IcosahedronGeometry(1, 4); const wireframeMesh new THREE.Mesh(geometry, wireframeMaterialRef); group.add(wireframeMesh);const pointsGeometry new THREE.IcosahedronGeometry(1, 128); const pointsMesh new THREE.Points(pointsGeometry, pointsMaterial); group.add(pointsMesh);const hemisphereLight new THREE.HemisphereLight(#ffffff, #080820, 3); scene.add(hemisphereLight);scene.add(group);// 创建一个名为 Debug 的文件夹 let debugFolder gui.addFolder(Debug);// 添加颜色控制器 debugFolder.addColor(params, color).name(color).onChange((value) { wireframeMaterialRef.color.set(value); });// 添加粒子大小控制器 debugFolder.add(params, pointSize, 0.1, 10, 0.1).name(粒子大小).onChange((value) { pointsShader.uniforms.size.value value; });// 添加海浪高度控制器 debugFolder.add(pointsShader.uniforms.uWaveHeight, value, 0.01, 0.5, 0.01).name(海浪高度).onChange((value) { pointsShader.uniforms.uWaveHeight.value value; });// 添加海浪变化速度控制器 debugFolder.add(pointsShader.uniforms.uWaveSpeed, value, 0.01, 1, 0.01).name(海浪变化速度).onChange((value) { pointsShader.uniforms.uWaveSpeed.value value; });// 渲染循环 function animate() { pointsShader.uniforms.uTime.value 10 * 0.016; group.rotation.y 0.002; requestAnimationFrame(animate); renderer.render(scene, camera); } animate();完整源码GitHub小结本文提供粒子地球完整 Three.js 源码与在线 Demo建议先运行案例再改 uniform/参数做二次实验更多 Three.js 实战案例见 three-cesium-examples 合集 与 GitHub 开源仓库

相关新闻

基于AES-256-GCM的SQLite文件级加密工具实现与源码解析

基于AES-256-GCM的SQLite文件级加密工具实现与源码解析

1. 项目概述:为什么我们需要一个独立的Sqlite加密工具? 如果你用过Sqlite,大概率会和我有一样的感受:它轻巧、快速、嵌入方便,简直是单机或轻量级应用的数据存储神器。但当你把应用部署出去,尤其是里面存了…

2026/7/4 11:29:15阅读更多 →
AI辅助学术写作工具链全解析与实战技巧

AI辅助学术写作工具链全解析与实战技巧

1. 学术写作的AI辅助工具全景图 写毕业论文那会儿,我电脑里常驻着七个浏览器标签页,每个都对应着不同的AI工具。凌晨三点的实验室里,这些数字助手成了我最靠谱的战友。不同于市面上泛泛而谈的工具推荐,这里要分享的是经过五十篇论…

2026/7/4 11:29:15阅读更多 →
2026年MacBook替代指南:五款Windows笔记本与开发环境迁移实战

2026年MacBook替代指南:五款Windows笔记本与开发环境迁移实战

🚀 30款热门AI模型一站整合,DeepSeek/GLM/Claude 随心用,限时 5 折。 👉 点击领海量免费额度 最近在技术社区和开发者群里,经常看到有朋友在讨论一个话题:手上的老款 Intel MacBook 还能再战几年&#x…

2026/7/4 11:24:15阅读更多 →
基于深度学习的图像真伪检测系统设计与实现

基于深度学习的图像真伪检测系统设计与实现

1. 项目背景与核心价值在数字图像处理领域,虚假图片鉴别技术正成为行业刚需。我最近完成了一个基于深度学习的图像真伪检测系统,这个项目源于实际工作中遇到的几个典型案例:某电商平台商家使用PS合成的产品效果图、社交媒体上经过局部修改的新…

2026/7/4 12:34:21阅读更多 →
基于深度学习的车牌识别系统设计与实现

基于深度学习的车牌识别系统设计与实现

1. 项目概述 这个基于深度学习的车牌识别系统是我在毕业设计期间完成的一个实用项目。作为计算机视觉领域的经典应用场景,车牌识别在实际生活中有着广泛的应用价值,比如停车场管理、交通违章抓拍、高速公路收费等场景。这个项目从零开始完整实现了车牌识…

2026/7/4 12:34:21阅读更多 →
Prompt工程实战指南:从官方教程到企业级应用的核心技巧

Prompt工程实战指南:从官方教程到企业级应用的核心技巧

1. 项目概述:从“会聊天”到“会干活”的跨越 如果你已经玩过ChatGPT,体验过它天马行空的闲聊能力,那么接下来我们要聊的,就是如何让它从一个“有趣的聊天伙伴”变成一个“可靠的业务伙伴”。这中间的桥梁,就是 Promp…

2026/7/4 12:34:21阅读更多 →
旋钮数字显示与语音播报系统设计与实现

旋钮数字显示与语音播报系统设计与实现

1. 项目概述:旋钮数字显示与语音播报系统这个项目本质上是一个通过物理旋钮控制数字显示与语音播报的交互系统。想象一下老式收音机的调频旋钮——当你旋转它时,不仅能看见频率数字的变化,还能听到"正在切换至98.7兆赫"这样的语音反…

2026/7/4 12:34:21阅读更多 →
STC3115与MKV44F256VLH16在BMS中的设计与优化

STC3115与MKV44F256VLH16在BMS中的设计与优化

1. STC3115与MKV44F256VLH16在电池管理系统中的核心作用 在现代电子设备中,电池管理系统(BMS)的重要性不言而喻。STC3115作为一款高精度电池电量监测芯片,与MKV44F256VLH16这款基于ARM Cortex-M4内核的微控制器配合使用,能够构建一套完整的电…

2026/7/4 12:34:21阅读更多 →
STM32矩阵键盘硬件去抖动与中断优化方案

STM32矩阵键盘硬件去抖动与中断优化方案

1. 项目背景与硬件选型解析在嵌入式系统开发中,键盘输入是最基础的人机交互方式之一。2x2矩阵键盘凭借其结构简单、成本低廉的优势,成为许多控制面板的首选方案。但传统矩阵键盘存在两个主要痛点:按键抖动导致的误触发,以及GPIO资…

2026/7/4 12:29:19阅读更多 →
AI Coding 六个月真实ROI账本:产品经理的血泪教训,研发的冷静忠告

AI Coding 六个月真实ROI账本:产品经理的血泪教训,研发的冷静忠告

6个月前的2025年12月,Boris Cherny 公开宣布自己卸载了 IDE。一时间,Vibe Coding 成了全行业最热的话题。6个月后,当我们回过头来拉一份真实账本,发现事情远没有"一句话生成一个App"那么浪漫。本文从产品经理和研发两个…

2026/7/3 14:18:39阅读更多 →
审计来了,数据权限全开——审计走了,怎么确保权限全部关掉?

审计来了,数据权限全开——审计走了,怎么确保权限全部关掉?

引言:审计结束三个月了,审计员的权限还没关某城商行每年按照监管要求开展至少一次数据安全审计。审计期间,内审部门需要抽样检查各类业务数据——交易流水、客户信息、员工操作日志、权限配置记录。这些数据分布在不同系统中,审计…

2026/7/3 14:38:35阅读更多 →
端到端自动驾驶:从GTC‘26看工程可信落地的核心逻辑

端到端自动驾驶:从GTC‘26看工程可信落地的核心逻辑

1. 项目概述:当算法工程师走进GTC26展厅,看到的不是芯片,而是“端到端”的呼吸节奏“端到端”这三个字,在GTC’26现场出现的频率,高得像NVLink带宽测试时的峰值曲线——它不再是一个论文里的技术路径选项,而…

2026/7/4 0:02:48阅读更多 →
缺牙修复科普:常见义齿类型与选择参考

缺牙修复科普:常见义齿类型与选择参考

缺牙修复科普:常见义齿类型与选择参考牙齿缺失是中老年人群中较为常见的口腔问题,不仅会造成咀嚼不便、进食受影响,长期还可能对营养摄入与日常社交带来困扰。义齿是改善缺牙问题的常用方式,目前市面上的义齿种类较多,…

2026/7/4 0:02:48阅读更多 →
STM32F091RC与LTC6904实现高精度方波信号生成

STM32F091RC与LTC6904实现高精度方波信号生成

1. 项目概述:LTC6904与STM32F091RC的精准方波生成方案在嵌入式系统开发中,精确的时钟信号和定时控制往往是项目成败的关键。LTC6904作为一款低功耗、高精度的可编程振荡器芯片,与STM32F091RC这款ARM Cortex-M0内核微控制器的组合,…

2026/7/4 0:02:48阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/4 1:16:56阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/4 2:33:55阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/4 2:33:55阅读更多 →