-
-
Save rexim/ef86bf70918034a5a57881456c0a0ccf to your computer and use it in GitHub Desktop.
| // $ cc -o checker checker.c | |
| // $ ./checker | |
| // $ ffmpeg -i output-%02d.ppm -r 60 output.mp4 | |
| #include <stdio.h> | |
| int main() | |
| { | |
| char buf[256]; | |
| for (int i = 0; i < 60; ++i) { | |
| snprintf(buf, sizeof(buf), "output-%02d.ppm", i); | |
| const char *output_path = buf; | |
| FILE *f = fopen(output_path, "wb"); | |
| int w = 16*60; | |
| int h = 9*60; | |
| fprintf(f, "P6\n"); | |
| fprintf(f, "%d %d\n", w, h); | |
| fprintf(f, "255\n"); | |
| for (int y = 0; y < h; ++y){ | |
| for (int x = 0; x < w; ++x) { | |
| if (((x + i)/60 + (y + i)/60)%2) { | |
| fputc(0xFF, f); | |
| fputc(0x00, f); | |
| fputc(0x00, f); | |
| } else { | |
| fputc(0x00, f); | |
| fputc(0x00, f); | |
| fputc(0x00, f); | |
| } | |
| } | |
| } | |
| fclose(f); | |
| printf("Generated %s\n", output_path); | |
| } | |
| return 0; | |
| } |
| // $ cc -O3 -o plasma plasma.cpp -lm | |
| // $ ./plasma | |
| // $ ffmpeg -i output-%03d.ppm -r 60 output.mp4 | |
| #include <stdio.h> | |
| #include <math.h> | |
| struct vec4 { | |
| float x, y, z, w; | |
| vec4(float x = 0, float y = 0, float z = 0, float w = 0): | |
| x(x), y(y), z(z), w(w) | |
| {} | |
| }; | |
| struct vec2 { | |
| float x, y; | |
| vec2(float x = 0, float y = 0): | |
| x(x), y(y) | |
| {} | |
| vec2 yx() const { return vec2(y, x); } | |
| vec4 xyyx() const { return vec4(x, y, y, x); } | |
| }; | |
| vec2 operator *(const vec2 &a, float s) { return vec2(a.x*s, a.y*s); } | |
| vec2 operator +(const vec2 &a, float s) { return vec2(a.x+s, a.y+s); } | |
| vec2 operator *(float s, const vec2 &a) { return a*s; } | |
| vec2 operator -(const vec2 &a, const vec2 &b) { return vec2(a.x-b.x, a.y-b.y); } | |
| vec2 operator +(const vec2 &a, const vec2 &b) { return vec2(a.x+b.x, a.y+b.y); } | |
| vec2 operator *(const vec2 &a, const vec2 &b) { return vec2(a.x*b.x, a.y*b.y); } | |
| vec2 operator /(const vec2 &a, float s) { return vec2(a.x/s, a.y/s); } | |
| float dot(const vec2 &a, const vec2 &b) { return a.x*b.x + a.y*b.y; } | |
| vec2 abs(const vec2 &a) { return vec2(fabsf(a.x), fabsf(a.y)); } | |
| vec2 &operator +=(vec2 &a, const vec2 &b) { a = a + b; return a; } | |
| vec2 &operator +=(vec2 &a, float s) { a = a + s; return a; } | |
| vec2 cos(const vec2 &a) { return vec2(cosf(a.x), cosf(a.y)); } | |
| vec4 sin(const vec4 &a) { return vec4(sinf(a.x), sinf(a.y), sinf(a.z), sinf(a.w)); } | |
| vec4 exp(const vec4 &a) { return vec4(expf(a.x), expf(a.y), expf(a.z), expf(a.w)); } | |
| vec4 tanh(const vec4 &a) { return vec4(tanhf(a.x), tanhf(a.y), tanhf(a.z), tanhf(a.w)); } | |
| vec4 operator +(const vec4 &a, float s) { return vec4(a.x+s, a.y+s, a.z+s, a.w+s); } | |
| vec4 operator *(const vec4 &a, float s) { return vec4(a.x*s, a.y*s, a.z*s, a.w*s); } | |
| vec4 operator *(float s, const vec4 &a) { return a*s; } | |
| vec4 operator +(const vec4 &a, const vec4 &b) { return vec4(a.x+b.x, a.y+b.y, a.z+b.z, a.w+b.w); } | |
| vec4 &operator +=(vec4 &a, const vec4 &b) { a = a + b; return a; } | |
| vec4 operator -(float s, const vec4 &a) { return vec4(s-a.x, s-a.y, s-a.z, s-a.w); } | |
| vec4 operator /(const vec4 &a, const vec4 &b) { return vec4(a.x/b.x, a.y/b.y, a.z/b.z, a.w/b.w); } | |
| int main() | |
| { | |
| char buf[256]; | |
| for (int i = 0; i < 240; ++i) { | |
| snprintf(buf, sizeof(buf), "output-%03d.ppm", i); | |
| const char *output_path = buf; | |
| FILE *f = fopen(output_path, "wb"); | |
| int w = 16*60; | |
| int h = 9*60; | |
| fprintf(f, "P6\n"); | |
| fprintf(f, "%d %d\n", w, h); | |
| fprintf(f, "255\n"); | |
| vec2 r = {(float)w, (float)h}; | |
| float t = ((float)i/240)*2*M_PI; | |
| for (int y = 0; y < h; ++y){ | |
| for (int x = 0; x < w; ++x) { | |
| vec4 o; | |
| vec2 FC = {(float)x, (float)y}; | |
| ////////////////////////////// | |
| // https://x.com/XorDev/status/1894123951401378051 | |
| vec2 p=(FC*2.-r)/r.y,l,i,v=p*(l+=4.-4.*abs(.7-dot(p,p))); | |
| for(;i.y++<8.;o+=(sin(v.xyyx())+1.)*abs(v.x-v.y))v+=cos(v.yx()*i.y+i+t)/i.y+.7; | |
| o=tanh(5.*exp(l.x-4.-p.y*vec4(-1,1,2,0))/o); | |
| ////////////////////////////// | |
| fputc(o.x*255, f); | |
| fputc(o.y*255, f); | |
| fputc(o.z*255, f); | |
| } | |
| } | |
| fclose(f); | |
| printf("Generated %s (%3d/%3d)\n", output_path, i + 1, 240); | |
| } | |
| return 0; | |
| } |
i have my own attempt with better vect here
output.mp4
Odin version from c version by https://claude.ai. Repo at https://github.com/rofrol/plasma-cpu-graphics.
// $ odin run .
// $ ffmpeg -i output-%03d.ppm -r 60 output.mp4
package main
import "core:fmt"
import "core:math"
import "core:os"
import "core:strings"
abs :: proc(x: f32) -> f32 {
return x if x > 0 else -x
}
vec2_yx :: proc(v: [2]f32) -> [2]f32 {
return {v.y, v.x}
}
vec2_xyyx :: proc(v: [2]f32) -> [4]f32 {
return {v.x, v.y, v.y, v.x}
}
vec2_cos :: proc(v: [2]f32) -> [2]f32 {
return {math.cos(v.x), math.cos(v.y)}
}
vec4_sin :: proc(v: [4]f32) -> [4]f32 {
return {math.sin(v.x), math.sin(v.y), math.sin(v.z), math.sin(v.w)}
}
vec4_tanh :: proc(v: [4]f32) -> [4]f32 {
return {math.tanh(v.x), math.tanh(v.y), math.tanh(v.z), math.tanh(v.w)}
}
vec4_exp :: proc(v: [4]f32) -> [4]f32 {
return {math.exp(v.x), math.exp(v.y), math.exp(v.z), math.exp(v.w)}
}
vec2_dot :: proc(a, b: [2]f32) -> f32 {
return a.x * b.x + a.y * b.y
}
main :: proc() {
w_ratio: u16 = 16
h_ratio: u16 = 9
factor: u16 = 60
w := w_ratio * factor
h := h_ratio * factor
max_ts: u16 = 240
for ts in 0..<max_ts {
// Open output file corresponding to current ts
output_fp := fmt.tprintf("plasma-%04d.ppm", ts)
f, err := os.open(output_fp, os.O_WRONLY | os.O_CREATE | os.O_TRUNC, 0o644)
if err != os.ERROR_NONE {
fmt.fprintf(os.stderr, "[ERROR] Could not open %s because: %v\n", output_fp, err)
os.exit(1)
}
defer os.close(f)
// Preamble output file
header := fmt.tprintf("P6\n%d %d\n255\n", w, h)
os.write_string(f, header)
r := [2]f32{f32(w), f32(h)}
t := f32(ts) / f32(max_ts) * 2.0 * math.PI
for y in 0..<h {
for x in 0..<w {
FC := [2]f32{f32(x), f32(y)}
p := FC * 2.0
p = p - r
p = p / r.y
l := [2]f32{0, 0}
l = l + (4.0 - 4.0 * abs(0.7 - vec2_dot(p, p)))
v := p * l
o := [4]f32{0, 0, 0, 0} // o: output of a single fragment (pixel)
for iy in 1..=8 {
tmp0 := vec2_yx(v)
tmp0 = tmp0 * f32(iy)
tmp0 = tmp0 + [2]f32{0.0, f32(iy)}
tmp0 = tmp0 + t
tmp0 = vec2_cos(tmp0)
tmp0 = tmp0 / f32(iy)
tmp0 = tmp0 + 0.7
v = v + tmp0
tmp1 := vec2_xyyx(v)
tmp1 = vec4_sin(tmp1)
tmp1 = tmp1 + 1.0
tmp1 = tmp1 * abs(v.x - v.y)
o = o + tmp1
}
tmp3 := [4]f32{-1.0, 1.0, 2.0, 0.0} * (-p.y)
tmp3 = tmp3 + (l.x - 4.0)
tmp3 = vec4_exp(tmp3)
tmp3 = tmp3 * 5.0
o = tmp3 / o
o = vec4_tanh(o)
pixel: [3]u8 = {
u8(o.x * 255.0),
u8(o.y * 255.0),
u8(o.z * 255.0),
}
os.write(f, pixel[:])
}
}
fmt.printf("[INFO] Generated %s (%3d/%3d)\n", output_fp, ts + 1, max_ts)
}
}Very cool demo!
I built a real-time CPU-based shader with audio playback + reactivity (C++ Win32 & Java cross-platform).
Repo + demo video: https://github.com/ljn7/Audio-Shader
RPI4 BareMetal port of the glsl compatibility layer
https://github.com/sidd-kishan/circle/tree/master/sample/48-GLSL_Compatibility_based_41
running on qemu can run on any rpi4 aswell
just place the follwoing file in the root of a fat32 formatted usb drive
- armstub8-rpi4.bin
- bcm2711-rpi-4-b.dtb
- config.txt
- fixup4.dat
- kernel8-rpi4.img
- start4.elf
I did a thing
GLSL C++ Library with Multithreaded Fragment Rendering
This version supports swizzling, and assigns line rendering tasks from a pool of worker threads.
- console
- SDL GUI application
- Raylib GUI application
void render_fragment(const vec4 FC,
const vec2 r,
const t_vec_float t, // double
vec4& o) {
vec2 p=(FC.xy*2.-r)/r.y,l,i,v=p*(l+=4.-4.*abs(.7-dot(p,p)));
for(;i.y++<8.;o+=(sin(v.xyyx)+1.)*abs(v.x-v.y))v+=cos(v.yx*i.y+i+t)/i.y+.7;
o=tanh(5.*exp(l.x-4.-p.y*vec4(-1,1,2,0))/o);
}Ported Xor's Interference Shader
screencap of the Interference shader
// https://www.xordev.com/arsenal?alphabetical=interference
// https://twigl.app?ol=true&ss=-OkoKgRL0jy4Ye8ktl51
void render_fragment(const vec4 FC,
const vec2 r,
const t_vec_float t,
vec4& o) {
vec2 p = (FC.xy * 2. - r) / r.y, v = p - clamp(p, -.3, .3),
l = vec2(atan(p.y, p.x), length(v));
o = tanh((cos(l.x + sin(l.x / .2) * sin(l.y / .02 - t) * .4 + t +
vec4(0, 2, 4, 0)) +
1.2) *
exp(cos(l.x / .2) * cos(l.y / .02 - t)) / l.y / 3e1) *
clamp(l * r * .1, 0., 1.).y;
}
so nice work i didnt know about ppm format.
this is my port to c# :
code port c#
output.mp4