改作实验

雨林瀑布 · 二十四小时

在经典调色循环作品上尝试连续昼夜、天气与 HD-2D 光效。

创作与来源

像素画
Mark Ferrari
CanvasCycle 与 BlendShift 引擎
Joseph Huckaby

实验记录:机制与算法

本次改作放弃了直接的图层切换,转而在 Canvas 的调色板底层注入了连续插值与叠加算法,以确保光影在二十四小时的任意刻度均能平滑自洽。以下是供复现参考的核心机制。

1. 昼夜周期的线性插值

将一天映射为浮点数 t0t<240 \le t < 24),并设立三个基准关键帧:晨(t=8.0)、午(t=14.0)、夜(t=22.0)。引擎在每一帧获取所处区间的两个关键帧颜色 c1c_1c2c_2,按时间比例 ratio 进行线性过渡:

clear[ch] = c1[ch] + (c2[ch] - c1[ch]) * ratio;

注:为避免塔楼灯光在插值时出现半透明伪影,发光像素利用了掩膜隔离,仅在夜间区间独立亮起;彩虹亦被剥离至离屏画布,按时间权重无痕淡出。

2. 雨滴的环境叠加

原图的雨点是画师在特定的背景色(如岩石、树叶)上涂抹的亮斑。直接参与插值会让雨滴带着白昼的底色在夜间发光。为了解开这种绑定,算法引入了基准底色映射:

先以原本的环境底色为基准,提取出纯粹的反光增量,再将其以叠加模式(Additive Blending)附着在当前的实时环境色上:

// 1. 提取雨水反光增量
const delta = Math.max(0, c_rain[ch] - base_rain[ch]);
// 2. 附着于实时环境底色
target[ch] = Math.min(255, Math.floor(c_bg[ch] + delta));

如此,无论底色怎样因时间推移而变暗,雨滴都能自然贴合。

3. 太阳雨的阈值处理

有了上一步的光度增量,只需简单的数学映射即可模拟出太阳雨(晴空骤雨)。

阴雨天中,雨滴通常带着柔和、长距的雾化拖尾以模拟漫反射;而在强烈的阳光直射下,水滴如同微小的透镜,雾化感消散,取而代之的是极度锐利刺眼的高光折射。算法通过对增量引入阈值扣除与乘数放大,呈现了这一物理特征:

// 阈值扣除(剔除柔弱的雾化拖尾)乘数放大(激发出短促、刺眼的阳光折射)
delta[ch] = Math.max(0, delta[ch] - 15) * 1.8;

经过这一计算,原本柔和绵长的雨丝,便化作了短促锐利的晶莹水滴。

4. 混合分辨率与光晕管线

为保留原图 8-bit 的锐利边缘,前述所有的像素运算均被限制在原始的 640×480 离屏画布中进行,随后关闭平滑抗锯齿,直接投射至高清主屏。

由于高分屏下实时滤镜(Bloom)会导致帧率骤降,这里的解法是引入额外的极小画布进行下采样模糊:

// 极低分辨率模糊
bloomCtx.filter = 'blur(2px)';
bloomCtx.drawImage(offCanvas, 0, 0);
// 滤色叠加至高清主屏
ctx.globalCompositeOperation = 'screen';
ctx.globalAlpha = 0.35;
ctx.drawImage(bloomCanvas, 0, 0, cw, ch);

最后铺陈一层正片叠底的暗角,算是完成了现代光晕与旧式像素的相互交融。

这是一次基于原有素材与开源引擎的技术实验,非原作者作品。

怎么玩

启动后可以在选项里调整时间、天气、声音、调色循环速度和混合方式。声音默认关闭;浏览器只有在你主动开启后才会播放环境音。

作品边界

像素画来自 Mark Ferrari;网页调色循环引擎来自 Joseph Huckaby。这里展示的是我在两者基础上完成的技术与视觉实验。原作图像与引擎代码具有不同的权利边界,转载或再利用时请分别核对原作者说明。