11import pyglet
2+ from utils .constants import c_for_julia_type
3+
24mandelbrot_compute_source = """#version 430 core
35
46uniform int u_maxIter;
5456
5557uniform int u_depth;
5658uniform int u_zoom;
59+ uniform vec2 u_center;
5760layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
5861layout(location = 0, rgba32f) uniform image2D img_output;
5962
6063void main() {
61- ivec2 coord = ivec2(gl_GlobalInvocationID.xy);
64+ {vec2type} centered = {vec2type}(gl_GlobalInvocationID.xy) - u_center;
65+ {vec2type} zoomed = centered / u_zoom;
66+ {vec2type} final_coord = zoomed + u_center;
67+
68+ ivec2 coord = ivec2(final_coord);
69+
6270 bool isHole = false;
6371
6472 for (int i = 0; i < u_depth; ++i) {
7583
7684"""
7785
86+ julia_compute_source = """#version 430 core
87+
88+ uniform int u_maxIter;
89+ uniform vec2 u_resolution;
90+ uniform vec2 u_real_range;
91+ uniform vec2 u_imag_range;
92+
93+ layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
94+ layout(location = 0, rgba32f) uniform image2D img_output;
95+
96+ {vec2type} map_pixel({floattype} x, {floattype} y, {vec2type} resolution, {vec2type} real_range, {vec2type} imag_range) {
97+ {floattype} real = real_range.x + (x / resolution.x) * (real_range.y - real_range.x);
98+ {floattype} imag = imag_range.x + (y / resolution.y) * (imag_range.y - imag_range.x);
99+ return {vec2type}(real, imag);
100+ }
101+
102+ void main() {
103+ ivec2 texel_coord = ivec2(gl_GlobalInvocationID.xy);
104+
105+ int R = {escape_radius};
106+ {vec2type} c = {vec2type}{julia_c};
107+
108+ {vec2type} z = map_pixel({floattype}(texel_coord.x), {floattype}(texel_coord.y), u_resolution, u_real_range, u_imag_range);
109+
110+ int iters = 0;
111+
112+ while ((z.x * z.x + z.y * z.y) < pow(R, 2) && iters < u_maxIter) {
113+ {floattype} xtemp = z.x * z.x - z.y * z.y;
114+ z.y = 2 * z.x * z.y + c.y;
115+ z.x = xtemp + c.x;
116+
117+ iters = iters + 1;
118+ }
119+
120+ vec4 value = vec4(0.0, 0.0, 0.0, 1.0);
121+
122+ if (iters != u_maxIter) {
123+ float t = float(iters) / float(u_maxIter);
124+ float pow_amount = 0.7;
125+ t = pow(t, pow_amount);
126+
127+ value.r = 9.0 * (1.0 - t) * t * t * t;
128+ value.g = 15.0 * (1.0 - t) * (1.0 - t) * t * t;
129+ value.b = 8.5 * (1.0 - t) * (1.0 - t) * (1.0 - t) * t;
130+ }
131+
132+ imageStore(img_output, texel_coord, value);
133+ }
134+ """
135+
78136def create_sierpinsky_carpet_shader (width , height , precision = "single" ):
79137 shader_source = sierpinsky_carpet_compute_source
80138
139+ if precision == "single" :
140+ shader_source = shader_source .replace ("{vec2type}" , "vec2" ).replace ("{floattype}" , "float" )
141+ elif precision == "double" :
142+ shader_source = shader_source .replace ("{vec2type}" , "dvec2" ).replace ("{floattype}" , "double" )
143+ else :
144+ raise TypeError ("Invalid Precision" )
145+
81146 shader_program = pyglet .graphics .shader .ComputeShaderProgram (shader_source )
82147
83148 sierpinsky_carpet_image = pyglet .image .Texture .create (width , height , internalformat = pyglet .gl .GL_RGBA32F )
@@ -87,6 +152,31 @@ def create_sierpinsky_carpet_shader(width, height, precision="single"):
87152
88153 return shader_program , sierpinsky_carpet_image
89154
155+ def create_julia_shader (width , height , precision = "single" , escape_radius = 2 , julia_type = "Classic swirling" ):
156+ shader_source = julia_compute_source
157+
158+ if precision == "single" :
159+ shader_source = shader_source .replace ("{vec2type}" , "vec2" ).replace ("{floattype}" , "float" )
160+ elif precision == "double" :
161+ shader_source = shader_source .replace ("{vec2type}" , "dvec2" ).replace ("{floattype}" , "double" )
162+ else :
163+ raise TypeError ("Invalid Precision" )
164+
165+ julia_c = c_for_julia_type [julia_type ]
166+ shader_source = shader_source .replace ("{julia_c}" , str (julia_c ))
167+
168+ shader_source = shader_source .replace ("{escape_radius}" , str (escape_radius ))
169+
170+ shader_program = pyglet .graphics .shader .ComputeShaderProgram (shader_source )
171+
172+ julia_image = pyglet .image .Texture .create (width , height , internalformat = pyglet .gl .GL_RGBA32F )
173+
174+ uniform_location = shader_program ['img_output' ]
175+ julia_image .bind_image_texture (unit = uniform_location )
176+
177+ return shader_program , julia_image
178+
179+
90180def create_mandelbrot_shader (width , height , precision = "single" ):
91181 shader_source = mandelbrot_compute_source
92182
0 commit comments