两款惊艳的 WebGL 开源项目推荐

0 阅读9分钟

作者:柳杉前端
标签:#Three.js #WebGL #开源项目 #游戏开发 #Shader特效

大家好,我是柳杉!今天给大家带来两个极具视觉冲击力的开源项目测评——一个是把经典台球游戏搬进太空的 Cosmic Pool,一个是用纯手写 Shader 打造的 Force Shield VFX。这两个项目分别代表了 WebGL 在游戏和视觉特效领域的巅峰玩法,无论你是想做游戏还是想学 Shader,都值得深入研究!


🎱 项目一:Cosmic Pool —— 太空台球美学巅峰

截屏2026-03-18 18.45.12.png

截屏2026-03-18 18.44.41.png

开源地址: github.com/lespuch-v/c…

项目简介

Cosmic Pool 是一款基于浏览器和 Three.js 的 8 球台球游戏原型。但别被"原型"二字骗了——它把传统台球桌搬进了浩瀚宇宙,用星球取代了普通球,整个视觉风格是太空奢华风 (Space-Luxury),看一眼就让人上头!

技术栈

技术版本/说明
构建工具Vite
语言TypeScript
3D 引擎Three.js
物理引擎自定义台球物理系统
代码规范ESLint

核心玩法测评

1. 拖拽式击球系统

// 核心交互逻辑:鼠标拖拽控制力度和方向
this.interactionController = new GameInteractionController({
  mountElement: this.mountElement,
  // 拖拽时实时计算力度
  strikeCueBall: (direction, shotPower) =>
    this.billiardsWorld.strikeCueBall(direction, shotPower),
  // 精准瞄准模式(按住 Shift)
  precisionAimEnabled: this.interactionController.isPrecisionAimEnabled(),
})

体验点评: 拖拽力度条的设计很直观,按住 Shift 进入精准模式时会降低鼠标灵敏度,这个细节非常贴心。整个击球手感流畅自然,球杆动画跟手性很强。

2. 太空主题视觉系统

项目最核心的亮点在于多层视觉叠加

🌌 星空穹顶 (Cosmic Dome)

// 旋转的星空背景
this.cosmicDome.mesh.rotation.y += delta * 0.0012

⭐ 动态星场 (Starfield)

// 内外双层星场漂移效果
this.starfield.rotation.y += delta * GAME_CONFIG.environment.innerStarfield.driftSpeed.y
this.starfield.rotation.x = Math.sin(elapsedTime * 0.12) * 
  GAME_CONFIG.environment.innerStarfield.driftSpeed.x

🌠 银河系背景 (Milky Way)

台球桌本身也很讲究:

  • 边缘线条带 Bloom 辉光效果
  • 星球球体表面纹理精致(从截图看有类似木星、火星的纹理)
  • 桌布采用深空色系,与环境融为一体

3. 物理引擎实现

项目没有使用现成的物理引擎,而是手写了一套台球物理系统

// BilliardsWorld 核心类
export class BilliardsWorld {
  // 球体碰撞检测
  update(delta: number): void
  // 球袋检测
  consumeEvents(): BilliardsEvent[]
  // 白球放置验证
  previewCueBallPlacement(position: Vector2): boolean
}

包含的物理特性:

  • 球与球的弹性碰撞
  • 球与桌边的反弹
  • 球袋判定(Pocket Detection)
  • 白球自由放置(Cue Ball in Hand)
  • 球体静止检测(Settled Detection)

4. AI 对战系统

CPU 对手的智能度可以调节(简单/普通/困难):

// CPU 决策流程
export interface CpuTurnState {
  currentTurn: 'human' | 'cpu'
  humanGroup: 'solids' | 'stripes' | null
  cpuGroup: 'solids' | 'stripes' | null
}

// AI 找最佳击球路线
const bestShot = findBestShot(balls, rulesState, difficulty)
// 构建安全球策略
const safeShot = buildSafeShot(balls, rulesState)

AI 行为特点:

  • 难度影响口袋容错率和瞄准精度
  • 会主动寻找最佳进球路线
  • 无法进攻时会尝试打安全球
  • 思考时间模拟(1.2秒延迟)

5. 后处理特效管线

// Bloom 辉光效果实现
const BLOOM_LAYER = 1
// 星星和特效启用 Bloom 层
this.starfield.traverse((obj) => obj.layers.enable(BLOOM_LAYER))

// EffectComposer 管线
this.bloomComposer = new EffectComposer(renderer)
this.bloomComposer.addPass(new UnrealBloomPass(/* ... */))
this.bloomComposer.addPass(new SMAAPass(/* 抗锯齿 */))

特效分层处理:

  1. 先渲染需要 Bloom 的物体到单独层
  2. UnrealBloomPass 提取高亮部分
  3. SMAAPass 抗锯齿
  4. OutputPass 输出最终画面

项目架构亮点

src/
├── entities/          # 游戏实体(球、球桌)
├── environment/       # 环境(星空、银河)
├── gameplay/          # 游戏玩法逻辑
├── physics/           # 物理引擎
├── rules/             # 8球规则引擎
├── cpu/               # AI 逻辑
├── effects/           # 特效系统
├── audio/             # 音频管理
└── ui/                # HUD 控制器

设计模式亮点:

  • 状态机模式:InteractionState 管理游戏流程
  • 组件化设计:Ball、Table、CueStick 都是独立实体
  • 观察者模式:BilliardsEvent 事件系统解耦物理与逻辑

可玩性评分

维度评分评价
视觉效果⭐⭐⭐⭐⭐太空主题执行得非常到位
操作手感⭐⭐⭐⭐流畅自然,精准模式加分
游戏性⭐⭐⭐基础规则完整,但内容较浅
代码质量⭐⭐⭐⭐TypeScript + 模块化,结构清晰
学习价值⭐⭐⭐⭐⭐物理引擎实现值得学习

🛡️ 项目二:Force Shield VFX —— 电影级能量盾 Shader

开源地址: github.com/cortiz2894/…

项目简介

这是一个生产级品质的 WebGL 能量盾特效,用纯手写 GLSL Shader 实现。作者 Christian Ortiz 是创意开发领域的顶尖高手,这个项目被设计为学习资源和创作起点,代码注释详尽,架构优雅。

先看效果:

截屏2026-03-18 18.45.44.png

截屏2026-03-18 18.46.19.png

截屏2026-03-18 18.48.23.png

技术栈

技术版本/说明
框架Next.js 16.1 (App Router)
3D 引擎Three.js + React Three Fiber
Shader手写 GLSL (Vertex + Fragment)
后处理@react-three/postprocessing
GUI 控制Leva
样式Tailwind CSS 4

Shader 核心实现解析

1. 六边形网格 (Hex Grid)

能量盾最标志性的特征就是蜂窝状网格:

// 三平面投影 (Tri-planar Projection)
// 从三个轴向投影六边形纹理,避免球面 UV 变形
vec3 hexTriplanar(vec3 pos, vec3 normal, float scale) {
  vec3 xPlane = hexGrid(pos.yz * scale);
  vec3 yPlane = hexGrid(pos.xz * scale);
  vec3 zPlane = hexGrid(pos.xy * scale);
  
  // 根据法线方向混合三个平面
  vec3 weights = abs(normal);
  weights = pow(weights, sharpness);
  weights /= dot(weights, vec3(1.0));
  
  return xPlane * weights.x + yPlane * weights.y + zPlane * weights.z;
}

技术难点: 球面上直接用 UV 映射六边形会产生拉伸变形。三平面投影从 XYZ 三个方向分别投影,然后根据表面法线混合,完美解决这个问题!

2. 菲涅尔发光 (Fresnel Glow)

边缘高亮是能量盾的灵魂:

// 菲涅尔效应 - 视线与法线夹角越大越亮
float fresnel = pow(1.0 - abs(dot(viewDirection, normal)), fresnelPower);
vec3 glowColor = baseColor * fresnel * fresnelIntensity;

3. 流动噪波 (Flow Noise)

// 多层 Simplex 噪波叠加
float flowNoise(vec3 pos, float time) {
  float noise = 0.0;
  float amplitude = 1.0;
  float frequency = 1.0;
  
  for(int i = 0; i < 4; i++) {
    noise += simplexNoise(pos * frequency + time * flowSpeed) * amplitude;
    amplitude *= 0.5;
    frequency *= 2.0;
  }
  return noise;
}

FBM (Fractal Brownian Motion) 分形布朗运动,通过叠加不同频率的噪波创造丰富的表面细节。

4. 受击系统 (Hit System)

这是我最惊艳的部分——最多同时追踪 6 个受击点

// Ring Buffer 存储受击信息
uniform vec3 hitPositions[6];    // 受击位置
uniform float hitTimes[6];        // 受击时间
uniform float hitStrengths[6];    // 受击强度

// 每个受击点产生扩散的噪波环
float calculateHitWave(vec3 worldPos, vec3 hitPos, float time, float hitTime) {
  float elapsed = time - hitTime;
  float distance = length(worldPos - hitPos);
  float waveRadius = elapsed * expansionSpeed;
  
  // 噪波扰动的环形波
  float wave = smoothstep(waveRadius + thickness, waveRadius, distance);
  wave *= smoothstep(waveRadius - thickness, waveRadius, distance);
  wave *= noise(worldPos * 10.0 + elapsed); // 添加噪波扰动
  
  return wave * exp(-elapsed * decayRate); // 随时间衰减
}

效果拆解:

  1. Geodesic Wavefront - 从受击点向外扩散的噪波环
  2. Hex Highlight Zone - 受击点附近六边形格子高亮
  3. Life Damage - 每次受击扣减护盾生命值
  4. 颜色渐变 - 护盾从蓝色渐变为红色表示受损

5. 显隐动画 (Reveal Animation)

// 基于 Simplex 噪波的溶解效果
float dissolveMask = simplexNoise(worldPos * dissolveScale) + (revealProgress * 2.0 - 1.0);
float edgeGlow = smoothstep(0.0, edgeWidth, dissolveMask) * smoothstep(edgeWidth * 2.0, edgeWidth, dissolveMask);

// 边缘发光
if (dissolveMask > 0.0 && dissolveMask < edgeThreshold) {
  emission += edgeColor * edgeIntensity;
}

discard; // 完全溶解的像素丢弃

参数化控制

作者用 Leva 做了完整的 GUI 控制面板,所有视觉属性都可以实时调节

参数类别可调项
网格六边形大小、缝隙宽度、闪烁频率
材质基础色、发光强度、透明度、底部淡出
噪波流动速度、噪波层级、扰动强度
受击波扩散速度、衰减率、六边形高亮范围
生命系统总血量、单次受伤比例、恢复速度
后处理Bloom 强度、阈值、胶片噪点

场景预设 (Presets)

项目提供了两个精心调教的场景预设:

  1. Default - 漂浮的能量球,中性展示场景
  2. Droideka - 星球大战中毁灭者的护盾效果,环绕在机器人模型周围

切换预设会同时修改 Shader 参数、光照设置和相机角度,一键体验完全不同的视觉风格。

代码架构赏析

app/
├── shaders/
│   ├── vertex.glsl      # 顶点着色器
│   ├── fragment.glsl    # 片段着色器
│   └── uniforms.ts      # Shader 参数定义
├── components/
│   ├── ShieldMesh.tsx   # 护盾网格组件
│   └── Scene.tsx        # 3D 场景
├── controls/
│   └── useShieldControls.ts  # Leva 控制器
└── presets/
    ├── default.ts
    └── droideka.ts

架构亮点:

  • Shader 代码完全手写,无外部依赖,学习价值极高
  • 参数与 UI 通过 Leva 绑定,实时调试体验极佳
  • 预设系统方便保存和分享配置

学习价值评分

维度评分评价
视觉效果⭐⭐⭐⭐⭐电影级品质,可直接用于项目
Shader 技术⭐⭐⭐⭐⭐涵盖多个高级技巧
代码质量⭐⭐⭐⭐⭐注释详尽,结构清晰
可扩展性⭐⭐⭐⭐参数化程度高
学习价值⭐⭐⭐⭐⭐最佳 Shader 学习资源之一

🎯 两个项目的对比与选型建议

维度Cosmic PoolForce Shield VFX
核心领域游戏开发视觉特效
技术重点物理引擎、游戏逻辑Shader、图形学
学习难度中等较高
适用场景休闲游戏、原型开发游戏特效、展示页面
亮点完整游戏循环生产级 Shader

你应该选哪个?

选择 Cosmic Pool 如果你:

  • 想学习 Three.js 游戏开发
  • 需要了解物理引擎的实现原理
  • 想做休闲类游戏项目
  • 喜欢太空/科幻主题

选择 Force Shield VFX 如果你:

  • 想深入学习 GLSL Shader
  • 需要炫酷的护盾/能量特效
  • 想了解后处理管线
  • 追求视觉品质

🚀 快速上手指南

Cosmic Pool

# 克隆仓库
git clone https://github.com/lespuch-v/cosmic-pool.git
cd cosmic-pool

# 安装依赖
npm install

# 启动开发服务器
npm run dev

# 打开 http://localhost:5173

Force Shield VFX

# 克隆仓库
git clone https://github.com/cortiz2894/flow-shield-effect.git
cd flow-shield-effect

# 安装依赖(推荐用 pnpm)
pnpm install

# 启动开发服务器
pnpm dev

# 打开 http://localhost:3000

💡 最后的碎碎念

这两个项目代表了 WebGL 领域的两种极致追求

  • Cosmic Pool 证明了用 Web 技术也能做出有品质的 3D 游戏,它的物理引擎实现虽然不如 Cannon.js 完善,但对于台球这种相对简单的场景完全够用。

  • Force Shield VFX 则展示了 Shader 的强大魅力——同样的几何体,通过不同的着色器可以呈现完全不同的视觉效果。作者 Christian Ortiz 的代码风格非常优雅,注释详尽,是学习 Shader 的绝佳素材。

如果你也对 WebGL 感兴趣,强烈推荐:

  1. 先把两个项目跑起来体验效果
  2. 然后啃一遍核心代码
  3. 尝试修改参数,看效果变化
  4. 最后尝试移植到你自己的项目中

希望这篇测评对你有帮助!如果觉得不错,点个在看支持一下~ 🌟


📌 开源地址汇总:

👨‍💻 作者信息:

  • Cosmic Pool: @lespuch-v
  • Force Shield VFX: Christian Ortiz (@cortiz2894)

本文完,感谢阅读!有任何问题欢迎在评论区交流~