2026-09-07 / 6 min

因为喜欢奶蛙,所以做了一个 3D 网页

从喜欢一个角色开始,把模型、粒子、声音和滚动体验串成一次完整的网页技术练习。

个人练习Three.jsWebGL交互设计

起点其实很简单

我喜欢奶蛙。有一天突然想拿它锻炼一下技术,于是开始做这个网页。

一开始我只想把一个 3D 模型放到浏览器里,让它能被看见、被旋转。做到模型能正常出现以后,我又想试试粒子:如果把模型拆开,网页还能不能保留它原来的辨识度?粒子散开以后,用户能不能用指针把它推开,再看着它慢慢回到原来的形状?

这件事没有一开始想得那么大,但每完成一层,就会自然地多出下一层。最后它从一个模型展示,变成了一条有章节、有声音、有滚动关系的完整体验。

我做了什么

奶蛙角色不是我创建的。网页里的 3D 模型是我自己制作的,参考了网络公开图片。这个说明对我来说很重要:我是在借喜欢的角色练习建模和网页图形,不是在重新定义角色归属,也不把参考资料做成公开素材包。

网页的主体是一只可以观察、旋转和解构的 3D 奶蛙。滚动时,它会从完整形体进入粒子状态,再在后面的章节里释放到更大的空间。标题、背景线条、说明文字和粒子变化跟着同一条滚动进度走,所以页面不是一组互相独立的动画。

最难的是粒子交互

粒子数量多起来以后,最容易出现两个问题:画面看起来很热闹,但交互没有重量;或者交互有反馈,性能却开始不稳定。

我最后把问题拆成了几部分。模型表面先被采样成粒子初始位置,粒子位置放进缓冲区,持续变化交给 shader。指针移动时,先判断是否命中模型或粒子场,再把影响范围、方向和速度传给粒子系统。粒子被排斥以后,不是立刻跳回原点,而是根据回归强度逐步收束,这样释放和回归才会像同一个过程的两个方向。

粒子数量也没有写死。桌面端和移动端使用不同预算,并且根据设备像素比限制渲染分辨率。对我来说,自适应不是单纯“低端设备少画一点”,而是先保证角色轮廓、释放动作和指针反馈,再把多余预算留给细节。

从效果到体验

单独看模型、粒子、滚动、声音,每一项都不算陌生。真正让我觉得这次练习完成了的,是它们终于能互相解释:模型为什么会变成粒子,粒子为什么在这个章节释放,声音为什么只在用户主动操作之后出现,滚动为什么能把这些变化连起来。

我给页面安排了四个阶段:ORIGIN、SOFT、STILL 和 RELEASE。它们不是四个页面,而是同一条体验的四个状态。向下滚动时状态展开,向上滚动时状态也可以收回,尽量不让动效变成一次性的播放。

这次练习留下的东西

我最喜欢的部分不是某一个单独的视觉效果,而是终于把“喜欢一个角色”转成了一个可以完整走完的网页。模型、材质、粒子、交互、声音和性能都各自有技术问题,但最后需要一起服务于同一个感受。

如果把它只看成一次 Three.js 练习,当然可以列出很多实现细节;但对我来说,它首先是一次很私人、很具体的练习:因为喜欢奶蛙,所以愿意把一个突然冒出来的想法继续做下去。

项目说明:NAIWA / 奶蛙。

技术记录: