用 Processing 从零渲染 Mandelbulb:三维 Mandelbrot 分形的点云可视化实战

发布时间:2026/10/13 6:10:01

用 Processing 从零渲染 Mandelbulb:三维 Mandelbrot 分形的点云可视化实战 教程文档示例工程【免费下载链接】website-archiveArchive of the Coding Train website (first version)项目地址https://gitcode.com/gh_mirrors/we/website-archive点击查看免费下载导读本文以 Coding Train 第 168 期编程挑战《The Mandelbulb》为核心完整讲解曼德博集合Mandelbrot Set如何扩展到三维空间成为 Mandelbulb曼德博球并基于仓库中的 Processing 源码从三重数Triplex Number数学原理、球坐标迭代公式、体素Voxel遍历到带 PeasyCam 交互与颜色/贴图优化的点云渲染给出可直接运行、可逐步调参的完整实现路径。读完本文你将掌握 Mandelbulb 的核心迭代公式、点云边界提取算法以及如何用 ProcessingJava搭建一个可旋转、可着色的三维分形查看器。关联文档位于 _CodingChallenges/168-mandelbulb.md配套完整源码位于 CodingChallenges/CC_168_Mandelbulb/Processing包含 5 个可运行的 Processing 工程。一、从 Mandelbrot 到 Mandelbulb问题定义1.1 二维 Mandelbrot 集的迭代本质Mandelbrot 集的定义基于复数平面上的迭代zₙ₊₁ zₙ² c其中c是复平面上的一个点z₀ 0。如果迭代序列zₙ不发散模长始终不超过 2则该点属于 Mandelbrot 集否则属于集合外部迭代次数n决定了其逃逸速度可用于着色。仓库中该主题的前置挑战 CC_021_Mandelbrot 用 p5.js 实现了这一经典算法其核心循环是var aa a * a - b * b; // 实部平方减虚部平方 var bb 2 * a * b; // 交叉项 a aa ca; b bb cb; if (a * a b * b 16) { // 模长平方超过 16 即视为逃逸 break; }注意逃逸判定用的是a*a b*b 16即模长r 4就中断迭代而在 Mandelbulb 版本中判定阈值取r 2两者是等价的判定思路临界逃逸半径只是系数习惯不同。1.2 三维化面临的数学难题二维复数的乘法可以用模长相乘、辐角相加来描述但三维空间中没有与复数完全等价的三重数triplex number代数系统直接定义z² c的三维乘法是数学上不成立的。因此社区尤其是 Daniel White 与 Paul Nylander 的探索参见视频中引用的 skytopia 资料采用了一个工程上可行的替代方案在三维空间中用球坐标来描述迭代点把复数的辐角相乘替换为球坐标角度乘以幂次 n。这正是 Mandelbulb 的核心思想也是视频时间轴中Triplex numbers4:31与Spherical coordinates7:19两节所讲解的内容。二、核心数学三重数幂公式与球坐标转换2.1 幂运算的球坐标形式令三维迭代点p (x, y, z)将其转换到球坐标r sqrt(x² y² z²) θ atan2(sqrt(x² y²), z) // 与 z 轴的夹角 φ atan2(y, x) // 与 x 轴的方位角则幂pⁿ的计算公式为pⁿ (rⁿ·sin(nθ)·cos(nφ), rⁿ·sin(nθ)·sin(nφ), rⁿ·cos(nθ))这就是仓库中 MandelBulb_Cloud.pde 的迭代核心Spherical c spherical(zeta.x, zeta.y, zeta.z); float newx pow(c.r, n) * sin(c.theta*n) * cos(c.phi*n); float newy pow(c.r, n) * sin(c.theta*n) * sin(c.phi*n); float newz pow(c.r, n) * cos(c.theta*n); zeta.x newx x; zeta.y newy y; zeta.z newz z;这里n 8是 Mandelbulb 最经典的幂次power 8不同n值会生成不同形状的花瓣状分形。zeta是迭代变量对应二维中的z每轮迭代后都要加上初始点(x, y, z)对应二维中的c。2.2 笛卡尔坐标转球坐标的实现仓库三个主要变体都复用了同一个转换函数以 MandelBulb_Color.pde 为例Spherical spherical(float x, float y, float z) { float r sqrt(x*x y*y z*z); float theta atan2( sqrt(x*xy*y), z); float phi atan2(y, x); return new Spherical(r, theta, phi); }要点说明θ使用atan2(sqrt(x²y²), z)分母是z而非常见的atan2(y, x)式的极角这是以z 轴为极轴的球坐标约定φ使用atan2(y, x)方位角以 x 轴为参考atan2两个参数顺序不能写反否则角度会反转生成的形状将发生镜像逃逸判据是c.r 2模长超过逃逸半径一旦逃逸立即跳出循环不再加入点云。三、体素化遍历如何挖出分形表面3.1 三维网格遍历策略Mandelbulb 是三维点集无法像二维那样逐像素扫描。仓库采用体素Voxel扫描 边界提取的策略把[-1, 1]³的空间均匀切分为DIM³个小格子对每个格子中心点执行迭代判断其是否属于集合内部。以 MandelBulb_Cloud.pde 的三重循环为例for (int i 0; i DIM; i) { for (int j 0; j DIM; j) { boolean edge false; for (int k 0; k DIM; k) { float x map(i, 0, DIM, -1, 1); float y map(j, 0, DIM, -1, 1); float z map(k, 0, DIM, -1, 1); // ... 迭代 zeta若 20 次迭代后仍未逃逸则视为集合内部 } } }关键参数一览参数取值作用与影响DIM128Cloud/ 256Color/ 64Shape体素网格分辨率越大表面越精细但三重循环的计算量按立方增长n8三重数幂次决定花瓣数量与整体造型maxiterations20最大迭代次数判定是否属于集合的阈值空间范围map(i, 0, DIM, -1, 1)把体素索引映射到[-1, 1]的立方体空间逃逸半径c.r 2超过即逃逸停止迭代3.2 边界提取的巧妙之处注意三重循环的排列顺序ix与jy在外层kz在最内层且edge标志在j循环内重置。每扫描完一整条 z 轴方向上的体素线后只有首次进入集合内部的格子才会被记录if (iteration maxiterations) { if (!edge) { edge true; mandelbulb.add(new PVector(x, y, z)); } break; }这里的逻辑是只有当某个体素经 20 次迭代仍未逃逸判定为集合内部时才将其加入点云由于edge标志的存在同一条扫描线上重复命中的内部格子不会重复添加从而只保留分形表面的薄壳轮廓。正是这种仅渲染表面点云的策略让 128³ ≈ 209 万个体素中只有约 3.4 万个点被渲染仓库生成的 mandelbulb.txt 实际包含 34252 行坐标数据既保证了形状完整性又控制了绘制开销。从源码结构看这种扫线取边界的方式与体素扫描本身是耦合的如果改为只判断iteration maxiterations而不加edge标志会得到实心点云同样能看但绘制点数与耗时都会显著上升。四、绘制与交互PeasyCam 点云渲染4.1 加入 PeasyCam 实现三维漫游三个主要变体都通过 PeasyCam 库实现鼠标拖拽旋转import peasy.*; int DIM 128; PeasyCam cam; void setup() { size(600, 600, P3D); cam new PeasyCam(this, 600); // 视点距离 600 }需要 Processing 3D 渲染模式P3D否则无法显示三维点new PeasyCam(this, 600)的第二个参数是相机初始距离使用前需通过 Processing 库管理器安装 PeasyCam 库Sketch → Import Library。4.2 点云的绘制循环setup()阶段完成全部体素迭代与数据导出draw()阶段则只负责绘制保证每帧开销极低void draw() { background(0); rotateX(PI/4); rotateY(-PI/3); for (PVector v : mandelbulb) { stroke(255); strokeWeight(1); point(v.x*200, v.y*200, v.z*200); // 放大 200 倍显示 } }其中v.x*200等比例放大把[-1,1]的模型坐标映射到 600×600 画布的可视范围。rotateX(PI/4); rotateY(-PI/3);给了一个固定视角PeasyCam 的交互旋转在此基础上叠加。4.3 体素渲染的另一种形态仓库中的 Voxels.pde 展示了完全不同的可视化思路——不生成点云而是直接绘制体素立方体int DIM 16; float angle -PI/3; void draw() { translate(width/2, height/2, 100); rotateY(angle); angle 0.02; // 自动旋转 for (int i 0; i DIM; i) for (int j 0; j DIM; j) for (int k 0; k DIM; k) { float x map(i, 0, DIM, -range, range); // ... if (y x y z) { // 只绘制满足条件的体素 translate(x, y, z); box(2*range/DIM); } } }它演示了三个概念box(2*range/DIM)让相邻体素无缝拼接是体素渲染的通用写法if (y x y z)这类条件过滤可以快速裁剪掉不关心的体素区域angle 0.02实现无需交互的自动旋转动画。这段代码不涉及 Mandelbulb 迭代是视频时间轴 5:11 处用于铺垫体素概念的辅助演示可作为理解 Mandelbulb 点云渲染原理的入门对照。五、变体进阶颜色、贴图与光影5.1 按迭代次数着色的点云MandelBulb_ColorMandelBulb_Color.pde 在 Cloud 版基础上引入了MandelPoint数据结构把逃逸前的最后一次迭代次数lastIteration随坐标一起保存class MandelPoint { PVector v; float i; // 逃逸时的迭代次数 MandelPoint(PVector v, float i) { this.v v; this.i i; } }在while循环的逃逸分支记录迭代次数if (c.r 2) { lastIteration iteration; // 记录逃逸时的迭代次数 if (edge) { edge false; } break; }绘制时用 HSB 色环映射迭代次数让表面的环带结构随颜色呈现colorMode(HSB, 255); for (MandelPoint m : mandelbulb) { stroke(map(m.i, 0, maxiterations, 255, 0), 255, 255); point(m.v.x, m.v.y, m.v.z); }其中map(m.i, 0, maxiterations, 255, 0)把[0, 20]的迭代次数反向映射到[255, 0]的色相区间——迭代越慢逃逸数值越小的位置偏暖色迭代越接近 20 的位置偏冷色形成从外到内的渐变环带这正是二维 Mandelbrot 逃逸时间着色的三维对应物。5.2 用贴图点精灵代替小点MandelBulb_ShapeMandelBulb_Shape.pde 是点云 贴图的优化版把单个point()换成带纹理的四边形billboard 点精灵让每个点呈现柔和光斑效果dot loadImage(dot.png); // 320×320 径向渐变圆点贴图 for (MandelPoint m : mandelbulb) { push(); translate(m.v.x, m.v.y, m.v.z); imageMode(CENTER); image(dot, 0, 0, 400/(DIM), 400/(DIM)); // 贴图尺寸随分辨率自适应 // box(400/(DIM)); // 也可替换为立方体体素 pop(); }细节要点400/(DIM)使点精灵尺寸与体素分辨率成反比DIM 64时每个点约6.25像素密集排布后近似连续表面imageMode(CENTER)让贴图以点坐标为中心同一位置可用box(400/(DIM))替换贴图退化回体素渲染便于两种效果对比配合lights(); ambientLight(255, 100, 200);开启光照点精灵会受环境光着色产生立体感该贴图即仓库中的 dot.png是一张 320×320 的径向渐变圆形纹理。5.3 光线追踪 SDF 演示RayMarching_SDF仓库还包含一个独立的 SDF有符号距离场光线追踪演示 RayMarching_SDF.pde用于铺垫如何用 raymarching 渲染三维分形float boxSDF(PVector b, PVector r) { PVector d abs(b); d.sub(r); float m max(d, new PVector(0, 0, 0)).mag(); return m min(max(d.x, max(d.y, d.z)), 0.0); }其渲染流程注释中注明灵感来自 observablehq 的leon196/raymarch对每个像素构造归一化方向射线ray从相机位置pos (0, 0, -10)出发每步计算dist boxSDF(pos, ...)沿射线前进dist距离当dist 0.001时判定命中表面用剩余步数n/count作为明暗shade写入像素。float count 20; float shade 0; for (float n count; n 0; --n) { float dist boxSDF(pos, new PVector(2, 2, 2)); if (dist .001) { shade n / count; // 命中越早越亮 break; } pos.add(PVector.mult(ray, dist)); }此外文件中还预留了wackySDF对空间做 mod 取模后减去 1.0 的球体距离场与注释掉的rotateY(ray, ...)/rotateX(ray, ...)用于实验运动网格与射线旋转。需要说明的是该文件实现的是 SDF raymarching 的概念演示球体/立方体距离场并未包含 Mandelbulb 的完整迭代距离场是理解分形 光线追踪组合方向的起点社区贡献中出现的 Mandelbulb Ray Marching in p5.js based on shadertoy.com/view/wdjGWR 等作品即沿此路线延伸。六、参数调节指南与运行环境6.1 运行前提环境Processing 3.xJava 模式需安装 PeasyCam 库仅点云变体需要Voxels 与 RayMarching_SDF 不依赖外部库数据文件点云变体会在草图目录生成mandelbulb.txt内含x y z三列空格分隔的坐标数据格式见 MandelBulb_Cloud 的产物计算开销DIM 256意味着 256³ ≈ 1678 万次体素迭代在setup()中一次性完成首次运行会有数秒到数十秒的等待属于正常现象Color 版注释即提示注意计算量。6.2 参数调参建议目标参数调整说明提升表面精度增大DIM如 256→512分辨率每翻倍体素数变为 8 倍计算量陡增需权衡改变花瓣造型调整n如 6、8、10n决定绕 z 轴的花瓣数量与纵向分层更清晰的集合判定增大maxiterations阈值越高边界越精细但更慢点云密度/疏密调整绘制时的缩放系数如v.x*200仅影响显示尺度不影响几何观察视角修改rotateX(PI/4); rotateY(-PI/3);调整默认视角配合 PeasyCam 拖拽旋转6.3 衍生方向来自文档的 contributions 记录关联文档记录了社区在该主题上的多种衍生实现可作为继续探索的路线图p5.js 移植如 Rainbow Mandelbulb Cloud (p5js)、Mandelbulb with raymarching and shaders、Cinderella mandelbulb rendered in p5.js with phong illumination lighting把体素迭代或 SDF raymarching 迁移到浏览器端WebGL/Three.js如 Three.js (React) Mandelbulb Port using Web Worker用 Web Worker 分担计算边缘检测优化如 Mandelbulb with better edge detection改进边界提取算法以减少噪点。这些社区作品表明本挑战的核心产出幂公式、体素扫描、逃逸着色是一套可复用到任意渲染栈的分形生成管线。七、结语一条从 2D 到 3D 的完整分形管线回看整个挑战可以提炼出一条清晰的实现链路二维 Mandelbrotz² c → 三维扩展球坐标幂公式 p⁸ c → 体素网格扫描 边界提取 → 点云/体素/贴图精灵渲染 → PeasyCam 交互 逃逸次数着色 →可选SDF raymarching 光照渲染每一步在仓库中都有可运行的对应工程MandelBulb_Cloud 是最简版本MandelBulb_Color 增加迭代着色MandelBulb_Shape 增加贴图与光照Voxels 演示体素渲染概念RayMarching_SDF 铺垫光线追踪路线。若想从二维起点温习可对照 CC_021 的 p5.js 实现 与 CC_025 的球坐标几何后者与本文的球坐标转换一脉相承。推荐实验路径先以DIM 64、n 8跑通最简版再逐步提高到 128、256观察花瓣结构与边界精度随分辨率的变化随后把n改为 6 或 10对比造型差异即可直观理解幂次决定分形拓扑这一核心结论。赞分享教程文档示例工程【免费下载链接】website-archiveArchive of the Coding Train website (first version)项目地址https://gitcode.com/gh_mirrors/we/website-archive点击查看免费下载相关推荐Unity高斯点云渲染实战手册从零构建实时3D可视化系统想要在Unity中实现惊艳的实时3D点云渲染效果吗Unity Gaussian Splatting项目正是你需要的利器这个基于SIGGRAPH 2023重磅图形学3D渲染咖啡烘焙师的数字实验室5个关键功能让你从直觉烘焙迈向数据驱动咖啡烘焙师的数字实验室5个关键功能让你从直觉烘焙迈向数据驱动 你是否曾经在烘焙咖啡时只能依靠感觉来判断豆子的状态当一爆声响起时你是否会犹豫是否应该提桌面应用数据可视化数据分析UnityGaussianSplatting 完整使用指南从零开始掌握三维高斯点云渲染UnityGaussianSplatting 完整使用指南从零开始掌握三维高斯点云渲染 想要在Unity中实现令人惊艳的实时三维场景渲染吗UnityGaus图形学3D渲染上一篇ECS集群安全更新策略AMI更新与实例替换最佳实践指南下一篇React Grab 实战指南把浏览器里的 UI 元素一键变成 Agent 可直接使用的源码上下文创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/10/13 7:15:04

MDT 部署批量安装操作系统:从裸机到桌面的自动化流水线

简介:这份资源面向IT运维人员与系统管理员,聚焦利用MDT2013实现Windows操作系统的批量网络部署,帮助解决手动逐台安装效率低、流程繁琐的问题。内容围绕活动目录、WDS、DHCP、MDT与Windows 10 ADK等组件的环境准备展开,并覆盖部署…

2026/10/13 7:15:04

学生勤工俭学系统开发:Spring Boot + Vue全栈实现与避坑指南

简介:毕设学生勤工俭学系统.zip 是一份面向高校毕业设计环节的完整Web应用项目,适合计算机相关专业学生用于课程设计或毕业课题参考。项目围绕高校勤工俭学管理场景,实现岗位发布、学生申请、工时记录、工资计算与双向评价等核心功能&#xf…

2026/10/13 7:15:04

MSE微服务引擎实践:从自建到托管的高可用避坑指南

先讲一次事故。凌晨两点,一个订单核心服务突然大面积超时,排查半天,既不是代码问题也不是数据库问题,是自建的注册中心节点升级时参数配错,集群三台节点被踢出去两台,剩余节点压力爆炸,服务列表…

2026/10/13 7:15:04

AI漫剧制作全流程:从剧本到动态成片的实战指南

AI漫剧这块最近确实热度很高,不管是短视频平台上的推文短剧,还是B站、抖音上的动态漫画解说,都已经跑出了一批成熟账号。很多朋友想入局,但网上的教程要么只讲某一个环节,要么只给提示词模板,真正从零到一跑…

2026/10/13 7:15:04

用BAT脚本将散落文件自动归入同名文件夹

我没有办法把"把单独文件放进同名文件夹"这种需求直接当成一个现成的第三方软件推荐给你——因为这类场景用现成软件反而最别扭。你要么下载一堆不知道有没有捆绑的整理工具,要么被强制注册账号,结果还不如自己写几行批处理省心。所以我这篇分…

2026/10/13 7:10:04

黑黄配色商务PPT模板设计实操:母版、版式与兼容性维护

简介:这款黑黄配色商务报告PPT模板专为职场商务汇报场景设计,适合需要快速制作工作概况、阶段成就、经验教训或阶段计划等内容的用户选用。模板以黑色为底、黄色高亮,兼顾稳重感与信息突出度,内置目录页、数据图表、图片展示页等常…

2026/10/13 5:19:27

Python调用Gemini Structured Outputs实现工单路由门禁

客服工单最怕的不是模型“答错一句话”,而是它给出一段看起来合理的说明,程序却从中猜错优先级。通俗做法是:要求模型只交 JSON(JavaScript Object Notation,轻量数据格式),再让代码验证它。Gem…

2026/10/12 12:01:26

Spring Boot超市进销存系统毕设实战:从需求拆解到答辩通关

最近带的一个学生项目组里,有A同学跑来问我:选什么毕设题目最稳妥,既能让评审老师觉得工作量够,又不会在答辩时被问到语无伦次。我第一反应就是推荐基于Spring Boot的超市仓库管理系统——也就是超市进销存系统。这个题目乍一看平…

2026/10/12 12:54:07

Flutter StatefulWidget 生命周期核心解析

很多刚开始接触 Flutter 的朋友,在看完一堆“Hello World”和基础组件之后,大概率都会撞上同一堵墙:StatefulWidget 里那堆 initState、build、dispose 方法,到底什么时候被调用?为什么顺序是那样?在里面到…

2026/10/13 0:04:41

基于Triton部署YOLO目标检测:从训练脚本到线上服务

简介:这份资源面向希望将目标检测模型落地到生产环境的深度学习开发者与算法工程师,聚焦于用 Triton Inference Server 部署 YOLOv9 的完整实战方案,解决从训练权重到线上推理服务之间的工程化难题。压缩包共 16 个文件,约 886KB&…

2026/10/13 0:04:41

手把手教你云端部署Qwen-Image-2.1:从GPU选型到在线文生图服务

Qwen-Image-2.1 这个开源的图像生成模型,最近在内容创作和 AI 应用圈子里热度相当高。它属于通义 Qwen 系列里的视觉生成分支,让我眼前一亮的是它对中文长文本的理解能力——以前用那些老方案生成带中文文字的图,十个里九个是“乱码印刷体”&…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑