程序员专属的跨时空浪漫指南:揭秘如何用Three构建动态深空幻境(开源)

342 阅读2分钟

大家好,我是日拱一卒的攻城师不浪,致力于前沿科技探索,摸索小而美工作室。这是2025年输出的第6/100篇文章。

效果预览

星系.gif

前言

技术与艺术的融合是一种跨界的创造力体现,既包含了理性与逻辑的技术,又融入了感性与美学的艺术。

今天给大家带来的是用Three实现的充满艺术细菌的宇宙星系,无需一行shader,纯粒子渲染,完全可以作为产品首页的3D背景,酷炫又拉风。开源地址请文末自取

实现原理

创建星系分支

通过 branches 参数将粒子平均分配到不同的旋臂中,然后使用模运算 i % params.branches 确定每个粒子属于哪个旋臂

螺旋效果

通过 spinAngle 实现螺旋形状,粒子距离中心越远,旋转角度越大,形成螺旋形态。

自然随机性

使用 radialRandomness 参数添加随机偏移,通过极坐标随机化使星系看起来更加自然

视觉效果增强

使用THREE.AdditiveBlending 实现粒子的叠加发光效果,从内到外的颜色渐变通过 lerp 插值实现 使用星形纹理(star.png)使粒子看起来更像真实的星星

主要参数

const params = {
    particleCount: 250000,    // 粒子总数
    particleSize: 0.02,       // 粒子大小
    branches: 6,              // 星系旋臂数量
    branchRadius: 5,          // 星系半径
    spin: 0.2,                // 旋转程度
    radialRandomness: 0.5,    // 径向随机度
    innerColor: '#ff812e',    // 内部颜色
    outerColor: '#a668ff',    // 外部颜色
};

动画效果

const tick = () => {
    requestAnimationFrame(tick);
    geometry.rotateY(0.001 * spinDirection);  // 持续旋转
    renderer.render(scene, camera);
};

核心逻辑

核心代码主要是 generateGalaxy 函数

// 为每个粒子计算位置
const radius = params.branchRadius * Math.random();  // 随机半径
const branchAngle = ((i % params.branches) / params.branches) * Math.PI * 2;  // 确定属于哪个旋臂
const spinAngle = params.spin * radius * Math.PI * 2;  // 计算旋转角度

// 添加随机偏移,使星系看起来更自然
const randRadius = Math.random() * params.radialRandomness * radius;
const { x: randX, y: randY, z: randZ } = getRandomPolarCoordinate(randRadius);

// 计算最终位置
positions[i3] = radius * Math.cos(branchAngle + spinAngle) + randX;
positions[i3 + 1] = randY;
positions[i3 + 2] = radius * Math.sin(branchAngle + spinAngle) + randZ;

// 计算颜色渐变
const mixedColor = innerColor.clone().lerp(outerColor, radius / params.branchRadius);

特殊效果实现

粒子材质设置

material = new THREE.PointsMaterial({
    size: params.particleSize,
    sizeAttenuation: true,     // 远近大小衰减
    depthWrite: false,         // 禁用深度写入
    blending: THREE.AdditiveBlending,  // 叠加混合
    vertexColors: true,        // 启用顶点颜色
    transparent: true,         // 启用透明
    alphaMap: particleTexture, // 使用星星纹理
});

这样会让星系看起来更加真实和绚丽。整个效果通过 requestAnimationFrame 实现持续旋转,创造出动态的星系效果。

最后

【效果预览&开源地址】:z2586300277.github.io/three-cesiu…

如果开源对您有帮助,也欢迎给我们一个免费的star,支持我们开源更多,也是支持国内三维可视化生态发展。

有需要进可视化&Webgis交流群可以加我:brown_7778(备注来意)。