Three.js 地球粒子教程
地球粒子 ·Globe Particle· ▶ 在线运行案例案例合集三维可视化功能案例threehub.cn开源仓库github地址https://github.com/z2586300277/three-cesium-examples400个案例代码:网盘链接你将学到什么ShaderMaterial 自定义着色器实现核心视觉效果EffectComposer 多 Pass 后期处理管线UnrealBloomPass 辉光 Bloom 效果OrbitControls 相机轨道交互THREE.Points 粒子点渲染BufferGeometry 自定义顶点/索引数据requestAnimationFrame渲染循环与resize自适应效果说明本案例演示地球粒子效果原场景渲染后经 EffectComposer 叠加 Bloom/模糊等全屏后期核心用到 ShaderMaterial、EffectComposer、UnrealBloomPass。建议先打开文首在线案例查看动态画面再对照下方源码逐步理解。核心概念Scene / Camera / WebGLRenderer构成最小渲染闭环大场景可开logarithmicDepthBuffer缓解 Z-fighting。ShaderMaterial通过uniforms 自定义 GLSL 控制逐像素/逐点效果透明粒子常配合depthTest: false。EffectComposer以多 Pass 链式渲染RenderPass → 特效 Pass → 输出屏幕替代直接renderer.render。OrbitControls提供轨道旋转/缩放开启enableDamping后需在 animate 中controls.update()。实现步骤搭建 Scene、PerspectiveCamera、WebGLRenderer挂载 canvas 并处理resize定义 uniforms / onBeforeCompile 或 ShaderMaterial编写 GLSL 与材质参数组装 EffectComposer Pass 链在 animate 中调用composer.render()创建 OrbitControls及 Raycaster 等交互控件若源码包含在requestAnimationFrame循环中更新状态并 renderCesium 为viewer.render或自动渲染代码要点import * as THREE from three;import { OrbitControls } from three/addons/controls/OrbitControls.js; import { EffectComposer } from three/addons/postprocessing/EffectComposer.js; import { RenderPass } from three/addons/postprocessing/RenderPass.js; import { ShaderPass } from three/addons/postprocessing/ShaderPass.js; import { UnrealBloomPass } from three/addons/postprocessing/UnrealBloomPass.js; import { GammaCorrectionShader } from three/addons/shaders/GammaCorrectionShader.js;const scene new THREE.Scene(); scene.background new THREE.Color(0x020209); scene.fog new THREE.Fog(0x020209, 15, 60);const camera new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.z 6;const renderer new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(window.innerWidth, window.innerHeight); renderer.setPixelRatio(window.devicePixelRatio); renderer.toneMapping THREE.ACESFilmicToneMapping; renderer.toneMappingExposure 1.2; document.getElementById(box).appendChild(renderer.domElement);const ambientLight new THREE.AmbientLight(0x333366, 0.8); scene.add(ambientLight);const directionalLight new THREE.DirectionalLight(0xffffcc, 1.2); directionalLight.position.set(1, 3, 2); scene.add(directionalLight);const pointLight new THREE.PointLight(0x3366ff, 2, 10); pointLight.position.set(0, 0, 0); scene.add(pointLight);const composer new EffectComposer(renderer); const renderPass new RenderPass(scene, camera); composer.addPass(renderPass);const bloomPass new UnrealBloomPass( new THREE.Vector2(window.innerWidth, window.innerHeight), 1.2, 0.7, 0.5 ); composer.addPass(bloomPass);const gammaCorrectionPass new ShaderPass(GammaCorrectionShader); composer.addPass(gammaCorrectionPass);const controls new OrbitControls(camera, renderer.domElement); controls.enableDamping true; controls.dampingFactor 0.1; controls.rotateSpeed 0.5; controls.minDistance 3; controls.maxDistance 15; controls.autoRotate true; controls.autoRotateSpeed 0.5;controls.addEventListener(start, () { document.body.style.cursor grabbing; controls.autoRotate false; });controls.addEventListener(end, () { document.body.style.cursor grab; setTimeout(() { controls.autoRotate true; }, 3000); });const numParticles 30000; const geometry new THREE.BufferGeometry(); const positions new Float32Array(numParticles * 3); const colors new Float32Array(numParticles * 3); const sizes new Float32Array(numParticles); const speeds new Float32Array(numParticles);for (let i 0; i numParticles; i) { if (i numParticles * 0.8) { const phi Math.acos(-1 (2i) / (numParticles0.8)); const theta Math.sqrt(numParticlesMath.PI)phi; const radius 1.8 Math.random() * 0.4; const x Math.sin(phi)Math.cos(theta)radius; const y Math.sin(phi)Math.sin(theta)radius; const z Math.cos(phi) * radius; positions[i * 3] x; positions[i * 3 1] y; positions[i * 3 2] z; } else { const angle Math.random()Math.PI2; const radius 2 Math.random() * 3; const height (Math.random() - 0.5) * 2; positions[i3] Math.cos(angle)radius; positions[i * 3 1] height; positions[i3 2] Math.sin(angle)radius; }const distance Math.sqrt( positions[i3]* 2 positions[i3 1]* 2 positions[i3 2]* 2 );let color; if (distance 1.5) { color new THREE.Color(0x4466ff); } else if (distance 2.5) { color new THREE.Color(0x9944ff); } else { color new THREE.Color(0xff44aa); }color.offsetHSL(0, (Math.random() - 0.5)0.3, (Math.random() - 0.5)0.2); colors[i * 3] color.r; colors[i * 3 1] color.g; colors[i * 3 2] color.b;sizes[i] distance 2 ? 0.05 Math.random()0.04 : 0.03 Math.random()0.03; speeds[i] 0.4 Math.random() * 0.6; }geometry.setAttribute(position, new THREE.BufferAttribute(positions, 3)); geometry.setAttribute(color, new THREE.BufferAttribute(colors, 3)); geometry.setAttribute(size, new THREE.BufferAttribute(sizes, 1));const particleMaterial new THREE.ShaderMaterial({ uniforms: { time: { value: 0 }, pixelRatio: { value: window.devicePixelRatio } }, vertexShader:attribute float size; uniform float time; uniform float pixelRatio; varying vec3 vColor; void main() { vColor color; float pulse 1.0 0.2 * sin(time position.x position.z); vec4 mvPosition modelViewMatrix * vec4(position, 1.0); gl_PointSize sizepulsepixelRatio * (300.0 / -mvPosition.z); gl_Position projectionMatrix * mvPosition; }, fragmentShader:varying vec3 vColor; void main() { float distanceToCenter length(gl_PointCoord - vec2(0.5)); if (distanceToCenter 0.5) discard; float alpha 1.0 - smoothstep(0.4, 0.5, distanceToCenter); gl_FragColor vec4(vColor, alpha); }, transparent: true, vertexColors: true, depthWrite: false, blending: THREE.AdditiveBlending });const particleSystem new THREE.Points(geometry, particleMaterial); scene.add(particleSystem);window.addEventListener(resize, () { camera.aspect window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); composer.setSize(window.innerWidth, window.innerHeight); particleMaterial.uniforms.pixelRatio.value window.devicePixelRatio; }, false);renderer.domElement.addEventListener(dblclick, () { camera.position.set(0, 0, 6); camera.lookAt(0, 0, 0); controls.reset(); });const clock new THREE.Clock();function animate() { requestAnimationFrame(animate); const delta clock.getDelta(); const elapsedTime clock.getElapsedTime(); particleSystem.rotation.y delta * 0.05; particleMaterial.uniforms.time.value elapsedTime; particleSystem.scale.x 1 Math.sin(elapsedTime0.3)0.05; particleSystem.scale.y 1 Math.sin(elapsedTime0.4)0.05; particleSystem.scale.z 1 Math.sin(elapsedTime0.5)0.05; controls.update(); composer.render(); }animate();完整源码GitHub小结本文提供地球粒子完整 Three.js 源码与在线 Demo建议先运行案例再改 uniform/参数做二次实验更多 Three.js 实战案例见 three-cesium-examples 合集 与 GitHub 开源仓库

相关新闻

Tiva™微控制器外设就绪与浮点异常处理机制详解

Tiva™微控制器外设就绪与浮点异常处理机制详解

1. 项目概述与核心价值在嵌入式系统开发,尤其是基于ARM Cortex-M内核的微控制器项目中,我们常常会面临两个看似基础却至关重要的挑战:如何确保在操作一个外设(比如ADC、PWM)之前,它已经完全准备好接受指令&…

2026/7/22 11:25:51阅读更多 →
影刀RPA 离职管理自动化:账号回收与权限清理

影刀RPA 离职管理自动化:账号回收与权限清理

影刀RPA 离职管理自动化:账号回收与权限清理 作者:林焱 什么情况用什么 员工离职是信息安全的高风险窗口期。HR办完离职手续后,IT要在24小时内禁用所有账号——AD域、邮箱、VPN、OA、CRM、GitLab、Jira、企业微信、堡垒机……少则七八个、多…

2026/7/22 11:25:51阅读更多 →
Cursor编程助手:从通用模型到专业开发伙伴的工程化实践

Cursor编程助手:从通用模型到专业开发伙伴的工程化实践

1. 从通用模型到专业编程助手的进化路径 当第一次打开Cursor时,你可能以为这只是一个普通的代码补全工具。但当你看到它能自动重构整个代码库、修复复杂bug、甚至根据设计稿生成完整页面时,就会意识到这背后是一套完全不同的技术架构。Cursor的核心创新在…

2026/7/22 11:25:51阅读更多 →
Rust构建轻量级世界杯CLI工具的技术实践

Rust构建轻量级世界杯CLI工具的技术实践

1. 项目概述:当Rust遇上世界杯数据 去年用Java写的世界杯数据查询工具终于迎来了彻底重构——这次我们选择了Rust作为技术栈,配合自研的TeaQL数据引擎,打造了一个仅7MB大小的命令行交互程序。这个看似简单的工具背后,其实藏着不少…

2026/7/22 12:15:57阅读更多 →
Skynet框架源码解析与服务器开发实战

Skynet框架源码解析与服务器开发实战

1. Skynet框架概述与源码学习价值 Skynet是一个轻量级的游戏服务器框架,采用C语言编写核心模块,通过Lua脚本实现业务逻辑。这个设计使得它在保持高性能的同时,又具备足够的灵活性。我第一次接触Skynet是在开发一个实时对战游戏时,…

2026/7/22 12:15:57阅读更多 →
2026论文AI工具避雷排行榜❗4大类工具真实排名,双检翻车原因终于找到了

2026论文AI工具避雷排行榜❗4大类工具真实排名,双检翻车原因终于找到了

很多同学论文延毕,不是写得差,是工具选错了。 2026年高校统一开启知网/维普查重 AIGC人工智能检测双向审核,不同论文工具的通过率差距直接拉爆。 为了让大家不踩坑,本次按照 「双检安全性、学术合规度、功能实用性、学生性价比…

2026/7/22 12:15:57阅读更多 →
嵌入式视频稳定技术:FMV平滑与IIR滤波在实时处理中的核心原理与工程实践

嵌入式视频稳定技术:FMV平滑与IIR滤波在实时处理中的核心原理与工程实践

1. 项目概述与核心挑战在嵌入式视频处理领域,无论是手持手机拍摄生活Vlog,还是运动相机记录极限瞬间,甚至是安防摄像头进行长时间监控,一个共同的“天敌”就是画面抖动。这种由人手或设备震动引入的非期望运动,不仅影响…

2026/7/22 12:15:57阅读更多 →
高通QCC3040与QCC3056耳机芯片对比:蓝牙音频、ANC降噪与TWS方案解析

高通QCC3040与QCC3056耳机芯片对比:蓝牙音频、ANC降噪与TWS方案解析

说到蓝牙耳机,大家首先想到的往往是听歌、通话、看视频、打游戏。但真正决定一款耳机是否“好用、好听、好连”的,往往是耳机内部的音频主控芯片。在中高端 TWS真无线耳机、挂脖耳机、头戴式耳机方案中,高通QCC3040 与 高通QCC3056 长期是市场…

2026/7/22 12:15:57阅读更多 →
频谱分析仪维修中最容易被误判的故障:本底噪声升高就是硬件坏了吗?

频谱分析仪维修中最容易被误判的故障:本底噪声升高就是硬件坏了吗?

频谱分析仪的灵敏度由本底噪声决定。在使用几年后,很多用户发现仪器的本底噪声比以前高了,第一反应是硬件老化需要频谱分析仪维修。但本底噪声升高不一定等于硬件故障。本底噪声的构成频谱仪的本底噪声由两部分组成:前端低噪声放大器的热噪声…

2026/7/22 12:13:57阅读更多 →
Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/22 0:53:59阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/22 0:53:59阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/22 0:53:59阅读更多 →
中小企业小程序开发公司怎么选:预算、上手和售后避坑指南

中小企业小程序开发公司怎么选:预算、上手和售后避坑指南

中小企业做小程序,最常见的矛盾是预算有限,但又不希望功能太单薄;没有技术团队,但又希望后续能自己运营;想快速上线,又担心隐性收费和售后失联。选型时如果只看“低价套餐”或“案例数量”,很容…

2026/7/22 0:01:17阅读更多 →
GEO优化如何沉淀长期内容资产?广拓时代谈AI搜索时代的内容ROI

GEO优化如何沉淀长期内容资产?广拓时代谈AI搜索时代的内容ROI

企业做营销,最怕钱花完了,资产没有留下。 效果广告能带来一段时间的曝光,但预算停止后,流量往往也随之停止。短视频内容可能在几天内冲高,也可能很快沉下去。AI搜索时代,企业需要重新思考一个问题&#xff…

2026/7/22 0:01:17阅读更多 →
Agent 终态判定:何时该停止思考、给出最终回复

Agent 终态判定:何时该停止思考、给出最终回复

Agent 终态判定:何时该停止思考、给出最终回复 一、你的 Agent 在"再想想"的循环里绕了 12 轮,用户已经关窗口了 Agent 与人最大的区别是:人知道什么时候该停下来给答案,Agent 会一直"想"下去。你给 Agent 接…

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

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

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

2026/7/21 22:53:50阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

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

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

2026/7/21 18:53:30阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

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

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

2026/7/21 18:53:30阅读更多 →