Skip to content

映射吸引子 (Map Attractor)

简介

alt text 映射吸引子将迭代映射(Iterated Map)转化为高密度的视觉艺术。通过在 GPU 上并行迭代数以十万计的粒子,利用密度累积(Density Accumulation)和色调映射(Tone Mapping)技术,你可以创造出具有极高视觉精细度的吸引子图像——这正是 Clifford 吸引子、Peter de Jong 吸引子等经典映射吸引子的标准渲染方式。

说明:从独立链路版本开始,Map AttractorSymmetry Chaos 在场景与运行时更新入口上已分离。两者共享点密度渲染内核,但各自维护独立配置与调优路径,避免跨场景耦合。

核心能力:

  • GPU 高性能渲染:纯 GPU 管线,支持数十万粒子并行迭代与密度累积
  • 迭代映射系统:支持 2D 和 3D 映射方程,y_next 可引用 x_next 的计算结果
  • 专业色调映射:内置亮度、对比度、伽马、动态范围、饱和度等完整的色调控制链
  • 步长度量着色:基于粒子每步移动距离的着色方式,揭示吸引子的运动特征
  • 完整动画支持:集成参数振荡动画系统,支持参数的平滑周期性变化

数学背景

什么是映射吸引子?

映射吸引子(又称迭代映射吸引子)是一类离散动力系统。与奇异吸引子(由微分方程定义的连续系统)不同,映射吸引子通过迭代函数直接计算下一步的状态:

与奇异吸引子的关键区别:

特性奇异吸引子映射吸引子
系统类型连续(微分方程)离散(迭代映射)
迭代方式数值积分(欧拉法等)直接函数计算
渲染方式粒子拖尾密度累积
典型代表Lorenz, RosslerClifford, Peter de Jong

映射方程的级联计算

映射吸引子的一个重要特征是方程之间的级联依赖关系:

  1. x_next 仅依赖当前状态 (x, y, z) 和自定义参数
  2. y_next 可以引用 x_next(也可写作 nx),即 y 的计算可以利用 x 的新值
  3. z_next(3D 模式)可以引用 x_next/nxy_next/ny

这种级联设计使得映射吸引子能够表达更丰富的动力学行为。

经典示例

Clifford 吸引子(2D):

x_next = sin(a * y) + c * cos(a * x)
y_next = sin(b * x) + d * cos(b * y)
参数:a = -1.7, b = 1.8, c = 1.6, d = 0.9

Peter de Jong 吸引子(2D):

x_next = sin(a * y) - cos(b * x)
y_next = sin(c * x) - cos(d * y)
参数:a = -2.24, b = 0.43, c = -0.65, d = -2.43

3D 映射吸引子

x_next = sin(a * y) + c * cos(a * x)
y_next = sin(b * x) + d * cos(b * y)
z_next = sin(e * x) + f * cos(e * z)

界面概览

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

  1. Geometry(几何):定义映射方程和空间变换
  2. Parameters(参数):定义方程中使用的自定义常量
  3. Simulation(模拟):配置迭代属性、色调映射和着色参数
  4. Camera(相机):控制观察视角
  5. Formulas(公式):显示数学公式和标注
  6. Apperance(外观):调整背景颜色等渲染参数

配置指南

1. Geometry(映射方程)

这里定义系统的迭代映射函数。

映射方程

  • x_next:计算下一个 x 值的映射方程

    • 支持变量x, y, z(当前状态坐标)以及自定义参数
    • 示例sin(a * y) + c * cos(a * x)
  • y_next:计算下一个 y 值的映射方程

    • 支持变量x, y, z, x_next(或 nx)以及自定义参数
    • 级联引用:可以在 y_next 中引用 x_next 的计算结果
    • 示例sin(b * x) + d * cos(b * y)
  • z_next(仅 3D 模式):计算下一个 z 值的映射方程

    • 支持变量x, y, z, x_next/nx, y_next/ny 以及自定义参数
    • 级联引用:可以引用 x_next 和 y_next 的计算结果
    • 示例sin(e * x) + f * cos(e * z)
  • 支持函数sin, cos, tan, asin, acos, atan, sinh, cosh, tanh, sqrt, abs, log, ln, log10, exp, floor, ceil, round, sign, pow, min, max, atan2

空间变换

  • Scale X/Y/Z:调整吸引子在场景中的大小
  • Offset X/Y/Z:调整吸引子在场景中的位置
  • 提示:不同的映射方程产生的数值范围差异巨大。使用 Scale 将其调整到合适的相机视野内

2. Parameters(自定义参数)

建议不要在方程中硬编码数字,而是在这里定义命名参数。

  • 添加参数:创建如 a, b, c, d 这样的变量
  • 使用方法:在 Geometry 面板的方程中直接使用这些变量名
  • 实时调节:在播放过程中修改这些数值,可以动态演变吸引子的形状
  • 优势
    • 方便调整和实验
    • 支持参数振荡动画
    • 提高配置的可读性和可维护性

3. Simulation(模拟设置)

控制系统的迭代行为和视觉呈现。映射吸引子使用纯 GPU 渲染管线,没有 CPU/GPU 模式切换。 模拟设置

维度选择

  • 2D / 3D:选择映射吸引子的维度
    • 2D 模式:仅使用 x_next 和 y_next 方程,z_next 自动设为 0
    • 3D 模式:使用全部三个方程,支持三维空间中的吸引子结构
    • 注意切换维度时,z_next 方程会被重置。从 3D 切换到 2D 时 z_next 将被清空,从 2D 切换到 3D 时 z_next 默认设为 z

迭代设置

  • Batch Size(批次大小):并行迭代的粒子数量

    • 作用:决定每帧参与计算的粒子总数
    • 默认值:262,144(约 26 万)
    • 建议
      • 简单映射(如 Clifford):100,000 - 500,000
      • 复杂映射:50,000 - 200,000
    • 注意过大的 Batch Size 会消耗大量 GPU 显存,可能导致渲染卡顿
  • Iterations Per Frame(每帧迭代次数):每渲染帧中执行的映射迭代次数

    • 范围:1 - 16
    • 作用:控制吸引子密度累积的速度
    • 建议:通常设为 1 即可;增大此值可以更快地填充吸引子
  • Burn-In Steps(预热步数):在绘制第一帧之前预先迭代的步数

    • 作用:将粒子从初始位置引导至吸引子轨道上
    • 建议:至少 50 步,避免初始随机分布造成的视觉突兀

初始范围

  • X₀ Min / X₀ Max:粒子初始 x 坐标的范围
  • Y₀ Min / Y₀ Max:粒子初始 y 坐标的范围
    • 默认值:[-1.0, 1.0]
    • 提示:初始范围的选择会影响预热效果。对于吸引子位于较大范围的映射,可能需要扩大初始范围

密度与色调映射

映射吸引子使用密度累积 + 色调映射的渲染管线,这是生成高质量映射吸引子图像的核心技术。

  • Accumulation Decay(累积衰减):控制历史密度数据的保留程度

    • 范围:0.0 - 1.0
    • 默认值:1.0(完全保留)
    • 作用:值为 1.0 时密度完全累积;降低此值会使旧的密度逐渐衰减,产生"淡出"效果
    • 建议:保持 1.0 以获得完整的吸引子图像;降低至 0.9-0.99 可观察参数变化时的过渡效果
  • Brightness(亮度):整体亮度偏移

    • 范围:-0.5 - 1.5
    • 默认值:0.3
    • 作用:调整累积密度的整体亮度
  • Contrast(对比度):密度分布的对比度

    • 范围:0.1 - 2.0
    • 默认值:1.0
    • 作用:增强或减弱密度分布的明暗对比
  • Gamma(伽马校正):非线性亮度映射

    • 范围:0.1 - 10.0
    • 默认值:2.2
    • 作用:控制中间调的亮度。较大的值使暗部细节更明显,较小的值使亮部更突出
    • 建议:2.2 是标准的 sRGB 伽马值,适合大多数场景
  • Dynamic Range(动态范围):密度映射的动态范围

    • 范围:0.1 - 1.0
    • 默认值:0.2
    • 作用:控制密度到亮度的映射范围。较小的值使吸引子更明亮,较大的值保留更多暗部细节
  • Saturation(饱和度):颜色饱和度

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

步长度量着色

步长度量(Step Metric)是映射吸引子特有的着色方式,它根据粒子每步移动的距离来分配颜色。

  • Step Metric Min / Max:步长度量的归一化范围

    • 作用:将粒子每步的移动距离映射到 [Min, Max] 范围内进行着色
    • 建议
      • Min 通常设为 0.0
      • Max 根据吸引子的特征调整,典型值 1.0 - 3.0
    • 注意Max 必须大于 Min,系统会自动保证 Max ≥ Min + 0.001
  • Color Speed(颜色速度):颜色循环的速度

    • 范围:0.1 - 2.0
    • 默认值:0.22
    • 作用:控制颜色在调色板中的循环频率
  • Color Phase(颜色相位):颜色循环的起始相位

    • 范围:0.0 - 360.0
    • 默认值:180.0
    • 作用:偏移颜色映射的起始位置,相当于旋转调色板
  • Invert(反转):反转亮度

    • 作用:将亮色与暗色互换,产生底片效果
    • 适用场景:深色背景上的亮色吸引子 ↔ 浅色背景上的暗色吸引子

4. Camera(相机控制)

调整观察视角和相机参数。

相机角度

  • Phi(俯仰角):相机的垂直角度

    • 范围:0 到 π(0 到 180度)
    • 默认值:π/2(90度,水平观察)
  • Theta(偏航角):相机的水平角度

    • 范围:0 到 2π(0 到 360度)
    • 默认值:0
  • Gamma(滚转角):相机的旋转角度

    • 范围:0 到 2π(0 到 360度)
    • 默认值:0

使用技巧

  • 2D 吸引子:通常使用正上方俯视(Phi = 0 或 π)或水平观察(Phi = π/2)
  • 3D 吸引子:通过调整 Phi 和 Theta 从不同角度观察三维结构
  • 动画效果:结合时间线系统创建相机旋转动画

5. Formulas(公式显示)

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

主方程显示

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

    • 作用:在场景中显示当前映射吸引子的迭代方程
    • 自动生成:系统会根据当前方程和参数自动生成 LaTeX 公式
  • 主方程位置

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

自定义公式

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

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

动画和时间线

参数振荡动画

映射吸引子支持参数振荡动画(Parameter Oscillation Animation),这是一种独特的动画方式,可以让参数在指定范围内做周期性正弦振荡。

工作原理

参数振荡动画通过 MapAttractorParameterAnimator 实现:

  1. 为每个参数指定振荡的步长(step)、范围(min, max)和边沿缓动(edge easing)
  2. 参数值在 [min, max] 范围内做正弦振荡:value = mid + amp * sin(phase)
  3. 振荡速度由步长和步长缩放因子(step scale)共同控制
  4. 边沿缓动确保参数接近范围边界时减速,避免突变

动画类型

  • StartMapAttractorParamAnimation:启动参数振荡动画

    • 可以为单个参数启动,也可以为所有参数同时启动
    • 启动时步长缩放从 0 渐增到 1,实现平滑过渡
    • 配置参数:
      • paramName:参数名称(为 null 时作用于所有参数)
      • step:振荡步长(正值正向振荡,负值反向振荡)
      • min:振荡范围下限
      • max:振荡范围上限
      • duration:启动过渡时长
      • edgeEasing:边沿缓动配置
  • StopMapAttractorParamAnimation:停止参数振荡动画

    • 步长缩放从当前值渐降至 0,实现平滑停止

可动画化的特殊参数

除了自定义参数外,以下系统参数也支持动画化:

  • colorSpeed:颜色循环速度
  • colorPhase:颜色相位偏移

相机动画

映射吸引子同样支持标准的相机动画:

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

配置方法

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

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

性能与最佳实践

推荐配置

目标Batch Size迭代/帧预热步数伽马动态范围
高质量图像500,000+1200+2.20.15-0.25
实时交互100,000-200,0001-250-1002.20.2-0.3
参数探索50,000-100,0001502.20.2

性能优化技巧

  1. Batch Size 调整

    • 降低 Batch Size 是最直接的性能优化手段
    • 复杂方程(含多个三角函数)建议使用较小的 Batch Size
  2. 色调映射调优

    • 增大 Dynamic Range 可以让更多细节可见,但可能需要同步调整 Brightness
    • Gamma 值对视觉效果影响显著,2.2 是一个良好的起点
  3. 预热优化

    • 适当的预热步数可以避免初始帧的视觉噪声
    • 过多的预热步数会增加场景加载时间
  4. 参数变化时的重建

    • 修改方程或参数时,系统会自动触发累积缓冲区的重建(Replay)
    • 重建过程会渐进式地重新填充密度,避免画面突然跳变
    • 频繁修改参数可能导致反复重建,建议在暂停状态下调整参数

常见问题

画面全黑或全白

问题:渲染结果完全黑色或完全白色

原因:色调映射参数不匹配当前吸引子的密度分布

解决方案

  • 调整 Brightness(全黑时增大,全白时减小)
  • 调整 Dynamic Range(全黑时减小,全白时增大)
  • 调整 Gamma(全黑时增大伽马值)
  • 检查 Batch Size 是否足够大以产生可见的密度

吸引子形状不完整

问题:吸引子只显示部分结构

原因:预热步数不足或初始范围过小

解决方案

  • 增加 Burn-In Steps(如从 50 增加到 200)
  • 扩大初始范围(X₀ 和 Y₀ 的 Min/Max)
  • 增大 Iterations Per Frame 以加速密度累积

粒子发散

问题:画面出现均匀的噪声或完全模糊

原因:映射方程不产生有界吸引子

解决方案

  • 检查方程是否正确——并非所有映射都能产生吸引子
  • 尝试经典的参数组合(如 Clifford 吸引子的参数)
  • 某些参数组合会导致迭代发散,这是映射本身的数学性质,而非软件错误

颜色不理想

问题:颜色单调或缺乏层次

原因:步长度度范围或颜色参数设置不当

解决方案

  • 调整 Step Metric Min/Max 以匹配吸引子的实际步长分布
  • 调整 Color Speed 改变颜色循环频率
  • 调整 Color Phase 偏移颜色起始位置
  • 调整 Saturation 增加或减少颜色饱和度

修改参数后画面闪烁

问题:修改参数时画面出现闪烁或跳变

原因:参数变化触发了累积缓冲区的重建

解决方案

  • 这是正常行为——系统需要重建密度累积以反映新的参数
  • 重建过程通常在 0.5 秒内完成
  • 如果闪烁过于频繁,可以在暂停状态下调整参数

经典映射吸引子示例

Clifford 吸引子

json
{
  "type": "MAP_ATTRACTOR",
  "dimension": 2,
  "equations": {
    "x_next": "sin(a * y) + c * cos(a * x)",
    "y_next": "sin(b * x) + d * cos(b * y)"
  },
  "parameters": {
    "a": -1.7,
    "b": 1.8,
    "c": 1.6,
    "d": 0.9
  }
}

Peter de Jong 吸引子

json
{
  "type": "MAP_ATTRACTOR",
  "dimension": 2,
  "equations": {
    "x_next": "sin(a * y) - cos(b * x)",
    "y_next": "sin(c * x) - cos(d * y)"
  },
  "parameters": {
    "a": -2.24,
    "b": 0.43,
    "c": -0.65,
    "d": -2.43
  }
}

级联映射吸引子(y_next 引用 x_next)

json
{
  "type": "MAP_ATTRACTOR",
  "dimension": 2,
  "equations": {
    "x_next": "sin(a * y) + c * cos(a * x)",
    "y_next": "sin(b * nx) + d * cos(b * y)"
  },
  "parameters": {
    "a": -1.4,
    "b": 1.6,
    "c": 1.0,
    "d": 0.7
  }
}

3D 映射吸引子

json
{
  "type": "MAP_ATTRACTOR",
  "dimension": 3,
  "equations": {
    "x_next": "sin(a * y) + c * cos(a * x)",
    "y_next": "sin(b * x) + d * cos(b * y)",
    "z_next": "sin(e * x) + f * cos(e * z)"
  },
  "parameters": {
    "a": -1.7,
    "b": 1.8,
    "c": 1.6,
    "d": 0.9,
    "e": -0.5,
    "f": 1.2
  }
}

更多效果展示

alt textalt text

技术细节

GPU 渲染管线

映射吸引子使用三遍 GPU 渲染管线:

  1. 状态更新遍(Update Pass)

    • 读取当前粒子状态纹理(位置 + 步长度量)
    • 执行映射方程计算下一状态
    • 使用 Ping-Pong 双缓冲技术实现状态交替读写
  2. 密度累积遍(Accumulate Pass)

    • 将粒子位置投影到屏幕空间
    • 使用加法混合(Additive Blending)将粒子密度累积到浮点纹理
    • 支持累积衰减(Decay)实现动态效果
  3. 呈现遍(Present Pass)

    • 对累积密度应用色调映射链:亮度 → 对比度 → 伽马 → 动态范围 → 饱和度 → 反转
    • 自动缩放因子根据累积采样数和视口大小计算,确保不同分辨率下视觉一致

着色器编译

映射方程在运行时编译为 GLSL 着色器代码:

  • 使用 MapAttractorExpressionCompiler 将用户输入的数学表达式转换为 GLSL
  • 自定义参数通过 Uniform 变量传递,修改参数值不需要重新编译着色器
  • 仅当添加新参数符号时才需要重新编译着色器

Replay 机制

当参数或相机发生变化时,系统会触发 Replay 重建:

  • 重置粒子状态到初始位置
  • 重新执行预热迭代
  • 渐进式地重新累积密度(约 0.5 秒内完成)
  • 确保画面平滑过渡,避免突然跳变

创作技巧

参数探索

  1. 从经典开始:先使用 Clifford 或 Peter de Jong 的经典参数值
  2. 小范围调整:在经典值附近小范围调整参数,观察形状变化
  3. 级联实验:尝试在 y_next 中引用 x_next,创造更复杂的动力学
  4. 记录发现:保存有趣的参数组合

视觉调优

  1. 色调映射

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

    • 调整 Color Speed 和 Color Phase 创造丰富的颜色变化
    • 降低 Saturation 可以获得更优雅的视觉效果
    • 使用 Invert 在明暗风格间切换
  3. 步长度量

    • Step Metric Max 决定了着色的敏感范围
    • 较小的 Max 值使缓慢移动的区域更突出
    • 较大的 Max 值使快速移动的区域更突出

动画设计

  1. 参数振荡

    • 为关键参数设置振荡动画,观察吸引子的形态演变
    • 使用不同的步长方向(正/负)创造非对称的运动模式
    • 边沿缓动确保参数在范围边界处平滑过渡
  2. 相机运动

    • 对于 2D 吸引子,缩放动画可以揭示细节
    • 对于 3D 吸引子,旋转动画展现空间结构

数学公式参考

常用函数

函数说明示例
sin, cos, tan三角函数sin(a * y), cos(b * x)
asin, acos, atan反三角函数atan(z)
sinh, cosh, tanh双曲函数tanh(x)
sqrt, abs平方根、绝对值sqrt(x*x + y*y)
log, ln, exp对数、指数exp(-x)
pow, min, max幂、最小、最大pow(x, 2)

级联变量

变量说明可用于
x, y, z当前状态坐标x_next, y_next, z_next
x_nextnxx 的下一个值y_next, z_next
y_nextnyy 的下一个值z_next

运算符

运算符说明示例
+, -, *, /四则运算x + y
%取模x % 2
^幂运算x ^ 2
(, )括号(x + y) * z

注意事项

  1. 方程正确性

    • 并非所有映射方程都能产生有界吸引子
    • 某些方程会导致迭代发散,表现为全屏噪声或空白
    • 建议从已知的经典映射开始实验
  2. GPU 显存

    • 过大的 Batch Size 会消耗大量 GPU 显存
    • 状态纹理大小为 ⌈√BatchSize⌉ × ⌈√BatchSize⌉
    • 累积纹理大小等于渲染分辨率,使用 RGBA32F 格式
  3. 参数变化

    • 修改方程或参数会触发 Replay 重建
    • 重建期间画面会渐进式恢复,这是正常行为
    • 修改 Color Speed 或 Color Phase 也会触发重建
  4. 维度切换

    • 从 3D 切换到 2D 时,z_next 方程会被清空
    • 从 2D 切换到 3D 时,z_next 默认设为 z(即 z 保持不变)
  5. 步长度量范围

    • Step Metric Max 必须大于 Min
    • 系统会自动保证 Max ≥ Min + 0.001
    • 不合理的范围会导致着色效果异常

进阶主题

自定义映射吸引子

创建自定义映射吸引子的步骤:

  1. 研究迭代映射的数学性质,确保映射是有界的
  2. 设计映射方程,利用级联引用创造复杂动力学
  3. 选择合适的参数范围
  4. 调整色调映射参数以获得最佳视觉效果
  5. 利用参数振荡动画创造动态效果

密度累积艺术

映射吸引子的渲染本质是密度估计:

  • 密度高的区域对应吸引子中粒子频繁访问的位置
  • 通过色调映射链将密度转化为视觉亮度
  • 不同的 Gamma 和 Dynamic Range 组合可以揭示不同的结构细节

与奇异吸引子的对比

方面映射吸引子奇异吸引子
方程类型离散映射连续微分方程
渲染方式密度累积粒子拖尾
视觉特征高密度精细图像流动轨迹线条
适合场景静态高精度图像动态轨迹动画
参数动画振荡动画时间线关键帧

参考资源

数学理论

  • Clifford Pickover - Computers, Pattern, Chaos and Beauty
  • Julien C. Sprott - Strange Attractors: Creating Patterns in Chaos

在线资源

软件文档

  • Processing 4 官方文档
  • OpenGL 着色器编程指南

All rights reserved.