OpenGL4.0 Shader 绘制的MandelBrot集合
OpenGL4.0 Shader 绘制的MandelBrot集合,先上一幅图
这个图形是用OpenGL 的Fragment计算生成的。CSDN不支持OpenGL Shader类型代码,这里用C类型贴出来试试。
#version 400
//#extension GL_ARB_gpu_shader_fp64 enable
uniform vec2 viewport;
uniform dvec2 pfrom;
uniform double psize;
#define GAP 20
#define INDSIZE 32
#define LIMIT GAP * GAP * GAP
in vec2 guv;
void main() {
int ix, iy;
ix = int(floor(guv.x * 1024));
iy = int(floor(guv.y * 1024));
if (ix >= (512 - 1) && ix <= (512 + 1) && (iy >= 512-1) && (iy <= 512+1) ) {
gl_FragColor = vec4(1.0f, 1.0f, 1.0f, 1.0f);
} else {
dvec2 z, c;
int i;
z = dvec2(0.0lf, 0.0lf);
c = dvec2(double(guv.x) - 0.5lf, double(guv.y) - 0.5lf);
c *= psize;
c += pfrom;
for (i = 0;i<LIMIT;i++) {
double zx = z.x;
z.x = z.x * z.x - z.y*z.y + c.x;
z.y = 2 * zx * z.y + c.y;
if (abs(z.x) >= 2.0lf || abs(z.y) >= 2.0lf)
break;
}
if (i == LIMIT) {
gl_FragColor = vec4(0.1, 0.1, 0.3, 1.0);
} else {
float ir = (i % GAP) / float(GAP);
float ig = ((i / GAP) % GAP) / float(GAP);
float ib = ((i / (GAP * GAP)) % GAP) / float(GAP);
gl_FragColor = vec4(ir, ig, ib, 1.0f);
}
}
}
M
a
n
d
e
l
B
r
o
t
集
合
是
由
迭
代
方
程
z
=
z
2
+
c
生
成
的
,
其
中
z
和
c
都
是
复
平
面
上
的
点
,
z
的
初
值
为
0
,
容
易
证
明
∣
c
∣
>
2
时
,
迭
代
会
发
散
到
无
穷
,
后
面
证
明
∣
c
∣
<
1
/
4
时
迭
代
收
敛
,
计
算
时
可
以
依
此
做
一
些
优
化
工
作
,
减
少
计
算
量
。
MandelBrot集合是由迭代方程z=z^2+c生成的,\\ 其中z和c都是复平面上的点,z的初值为0,容易证明 \\ |c|>2时,迭代会发散到无穷,后面证明|c|<1/4时 \\ 迭代收敛,计算时可以依此做一些优化工作,减少计算量。
MandelBrot集合是由迭代方程z=z2+c生成的,其中z和c都是复平面上的点,z的初值为0,容易证明∣c∣>2时,迭代会发散到无穷,后面证明∣c∣<1/4时迭代收敛,计算时可以依此做一些优化工作,减少计算量。
下面时c=-0.683920704845814时的迭代结果:
序号 | 迭代次数 | 迭代值 |
---|---|---|
1 | 0 | -0.683920704845814 |
2 | 1 | -0.216173174329018 |
3 | 64 | -0.468359644296487 |
4 | 65 | -0.464559948440282 |
5 | 66 | -0.468104759150976 |
6 | 67 | -0.464798639306020 |
7 | 68 | -0.467882929745086 |
8 | 69 | -0.465006268898969 |
9 | 70 | -0.467689874730474 |
10 | 71 | -0.465186885920408 |
11 | 72 | -0.467521866013488 |
12 | 73 | -0.465344009645080 |
13 | 74 | -0.467375657533253 |
14 | 75 | -0.465480699591173 |
15 | 76 | -0.467248423153926 |
16 | 77 | -0.465599615905984 |
17 | 78 | -0.467137702514014 |
18 | 79 | -0.465703071735742 |
19 | 99984 | -0.466395728904994 |
20 | 99985 | -0.466395728904993 |
21 | 99986 | -0.466395728904994 |
22 | 99987 | -0.466395728904993 |
23 | 99988 | -0.466395728904994 |
24 | 99989 | -0.466395728904993 |
25 | 99990 | -0.466395728904994 |
26 | 99991 | -0.466395728904993 |
27 | 99992 | -0.466395728904994 |
28 | 99993 | -0.466395728904993 |
29 | 99994 | -0.466395728904994 |
30 | 99995 | -0.466395728904993 |
31 | 99996 | -0.466395728904994 |
32 | 99997 | -0.466395728904993 |
33 | 99998 | -0.466395728904994 |
34 | 99999 | -0.466395728904993 |
后面应该时收敛到一个数了,最低位出现跳动应该时计算精度不够导致的。
以下来证明|c|<1/4时,迭代收敛,只需对c时正实数时证明即可:
对
z
=
0
,
c
为
正
实
数
而
且
c
<
1
/
4
,
迭
代
:
z
n
=
z
n
−
1
2
+
c
,
求
证
:
z
n
收
敛
证
明
:
首
先
证
明
z
n
<
1
/
2
,
用
数
学
归
纳
法
,
显
然
:
z
0
=
0
<
1
/
2
,
z
1
<
1
/
4
<
1
/
2
假
设
:
z
n
−
1
<
1
/
2
,
记
:
z
n
−
1
=
1
/
2
−
x
,
则
:
z
n
=
z
n
−
1
2
+
c
=
1
/
4
−
x
+
x
2
+
c
<
1
/
4
−
x
+
x
2
+
1
/
4
=
1
/
2
+
x
(
x
−
1
)
注
意
到
x
在
(
0
,
1
/
2
)
中
,
所
以
x
(
x
−
1
)
<
0
,
因
此
z
n
<
1
/
2
其
次
证
明
z
n
单
调
递
增
。
注
意
到
,
z
n
−
z
n
−
1
=
(
z
n
−
1
2
+
c
)
−
(
z
n
−
2
2
+
c
)
=
z
n
−
1
2
−
z
n
−
2
2
,
可
知
z
n
−
z
n
−
1
与
z
n
−
1
−
z
n
−
2
同
号
,
注
意
到
z
1
>
z
0
,
用
数
学
归
纳
法
同
样
证
明
z
n
单
调
递
增
。
单
调
递
增
数
列
必
收
敛
。
证
毕
。
\begin{aligned} 对z &= 0, c为正实数而且 c < 1/4,迭代:\\ z_n&=z_{n-1} ^2 + c ,\\ 求证&:z_n 收敛 \\ 证明&:首先证明z_n<1/2,用数学归纳法,\end{aligned} \\ \begin{aligned} 显然:z_0&=0<1/2, \\z_1&<1/4 < 1/2 \\ 假设: z_{n-1}&< 1/2,\\ 记:z_{n-1}&=1/2-x, \\ 则:z_n &= z_{n-1}^2+c \\ &= 1/4-x+x^2 + c \\ &< 1/4-x+x^2 + 1/4 \\ &= 1/2+x(x-1) \end {aligned} \\ 注意到x在(0,1/2)中,所以x(x-1)<0,因此 z_n<1/2 \\其次证明 z_n单调递增 。注意到,\\ \begin{aligned} z_n-z_{n-1}&=(z_{n-1}^2+c) - (z_{n-2}^2+c) \\ &=z_{n-1}^2-z_{n-2}^2,\\ 可知 z_n-z_{n-1}&与z_{n-1}-z_{n-2}同号,注意到z_1>z_0,\\ \end{aligned}\\ 用数学归纳法同样证明z_n单调递增。\\ 单调递增数列必收敛。证毕。
对zzn求证证明=0,c为正实数而且c<1/4,迭代:=zn−12+c,:zn收敛:首先证明zn<1/2,用数学归纳法,显然:z0z1假设:zn−1记:zn−1则:zn=0<1/2,<1/4<1/2<1/2,=1/2−x,=zn−12+c=1/4−x+x2+c<1/4−x+x2+1/4=1/2+x(x−1)注意到x在(0,1/2)中,所以x(x−1)<0,因此zn<1/2其次证明zn单调递增。注意到,zn−zn−1可知zn−zn−1=(zn−12+c)−(zn−22+c)=zn−12−zn−22,与zn−1−zn−2同号,注意到z1>z0,用数学归纳法同样证明zn单调递增。单调递增数列必收敛。证毕。
原文有绘制的c语言代码和对应的OpenGL Shader代码,发布在微信公众号上。点此查看微信公众号原文。
以上测试了CSDN对图片显示,源代码代码,表格,数学公式等方面的支持,功能还是不错的。后面发类似的文干脆搬这边来算了。数学公式这边对齐是个问题,估计是由于对公式编辑这部分还不熟悉,后面有机会好好学习一下。