10 万欧元赎身的 Blender,凭什么活过 30 年
- Blender 源自 1994 年 NaN 公司内部工具,2002 年公司破产后由创始人通过 10 万欧元众筹买断源码并以 GPL 开源
- GitHub 仓库仅为镜像且关闭 issue,真正开发在自建 Gitea 实例 projects.blender.org,降低对商业平台的依赖
- 300 万行 C++ 采用三层结构:source 主程序、intern 自研库(Cycles、GHOST 等)、extern 捆绑的第三方库,边界严格
- DNA 序列化系统让结构体自描述,配合 2009 年至今逐版本累积的 versioning 文件链,实现 30 年 .blend 文件向后兼容
- 治理上依靠月筹 33 万美元的开发基金、十年稳定的三月一版节奏,以及用开放电影做真实生产压测的机制
2002 年 3 月,阿姆斯特丹,一家叫 NaN 的公司进入破产清算。创始人 Ton Roosendaal 名下的资产里有一套内部工具,1994 年写出来给动画工作室自己用的 3D 软件,叫 Blender。投资人打算把它卖给能出价的人,或者干脆封存。
Ton 没有走「再融一轮」的路。他成立了非营利的 Blender Foundation,7 月 18 日发起「Free Blender」众筹,目标 10 万欧元,条件是与投资人谈妥,买断源码然后以 GPL 开源。7 周后,9 月 7 日,目标达成。那时 Kickstarter 还要等 7 年才上线,这群人用邮件列表和 PayPal 凑出了救命钱。
24 年后的今天,这套代码在 Blender 上有 20,038 个 star,主语言 C++,仓库体积 1.4 GB,最新版本 v5.2.1,昨天还有代码推送。它是怎么从一具破产遗产活成行业基础设施的,我拆了它的源码,答案比想象中具体。
先说一个反常识,这个仓库不是主仓库
你打开 blender/blender,star 两万,fork 三千多,但 issue 区是空的。不是没人提 bug,是官方直接关掉了。我查了仓库配置,has_issues 字段是 false。
真正的开发发生在 projects.blender.org,那是 Blender 自建的 Gitea 实例。代码评审、bug 追踪、设计文档全在那边跑。仓库里还留着一个 .gitea 目录,里面有 workflows、issue_template、CODEOWNERS、pull_request_template,也就是说这个仓库把给 Gitea 准备的整套 CI 配置原样搬到了 GitHub,镜像的时候连目录都没摘。
说真的,这个细节我盯了很久。GitHub 对 Blender 而言只是一个广播频道,代码只出不进。这样做有代价,贡献者的第一道门槛就变高了,你要去一个陌生的平台注册账号、学一套新流程。但好处也直白,社区操作系统不依赖任何商业平台,托管方倒闭、被收购、改政策,都伤不到主仓库。
一家 2002 年差点连源码都保不住的组织,对平台依赖有肌肉记忆,我不觉得这是偏执。
300 万行 C++ 是怎么摆的
GitHub 的语言统计显示这个仓库有 109.6 MB 的 C++ 代码,粗算 300 万行上下。另有 20.6 MB 的 Python(大头是测试)、1.5 MB 的 GLSL 着色器、1.98 MB 祖传 C 代码。
这个量级的代码怎么组织,Blender 给出的答案是一个三层结构。
source/ 是主程序。source/creator 放着 main 函数入口,隔壁 source/blender 下 38 个子目录按职责切分,blenkernel 是核心数据层,editors 装着所有编辑器界面,nodes 是节点系统,depsgraph 负责场景求值,draw 和 gpu 管绘制,modifiers、bmesh、compositor、sequencer、animrig 各管一摊。每个目录都是一个独立的 CMake 目标,依赖关系写得很死。
intern/ 是自家的工具库,26 个。Cycles 渲染器整个住在这里,窗口系统抽象 GHOST 在这里,内存分配器 guardedalloc 在这里,运动跟踪的 libmv、流体模拟的 mantaflow、细分曲面的 opensubdiv、IK 求解的 iksolver 和 itasc 也都在。
extern/ 是捆绑的第三方库,27 个,Bullet 物理、Vulkan 内存分配器、Tracy 性能分析器、解析 FBX 的 ufbx,直接进树维护。
你想想看这个分层的逻辑,intern 和 extern 都是库,区别只有一个,前者是 Blender 社区自己开发自己改的,后者是跟着上游同步的第三方。三层之间不许乱伸手,想用别的模块的数据,走接口。一个 30 年的项目能把边界守成这样,靠的不是重构热情,是每一个新功能想进树都得先回答「你住哪一层」。
30 年兼容的秘密,全在一个目录里
拆到这里,最值钱的部分来了。
Blender 最老的资产不是哪段代码,是 .blend 文件格式。今天你用 5.2 打开一个 2009 年存的 .blend 文件,能开。这不仅靠格式设计,背后是一套叫 DNA 的序列化系统。
source/blender/makesdna/ 目录下躺着几十个 DNA_*_types.h,DNA_mesh_types.h、DNA_camera_types.h、DNA_armature_types.h,场景里每一种数据结构在这都有定义。这个文件的版权头我看了,第一行写着 SPDX-FileCopyrightText: 2001-2002 NaN Holding BV。NaN 2002 年就破产了,这家公司的名字在源码文件头里躺了 24 年,每个贡献者打开文件都能看见。
DNA 系统干的事,其实是让结构体自己描述自己。保存文件时,Blender 把结构体的字段名、类型、偏移量一并写进文件,形成一份 SDNA 表。读取时,程序比对内存里的新结构和文件里的旧结构,字段对得上的原样搬,改了名的按改名映射搬,删掉的字段丢弃,新增的字段填默认值。文件格式不版本化,结构对结构,一场一场字段级的迁移。
这套机制的落地证据在 source/blender/blenloader/intern/,那里的文件名连起来就是半部 Blender 史。
versioning_250.cc # 2.5x 时代,2009 年
versioning_260.cc
versioning_270.cc
versioning_280.cc # 2.8 大改 UI 的版本
versioning_290.cc
versioning_300.cc
versioning_400.cc
versioning_401.cc
...
versioning_500.cc
versioning_501.cc
versioning_502.cc
versioning_503.cc # 为尚未发布的 5.3 预留
从 2009 年的 2.5 到今年的 5.3,17 年里每个大版本一个升级文件,负责把老文件迁到新结构。这批代码没人喜欢写,但没人敢删,删掉的那天,某个人 2009 年的作品就打不开了。
我一直觉得这是整个项目最反直觉的决策。行业主流做法是格式大版本化,旧格式给个导入器,甚至直接抛弃。Blender 选了最贵的那条路,兼容性是硬约束,所有新功能在这个约束下面设计。贵有贵的回报,30 年攒下来的用户资产全都还能用,这才是真正搬不走的东西。
几处顺手的工程细节
拆源码的过程中还看到几个值得记一笔的设计。
intern/guardedalloc 是个自研内存分配器。30 年前的 C 项目没有 AddressSanitizer,Blender 就自己写了一个带守卫的分配器,每块内存记录分配时的栈信息,程序退出时把没释放的块连同来源打印出来。这个 90 年代的「穷人版泄漏检测」至今还在树里服役。
intern/ghost 名字展开是 Generic Handy Operating System Toolkit,把 Windows、macOS、Linux 的窗口和输入事件统一成一套接口。有意思的是隔壁 intern/wayland_dynload,Wayland 的支持是运行时动态加载的,编译期不需要系统装着 Wayland 开发库,这份为老发行版留的体贴也是兼容哲学的延伸。
Cycles 渲染器整个住在 intern/cycles,不挂在 source/blender 底下。这是刻意的,Cycles 可以独立编译成渲染服务器,社区甚至有人把它接进别的软件。一个「Blender 的功能」被当成独立库来养,边界感换来了意外的大众性。
source/blender/depsgraph 是求值引擎,你拖动一根骨骼,它决定场景里哪些修改器、驱动、材质需要重算,哪些可以不动。实时交互的底气全在这张依赖图上。
钱从哪来,人往哪去
技术拆完,说治理。这部分其实是 Blender 活下来的另一半答案。
2002 年那套「众筹赎身」后来进化成了正式制度。Blender Development Fund 现在的数据是每月筹款 $330,062,7,642 名个人捐赠者,47 家企业会员。企业名单拉出来很扎眼,NVIDIA、Netflix Animation、Microsoft、AMD、Intel、Meta、Adobe、Google,在商业上互相掐的公司,在同一个捐赠名单里给 Blender 付月费。
这些钱养着一支全职核心团队。GitHub 镜像的贡献榜上,ideasman42(Campbell Barton,现任首席维护者)39,713 次提交,sergeyvfx 11,455 次,brechtvl 10,386 次,Cycles 渲染器就是他写的。往下翻能看到 tonroosendaal 本尊,4,831 次提交,32 年了创始人还在提交代码。
发布节奏十年没乱过。v4.5.0 是 2025 年 7 月 14 日,v5.0.0 是 11 月 18 日,v5.1.0 是 2026 年 3 月 16 日,v5.2.0 是 7 月 13 日。一年三版,每四个月一版,回回卡在月中。你想想绝大多数开源项目连下个版本什么时候发都说不清。
还有一条被低估的机制,开放电影。2006 年的 Elephants Dream、2008 年的 Big Buck Bunny、2010 年的 Sintel、2012 年的 Tears of Steel,基金会出钱组织团队用开发中的 Blender 做短片。Sintel 做完,路径追踪渲染器 Cycles 诞生,Tears of Steel 做完,运动跟踪进了主程序。每一部片子就是一次全功能压测,艺术家们在片子里踩到的坑,直接变成下个版本的路线图。
别急着学,先看清楚代价
坦白讲,这篇文章写到这全是好消息,接下来说几句拆解中亲手验证过的坏消息。
先说使用层面。这个仓库 1.4 GB,从 GitHub 镜像克隆还可能碰到 Git LFS 报错,README 第一段就提醒你要用 GIT_LFS_SKIP_SMUDGE=1。想自己编译,还得另外下载一堆预编译依赖库,构建文档要读半天。
想贡献代码的人会在流程上被劝退一次。GitHub 上不收 issue 也不做评审,你得去 Gitea 注册、看邮件列表、适应他们的节奏。自主是自主,门槛也是真门槛,这个选择的成本他们自己认了。
历史包袱也是显性的。仓库里还有 1.98 MB 的 C 代码没迁完,editors 里一批老文件,C++ 现代化改了十年还在路上。Python 那 20 MB 里相当一部分是测试,4.2 之后官方把插件体系搬去独立的 extensions 平台,老教程全在失效中。
顺便替它澄清一个流传很广的误会,很多人被 GPL 吓退。GPL 约束的是 Blender 程序本身和它的修改版,你用它做的模型、动画、渲染图、导出的视频,完全不受传染,商业项目随便用。真正要注意的只有一条,你别把 Blender 源码改一改闭源卖钱。
把格式当宪法,把生产当测试集
拆完这 300 万行代码,能带走的判断有两个,都够起个名字。
格式即宪法。Blender 把 .blend 格式当成宪章级约束,任何版本都不许破坏对老文件的承诺,DNA 系统和那条 versioning 文件链就是这个约束的执法机构。多数软件把兼容当成技术债,Blender 把它当成护城河,30 年下来,用户的每一份历史资产都还在它手里活着。你维护的软件如果超过三年,去看一眼自己的版本迁移代码攒了多少行,这个数字基本等于你对历史的信用。
生产即测试。开放电影不是情怀项目,是用真实交付压力做集成测试的制度化方案。测试用例能骗过你,上线日期骗不过,短片要在电影节放,艺术家要在死线前交镜头,这种压力筛出来的 bug 和优先级,比任何用户调研都诚实。
一个 32 年的项目能活到今天,靠的不是某次技术选型押对了,C++ 都换了三个时代的写法了。靠的是这两条慢纪律,格式不背叛用户,生产不说谎。10 万欧元买来的从来不是一套代码,是把这两条纪律写进组织里的机会。
项目地址在上面,感兴趣的自己去拆,记得带上 GIT_LFS_SKIP_SMUDGE=1。

评论互动