MiaAInow

老电视质感,代码算出来

老电视亮起、调台、放出一段夏夜录像。没有一张图片,每个像素的颜色都是着色器当场算的,提示词在下面。

夏夜萤火 · 老电视

下载 HTML 文件全屏打开 ↗
夏夜萤火 · 提示词
用 WebGL2 写一个单独的 HTML 文件,做一段 15 秒、1920×1080 的视频画面:一台九十年代的显像管电视,放着一段 1996 年夏夜的家庭录像。
画面里不要任何图片和素材,所有东西都用着色器(GLSL)现算。

时间线:
- 0–0.55 秒:开机。先是一个亮点拉成一条横线,再上下展开成整屏。
- 0.55–2 秒:没有信号,满屏雪花,一道暗带慢慢往下滚。
- 2–2.9 秒:调台。每一行左右撕开、画面上下滚动,然后稳定下来。
- 2.9–13.7 秒:夏夜池塘。月亮(带月晕、薄云)、两边高中间低的松树林(一格一棵、高矮随机的三角形)、地平线上的薄雾、水面是上面世界的倒影加波纹再压暗、月光在水面碎成一条路。
  520 只萤火虫:用 gl.POINTS 画,每只的位置只由「编号 + 时间」决定(不记上一帧),一闪一闪 = max(0, sin)^8,近大远小、近处虚。第 8 秒起一道同步闪光从左往右扫过去。萤火虫也要在水里有倒影。
  镜头从天上慢慢摇下来,同时推近 10%。
- 13.7–14.15 秒:关机。画面先压成一条横线,再收成一个亮点消失。

画面分层,从下往上,每层都能单独开关(window.setup({particles, bloom, film, crt})):
1. 场景 → 渲到浮点贴图(亮度允许超过 1,月亮约 2.5)。
2. 粒子:叠加混合画到场景上。
3. 发光:抠出亮的地方 → 缩小到 1/2、1/4、1/8 各做一次高斯模糊 → 加回原图。
4. 胶片:高光压缩、暗部偏青亮部偏暖、颗粒(每个小格一个随机数,按帧号算,一秒换 24 次)、整格轻微晃动、暗角、偶尔一道竖划痕。
5. 老电视:弧面(离中心越远往外推得越多)、扫描线(sin,一行亮一行暗)、每 3 个像素一组红绿蓝荧光点、红绿蓝三色错开一点的色散、轻微闪烁、慢慢滚过的电源干扰暗带、圆角边框、玻璃反光。
录像机屏显(「CH 03」「PLAY ▶」、右下角「PM 9:47:12 / JUL. 14 1996」走秒)用 Canvas 2D 画好当贴图叠进去。

要求:
- 提供 window.render(t):给一个秒数就同步画出那一帧,所有会动的东西(颗粒、闪烁、波纹、萤火虫)只跟 t / 帧号走,不跟电脑的真实时间走。
- getContext('webgl2', { preserveDrawingBuffer: true }),方便逐帧截图。
- 随机数用 Dave Hoskins 的 hash12,别用简单的 fract(p*常数) 那种,在整数格子上会出斜纹。
- 再写一个 Playwright 脚本:逐帧调用 render(t)、截图、用 ffmpeg 拼成 MP4(30 fps)。没有显卡也要能跑(Chromium 会自动用 SwiftShader)。
- 再用 numpy 合成声音:开机的「嘭」、雪花沙沙声、调台的扫频、虫鸣和水声、一层很轻的和弦、同步闪光时一串上行铃音、关机的「咻」和最后一下咔。

不要:所有东西都发光、紫粉霓虹配色、居中大字淡入淡出、弹跳缓动。先给我 0.5、1.2、2.4、6、9、14 秒六张静帧看构图,确认了再拍视频。