FractalPark
FRM 公式语言

用 FRM 编写分形公式

了解 FractalPark 经过测试的 FRM 语法子集,理解源码如何转为 GPU 着色器,并使用与编辑器完全共享的三个示例逐步写出可运行公式。

01

什么是 FRM

FRM 是一种紧凑的文本格式,用来描述迭代分形。一个公式分别规定轨道的初始状态、每轮重复执行的计算,以及决定是否继续迭代的条件。

这种格式源自 Fractint 生态。公式文件让使用者不必重新构建渲染程序,也能交换和修改实验。FractalPark 将这种创作方式带入浏览器,但只说明自身经过测试的语法子集,不宣称完整兼容。

关于这一体系更广泛的起源与历史,可参阅 Fractint 项目网站.

02

FractalPark 的 FRM 支持

FractalPark 会对明确限定的 FRM 子集进行词法分析、解析、校验和编译。下表区分可直接使用的语法、采用 FractalPark 语义的写法,以及当前工作流无法保真的内容。

级别含义已验证范围
支持已有编译器测试覆盖,可以直接使用,无须额外说明语义差异。
  • 每份源码包含一个公式声明
  • init、loop 和 bailout 三个区段
  • 赋值与用户变量
  • 实数和复数常量;算术、比较、逻辑、单目与模长表达式
  • if / elseif / else / endif 条件分支
  • z、c、pixel、zPrev、p1–p5、常量及经过测试的内置函数
  • FRM 注释
  • 结构化诊断与 FRM 到 GLSL 的源码映射
适配可以使用,但采用有说明的 FractalPark 语义,或属于 FractalPark 扩展。
  • ismand 映射到 FractalPark 当前的 Mandelbrot / Julia 运行模式
  • fn1–fn4 使用编译期函数分派
  • @mode: native、@default-view 和 @default-coloring 是 FractalPark 扩展;默认值指令仅在 native 模式生效
暂不支持当前编译器或文件流程无法保真处理;会明确拒绝,而不会静默改写。
  • 在同一文件的多个公式之间进行选择
  • 自动转换经典 Fractint 方言
  • 任意源码指令
  • 非 ASCII 标识符
  • 用户自定义函数或宏
  • 预处理器功能
  • 当前编译流水线拒绝的其他写法

这是经过测试的兼容性基线,不代表完整兼容 Fractint。编译器能力变化时,本表及其测试必须在同一项改动中同步更新。

已验证的兼容性

这些能力统计来自版本化清单:588 个目标条目由 579 个严格 v2 通过项和 9 个有据可查的豁免项组成;另有 117 个条目按稳定原因排除。

目标条目
588
严格 v2 通过
579
有据豁免
9
按原因排除
117
bailout 描述符种类
4
内置函数
20

Bailout 描述符

  • C1
  • C2
  • C4R
  • C5

稳定拒绝原因

  • unknown-predicate
  • unknown-magnitude-form
  • threshold-not-loop-invariant
  • chained-logical

内置函数

  • sin
  • cos
  • tan
  • sinh
  • cosh
  • tanh
  • exp
  • log
  • sqrt
  • abs
  • sqr
  • conj
  • flip
  • recip
  • cabs
  • real
  • imag
  • atan2
  • cosxx
  • cotanh

参数:p1, p2, p3, p4, p5 · 函数槽:fn1, fn2, fn3, fn4

能力清单 v1 · 严格语义 v2

03

公式结构

FractalPark FRM 由一个具名公式声明和三个明确区段组成,它们共同定义每个像素对应的状态迭代过程。

01

init:

每个像素只运行一次。在这里设置轨道初值和所需的辅助变量。

02

loop:

每轮迭代运行一次。更新 z,以及下一轮仍需使用的其他状态。

03

bailout:

返回是否继续迭代的条件。条件变为假时,当前点已经逃逸。

这些区段名是语法结构而非注释;缺少或拼错任何一个都会产生诊断信息。

04

语法指南

这门语言有意保持精简:表达式描述复数运算,语句更新轨道状态,控制流则从不同更新方式中做出选择。

声明与区段
用大括号包住一个具名公式,并依次编写 init:、loop: 和 bailout:。
数值与变量
可以使用 0.15 这样的实数、(0.05, -0.02) 这样的复数对、内置轨道值,或自行赋值的变量。
表达式
可以组合算术、乘方、比较、逻辑、单目运算、|z| 模长语法,以及经过测试的复函数。
控制流
当轨道更新取决于条件时,可使用 if、elseif、else 和 endif;所有分支块必须完整闭合。
内置名称
核心名称包括 z、c、pixel、zPrev、p1–p5、pi、e、maxit、ismand、fn1–fn4,以及编译器测试覆盖的函数。
注释与指令
分号注释用于说明源码。已识别的 @ 指令配置 FractalPark native 行为;未知指令不会被静默忽略。
05

FRM → AST → GLSL 流水线

FractalPark 不会把 FRM 文本直接拼入着色器,而是让源码经过分阶段编译,从而保持语法、语义、生成代码和诊断之间的对应关系。

  1. 1

    FRM 源码

    来自编辑器、粘贴或本地文件的原始文本,是编译流程的权威输入。

  2. 2

    词法单元

    词法分析器识别名称、数字、运算符、区段标记、注释和指令,同时保留源码位置。

  3. 3

    解析后的 AST

    解析器构建结构化公式树,并报告格式错误的声明、表达式和控制流块。

  4. 4

    校验与规范形式

    校验器检查名称、类型、区段和受支持语义,通过后才建立规范化公式。

  5. 5

    GLSL 与源码映射

    代码生成器输出着色器函数,并记录生成 GLSL 到原始 FRM 位置的映射。

  6. 6

    公式插件

    编译成功后,公式会转成渲染器和着色器组装系统共同使用的标准插件契约。

统一的编译器契约让 Explore、独立 Editor、已保存自定义公式、示例与测试始终走同一条实现路径。

06

渐进式教程

三个示例从最小二次公式逐步扩展到参数和状态反馈。每段源码都直接读取共享示例注册表,并在测试中实际编译。

第 1 课

最简 Mandelbrot

最基础的逃逸时间公式, 适合先看清 init / loop / bailout 的最小结构.

重点:公式声明与 init / loop / bailout 结构。先确认最小版本能够编译,再尝试修改指数或逃逸阈值。

starter-brot.frm
StarterBrot {
init:
  z = 0
loop:
  z = z^2 + c
bailout:
  |z| < 4
}

第 2 课

参数漂移

演示 p1 / p2 参数槽位, 以及 cabs 与 |z| 的不同用法.

重点:p1 与 p2 参数槽、复数常量,以及把 cabs(z) 作为显式模长函数。

parameter-drift.frm
ParameterDrift {
init:
  z = 0
loop:
  z = z^2 + c + p1 * 0.15 + p2 * (0.05, -0.02)
bailout:
  cabs(z) < 8
}

第 3 课

轨迹回声

用 zPrev 做记忆反馈, 并推荐搭配 orbitEcho 着色查看轨道包络.

重点:用 zPrev 取得上一轮轨道状态。无需手动维护第二个状态变量,也能引入记忆反馈。

orbit-echo.frm
OrbitEcho {
init:
  z = pixel
loop:
  z = sqr(z) + zPrev * (0.30, -0.12) + pixel * (0.85, 0.0)
bailout:
  |z| < 48
}

FRM 编辑器通过稳定 ID 打开这些同样经过编译检查的示例。保存到云端公式库之前,公式源码只保留在当前标签页中,绝不会嵌入 URL。

07

错误与诊断

编译会在最早出现不安全状态的阶段停止,并提供面向源码的错误信息。被拒绝的语法不会被改写成一个只是看起来相似的结果。

词法错误

意外字符和不支持的标识符会连同行号、列号一起报告。

解析错误

格式错误的区段、表达式或控制流块会在语义校验之前被诊断。

校验错误

未知变量、无效赋值、类型不匹配和未支持语义都会阻止代码生成。

着色器源码映射

生成的 GLSL 保留位置映射,可将着色器编译失败定位回原始 FRM 代码。

修复错误时应从第一条信息开始;后续诊断往往只是同一个缺失符号或无效表达式引发的连锁结果。

08

分享与发布

你写的公式默认是私有的,除非你明确选择分享。公式有三种流转方式——每一种都由你显式触发,没有静默发生。

  • 默认私有

    公式保存在你的云端库中,仅自己可见。保存的作品会把公式源码副本存进草稿里,所以作品打开时永远是你离开时的样子。

  • 下载 .frm 文件

    你的公式是纯文本。随时从「我的公式」下载,自己留一份——不需要导出申请,不需要等待。

  • 发布作品,分享源码

    发布使用了自定义公式的作品,会以 MIT 许可证公开公式源码:任何人都可以阅读、复制并在其上继续创作。社区页面会展示来自元数据的公式名,并提供源码下载。对已发布的作品而言,这一步不可撤销。

完整的 MIT 许可证文本见 opensource.org

09

示例、下一步与参考资料

先在完整渲染环境中观察

打开 Explore,比较内置公式的行为、着色、变换、动画和导出控制,再开始编写自定义公式。

打开 Explore

使用专用 FRM 编辑器编译、预览、导入和下载公式;登录并保存到云端公式库后,再将它交给探索器。

参考资料

历史背景与实现细节分开链接,以明确区分 Fractint 传承和 FractalPark 当前的编译器契约。