Skip to content

Samila 散点采样 (Samila Scatter Sampling)

📖 简介

Samila 示例效果图

Samila 散点采样是一种基于函数空间采样的生成艺术形式。其灵感源自 Python 开源库 samila,核心理念是将数学函数 f1(x,y) 和 f2(x,y) 在采样空间中求值,然后将函数输出映射到二维平面上形成散点图。通过在 GPU 上以高达数十万粒子的速度并行采样,利用密度累积和色调映射技术,Samila 能够生成富有层次感、结构精美且色彩丰富的数学艺术图像。

核心能力:

  • GPU 高速渲染:纯 GPU 管线,每帧最大支持三十万粒子同步采样与密度累积
  • 双函数变换系统:自由定义 f1(x,y) 和 f2(x,y) 两个变换函数,支持任意复杂度的数学表达式
  • 26 种生成模式:从纯函数对比到万花筒折叠、漩涡扭曲、余弦调制等丰富的坐标映射方式
  • 6 种地图投影:直角网格、极坐标、Aitoff、Hammer、Lambert、Mollweide 投影任意切换
  • 智能随机方程:基于美感评分收敛的随机方程生成器,一键生成参数搭配合理的动人图案
  • 专业色调映射:完整的亮度、对比度、伽马、动态范围、饱和度控制链,还原丰富的密度层次
  • 调色板系统:支持手动、余弦和曲线三种渐变模式,配合 LUT 纹理实现丰富的色彩表达
  • 完整动画支持:集成参数振荡动画系统和持久参数漂移,支持平滑的周期性变化

Samila 核心概念示意图

🧮 数学背景

什么是 Samila?

Samila 的核心思想简洁而强大:在一个二维采样空间中均匀散布采样点,每个采样点 (x, y) 通过两个变换函数 f1 和 f2 计算出两个输出值,然后根据生成模式将这些输出值映射为平面上的一个散点坐标。当数百万个这样的散点累积叠加时,就形成了具有结构美感的数学图案。

与对称混沌或映射吸引子等迭代动力系统不同,Samila 不追踪粒子状态——每一帧都是对函数空间的全新独立采样。随着时间的推移,累积缓冲区逐渐填满所有可能的屏幕位置,最终呈现出函数空间结构的全貌。

数学模型

给定两个变换函数 f1(x,y) 和 f2(x,y),以及采样范围 [start, stop]:

其中 GenerateMode 决定如何将 (v1, v2, x, y) 四个变量映射到绘图坐标。

生成模式详解

生成模式是 Samila 最具创造力的设计。它决定了哪些数据映射到 x 轴、哪些映射到 y 轴:

模式类别模式名称描述
函数对函数F1 vs F2, F2 vs F1经典模式,展示两个函数的相互关系
函数对坐标F1 vs X, F2 vs X, F1 vs Y, F2 vs Y展示函数值随输入坐标的变化趋势
坐标对函数X vs F1, X vs F2, Y vs F1, Y vs F2展示输入坐标如何影响函数输出
函数乘积F1·F2 vs F1, F1·F2 vs F2, F1 vs F1·F2, F2 vs F1·F2引入非线性耦合,产生更复杂的结构
万花筒Kaleidoscope vs X, X vs Kaleidoscope将 (v1, v2) 极坐标进行扇区折叠,产生对称图案
漩涡Swirl vs X, X vs Swirl极坐标半径扭曲,产生流动的漩涡效果
域扭曲Warp vs X, X vs Warp正弦域扭曲,产生有机的波形结构
余弦调制CosMod vs X, X vs CosMod双频余弦调制,产生几何网格纹理
径向距离Radial vs X, X vs Radial距离的幂函数映射,产生辐射状结构
折叠平铺Fold vs X, X vs Fold周期性折叠,产生平铺的几何纹理

地图投影

投影变换将生成模式的输出坐标重新映射到新的坐标空间:

投影描述最适合场景
Rectilinear直角映射,保持原始坐标不变展示函数的原始结构
Polar极坐标映射:x=θ, y=r产生漩涡和放射状图案,对三角函数特别有效
Aitoff等面积伪方位投影产生球体表面的视觉感受
HammerHammer-Aitoff 等面积投影更紧凑的球体投影效果
Lambert方位等面积投影产生地图般的视觉效果
Mollweide等面积伪圆柱投影产生优雅的椭圆边界

提示:随机生成方程时,系统会根据方程类型自动推荐最优的生成模式和投影。不同组合会产生截然不同的视觉效果,大胆尝试!

随机方程生成的美学原理

Samila 内置的随机方程生成器不同于普通的随机化——它基于美感评分收敛:

  1. 函数分级:三角函数(sin/cos)作为 Tier 1(高美感),因为它们的有界性和周期性是美感基础
  2. 加权选择:sin/cos 被选中的概率是其他函数的 7 倍
  3. 强制三角:两个方程都必须包含至少一个三角函数
  4. 不对称复杂度:f1 和 f2 保持不同的复杂度,避免过度对称导致单调
  5. 参数收敛:参数值控制在 [0.1, 2.5] 范围内,确保图形密度可控
  6. 质量验证:随机采样 8 个点验证方程不会产生极端值或常量输出

🖥️ 界面概览

所有控制项位于右侧的属性面板中,分为六个主要部分:

  1. Geometry(几何):定义变换方程、选择生成模式与投影、调整空间变换
  2. Simulation(模拟):配置采样参数、色调映射和颜色速度
  3. Formulas(公式):显示数学公式和标注
  4. Appearance(外观):调整背景颜色和渐变调色板
  5. Parameters(参数):定义方程中使用的自定义常量

Geometry 面板截图

⚙️ 配置指南

1. Geometry(几何设置)

几何面板是 Samila 的核心控制区,在这里定义数学方程和空间映射规则。

方程定义

  • f1(x,y):第一个变换函数,支持任意复杂的数学表达式

    • 支持运算符:+, -, *, /, ^(幂运算)
    • 支持函数:sin, cos, tan, sinh, cosh, tanh, asin, acos, atan, sqrt, abs, log, exp, round, pow
    • 支持变量:x, y(采样坐标),以及任意自定义参数名(a, b, c, d, e 等)
    • 默认值:sin(x*y)
  • f2(x,y):第二个变换函数,语法与 f1 相同

    • 默认值:cos(x-y)

用法提示:方程中的变量和参数名区分大小写。如果定义了参数 a,需要在 Parameters 面板中添加对应的参数名并设置值。

随机方程按钮

这是 Samila 最令人惊喜的功能。点击"随机方程"按钮,系统会:

  1. 生成一对具有美学质量的随机方程
  2. 自动计算最优的参数组合
  3. 智能推荐生成模式和投影类型
  4. 动态估算输出范围并设置合适的缩放比例

只需一键,就能获得一个完全不同的、视觉效果出色的数学图案。

采样范围

  • Start / Stop:定义采样空间的范围
    • 默认值:[-π, π](从 -3.14 到 3.14)
    • 作用:采样点在这个区间内均匀分布
    • 建议:保持默认的 [-π, π],因为这个范围对三角函数最友好。扩大范围可能会让图案的层次感减弱

生成模式选择

从下拉菜单选择一种生成模式(共 26 种),包含函数对比、万花筒、漩涡、域扭曲等类别。切换模式将立即在画布上呈现不同的视觉效果。

投影选择

从下拉菜单选择一种投影方式。选择 Polar 投影最常用于产生漩涡状的图案,Rectilinear 最适用于展示函数的原始结构。

空间变换

  • Scale X/Y:调整散点图在场景中的水平/垂直缩放

    • 默认值根据方程自动计算适配
    • 增加 Scale 值使图案变大(放大效果)
    • 减小 Scale 值使图案变小(缩小效果)
  • Offset X/Y:调整散点图在场景中的位置

    • 范围:有效 NDC 范围为 [-1, 1]
    • 正值使图案向屏幕右方/上方移动
  • Rotation(旋转):旋转整个散点图(弧度制)

    • 正值逆时针旋转,负值顺时针旋转

提示:Samila 始终为 2D 渲染,Z 轴的缩放和偏移通常不需要调整。


Simulation 面板截图

2. Simulation(模拟设置)

控制采样行为和视觉呈现。Samila 使用纯 GPU 渲染管线,所有计算都在 GPU 上完成。

采样设置

  • Batch Size(批次大小):每帧采样的点数量

    • 默认值:262,144(约 26 万)
    • 作用:决定每帧在采样空间中的采样密度
    • 建议
      • 快速预览:100,000 - 200,000
      • 精细渲染:300,000 - 500,000
      • 高分辨率输出:500,000+
    • 注意:过大的批次大小会消耗更多 GPU 显存
  • Alpha(透明度):每个采样点的透明度

    • 范围:0.0 - 1.0
    • 默认值:0.1
    • 作用:较小的 Alpha 产生更平滑的密度过渡,较大的 Alpha 产生更鲜明的点

色调映射

色调映射是将 GPU 中累积的浮点密度数据转换为屏幕上可见颜色的关键步骤:

  • Brightness(亮度):整体亮度偏移

    • 范围:0.0 - 1.0
    • 默认值:0.5
    • 作用:画面偏暗时增大,画面偏亮时减小
  • Contrast(对比度):密度分布的对比度

    • 范围:0.1 - 2.0
    • 默认值:1.0
    • 作用:增大对比度使亮部更亮、暗部更暗
  • Gamma(伽马校正):非线性亮度映射

    • 范围:0.1 - 10.0
    • 默认值:2.2
    • 作用:控制中间调的亮度。2.2 是标准的 sRGB 伽马值
  • Dynamic Range(动态范围):密度映射范围

    • 范围:0.1 - 1.0
    • 默认值:0.5
    • 作用:较大值保留更多暗部细节,较小值让画面更明亮
  • Saturation(饱和度):颜色鲜艳程度

    • 范围:0.0 - 1.0
    • 默认值:0.8
    • 作用:0.0 为灰度,1.0 为全饱和

颜色设置

  • Color Speed(颜色速度):控制颜色在输出空间的变化速度

    • 默认值:0.22
    • 作用:影响调色板在画面上的色相分布密度
  • Color Phase(颜色相位):调色板的偏移相位

    • 默认值:180.0
    • 作用:旋转调色板的起始位置

拖尾效果

  • Show Trails(显示拖尾):启用拖尾效果

    • 默认开启
    • 作用:开启后,随时间推移旧的密度数据会逐渐衰减,产生动态的拖尾效果
  • Trail Lifetime(拖尾寿命):拖尾持续时长(秒)

    • 默认值:4.0 秒
    • 作用:控制旧密度数据衰减到 1% 所需的时间。数值越小,拖尾消失越快
  • Accumulation Decay(累积衰减):额外衰减系数

    • 范围:0.0 - 1.0
    • 默认值:1.0(不额外衰减)
    • 作用:值小于 1.0 时施加额外衰减,可产生淡出效果

Formulas 面板截图

4. Formulas(公式显示)

在场景中显示数学公式和方程。

主方程显示

  • Show Main Equation(显示主方程):开启/关闭主方程显示

    • 作用:在场景中显示当前的 f1 和 f2 变换方程
    • 自动生成:系统会根据当前方程自动生成 LaTeX 公式
  • 主方程位置和样式

    • X:水平位置坐标
    • Y:垂直位置坐标
    • Scale:公式缩放比例
    • Color:公式颜色

自定义公式

可以添加多个自定义公式到场景中:

  • 添加公式:点击 "Add Formula" 按钮添加新公式
  • 公式内容
    • LaTeX:LaTeX 格式的数学公式
    • X / Y:公式显示位置
    • Scale:公式缩放比例
    • Color:公式颜色
  • 删除公式:点击公式右上角的删除按钮移除

Appearance 面板截图

5. Appearance(外观设置)

背景颜色

  • Background Color:设置渲染背景颜色
    • 深色背景通常能更好地衬托散点图的色彩层次
    • 黑色是最经典的选择

渐变调色板

Samila 使用 1D LUT(查找表)纹理进行着色,支持三种渐变模式:

  • Manual(手动模式)

    • 手动添加、删除和调整颜色节点
    • 支持拖拽重排颜色顺序
    • 四种随机策略:单色、类似色、互补色、分裂互补色
  • Cosine(余弦模式)

    • 使用 IQ 余弦调色板公式:color(t) = a + b · cos(2π(c·t + d))
    • 分别控制 R/G/B 三个通道的偏移、振幅、频率和相位
    • 支持一键随机化和应用
  • Curve(曲线模式)

    • 通过可编辑的贝塞尔曲线分别控制 R/G/B 三个通道
    • 提供最灵活的颜色控制
    • 支持一键随机化和应用

调色板切换提示:切换调色板模式会触发累积缓冲重建,画面会在约 0.5 秒内平滑过渡到新颜色。


6. Parameters(参数设置)

管理方程中使用的自定义参数。

  • 添加参数:在底部的输入框中输入参数名(如 a)和值(如 1.5),点击添加按钮
  • 参数编辑:使用滑块或直接输入数值实时修改参数
  • 删除参数:点击参数行右侧的删除按钮移除参数

重要提示:修改方程结构(添加/删除参数名)需要重新编译着色器,可能有短暂的卡顿。修改参数值不需要重新编译,可以实时热更新。


🎬 动画和时间线

参数振荡动画

Samila 支持参数振荡动画(Parameter Oscillation Animation),可以让参数在指定范围内做周期性正弦振荡。

工作原理

  1. 为每个参数指定振荡的步长(step)、范围(min, max)
  2. 参数值在 [min, max] 范围内做正弦振荡:value = mid + amp · sin(phase)
  3. 振荡速度由步长控制

持久参数漂移

参数动画结束后,振荡不会立即停止——系统会进入持久漂移模式,参数继续以全速振荡变化,直到收到停止指令。这意味着在动画的 wait 阶段,图案仍然在动态演化。

可动画化的参数

所有方程中的自定义参数(a, b, c, d, e 等)均支持动画化。

相机动画

Samila 同样支持标准的相机动画:

  • 旋转:围绕图案旋转相机
  • 对齐:将相机对齐到特定角度
  • 缩放:调整相机距离

配置方法

通过 JSON 配置文件中的 timeline 数组定义动画序列:

json
{
  "timeline": [
    {
      "type": "animate",
      "duration": 15.0,
      "easing": "SINE_IN_OUT",
      "actions": [
        {"method": "rotateTheta", "args": [6.283]}
      ]
    },
    {
      "type": "hold",
      "duration": 2.0
    }
  ]
}

参数动画的配置示例:

json
{
  "timeline": [
    {
      "type": "animate",
      "duration": 8.0,
      "easing": "LINEAR",
      "actions": [
        {
          "method": "paramStart",
          "args": [{
            "parameters": {
              "a": {"enable": true, "step": 0.002, "min": 0.5, "max": 2.5},
              "b": {"enable": true, "step": 0.003, "min": 0.8, "max": 2.0}
            }
          }]
        }
      ]
    },
    {
      "type": "hold",
      "duration": 10.0
    },
    {
      "type": "animate",
      "duration": 2.0,
      "easing": "SINE_IN_OUT",
      "actions": [
        {"method": "paramStop", "args": [{}]}
      ]
    }
  ]
}

🚀 性能与最佳实践

推荐配置

目标Batch SizeAlphaGamma动态范围Dot Size
快速预览50,000 - 100,0000.2 - 0.52.20.50.02 - 0.05
实时交互200,000 - 300,0000.1 - 0.22.20.4 - 0.60.01 - 0.02
高质量图像500,000+0.05 - 0.12.20.3 - 0.50.005 - 0.01

性能优化技巧

  1. Batch Size 调整

    • 降低 Batch Size 是优化性能的最直接方法
    • 高投影复杂度(如 Mollweide)建议使用较小的 Batch Size
  2. 点大小与透明度

    • 较小的 Dot Size 配合较小的 Alpha 可以产生最精细的细节
    • 增大 Dot Size 可以减少达到视觉饱和所需的帧数
  3. 色调映射调优

    • 在 Batch Size 较小时,适当降低 Dynamic Range 让画面更明亮
    • Gamma 值对视觉效果影响显著,2.2 是最佳起点
  4. 使用随机方程

    • 不熟悉数学时,使用随机方程按钮是最快上手的途径
    • 找到喜欢的图案后,可以微调参数进行个性化优化

❓ 常见问题

画面全黑或过暗

问题:渲染结果几乎全黑

原因:密度累积不足或色调映射参数不当

解决方案

  • 增加 Batch Size(如从 26 万增加到 50 万)
  • 增大 Brightness(如从 0.5 增加到 0.8)
  • 减小 Dynamic Range(如从 0.5 减小到 0.3)
  • 减小 Gamma(如从 2.2 减小到 1.5)
  • 等待几秒让密度累积充分

画面全白

问题:渲染结果完全白色

原因:色调映射参数使密度过度明亮

解决方案

  • 减小 Brightness
  • 增大 Dynamic Range
  • 增大 Dot Size 配合减小 Alpha

图案看不出结构

问题:散点图看起来像是随机噪声

原因:方程缺乏周期性或分布过于均匀

解决方案

  • 使用随机方程按钮获取有结构的初始方程
  • 尝试切换生成模式,特别是 F1 vs F2 或 Polar 投影
  • 确保方程中包含三角函数(sin/cos)

修改参数后画面闪烁

问题:修改参数值后画面出现短暂的闪烁或清空

原因:参数变化触发了累积缓冲区的重建(这是正常行为)

解决方案

  • 累积缓冲区在约 0.5-1.0 秒内重新填满
  • 这是为了保证画面与当前参数完全一致的必要步骤

修改方程后没有效果

问题:修改 f1 或 f2 方程后画面没有变化

原因:修改方程需要点击"Apply"按钮编译新的着色器

解决方案

  • 修改方程后点击 Inspector 面板顶部的"Apply"按钮
  • 确认方程语法正确,没有括号不匹配等问题

📐 经典示例

极坐标漩涡图案

f1: sin(a*x*y) + cos(b*x)
f2: cos(c*x+y) + sin(d*y)
生成模式: Kaleidoscope vs X
投影: Polar
参数: a=2.0, b=1.0, c=1.5, d=0.5

Samila 更多效果展示 3

漩涡流动效果

f1: sin(a*x*y) + cos(b*x)
f2: cos(c*x+y) + sin(d*y)
生成模式: Swirl vs X
投影: Polar
参数: a=2.0, b=1.0, c=1.5, d=0.5

Samila 更多效果展示

Hammer 投影效果

f1: sin(a*x*y) + cos(b*x)
f2: cos(c*x+y) + sin(d*y)
生成模式: F1 vs F2
投影: Hammer
参数: a=2.0, b=1.0, c=1.5, d=0.5

Samila 更多效果展示 2


🔧 技术细节

GPU 渲染管线

Samila 使用随机采样 + 密度累积的 GPU 管线(区别于迭代粒子系统):

  1. Splat Pass(采样投射遍)

    • Vertex Shader 通过 PCG Hash 算法内生生成随机采样位置
    • 无需 CPU 上传 VBO 数据,大幅降低 CPU→GPU 带宽消耗
    • 对每个采样点计算 f1 和 f2,然后应用生成模式和投影变换
    • 以 GL_POINTS + 加法混合(GL_ONE, GL_ONE)将粒子投射到累积缓冲
  2. Decay Pass(衰减拷贝遍)

    • 将上一帧的累积缓冲按衰减系数拷贝到当前写缓冲
    • 同时施加密度天花板约束(默认 300),防止高密度区域无限堆积
  3. Present Pass(呈现遍)

    • 对累积密度应用对数色调映射:value = log(density) → brightness
    • 执行完整的色调映射链:亮度 → 对比度 → 伽马 → 动态范围 → 饱和度
    • 使用 Palette LUT 进行空间驱动颜色映射

PCG Hash 随机采样

Samila 的核心创新之一:顶点着色器通过 gl_VertexID ^ u_frameSeed 的 PCG Hash 算法内生生成随机采样位置,无需 CPU 预计算或 VBO 上传。每帧随机种子变化保证逐帧随机性,同时保证了高效性和独立性。

噪声驱动调色板

Samila 在 Vertex Shader 中计算 Simplex 2D 噪声,用于驱动调色板的 U 坐标。由于 GL_POINTS 的所有 fragment 共享相同的 varying 值,噪声计算仅在顶点着色器执行一次(而非每个 fragment 重复计算),极大节省了 GPU 计算资源。

色调映射的自适应缩放

Samila 的色调映射系统自动适应不同的渲染场景:

  • 无衰减模式:使用 √N 增长公式防止密度随时间无限膨胀
  • 有衰减模式(拖尾开启):根据拖尾寿命计算每帧衰减系数,自动匹配稳态密度到合理的亮度范围
  • 天花板限制:密度天花板对标度计算提供上限约束,确保最亮像素不过曝

🎨 创作技巧

探索策略

  1. 从随机方程开始:点击随机方程按钮是最快上手的途径
  2. 切换生成模式和投影:同样的方程在不同的生成模式/投影组合下差异巨大
  3. 微调参数:改变单个参数的值观察图案的连续变化
  4. 尝试自定义方程:熟悉基本模式后,编写自己的数学表达式

视觉调优

  1. 色调映射

    • 先调整 Dynamic Range 让图案整体可见
    • 再调整 Gamma 让中间调细节呈现
    • 最后微调 Brightness 和 Contrast
  2. 着色方案

    • 使用余弦调色板模式快速生成和谐的色彩方案
    • 深色背景配合高饱和度色彩通常效果最佳
    • 调整 Color Speed 和 Color Phase 改变色彩分布密度
  3. 点大小与透明度

    • 小点 + 低透明度 = 极度平滑细腻(适合最终输出)
    • 大点 + 高透明度 = 快速预览图案结构(适合探索阶段)

动画设计

  1. 参数振荡

    • 为不同参数设置不同的振荡速度,创造丰富的动态变化
    • 使用持久漂移效果,让图案在 wait 阶段持续演化
  2. 相机运动

    • 旋转动画是最简单有效的动画形式
    • 注意在动画场景中,单帧会执行 6 轮 splat 以补偿无法跨帧累积的密度损失

⚠️ 注意事项

  1. 方程语法

    • 乘法必须显式写 *a*x 而不是 ax
    • 幂运算使用 pow 函数或 ^ 符号
    • 参数名区分大小写
  2. GPU 显存

    • 过大的 Batch Size 会消耗更多 GPU 显存
    • 累积纹理大小等于视口分辨率,使用 RGBA32F 格式
  3. 累积缓冲重建

    • 修改参数值、方程或调色板会触发累积缓冲重建
    • 重建期间画面约需 0.5-1.0 秒恢复视觉密度
    • 这是正常行为,确保画面始终与当前参数一致
  4. 动画性能

    • 动画场景(参数变化或旋转)中,单帧执行 6 轮 splat 补偿
    • 在动画过程中建议使用较小的 Batch Size 以保持流畅
  5. 参数漂移

    • 参数动画结束后,参数会继续以漂移模式变化
    • 只有在显式调用 paramStop 后才会停止漂移

📚 参考资源

灵感来源

  • Samila Mappings — samila mappings
  • Generative Art: A Practical Guide Using Processing — 生成艺术入门经典

数学参考

软件文档

  • OpenGL 着色器编程指南
  • GLSL 语言规范

All rights reserved.