commit a2beea11221ab50b2faa7dd6651e6458620e4c48
parent deb6c72f2428afd5ca5c69559982073659fabbee
Author: Pollux <pollux@pollux.codes>
Date: Sun, 19 Jan 2025 13:59:30 -0600
docs: Improve examples
Signed-off-by: Pollux <pollux@pollux.codes>
Diffstat:
4 files changed, 188 insertions(+), 24 deletions(-)
diff --git a/README.md b/README.md
@@ -32,6 +32,8 @@ runcl \
output-png-file
```
+The default image size is `640x480`.
+
Use `clinfo` to see platform information. By default the platform with index 0
is chosen.
@@ -41,5 +43,6 @@ In order for `runcl` to work, the OpenCL file used must have a kernel named
`render` with three arguments, `const int width`, `const int height`, and
`__global float *out`.
-See the `example.cl` file for a demonstration of these requirements, as well as
-the suggested way of using the arguments.
+See `examples/gradient.cl` for a demonstration of these requirements, as well
+as the suggested way of using the arguments. The other files in the `examples`
+folder contain more sophisticated files for generating more complex images.
diff --git a/example.cl b/example.cl
@@ -1,22 +0,0 @@
-// This is the main function of the program.
-// Runcl passes the following arguments to the program.
-// - width: the width of the image in pixels
-// - height: the height of the image in pixels
-// - *out: the output of the program, formatted as an 3xwxh array of normalized rgm pixel colors
-kernel void render(const int width, const int height, __global float *out)
-{
- // this gets the id of the particular instance
- const int i = get_global_id(0);
-
- if ( i < width * height )
- {
- // this converts the id into normalized image coordinates
- float x = (float)(i % width) / width;
- float y = (float)(i / width) / height;
-
- // output the rgb color to the out array
- out[3*i] = x;
- out[3*i+1] = x;
- out[3*i+2] = x;
- }
-}
diff --git a/examples/calligraphy.cl b/examples/calligraphy.cl
@@ -0,0 +1,158 @@
+#define CROSSHAIRS false
+
+#define AA 1.f
+#define MAX_DWELL 10000
+#define BAILOUT 1000000000000.f
+
+#define LOG2 0.6931471806
+
+#define SCALE 0.00151f
+#define XCENTER -0.77235f
+#define YCENTER -0.10664f
+
+kernel void render(const int width, const int height, __global float *out)
+{
+ const int i = get_global_id(0);
+
+ if(CROSSHAIRS && (i%width == 1146 || i%width == 2294 || i/width == 480 || i/width == 960))
+ {
+ out[3*i] = 1.f;
+ out[3*i+1] = 0.f;
+ out[3*i+2] = 0.f;
+ return;
+ }
+
+ if(i < width * height)
+ {
+
+ float4 pix_col = (float4)(0.f);
+
+ for(float dx = 0.f; dx < 1.f; dx += AA)
+ {
+ for(float dy = 0.f; dy < 1.f; dy += AA)
+ {
+
+ float x = (float)(i % width - width/2 + dx) / height;
+ float y = (float)(i / width - height/2 + dy) / height;
+
+ float cx = x * SCALE + XCENTER;
+ float cy = y * SCALE + YCENTER;
+
+ float zx = 0.f;
+ float zy = 0.f;
+
+ float dzx = 0.0f;
+ float dzy = 0.0f;
+ float tmp;
+
+ int n;
+ float x2, y2;
+
+
+ // Color
+ float arg;
+ float4 st_avg = (float4)(0.f);
+ float4 st_avg2 = (float4)(0.f);
+
+ float highlight = 0.f;
+
+ // Main Loop
+ for(n = 0; n < MAX_DWELL; n++)
+ {
+ arg = atan2(zy, zx);
+
+ st_avg = st_avg.xxyz;
+ st_avg.x += sin( 11.f * arg);
+
+ st_avg2 = st_avg2.xxyz;
+ st_avg2.x += sin( 11.f * arg);
+
+ highlight += exp(-(zx-.5f)*(zx-.5f)*100000.f);
+
+ x2 = zx*zx;
+ y2 = zy*zy;
+
+ if(x2 + y2 > BAILOUT)
+ {
+ break;
+ }
+
+ tmp = 2.0f * (zx*dzx - zy*dzy) + 1.0f;
+ dzy = 2.0f * (zx*dzy + zy*dzx);
+ dzx = tmp;
+
+ zy = (zx+zx)*zy + cy;
+ zx = x2 - y2 + cx;
+ }
+
+ if(n < MAX_DWELL)
+ {
+ float z_mag = sqrt(zx*zx+zy*zy);
+ float dist = z_mag * log(z_mag) / sqrt(dzx*dzx + dzy*dzy);
+ float c1 = pow(min(1.f, 5000000.f*dist), 3.f);
+
+
+
+ float4 fac = (float4)(1.f) / (float4)(n, n-1, n-2, n-3);
+ st_avg = st_avg * fac + (float4)(1.f);
+ st_avg2 = st_avg2 * fac + (float4)(1.f);
+
+ float nu, nu2, nu3, nc;
+
+ nu = 1.f - log2(log(zx*zx + zy*zy)/log(10000000000.f));
+ nu2 = nu*nu;
+ nu3 = nu2*nu;
+ nc = n + nu;
+
+ float4 interp = (float4)(
+ -nu2 + nu3,
+ nu + 4.f*nu2 - 3.f*nu3,
+ 2.f - 5.f*nu2 + 3.f*nu3,
+ -nu + 2.f*nu2 - nu3
+ );
+
+ float c2 = max(0.f, min(1.f, dot(interp, st_avg)-1.0f));
+
+
+ float gx = (zx*dzx + zy*dzy)/(dzx*dzx + dzy*dzy);
+ float gy = (zy*dzx - zx*dzy)/(dzx*dzx + dzy*dzy);
+ float l = sqrt(gx*gx + gy*gy);
+ gx /= l;
+ gy /= l;
+ float c3 = 1.0f/sqrt(2.0f) * (gx + gy);
+
+ c3 = max(0.f, c3 + 1.f) * 0.3f + 0.4f;
+
+
+ float c5 = max(0.f, min(1.f, (dot(interp, st_avg2) - 2.f)/(n+nu)*100.f));
+ c5 = pow(c5, 2.5f);
+
+ //c1=1.f;
+ //c2=1.f;
+ //c3=1.f;
+
+
+ float4 base = (float4)(239, 241, 245, 0)/255.f;
+ float4 base2 = (float4)(172, 176, 190, 0)/255.f;
+ float4 red = (float4)(114, 135, 253, 0)/255.f;
+ float4 text = (float4)(76, 79, 105, 0)/255.f;
+
+
+ float4 color = mix(base2, base, c2*c3);
+ color = mix(text, color, c1);
+
+ pix_col += color;
+ }
+ else
+ {
+ float4 color = (float4)(76, 79, 105, 0)/255.f;
+ pix_col += color;
+ }
+ }
+ }
+
+ out[3*i] = pix_col.x*AA*AA;
+ out[3*i+1] = pix_col.y*AA*AA;
+ out[3*i+2] = pix_col.z*AA*AA;
+ }
+}
diff --git a/examples/gradient.cl b/examples/gradient.cl
@@ -0,0 +1,25 @@
+// This is the main function of the program.
+// Runcl passes the following arguments to the program.
+// - width: the width of the image in pixels
+// - height: the height of the image in pixels
+// - *out: the output of the program, formatted as an 3xwxh array of
+// normalized rgb pixel colors
+kernel void render(const int width, const int height, __global float *out)
+{
+ // This gets the id of the particular instance.
+ const int i = get_global_id(0);
+
+ // Depending on the image size, some instances may be outside of the image
+ // bounds. Make sure to check for this!
+ if ( i < width * height )
+ {
+ // This converts the instance ID into normalized image coordinates.
+ float x = (float)(i % width) / width;
+ float y = (float)(i / width) / height;
+
+ // Finally, output the rgb color to the output array.
+ out[3*i] = x;
+ out[3*i+1] = x;
+ out[3*i+2] = x;
+ }
+}