☰
Git City技术栈拆解:Next.js 16 + React Three Fiber + Supabase如何渲染上千栋3D建筑
2026/10/3 3:46:05 网站建设 项目流程

Git City技术栈拆解:Next.js 16 + React Three Fiber + Supabase如何渲染上千栋3D建筑

【免费下载链接】git-cityYour GitHub profile as a 3D pixel art building in an interactive city项目地址: https://gitcode.com/gh_mirrors/gi/git-city

Git City 把每个 GitHub 开发者变成一座 3D 像素建筑,组成一座可自由飞行的互动城市:贡献越多楼越高、仓库越多楼越宽、最近活跃则窗户亮灯。这篇文章拆解它的技术栈——Next.js 16负责页面与 API 路由,React Three Fiber(Three.js)用一次绘制调用渲染上千栋建筑,Supabase承担 PostgreSQL 数据、认证与实时推送。

技术栈分工:三大件各管什么

层技术职责
前端框架Next.js 16(App Router)页面路由、API Routes、SSR 与缓存
3D 渲染Three.js + @react-three/fiber + dreiWebGL 场景、实例化网格、后处理
数据/认证Supabase(PostgreSQL + RLS + Realtime)开发者数据、GitHub OAuth、行级安全
样式Tailwind CSS v4 + Silkscreen 像素字体复古像素风 UI

版本依赖可以在 package.json 中确认:next 16.2.3、@react-three/fiber ^9.5、@supabase/supabase-js ^2.97、three ^0.183。

数据层:Supabase 如何把开发者喂给 3D 城市

城市的数据流是一条清晰的三步管道:

  1. API 聚合:route.ts 这个 Next.js API Route 用Promise.all并行查询developers、purchases、raid_tags等十余张表,把排行榜数据一次取回,并附带Cache-Control: s-maxage=300让 CDN 缓存 5 分钟。
  2. 客户端缓存:cityCache.ts 用模块级单例在页面内导航时保持数据存活,5 分钟过期,避免每次切页都重新拉全城数据。
  3. 双客户端策略:supabase.ts 里浏览器端用 anon key(受行级安全 RLS 约束),服务端写操作用getSupabaseAdmin()走 service role 绕过 RLS——这是 Supabase 项目的标准安全姿势。

数据库共 117 个顺序迁移文件,从 001_initial_schema.sql 到 117_earn_rules_english_descriptions.sql,全部可在supabase/migrations/目录逐条阅读。

渲染核心:InstancedMesh 一次画完上千栋楼

这是整个项目最有学习价值的部分。普通做法是每栋楼一个 React 组件,上千栋意味着上千个 draw call,GPU 直接卡死。Git City 的做法是把几乎所有楼合并进一个instancedMesh:

  • 单一几何体:所有楼共享一个单位立方体SHARED_BOX_GEO,每栋楼靠 instanceMatrix 缩放位移,避免了几百份几何体分配(见 Building3D.tsx 注释)。
  • 自定义 GLSL 着色器:InstancedBuildings.tsx 的顶点着色器为每栋楼附加aUvFront、aTint、aLive等自定义属性,让一栋实例网格也能表现"每楼不同颜色、不同亮灯率、升起动画"。
  • 像素级抠雾:片元着色器对超出雾距的碎片直接discard,省掉不可见楼的片元着色开销。

纹理图集与 LOD:楼各不相同又不爆显存

上千栋楼如果各用一张贴图,显存和纹理单元立刻爆炸。项目用了两张巧牌:

  1. 2048×2048 窗户图集:一整张 Canvas 生成的图集切成 6 个"亮灯率"横带(20%~95%),每栋楼只改变量的 UV 偏移就能拿到独一无二的窗灯图案(Building3D.tsx)。
  2. 空间网格 LOD:CityScene.tsx 维护一个cellSize=200的空间索引,只有靠近相机的楼才挂皇冠、光环、霓虹等特效组件(Building3D.tsx 中的二十余种建筑特效按需装配),远处的楼保持精简几何。

性能模式:GPU 自动检测与动态分辨率

🏃 移动端跑不动 3D 城市怎么办?perfMode.ts 给出了一套完整的自适应方案:

  • 用@pmndrs/detect-gpu把用户 GPU 型号匹配到自托管的基准库(public/gpu-benchmarks/下按 Adreno/AMD/Apple/GeForce/Intel 等厂商分类的 JSON);
  • 检测期间先用内存/CPU 核数启发式猜测,避免首帧白屏;
  • 低端模式下调低 DPR(CityCanvas.tsx 中dpr = lowPerf ? 0.75 : 1.25)并关闭 Bloom 等重后处理;
  • 若加载画面里实测帧率仍低,再自动降级到 low——"实测信号永远胜过跑分"。

主题系统(Midnight/Sunset/Neon/Emerald 四套)与 Bloom、SMAA 后处理同样定义在 CityCanvas.tsx 中,切换主题即切换整套天空、雾、光照与楼体配色。

本地运行 Git City:最快启动方法

无需远程 Supabase 项目,本地即可跑通(详见 README.md):

git clone https://gitcode.com/gh_mirrors/gi/git-city cd git-city && npm install supabase start # 本地拉起 Postgres/Auth/Storage 并应用全部迁移 npm run dev # 打开 localhost:3001

本地未配置 GitHub OAuth 时,点击登录会进入内置 dev 登录页,输入任意用户名即可生成你的楼——这条 route.ts 在生产环境自动禁用。

关键文件速查:从源码继续深挖

想学什么看哪里
实例化渲染 + 自定义着色器src/components/InstancedBuildings.tsx
纹理图集生成src/components/Building3D.tsx
场景组装、后处理、主题src/components/CityCanvas.tsx
空间网格 LODsrc/components/CityScene.tsx
GPU 性能自适应src/lib/perfMode.ts
数据聚合 APIsrc/app/api/city/route.ts
Supabase 双客户端src/lib/supabase.ts
完整数据库演进史supabase/migrations/

🧱 总结:Git City 的性能秘诀不在单点优化,而在分层协作——Supabase 把数据压成一次批量请求,Next.js 用缓存削峰,Three.js 用实例化把上千栋楼压成一次绘制,GPU 检测再把画质适配到每台设备。这套"数据聚合 + 实例渲染 + 自适应画质"的组合拳,是学习大规模 Web 3D 应用非常有价值的完整样本。

【免费下载链接】git-cityYour GitHub profile as a 3D pixel art building in an interactive city项目地址: https://gitcode.com/gh_mirrors/gi/git-city

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询