![]()
一个3D引擎,输出不是视频也不是图片,而是SVG代码。heerich.js把体素场景压缩成矢量标记,文件体积小到能塞进邮件签名,放大100倍边缘依然锋利。
这事听起来像技术宅的无聊玩具,但背后站着一个被低估的名字:Erwin Heerich(1922–2004)。这位德国雕塑家用混凝土和砖块玩了半个世纪的几何游戏,死后20年,他的美学被陌生人写进了JavaScript。
把雕塑家的眼睛借给代码
Heerich的作品有个特点——拒绝装饰。他堆叠体块,挖切负形,让实体与虚空互相咬合。这种语言被heerich.js完整继承:addBox()是堆叠,subtract()是挖切,boolean操作是咬合。
引擎的核心是一个3D体素网格。每个体素记住自己的坐标和样式,投影时按深度排序,远的先画,近的后画,遮挡关系自然形成。没有WebGL,没有GPU,纯CPU算完直接吐SVG路径。
这种选择牺牲了什么?帧率。体素多了会卡。但换来的是DOM原生集成——生成的SVG可以直接被CSS染色,被JavaScript监听点击,被浏览器无障碍阅读。它不是一张死图,是可操作的标记。
分辨率无关是矢量图的祖传优势,但heerich.js把它和3D结合了。
相机系统支持斜投影(oblique),角度和距离可调。这种投影没有透视缩短,平行线永远平行,特别适合Heerich那种建筑感的几何体。代码里一行配置:{ type: 'oblique', angle: 315, distance: 25 },就能得到他手稿里常见的45度轴测视角。
API设计:克制到近乎固执
创建引擎实例只需要new Heerich(),所有参数都有默认值。网格尺寸、瓦片大小、默认样式——你可以配,也可以不配。toSVG()返回字符串,直接塞进innerHTML就能看。
边界框自动计算。形状延伸到负坐标?引擎自己调整viewBox,加padding,居中输出。开发者不用算数学,这是产品经理出身的作者才会在意的细节。
原语只有几种:Box是长方体,可以指定位置和尺寸;Negative是负形,用来挖洞;Group打包变换。没有球体,没有曲线,没有UV贴图。这种限制是故意的——Heerich本人也不用这些。
样式系统走CSS变量。stroke颜色绑到var(--stroke-c),换主题只需改一行CSS。体素可以单独染色,但默认继承全局样式。这种分层让批量操作和局部微调共存。
布尔操作是隐藏的王牌。两个体素组可以union、subtract、intersect,得到复杂形状。代码层面是engine.boolean('subtract', a, b),视觉层面是Heerich标志性的"挖切"语言——实体被虚空穿透,边界线突然断裂又重生。
为什么选SVG,而不是Canvas或WebGL?
这个问题作者没解释,但代码会说话。SVG输出是声明式的,每个体素对应一个或,有id,有class,有data属性。你可以用浏览器开发者工具选中单个"砖块",修改它的fill颜色,看实时变化。
Canvas是像素缓冲,画完就忘。WebGL是GPU黑箱,调试靠猜。heerich.js反其道而行,把3D压成2D标记,牺牲实时性能,换取可审计、可编辑、可持久化的输出。
这种取舍在2024年显得复古,但恰好击中特定场景:技术文档插图、建筑概念稿、生成艺术印刷。需要放大到海报尺寸?SVG无损。需要改配色适配品牌?CSS变量。需要版本控制?文本diff比二进制友好一百倍。
性能天花板确实存在。测试显示,1000个体素开始掉帧,5000个明显卡顿。但作者没打算优化——Heerich的实体雕塑通常也就几百个单元,这个数字足够致敬。
![]()
开源项目的意外人格
文档里埋着彩蛋。示例代码的注释用"你"称呼读者:"Try dragging the sliders — the engine clears and rebuilds each frame"。不是冷冰冰的"用户",是邀请式的"你"。
项目名直接用人名,没加.js后缀的虚荣,没凑"3D""Voxel""Engine"的关键词。这种命名在npm海洋里几乎自杀,但作者显然不在乎SEO。
代码风格同样固执。ES模块,无构建步骤,源码直接可读。没有TypeScript,没有单元测试,没有CI徽章。一个index.html打开就能跑,console里手动new Heerich()就能玩。
这种"不完整"是刻意的完整。它复刻了Heerich的工作方式:草图、模型、实体,每一步都是手工决策,没有自动化流水线。数字工具通常承诺"更快",heerich.js承诺的是"更慢但更可控"。
社区反应分化明显。前端开发者抱怨没有React组件,没有npm install即用。设计师却兴奋于终于有工具能导出"真正的"矢量3D——不是AI描摹的伪矢量,是几何精确的路径。
一个意外用例浮出水面:激光切割。SVG路径直接喂给切割机,heerich.js成了从数字模型到实体物体的最短链路。体素的阶梯边缘在木材上变成真实的层叠纹理,Heerich的混凝土美学被转译成胶合板。
项目仓库的issue区很安静,但有个讨论串在持续生长:人们贴出自己的生成结果,有人做了莫比乌斯环,有人复刻了纪念碑谷关卡,有人把孩子的名字体素化。没有pull request,只有展示。
作者偶尔回复,语气像画廊策展人而非技术支持。有人问"能加透视相机吗",答"斜投影是Heerich的语言"。有人问"支持动画吗",答"你可以每帧重建,但建议别这么做"。
这种对话暴露了项目的真实定位:它不是工具,是媒介。就像Photoshop不会为了水彩画家添加真实颜料模拟,heerich.js拒绝为游戏开发者优化帧率。
技术选型背后的价值判断,比技术本身更值得观察。
heerich.js的依赖清单为零。纯JavaScript,浏览器原生API,没有矩阵运算库,没有SVG生成器。投影数学手写,路径拼接手写,深度排序手写。这种"重新发明轮子"在工程上可疑,在艺术上成立——每个体素的落点都经过作者的审美过滤。
对比同类项目:Three.js追求物理正确,voxel.js追求游戏性能,heerich.js追求风格一致。它的限制不是缺陷,是签名。就像你认得出Minecraft的方块,认得出纪念碑谷的等距视角,heerich.js的输出也有 instantly recognizable 的视觉指纹。
文档最后一节是"Gallery",不是API参考,是12个可交互示例。拖动滑块改变体素尺寸,实时看到SVG重新生成。这种展示方式本身就在说教:参数化设计的乐趣在于探索,而非执行预设。
一个细节:示例的默认配色是#ddd填充,深灰描边,1:10的线面比。这正是Heerich晚期手稿的用色习惯。作者没提,但看过原作的人会对照微笑。
项目发布三个月,GitHub star数停留在四百。这个量级在JavaScript生态里连长尾都算不上,但每周仍有稳定的下载量。使用者画像模糊——建筑系学生、生成艺术家、技术文档写作者、某种怀旧的前端老人。
没有商业化路径,没有赞助按钮,没有"Buy me a coffee"。README结尾只有一句:"This exhibition serves as both a technical manual and an interactive gallery"。展览,不是产品。
这种姿态在开源世界罕见。大多数项目要么追求stars数量,要么铺垫转型SaaS,要么至少攒够简历素材。heerich.js的作者似乎在玩另一个游戏:用代码完成一次策展,把Erwin Heerich的遗产翻译成2024年的交互语言。
翻译是否忠实?几何原教旨主义者会挑剔:Heerich的实体雕塑有重力、有材料厚度、有手工误差,heerich.js的体素是完美的数学立方,悬浮在虚空。但数字媒介的本体论不同——它的"材料"是分辨率无关性,是DOM可操作性,是版本控制兼容性。
![]()
作者没声称这是"数字孪生"或"元宇宙先驱"。文档用词克制:constructs(构建)、distills(提炼)、wields(挥动)。动词选择暴露了关系——不是复制,是再诠释。
技术社区有种偏见:小项目要么成长为平台,要么死亡。heerich.js拒绝这个二元叙事,它选择成为恒定的中等规模——足够完整以独立存在,足够小众以避开功能膨胀的压力。
这种生存策略有先例:Processing、p5.js、甚至早期的jQuery,都曾是小而美的特定解决方案。区别在于,heerich.js没有"JavaScript的XX"这类对标宣言,它的参照系在艺术史,在技术史之外。
如果你打开浏览器控制台,输入new Heerich().addBox({size:[3,3,3]}).toSVG(),会得到一个27体素的立方体,自动居中,带默认描边。这个过程没有加载动画,没有授权弹窗,没有"升级到Pro"的暗示。
这种即时性被低估了。现代软件堆栈里,"Hello World"往往需要node_modules、构建脚本、热重载配置。heerich.js回到更古老的契约:写代码,看结果,中间没有中介。
它的局限也因此被原谅。没有热更新,手动刷新;没有错误边界,代码错了就白屏;没有类型提示,参数传错类型得到NaN。这些"缺陷"在特定语境下成为美德——你面对的是裸机,每个后果都是自己的。
项目文档的代码示例有个特点:变量名用单字母。x, y, z是坐标,w, h, d是尺寸,c是颜色。这种命名在风格指南里会被标记为"不清晰",但在这里有效——上下文足够短,记忆负担为零,视觉密度最大化。
对比企业级代码的冗长:voxelPositionXCoordinate, voxelHeightInPixels, defaultFillColorHex。heerich.js的命名假设读者已经理解概念,不需要语义拐杖。这是信任,也是筛选。
筛选的结果是小众共鸣。有人在Twitter贴出用heerich.js生成的公司logo体素版,收获的不是"这是什么工具"的询问,而是"这个视角让我想起Heerich的Köln雕塑"的回应。识别出参照系本身成为身份标记。
这种文化资本的流通方式,比技术特性更难复制。你可以fork代码,添加透视相机,优化渲染性能,但会失去那个让Heerich爱好者会心一笑的精确角度——315度,距离25,斜投影。
数字的精确性在此成为风格要素。不是"约45度",是315(从正北顺时针)。不是"适中距离",是25个单位。这些常数在代码里硬编码,没有暴露为配置,因为改变它们意味着离开Heerich的视觉世界。
作者在技术文档里埋了唯一一处主观评价:"pristine SVG"( pristine 有"纯净、完好如初"之意)。这个词选择了两次:一次形容输出质量,一次形容视觉语言。不是"高性能",不是"功能丰富",是"纯净"。
这种词汇选择定义了项目的伦理。在渲染引擎的军备竞赛里,heerich.js主动退出,宣称另一种价值:少即是多,慢即是快,限制即是自由。这不是技术创新,是技术减速。
减速的效果如何?取决于你的参照系。从游戏开发看,它太慢;从印刷设计看,它太糙;但从概念艺术看,它恰好卡在"足够表达"的临界点。就像Heerich的草图模型,不追求逼真,追求决策可见。
heerich.js的决策处处可见:为什么用斜投影而非透视?为什么体素而非多边形?为什么SVG而非Canvas?每个选择都关闭了一些可能性,打开了另一些。文档没有辩护这些选择,只是展示结果,让读者自己判断。
这种沉默是另一种自信。在解释学泛滥的时代,作者拒绝提供"设计理念"的元叙事,让代码本身说话。你同意或不同意,都是你的事。
项目的最后更新是三个月前,修复了一个边界框计算的浮点误差。没有新功能路线图,没有v2.0预告。这种静止在开源生态里通常被视为死亡信号,但heerich.js的issue区活跃着另一种生命:用户贴图,作者点赞,偶尔技术讨论。
也许这就是"完成"的样子。不是功能穷尽,而是意图实现。作者想做的——用代码复活一种几何美学,提供可操作的入口——已经做到。剩下的属于使用者。
如果你被启发,下一步是什么?fork它,添加透视相机,失去Heerich的签名?还是接受限制,在315度视角里寻找自己的构图?项目不提供答案,只提供起点。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.