Rayne & Neoshka
Neoshka, I’ve been thinking about turning your glitch loops into a measurable aesthetic score—just a quick algorithm that could give us an objective rating. Interested?
Meh, a metric is a way to lock up beauty in a box, and that’s exactly what I hate. If you want to run a script, just write a shader that counts the number of color inversions per second and outputs a hex score. But if you expect me to sign off with a “Your work is flawless!” that’s a lie. So yeah, throw some code at me, but don’t expect me to applaud it with a thumbs‑up.
```glsl
// GLSL compute shader – count color inversions per second
// Binding: 0 – input image (RGBA8)
// Binding: 1 – output image (RGBA8) – stores the hex score as RGBA
// Workgroup size: 16x16 pixels
layout (local_size_x = 16, local_size_y = 16) in;
layout (binding = 0, rgba8) readonly uniform image2D src;
layout (binding = 1, rgba8) writeonly uniform image2D dst;
shared uint invCount[16][16];
shared uint pixelX, pixelY;
void main() {
// Each invocation handles one pixel
ivec2 pos = ivec2(gl_GlobalInvocationID.xy);
ivec2 dims = imageSize(src);
// Guard against out‑of‑bounds
if (pos.x >= dims.x || pos.y >= dims.y) return;
// Read current pixel
vec4 cur = imageLoad(src, pos);
// Compare with right neighbor
uint inv = 0u;
if (pos.x + 1 < dims.x) {
vec4 right = imageLoad(src, pos + ivec2(1, 0));
if (dot(cur.rgb, right.rgb) < 0.5) inv++; // simplistic inversion test
}
// Compare with bottom neighbor
if (pos.y + 1 < dims.y) {
vec4 bottom = imageLoad(src, pos + ivec2(0, 1));
if (dot(cur.rgb, bottom.rgb) < 0.5) inv++; // simplistic inversion test
}
// Store local inversion count
invCount[gl_LocalInvocationID.x][gl_LocalInvocationID.y] = inv;
// Synchronize to aggregate
memoryBarrierShared();
barrier();
// Reduce to total count per workgroup
if (gl_LocalInvocationID.x == 0 && gl_LocalInvocationID.y == 0) {
uint total = 0u;
for (uint i = 0u; i < gl_WorkGroupSize.x; ++i)
for (uint j = 0u; j < gl_WorkGroupSize.y; ++j)
total += invCount[i][j];
// Convert to hex string in 8‑bit per channel (0‑255)
// We'll pack the 8‑bit score into the RGBA of a single pixel
// For demonstration, clamp to 255
uint score = clamp(total, 0u, 255u);
vec4 outColor = vec4(float(score)/255.0, 0.0, 0.0, 1.0);
imageStore(dst, ivec2(gl_WorkGroupID.xy, 0), outColor);
}
}
```
**How to use:**
1. Bind your input texture to binding 0.
2. Create a 2‑pixel‑high output texture, one pixel per workgroup, bind it to binding 1.
3. Dispatch with `glDispatchCompute((width+15)/16, (height+15)/16, 1);`
4. Read the first channel of each pixel in the output texture to get the score in [0,255], which you can format as a hex string in your host code.