2025 年 5 月 7 日:
- 文章探讨用 WebGL 和 GLSL 着色器重现 iPhone 动画,涵盖图形编程基础概念,如写简单片段着色器、利用对称性提升性能、用透明度合成等。
动画剖析:iOS 中 AirPods 听力测试动画由 3328 个小渐逝点组成,用 WebGL 可利用 GPU 多核绘制,先从少点开始。简化表示保留原动画视觉风格和结构,先画单个点,再利用径向对称性创建重复径向图案,最后处理重叠半透明元素并让点移动。
- 画单个点:WebGL 中片段着色器 per-pixel 运行一次,决定像素颜色,这里用简单常量颜色并改变像素不透明度。通过计算像素到原点距离,若小于半径则不透明,否则透明,可利用
length()
和step()
内置函数优化代码,还可通过全局输入参数uRadius
改变点的大小,可在 CodePen 中实验get_opacity()
的不同实现。 - 移动点:比较位置向量长度与半径可画原点的点,要画不在原点的点,将像素位置减去实际中心坐标,可通过
uv - vec2(uShift, 0.)
实现,若需画更复杂形状可参考 Inigo Quilez 的 2D 距离函数。
- 画单个点:WebGL 中片段着色器 per-pixel 运行一次,决定像素颜色,这里用简单常量颜色并改变像素不透明度。通过计算像素到原点距离,若小于半径则不透明,否则透明,可利用
- 利用模运算符免费重复图案:利用径向对称性,用
mod()
运算符可使图案重复而无需循环,以简化计算工作于极坐标,通过theta
和rho
描述位置,用mod()
可使图案随theta
重复,如重复径向渐变和径向重复点,还可通过slice_ix
索引切片来改变点的不透明度。 - 水平重复点:考虑沿水平轴的切片,可用
mod
运算符重复点的图案,但存在点不融合和溢出的问题,对于透明点无法像处理不透明点那样用常数时间解决,需计算每个点的不透明度并考虑其他重叠点。 - 合成重叠点:通过光子穿过多层材料的例子说明计算重叠点透明度的方法,即总透明度为 1 减去各层透明度的乘积,实现时可通过循环计算每个点的透明度并相乘,注意 GLSL 在 WebGL 中对动态控制流支持有限,如
nSideDots
需为编译时常量。 - 最终结果与结论:将各部分组合,添加运动,处理用户交互留作练习,可尝试改变颜色等,若喜欢文章可订阅更新,还可了解更多 WebGL 和 JavaScript 相关内容,如 SKÅPA 应用和设置 WebGL 着色器颜色的方法。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。