曼德尔灯泡是如何渲染的?

How is a mandelbulb rendered?

我一直不明白如何从数学数据中生成像曼德尔灯泡这样的东西。对我来说唯一有意义的方法是使用体素,这显然没有在此处链接的图像中使用。所以如果有人能给我解释一下,请解释一下。

我不知道确切的数学,但我知道如何从 2D 分形到 3D 分形。但首先让我们看看如何进行二维分形:

在计算一般 (2D) 分形时,您选择一些像素坐标并使用函数对其进行变换,例如 [x,y] = somefunc(x,y) 并检查结果是否满足某些条件。如果没有,你再重申一遍,再一遍...

您的数字可能永远不会满足此条件,因此您添加一些全局计数器,假设每个像素迭代 100 次 - 如果在 100 次迭代后它不满足条件,您认为它永远不会停止。

如果从未满足条件,则假设当前像素在分形之外,如果满足条件,则存储这样做所需的迭代次数。

为每个像素计算所有这些,将迭代次数映射到颜色,我经常看到 outside 绘制为黑色,迭代次数映射到某种自定义颜色。您可以使用渐变、条带、灰度或任何您想要的。您也可以循环使用这些颜色来制作假动画。

这里要注意的一件事是,当您开始计算某个像素时,经过一些迭代后,您最终会得到该像素的结果——这在 3D 情况下会有所不同。

3D

在 3D 情况下,大多数计算都是相同的,只是数量更多。

您从一些像素开始,但现在您计算从您的眼睛到该像素的 3D 射线,并选择靠近您的一些起点(例如近裁剪平面)。您对这个 3D 点进行迭代,但如果您不满足条件,则将您的点向前推进一小步并重新计算这个新点的所有内容。这意味着计算一些迭代以获得当前像素的结果是不够的 - 对于沿射线的每个测试点,您可能需要多次执行此操作,这会使您的计算速度变慢。

基本上,当您找到满足您条件的第一个点并对该点进行迭代计数时,您可以使用与 2D 情况下相同的方式为其着色,但 3D space 为您提供更多选项。您可以跟踪此点和灯光之间的线以检查它是否被遮蔽,或尝试计算照明的法线(分形中没有典型的 normals 但您可以尝试伪造它)。

这是一个您可以发挥最大创造力的地方 - 虽然当前的计算机速度太慢,无法快速完成所有这些数学运算,但您可能会发现许多有用的技巧。例如,在您发布的图片中,我相信他们还跟踪了每个最终点的一些接近度以获得 ambient occlusion.

根据我的 somefunccondition,您可以查看有关 Mandelbrot 和 Julia 集的 Wiki 页面。它们看起来很简单,但我没有自己做所以不会假装我是描述它的好人。

Mandelbulb 的公式与 Mandelbrot 集的公式类似,但多了一个维度。首先,我将介绍如何使用实数而不是对复数进行迭代来生成 Mandelbrot 集。

而不是计算 r=2 圆内所有点 c 的零轨道 z_new = z_old^2 + c 我们使用 e^(I theta)=cos(theta)+I sin(theta)

将公式分解为 x 和 y 分量

那么我们的公式就是

X_new= r^2 cos(2 theta)

Y_new= r^2 sin(2 theta)

其中 X_old=r cos(theta)y_old =r sin(theta)

为了把它带到三个维度,我们用球坐标写所有东西

x_old= r sin(phi) cos(theta)
y_old= r sin(phi) sin(theta)
z_old= r cos(phi)

现在我们可以迭代

x_new=r^2 sin(phi) cos(2 theta)
y_new=r^2 sin(phi) cos(2 theta)
z_new=r^2 cos(2 phi)

这是可行的,因为 Mandelbrot 方程中的平方函数被替换为对半径求平方并旋转两倍的角度,并且通过在 z 方向添加相同的变换来实现一维。上图是曼德尔灯泡的8次方,所以我们用8次方代替平方。