从构建一个具有1,000+栋建筑的3D城市渲染器的React Three Fiber教训

我构建了一个将Steam库转换为3D像素艺术城市的Web应用。这个概念受到了Git City的启发,该网站由Samuel Rizzon创建,同样将GitHub资料转换为3D像素艺术城市。 我想将这个想法带到游戏世界并在这个过程中学到了很多。

概念:每个在你的Steam库中的游戏都变成一个建筑物。玩游戏的时间决定了建筑物的高度,库中的游戏数量决定了建筑物的宽度,点亮的窗户代表着你实际上玩过的游戏。

技术挑战:

  1. 1,000栋建筑物的性能:我最初尝试使用LOD(级别细节)和距离基准简化,但它导致了从React re-renders内部的useFrame中出现的可视性异常。最终我只使用了简单的盒子几何体和canvas纹理来表示窗户。结果1,000个盒子形状的基本材料在没有任何优化技巧的情况下运行得很好。

  2. 霧效和可见的天空物体:Three.js中的霧效会根据距离使所有物体都淡化到背景色中。然而,我需要在天空中看到太阳和月亮,但霧效却把它隐藏了起来。解决方案是禁用霧效在白天,并将天空中的物体放置在天空的边缘而不是上方。

  3. 日夜循环与SSR:useState(true)用于isNight,在静态生成期间(UTC)在服务器上运行,所以用户最初总是看到夜间模式。通过使用懒加载器来解决这个问题。

  4. 仿真城市的布局:螺旋布局看起来太过均匀了。换成了块状网格系统(每个块包含2x2栋建筑物和街道之间的街区),从上方看起来更像是一个真正的城市。

  5. 相机自旋:将autoRotate添加到OrbitControls中可以在没有人交互时让场景有生命。这个小细节对第一印象有着重要的影响。

技术栈:Next.js 15,React Three Fiber,drei,Supabase,Tailwind v4

如果你想在实时环境中查看它:https://thesteamcity.com

如果你有任何关于R3F设置或建筑物生成逻辑的问题,我很愿意回答。