程序化绘制能力记录 PROCEDURAL DRAWING NOTES
CAPABILITY NOTES · 2026

程序化绘制
能力记录

记录「二十四节气 · 一纸山河」中真正用到的程序化绘制能力:哪些对象比较稳定、分别是怎么画的、边界在哪里,以及下一次如何直接复用。

目录 / CONTENTS

记录「二十四节气 · 一纸山河」中实际使用到的程序化绘制能力:哪些对象比较稳定、分别是怎么画的、边界在哪里。

相关页面:二十四节气主页面 · 程序化绘制能力库 · 本次工作说明

可交互版本:程序化绘制能力库,含 40 个母题的实时预览、参数与源码。

记录时间:2026-10-21


#0. 先明确“稳定”是什么意思

这里的“稳定”不是指“每次都能一次画成”,而是:

在这套低饱和、纸本水墨、二维剪影式插画的风格里,给定 1–3 轮截图反馈(个别对象会更多),能比较可靠地得到一个可识别、可复用、不会明显崩坏的结果。

它依赖三个前提:

  1. 允许风格化:不要求照片级写实,也不要求植物学、动物学、建筑学上的精确复原。
  2. 有明确的母题:画山、雨、荷叶、灯笼,比画“任意复杂场景”容易得多。
  3. 有构图和配色托底:同样的线条,放在合适的留白、纸色和主色里,观感会显著提升。

因此,这份记录描述的是 二维程序化插画能力,不是“什么都能画”的通用图像生成能力。


#1. 能力分层

层级 典型对象 当前表现 主要限制
稳定 山、水、日月、云雨雪、草、芦苇、柳、麦穗、荷叶、菊花、飞鸟、蝉、蜻蜓、房屋、灯笼、渔船、石桥、露珠、霜、冰裂 可稳定生成风格化版本 不追求写实和精确解剖
中等 特定物种的精确复原、人物剪影、复杂建筑、复杂动物姿态、真实光影材质 需要参考和更多迭代 容易“像但不够准”
较弱 人脸、手、复杂表情、写实人物、复杂机械、照片级材质、复杂多角色互动 不适合作为主能力 程序化拆解成本高,且容易失真

这张表是“当前这套代码 + 这套风格”的边界,不是理论上永远做不到。换 3D、骨骼、贴图、着色器或 AI 辅助,边界会变化。


#2. 稳定对象与绘制思路

#2.1 背景基底:纸、天空、山、水

纸感

  • 做法:Canvas 铺低饱和纸色渐变,再叠 CSS 内联 SVG feTurbulence 噪点,最后加暗角和极细边框。
  • 关键:纸色不是纯色,通常从偏亮的顶部过渡到更接近主色的底部;颗粒透明度很低,只负责“去塑料感”。
  • 代码:paintBackground、纸纹 index.html。
  • 注意:颗粒是浏览器滤镜生成的,不是我逐点画的;它属于“内置噪声”,不是外部图片。

天空/背景

  • 做法:一条线性渐变 + 一个大范围径向色晕。
  • 参数:纸色、主色、色晕中心、色晕半径、透明度。
  • 作用:先把画面从“白底”变成有空气感的纸面,再往上放山、云、主体。

山脊

  • 做法:多组正弦波叠加出轮廓,填充线性渐变,再描一条低透明度山脊线。
  • 公式直觉:
    y = y0 + sin(x * f1 + s1) * a1
          + sin(x * f2 + s2) * a2
          + sin(x * f3 + s3) * a3
    
  • 分层:远山浅、低对比;中山略深;近山更深、更贴近纸色。3 层就足够产生纵深。
  • 代码:ridge。
  • 局限:只能做“山形轮廓”,不能做具体岩石、植被和真实地质结构。

水面

  • 做法:以地平线为界,画一条从半透明主色到更浅纸色的竖直渐变;再叠若干水平短线或椭圆涟漪。
  • 动效:涟漪用不断扩大的椭圆环;水纹用低透明度横线。
  • 代码:ripples,水面渐变在各场景函数中内联。
  • 局限:不是流体模拟,没有真实反射、折射和波纹交互。

雾/云气

  • 做法:横向的线性渐变带,中间透明度高、两端透明;或大范围径向渐变。
  • 参数:雾带高度、颜色、透明度、位置。
  • 代码:haze。
  • 作用:分隔山层、柔化边界、制造“空气透视”。

#2.2 天体与天气

太阳

  • 做法:径向渐变圆盘 + 外层径向光晕 + 可选同心细环。
  • 参数:半径、颜色、光晕强度、光环数量、透明度。
  • 代码:orb。
  • 变化:春分用暖金,夏至用朱砂,大暑用焦橙,立冬用几乎融入纸面的淡日。
  • 局限:是图形化的太阳,不是物理天空模型。

月亮

  • 做法:径向渐变圆盘 + 外部光晕 + 内部低透明度“陨石坑”圆斑;需要弯月时,用接近纸色的圆盘遮住一部分。
  • 代码:moon。
  • 注意:弯月本质上是“遮罩”,不是精确的月相几何;在深色场景里效果更自然。

云

  • 做法:多个重叠椭圆 + 透明度 + 可选 blur,先铺大团,再补边缘小团。
  • 代码:cloud。
  • 经验:深色场景不要用“浅色墨 + 纸色”去混云色,容易越混越亮;应显式给暗色云团。
  • 局限:是“云雾团块”,不是有体积、有自阴影的云。

雨

  • 做法:基于种子伪随机的粒子;每个粒子有 x、y、速度、长度、透明度;绘制成带轻微倾角的线段,按时间循环。
  • 代码:rain。
  • 参数:数量、颜色、透明度、速度、角度、长度。
  • 局限:没有碰撞、积水、风场变化;只是视觉雨幕。

雪

  • 做法:与雨类似,但用圆点;部分大颗粒叠加三根短线做成六角雪花;x 方向加正弦漂移。
  • 代码:snow。
  • 参数:数量、大小、速度、是否画六角、透明度。
  • 局限:雪不会堆积,也没有真实的湍流。

风

  • 做法:两到三组贝塞尔曲线,随时间改变控制点和透明度,形成“风扫过”的线。
  • 代码:windCurves。
  • 作用:让静态画面产生方向感和季节感,尤其适合立秋、清明、小满。

涟漪

  • 做法:以中心为原点,绘制不断增大、逐渐变淡的椭圆环;用 flat 参数压扁成水面透视。
  • 代码:ripples。

热浪

  • 做法:多条水平折线,每条线的 y 加正弦扰动;越往下透明度越低。
  • 代码:heatWaves。
  • 作用:小暑、大暑的“空气在抖动”的感觉。

#2.3 植物

草

  • 做法:一根从根部到叶尖的二次贝塞尔曲线,随时间轻微摆动;多个草叶通过 grassPatch 成组生成。
  • 参数:高度、弯曲方向、宽度、颜色、透明度、随机种子。
  • 代码:grassPatch、单根草叶在场景中内联。
  • 局限:是剪影草,不是有叶脉和厚度的真实草叶。

芦苇 / 芦花

  • 做法:弯曲主茎 + 两片细叶 + 顶部的羽状穗;穗由多根从中心向外发散的细线组成,分深色轮廓和浅色高光两层。
  • 代码:基础芦苇 reeds,白露用的羽状芦苇 plumeReed。
  • 参数:高度、倾斜、穗长、颜色、透明度、种子。
  • 局限:不是植物学精确的芦花结构,但远看辨识度足够。

柳

  • 做法:一根三次贝塞尔主枝 + 沿线取点的小叶;叶子用旋转的椭圆/叶形,左右交替,形成垂坠感。
  • 代码:willowStrand。
  • 参数:长度、方向、弯曲、叶密度、叶色、种子。
  • 经验:叶子太密会像珠帘;减少柳条数量、拉开间距、把叶子做成成组小叶,会更自然。

麦穗

  • 做法:弯曲茎 + 一片软叶 + 穗头;穗头由一列交替倾斜的窄椭圆“麦粒”组成,再加几根麦芒。
  • 代码:wheat。
  • 参数:高度、倾斜、麦粒数量、茎色、穗色、种子。
  • 局限:不是精确的禾本科结构,但能表达“麦浪”和“小满”的意象。

荷叶

  • 做法:一个带缺口的圆,压扁成椭圆透视;从中心向外的放射状叶脉;填充径向渐变。
  • 代码:lotusLeaf。
  • 参数:半径、缺口角度、旋转、压扁比例、叶色、叶脉色。
  • 作用:立夏、大暑的主要水面母题。

荷花 / 花苞

  • 做法:多层尖卵形花瓣围绕中心旋转排列;花苞用更少、更闭合的花瓣。
  • 代码:lotusBud,荷花在场景中组合。
  • 局限:是风格化荷花,不是精确的莲属植物结构。

牡丹

  • 做法:4 层左右的花瓣,从外到内逐渐变小、变深;每片花瓣是一个宽而圆的贝塞尔形状;中心加少量金色花蕊。
  • 代码:peonyPetal、peony。
  • 参数:花瓣层数、每层数量、长度、宽度、旋转偏移、外/中/内色。
  • 经验:花瓣太尖会像莲花,太宽会像向日葵;牡丹的关键是“宽、圆、层叠、花心小”。

菊花

  • 做法:5 层细长花瓣,每层数量不同、旋转偏移不同;花瓣有轻微侧弯,中心和内层颜色更深。
  • 代码:chrysanthemum。
  • 参数:5 层花瓣的长度、宽度、数量、弯曲、颜色。
  • 经验:这是本次迭代最多的花。太细像蒲公英,太宽像向日葵,最后才找到“多层宽花瓣 + 小中心”的平衡。

银杏

  • 做法:扇形贝塞尔外轮廓 + 中央缺口 + 从叶柄放射的叶脉;叶柄单独画线。
  • 代码:ginkgoLeaf。
  • 参数:半径、旋转、颜色、透明度。
  • 局限:小尺寸时容易像蝴蝶或心形,需要配合树枝和尺寸层级使用。

桃花 / 梅花

  • 做法:递归枝条 + 五瓣小花;花瓣是五个旋转的椭圆,中心一个小圆点;枝条用二次贝塞尔并递归分叉。
  • 代码:peachBranch、plumBranch、blossom。
  • 参数:递归深度、枝长、分叉角度、花色、花心色、种子。
  • 局限:不是精确的蔷薇科花结构,但五瓣 + 枝干已经足够识别。

竹子

  • 做法:弯曲主竿 + 横向竹节 + 从节点分出的侧枝 + 成组的披针形竹叶 + 叶面雪线。
  • 代码:bambooLeaf,大雪场景中的竹竿和侧枝在场景函数中组合。
  • 参数:竿高、倾斜、竹节数量、叶长、叶宽、雪线宽度。
  • 经验:竹叶不能太大太散,否则像纸片;要成组挂在枝节上。

柿子

  • 做法:径向渐变圆 + 顶部四/五瓣花萼 + 高光 + 细果柄;叶子用叶形函数。
  • 代码:persimmon。
  • 参数:半径、果色、叶色、花萼色。
  • 局限:是剪影式果实,不是有真实表皮质感的柿子。

芦苇/莲蓬/其他

  • 莲蓬:椭圆顶面 + 锥形身体 + 七个暗色种子孔 + 弯曲茎,见 lotusPod。
  • 草叶、花瓣、叶片:基本都用贝塞尔或椭圆,组合方式比单个形状更重要。

#2.4 动物

飞鸟

  • 做法:两条弯曲的翅膀笔画 + 小身体 + 分叉尾,远看像中国画里的墨鸟。
  • 代码:distantBird。
  • 经验:早期用完整填充剪影,结果像蝙蝠;改成两笔式后,小尺寸下反而更像鸟。

蝉

  • 做法:透明的翅膀路径 + 翅脉 + 分节腹部 + 头胸 + 六条腿;翅膀用低透明度渐变和描边。
  • 代码:cicada。
  • 参数:身体色、翅膀色、角度、大小。
  • 局限:是风格化蝉,不是精确的蝉科解剖。

蟋蟀

  • 做法:细长腹部 + 折叠翅膀 + 头和触角 + 折叠后腿;整体侧视。
  • 代码:cricket。
  • 经验:早期版本腿太直、身体太圆,像蜘蛛;后来把后腿折起来、身体拉长,才像蟋蟀。

蜻蜓

  • 做法:细长身体 + 两对透明翅膀 + 头部 + 分节腹部;翅膀用椭圆 + 旋转 + 低透明度。
  • 代码:dragonfly。
  • 作用:立夏、芒种、小暑的点睛元素。

喜鹊

  • 做法:身体椭圆 + 头部 + 长尾 + 白色腹部 + 白色肩斑 + 腿和爪 + 喙。
  • 代码:magpie。
  • 经验:黑白对比和长尾是识别关键;早期版本像企鹅,补上尾巴和腿后改善。

白鹭

  • 做法:椭圆身体 + S 形脖子 + 细腿 + 长喙 + 翅膀线;用深色描边保证在白纸背景上可见。
  • 代码:egret。
  • 局限:是剪影式涉禽,不是精确的鹭科结构。

甲虫

  • 做法:椭圆鞘翅 + 头部 + 六条腿 + 触角 + 中缝线 + 高光。
  • 代码:beetle。
  • 作用:惊蛰的“苏醒昆虫”母题。

#2.5 人造物

房屋

  • 做法:2.5D 小屋:正面墙 + 侧面墙 + 斜屋顶 + 雪顶 + 门 + 窗 + 烟囱 + 炊烟 + 屋檐冰凌。
  • 代码:house。
  • 参数:大小、墙色、屋顶色、窗光色、炊烟色。
  • 经验:雪顶要和纸色拉开一点冷灰差,否则在雪景里会消失;窗户要用暖色,才有“有人居住”的感觉。

灯笼

  • 做法:椭圆灯笼身 + 上下盖 + 竖向/椭圆肋线 + 内部暖光 + 挂绳 + 流苏 + 外发光。
  • 代码:lantern。
  • 经验:挂绳长度必须和树枝位置对齐,否则灯笼会像悬空;本体要做出肋线,才不只是一个橙色圆球。

渔船

  • 做法:船体用两段二次贝塞尔收出船头和船尾 + 船板线 + 坐姿渔翁 + 斗笠 + 鱼竿 + 鱼线 + 鱼漂 + 小船灯 + 水面倒影。
  • 代码:fisherBoat。
  • 经验:船的识别关键是“两端翘起”的轮廓;渔翁的斗笠和钓线是叙事核心。

石桥

  • 做法:半圆弧桥拱 + 桥面横线 + 栏杆竖线 + 低透明度倒影;在清明场景里再叠加撑伞小人。
  • 代码:清明场景内联,见 index.html。
  • 局限:是二维剪影桥,不是有砖石结构的建筑。

#2.6 微元素与氛围

露珠

  • 做法:小径向渐变球 + 左上高光点 + 轻微透明边缘。
  • 代码:dew。
  • 作用:白露、寒露的关键细节,数量不需要多,点状高光就能表达“露”。

流萤

  • 做法:径向光晕 + 小亮点 + 时间脉冲 + 正弦漂浮。
  • 代码:fireflies。
  • 作用:处暑夜景的主要动效。

霜

  • 做法:递归分叉的细线,模拟霜晶;在叶缘、地面、果面上少量叠加。
  • 代码:frostBranch。
  • 局限:是二维霜纹,不是真实的冰晶生长模拟。

冰裂

  • 做法:递归分叉线,每次分叉缩短、降低透明度。
  • 代码:iceCrack。
  • 作用:大寒、立冬的冻土/冰面纹理。

雾气/水汽

  • 做法:低透明度线性渐变带 + 局部径向渐变。
  • 代码:haze。
  • 作用:把前后景分开,增加空气感。

#3. 为什么这些对象能稳定画出来

#3.1 可以拆成少量图元

这些对象基本都能还原成:

  • 圆 / 椭圆;
  • 三次或二次贝塞尔曲线;
  • 多段线;
  • 线性/径向渐变;
  • 低透明度叠色;
  • 重复 + 旋转 + 缩放。

不需要复杂的 3D 网格、物理模拟或真实材质。

#3.2 剪影识别优先于细节

在纸本水墨风格里,观众先认出轮廓,再注意细节:

  • 荷叶先看“圆 + 缺口”;
  • 麦穗先看“细长穗头”;
  • 蝉先看“透明翅膀 + 分节身体”;
  • 渔船先看“两端翘起的船体”;
  • 灯笼先看“椭圆 + 挂绳 + 流苏”。

所以代码优先把剪影做对,再补叶脉、翅脉、肋线等细节。

#3.3 低细节容忍度高

风格化插画允许“像”而不是“精确”:

  • 芦苇不需要每一根穗都符合植物学;
  • 山不需要真实地质;
  • 云不需要体积渲染;
  • 鸟不需要解剖级准确。

这给程序化绘制留下了很大空间。

#3.4 参数化程度高

同一套函数可以通过参数复用:

  • 大小、位置、旋转;
  • 颜色、透明度;
  • 种子、数量、层数;
  • 弯曲方向、长度、宽度。

24 个场景不是 24 套完全不同的画法,而是同一套绘图词汇的不同组合。

#3.5 可以截图反馈

这些结果不是“盲写”出来的。实际流程是:

写代码 → headless Chromium 渲染 → 截图 → 读取截图 → 找问题 → 调参数 → 再截图

例如:

  • 鸟像蝙蝠 → 改成两笔式墨鸟;
  • 寒露的花像蒲公英 → 重新设计花瓣层次;
  • 冬至灯笼悬空 → 对齐挂绳和树枝;
  • 深色场景树枝发白 → 改用显式深色;
  • 大寒雪堆像煎蛋 → 改成寒江独钓。

没有截图反馈,稳定度会明显下降。


#4. 通用绘制套路

如果要把一个新对象加入这套系统,可以按这个顺序:

  1. 先画剪影:只用一个颜色,确认远看能认出是什么。
  2. 拆 2–4 层:主体、暗部、亮部、细节;不要一开始就画很多线。
  3. 加主色和辅色:从所属节气的 paper / ink / accent / accent2 里取色。
  4. 加纹理:叶脉、翅脉、竹节、灯肋、冰裂等,只加 1–2 种。
  5. 加动效:只让 1–2 个部分动,例如柳条摆动、翅膀轻颤、流萤呼吸。
  6. 截图检查:看小尺寸是否还能识别,看和相邻场景是否风格一致。
  7. 参数化:把大小、颜色、角度、种子抽出来,方便复用。

一句话:

剪影优先、层次少量、颜色克制、细节点到为止、动效只动局部。


#5. 不稳定或做不到的对象

对象 为什么难 可能改善方式
人脸、手、复杂表情 需要精确解剖和微妙比例;程序化拆解成本高 参考图 + 3D 基础 + 手工修正
写实人物、复杂姿态 骨骼、肌肉、布料、透视相互耦合 骨骼系统、动作捕捉、3D 模型
特定物种的精确复原 需要植物学/动物学结构知识 真实参考、标本图、专业建模
复杂建筑、机械 结构、材质、透视、细节层级复杂 CAD/BIM、3D、纹理贴图
照片级材质 需要真实光照、反射、粗糙度、次表面散射 PBR、着色器、渲染器
多角色复杂叙事 构图、遮挡、动作、表情同时变化 分镜 + 3D + 合成
精确复刻某张具体作品 风格、笔触、构图、色彩关系高度依赖参考 专门研究 + 人工绘制/训练
复杂手写字/书法 需要字形结构和笔势 字体、书法字库或人工书写

#6. 如果想继续提升

  • 参考图驱动:给每个对象准备 2–3 张参考,先确定剪影和比例,再写代码。
  • 3D 基础 + 2D 风格化:用简单 3D 模型确定透视和光影,再在 Canvas 里描线。
  • 骨骼/参数化系统:给人物、动物加关节和姿态参数,避免每次都硬编码。
  • 着色器/材质:如果允许 WebGL,可以做更真实的纸、墨、雾、光。
  • L-system / 分形:适合树枝、竹叶、霜花、藤蔓。
  • 纹理贴图:如果不再要求“无外部资源”,可以用授权的纸纹、墨迹贴图提升质感。
  • AI 辅助:可用于概念参考、局部素材生成,但需要额外解决风格一致性和版权问题。

#7. 与本次交付的关系

  • 24 个节气的数据在 index.html。
  • 24 个场景函数在 index.html。
  • 公共绘图函数在 index.html。
  • 渲染循环与 5 秒计时在 index.html。
  • 纸张颗粒在 index.html。
  • 文字字形来自系统字体,不是程序化绘制;这是本记录中唯一需要单独说明的“非代码图形”来源。

#8. 结论

这套作品证明的是:

在明确的风格约束下,常见的二维场景元素可以被拆成少量图元,通过参数化组合和截图反馈,稳定地程序化绘制出来。

但它不等于“任意素材都能画”。稳定的是:

  • 有清晰剪影的自然元素;
  • 重复结构明显的植物;
  • 低细节容忍度的动物剪影;
  • 简单的人造物;
  • 天气、雾、露、霜、冰裂等氛围元素。

不稳定的是:

  • 高精度人物;
  • 复杂解剖;
  • 写实材质;
  • 多角色复杂叙事;
  • 必须精确复刻的参考对象。

理解这个边界,比笼统地说“AI 会画画”更有用。