Quellcode durchsuchen

add a grayscale mandelbulb adaptation

Lucas Stadler vor 10 Jahren
Ursprung
Commit
e443a8b5b1
1 geänderte Dateien mit 95 neuen und 0 gelöschten Zeilen
  1. 95 0
      glsl/mandelbulb.frag

+ 95 - 0
glsl/mandelbulb.frag

@ -0,0 +1,95 @@
1
/*
2
 * A "Mandelbulb", i.e. a mandelbrot fractal in 3d.
3
 *
4
 * Adapted for Fragmentarium from [1].
5
 *
6
 * [1]: http://2008.sub.blue/blog/2009/12/13/mandelbulb.html
7
 */
8
#include "3D.frag"
9
10
#group Mandelbulb
11
uniform float MinimumDistance; slider[0.0,0.01,10.0]
12
uniform int MaximumRaySteps; slider[1,10,200]
13
uniform int MaxIterations; slider[1,2,30]
14
uniform float bailout; slider[0.5,4.0,12.0]
15
uniform float power; slider[-20.0,8.0,20.0]
16
uniform float phaseX; slider[-2.0,0.0,2.0]
17
uniform float phaseY; slider[-2.0,0.0,2.0]
18
19
// Defined later, must be forward declared for use in `trace`.
20
float DistanceEstimator(vec3 pos);
21
22
float trace(vec3 from, vec3 direction) {
23
	float totalDistance = 0.0;
24
	int steps;
25
	for (steps=0; steps < MaximumRaySteps; steps++) {
26
		vec3 p = from + totalDistance * direction;
27
		float distance = DistanceEstimator(p);
28
		totalDistance += distance;
29
		if (distance < MinimumDistance) break;
30
	}
31
	return 1.0-float(steps)/float(MaximumRaySteps);
32
}
33
34
float DistanceEstimator(vec3 z0) {
35
	vec3 c = z0;
36
	vec3 z = z0;
37
	float pd = power - 1.0; // power for derivative
38
	
39
	// Convert z to polar coordinates
40
	float r = length(z);
41
	float th = atan(z.y, z.x);
42
	float ph = asin(z.z / r);
43
	
44
	vec3 dz;
45
	float ph_dz = 0.0;
46
	float th_dz = 0.0;
47
	float r_dz	= 1.0;
48
	float powR, powRsin;
49
	
50
	// Iterate to compute the distance estimator.
51
	for (int n = 0; n < MaxIterations; n++) {
52
		// Calculate derivative of
53
		powR = power * pow(r, pd);
54
		powRsin = powR * r_dz * sin(ph_dz + pd*ph);
55
		dz.x = powRsin * cos(th_dz + pd*th) + 1.0;
56
		dz.y = powRsin * sin(th_dz + pd*th);
57
		dz.z = powR * r_dz * cos(ph_dz + pd*ph);
58
		
59
		// polar coordinates of derivative dz
60
		r_dz  = length(dz);
61
		th_dz = atan(dz.y, dz.x);
62
		ph_dz = acos(dz.z / r_dz);
63
		
64
		// z iteration
65
		powR = pow(r, power);
66
		powRsin = sin(power*ph);
67
		z.x = powR * powRsin * cos(power*th);
68
		z.y = powR * powRsin * sin(power*th);
69
		z.z = powR * cos(power*ph);
70
		z += c;
71
		
72
		r  = length(z);
73
		if (r > bailout) break;
74
		
75
		th = atan(z.y, z.x) + phaseX;
76
		ph = acos(z.z / r) + phaseY;
77
		
78
	}
79
	
80
	// Return the distance estimation value which determines the next raytracing
81
	// step size, or if whether we are within the threshold of the surface.
82
	return 0.5 * r * log(r)/r_dz;
83
}
84
85
vec3 color(vec3 pos, vec3 direction) {
86
  float dist = trace(pos, direction);
87
  return vec3(dist, dist, dist);
88
}
89
90
#preset Default
91
Eye = 0.0,0.0,2.0
92
Target 0.0,0.0,1.0
93
MinimumDistance=0.00001
94
MaximumRaySteps=100
95
MaxIterations=4