summaryrefslogtreecommitdiff
path: root/animation
diff options
context:
space:
mode:
authorBrett Weiland <brett_weiland@gmail.com>2024-06-11 14:50:14 -0500
committerBrett Weiland <brett_weiland@gmail.com>2024-06-11 14:50:14 -0500
commitcb69732f68c0bd46c1574de16ce1aee6f38e439b (patch)
treedef1daaec81a0d4cd7b3d44b2c26b9535e07579c /animation
restartingHEADmaster
Diffstat (limited to 'animation')
-rw-r--r--animation/asdf.pngbin0 -> 1051370 bytes
-rwxr-xr-xanimation/gpu_migration.py146
-rw-r--r--animation/kernel.c30
-rw-r--r--animation/notes79
4 files changed, 255 insertions, 0 deletions
diff --git a/animation/asdf.png b/animation/asdf.png
new file mode 100644
index 0000000..bbb1747
--- /dev/null
+++ b/animation/asdf.png
Binary files differ
diff --git a/animation/gpu_migration.py b/animation/gpu_migration.py
new file mode 100755
index 0000000..bbf718a
--- /dev/null
+++ b/animation/gpu_migration.py
@@ -0,0 +1,146 @@
+#!/usr/bin/env python3
+import numpy as np
+import matplotlib.pyplot as plt
+import matplotlib.animation as animation
+import pyopencl as cl
+from alive_progress import alive_bar
+from matplotlib.backend_bases import MouseButton
+
+img_res_x = 1000
+img_res_y = 1000
+total_pixels = img_res_x * img_res_y # so we don't gotta compute it every time
+
+periods = 1
+square_x = 0
+square_y = 0
+
+x_min = (-periods * np.pi) + (square_x * np.pi)
+x_max = (periods * np.pi) + (square_x * np.pi)
+y_min = (-periods * np.pi) + (square_y * np.pi)
+y_max = (periods * np.pi) + (square_y * np.pi)
+
+escape = 10000
+iterations = 255*3
+c_x = 2 * np.pi
+c_y = 2 * np.pi
+
+animation_progres_save = "ani1_less.mp4"
+single_frame_save = "asdf.png"
+
+opencl_context = cl.create_some_context(interactive=False)
+opencl_queue = cl.CommandQueue(opencl_context)
+
+kernel_src_path = "./kernel.c"
+
+frames = 200
+rendered_frames = []
+
+image = np.empty([img_res_x, img_res_y], np.uint32)
+image_buffer = cl.Buffer(opencl_context, cl.mem_flags.WRITE_ONLY, image.nbytes)
+
+plt.style.use('dark_background')
+# fuck this shit
+fig = plt.figure(frameon=False)
+fig.set_size_inches(img_res_x/fig.dpi, img_res_y/fig.dpi)
+#fig.set_size_inches(width/height, 1, forward=False)
+
+
+ax = plt.Axes(fig, [0., 0., 1., 1.])
+#ax.set_axis_off()
+fig.add_axes(ax)
+
+cmap = plt.cm.viridis
+cmap.set_bad((0,0,0))
+cmap.set_over((0,0,0))
+cmap.set_under((0,0,0))
+
+bruh = None
+
+def on_click(event):
+ global bruh
+ split_ratio = 1
+ if (event.button is MouseButton.MIDDLE) and (event.inaxes):
+ # there's probably a way to set global coordinates;
+ # I don't expect this to go anywhere so I don't really care
+ on_x = ((event.xdata / img_res_x) * abs(x_max - x_min)) + x_min
+ on_y = ((event.ydata / img_res_y) * abs(y_max - y_min)) + y_min
+
+ #I, uh, also don't know the best way to replicate the openCL code automaticly in python
+ #so ajust if nessesary
+ x_hops = []
+ y_hops = []
+ for i in range(iterations):
+ x_hops.append(((on_x - x_min) / abs(x_max - x_min)) * img_res_x)
+ y_hops.append(((on_y - y_min) / abs(y_max - y_min)) * img_res_y)
+ next_x = on_x/np.tan(on_y)
+ on_y = on_y/np.tan(on_x)
+ on_x = next_x
+ if on_x**2 + on_y**2 > escape:
+ break
+ print(y_hops[0])
+ print(on_y)
+ print("{} hops".format(len(x_hops)))
+ if bruh:
+ bruh.pop(0).remove()
+ bruh = ax.plot(x_hops, y_hops)
+ plt.draw()
+
+
+
+ print(on_x, on_y)
+
+
+print("compiling openCL kernel...")
+with open(kernel_src_path, 'r') as kernel_src:
+ compiled_kernel = cl.Program(opencl_context, kernel_src.read()).build()
+
+encoding_progress = alive_bar(frames, bar = 'filling', spinner = 'waves')
+
+def display_encoder_progress(current_frame: int, total_frames: int):
+ print("Encoding: frame {}/{}".format(current_frame, frames))
+
+
+mp_image = None
+
+print("Rendering {} frames...".format(frames))
+plt.show(block=False)
+if frames > 1:
+ with alive_bar(frames, bar = 'filling', spinner = 'waves') as bar_total:
+ for frame_i in range(0, frames):
+ compiled_kernel.render_frame(opencl_queue, image.shape, None, image_buffer,
+ np.double(abs(x_max - x_min) / img_res_x),
+ np.double(abs(y_max - y_min) / img_res_y),
+ np.double(x_min), np.double(y_min),
+ np.uint32(iterations), np.uint32(escape),
+ np.double(frame_i / frames))
+
+
+ cl.enqueue_copy(opencl_queue, image, image_buffer).wait()
+ rendered_frame = ax.imshow(image, norm="log", aspect="auto", cmap=cmap, animated="True", interpolation='none')
+ if frame_i == 0:
+ mp_image = rendered_frame
+ else:
+ pass
+ #mp_image.set_array(image)
+ rendered_frames.append([rendered_frame])
+ bar_total()
+ #fig.canvas.draw()
+ #fig.canvas.flush_events()
+ print("Encoding/Saving...")
+ ani = animation.ArtistAnimation(fig, rendered_frames, interval=30, blit=True)
+ ani.save(animation_progres_save, extra_args=['-preset', 'lossless'], progress_callback=display_encoder_progress, codec="h264_nvenc")
+else:
+ compiled_kernel.render_frame(opencl_queue, image.shape, None, image_buffer,
+ np.double(abs(x_max - x_min) / img_res_x),
+ np.double(abs(y_max - y_min) / img_res_y),
+ np.double(x_min), np.double(y_min),
+ np.uint32(iterations), np.uint32(escape),
+ np.double(1))
+ cl.enqueue_copy(opencl_queue, image, image_buffer).wait()
+ ax.imshow(image, norm="log", aspect="auto", cmap=cmap)
+ fig.savefig(single_frame_save)
+ plt.autoscale(False)
+ plt.connect('motion_notify_event', on_click)
+ plt.show()
+
+
diff --git a/animation/kernel.c b/animation/kernel.c
new file mode 100644
index 0000000..9c99b2b
--- /dev/null
+++ b/animation/kernel.c
@@ -0,0 +1,30 @@
+__kernel void basic_test() {
+ printf("this cores ID: (%lu, %lu)\n", get_global_id(0), get_global_id(1));
+}
+double cosecant_single(double a, double b) { return a / tan(b); }
+double secant_single(double a, double b) { return a / sin(b); }
+
+__kernel void render_frame(__global unsigned int *frame_output,
+ double x_step, double y_step,
+ double x_start, double y_start,
+ unsigned int iterations, unsigned int escape, double r) {
+ unsigned int iter;
+
+ double x_cart = (get_global_id(0) * x_step) + x_start;
+ double y_cart = (get_global_id(1) * y_step) + y_start;
+ size_t img_index = (get_global_id(1) * get_global_size(1)) + get_global_id(0);
+
+
+ double x = sqrt(pow(x_cart, 2) + pow(y_cart, 2));
+ double y = atan(y_cart / x_cart);
+ double next_x;
+
+ for(iter = 0; iter < iterations; iter++) {
+ next_x = (r * cosecant_single(x, y)) + ((1 - r) * secant_single(x, y));
+ y = (r * cosecant_single(y, x)) + ((1 - r) * secant_single(y, x));
+ x = next_x;
+ if((pow(x, 2) + pow(y, 2)) >= escape) break;
+ }
+
+ frame_output[img_index] = iter;
+}
diff --git a/animation/notes b/animation/notes
new file mode 100644
index 0000000..50249d7
--- /dev/null
+++ b/animation/notes
@@ -0,0 +1,79 @@
+#!/usr/bin/env python3
+import numpy as np
+import matplotlib.pyplot as plt
+import matplotlib.animation as animation
+import pyopencl as cl
+from alive_progress import alive_bar
+
+img_res_x = 2000
+img_res_y = 2000
+total_pixels = img_res_x * img_res_y # so we don't gotta compute it every time
+
+periods = 1
+square_x = 0
+square_y = 0
+
+xmin = (-periods * np.pi) + (square_x * np.pi)
+xmax = (periods * np.pi) + (square_x * np.pi)
+ymin = (-periods * np.pi) + (square_y * np.pi)
+ymax = (periods * np.pi) + (square_y * np.pi)
+
+escape = 10000
+iterations = 255*3
+c_x = 2 * np.pi
+c_y = 2 * np.pi
+
+animation_progres_save = "./animations"
+frames = 120
+
+rendered_frames = []
+
+
+plt.style.use('dark_background')
+# fuck this shit
+fig = plt.figure(frameon=False)
+fig.set_size_inches(img_res_x/fig.dpi, img_res_y/fig.dpi)
+#fig.set_size_inches(width/height, 1, forward=False)
+
+ax = plt.Axes(fig, [0., 0., 1., 1.])
+ax.set_axis_off()
+fig.add_axes(ax)
+
+cmap = plt.cm.viridis
+cmap.set_bad((0,0,0))
+cmap.set_over((0,0,0))
+cmap.set_under((0,0,0))
+
+opencl_context = cl.create_some_context()
+opencl_queue = cl.CommandQueue(opencl_context)
+
+
+#def render():
+# image = np.empty([img_res_y, img_res_x])
+# print("Rendering frames")
+# with alive_bar(frames, bar = 'filling', spinner = 'waves') as bar_total:
+# for frame in range(frames):
+# split_ratio = frame / frames
+# for pix_y, y in enumerate(np.linspace(ymin, ymax, img_res_y)):
+# for pix_x, x in enumerate(np.linspace(xmin, xmax, img_res_x)):
+# on_x = x
+# on_y = y
+# for i in range(iterations):
+# next_x = (split_ratio * (on_x/np.sin(on_y))) + ((1 - split_ratio) * on_x/np.tan(on_y))
+# on_y = (split_ratio * (on_y/np.sin(on_x))) + ((1 - split_ratio) * on_y/np.tan(on_x))
+# on_x = next_x
+# if on_x**2 + on_y**2 > escape:
+# break
+# image[pix_y][pix_x] = i
+# rendered_frame = ax.imshow(image, norm="log", aspect="auto", cmap=cmap, animated=False)
+# rendered_frames.append([rendered_frame])
+# bar_total()
+
+def display():
+ print(rendered_frames)
+ ani = animation.ArtistAnimation(fig, rendered_frames, interval=30, blit=True)
+ ani.save("test.mp4")
+ plt.show()
+
+render()
+display()