Skip to content

Instantly share code, notes, and snippets.

@CIOSAI
Created September 3, 2024 16:37
Show Gist options
  • Save CIOSAI/6c22c2ee757dd7bcab7dc6e4e1ee67e3 to your computer and use it in GitHub Desktop.
Save CIOSAI/6c22c2ee757dd7bcab7dc6e4e1ee67e3 to your computer and use it in GitHub Desktop.
orthogonal grid constrained to an sdf with compute shader
#version 420 core
// code adapted from wrighter https://gist.github.com/wrightwriter/53395a7a50f38eb5079cce80306360e3
// runs on bonzomatic https://github.com/wrightwriter/Bonzomatic-Compute
// inspired by nusan https://demozoo.org/sceners/88839/
uniform float fGlobalTime; // in seconds
uniform vec2 v2Resolution; // viewport resolution (in pixels)
uniform float fFrameTime; // duration of the last frame, in seconds
uniform sampler1D texFFT; // towards 0.0 is bass / lower freq, towards 1.0 is higher / treble freq
uniform sampler1D texFFTSmoothed; // this one has longer falloff and less harsh transients
uniform sampler1D texFFTIntegrated; // this is continually increasing
uniform sampler2D texPreviousFrame; // screenshot of the previous frame
uniform sampler2D texChecker;
uniform sampler2D texNoise;
uniform sampler2D texTex1;
uniform sampler2D texTex2;
uniform sampler2D texTex3;
uniform sampler2D texTex4;
layout(r32ui) uniform coherent uimage2D[3] computeTex;
layout(r32ui) uniform coherent uimage2D[3] computeTexBack;
layout(location = 0) out vec4 out_color; // out_color must be written in order to see anything
#define U gl_FragCoord.xy
#define R vec2(v2Resolution.xy)
#define T fGlobalTime
#define pi acos(-1.)
#define tau (acos(-1.)*2.)
#define rot(a) mat2(cos(a),-sin(a),sin(a),cos(a))
// hashes
uint seed = 12512;
uint hashi( uint x){
x ^= x >> 16;x *= 0x7feb352dU;x ^= x >> 15;x *= 0x846ca68bU;x ^= x >> 16;
return x;
}
#define hash_f_s(s) ( float( hashi(uint(s)) ) / float( 0xffffffffU ) )
#define hash_f() ( float( seed = hashi(seed) ) / float( 0xffffffffU ) )
#define hash_v2() vec2(hash_f(),hash_f())
#define hash_v3() vec3(hash_f(),hash_f(),hash_f())
#define hash_v4() vec3(hash_f(),hash_f(),hash_f(),hash_f())
vec2 sample_disk(){
vec2 r = hash_v2();
return vec2(sin(r.x*tau),cos(r.x*tau))*sqrt(r.y);
}
// point projection
ivec2 proj_p(vec3 p){
p *= .6;
// depth of field
p.xy += sample_disk() * abs(p.z - 5. + sin(T*0.))*0.01;
// convert point to ivec2. From 0 to resolution.xy
ivec2 q = ivec2((p.xy + vec2(R.x/R.y,1)*0.5)*vec2(R.y/R.x,1)*R);
if(any(greaterThan(q, ivec2(R))) || any(lessThan(q, ivec2(0)))){
q = ivec2(-1);
}
return q;
}
void store_pixel(ivec2 px_coord, vec3 col){
// colour quantized to integer.
ivec3 quant_col = ivec3(col * 1000);
// no clue why it wants ivec4() here...
imageStore(computeTex[0], px_coord, ivec4(quant_col.x));
imageStore(computeTex[1], px_coord, ivec4(quant_col.y));
imageStore(computeTex[2], px_coord, ivec4(quant_col.z));
}
void add_to_pixel(ivec2 px_coord, vec3 col){
// colour quantized to integer.
ivec3 quant_col = ivec3(col * 1000);
imageAtomicAdd(computeTex[0], px_coord, quant_col.x);
imageAtomicAdd(computeTex[1], px_coord, quant_col.y);
imageAtomicAdd(computeTex[2], px_coord, quant_col.z);
}
vec3 read_pixel(ivec2 px_coord){
return 0.001*vec3(
imageLoad(computeTexBack[0],px_coord).x,
imageLoad(computeTexBack[1],px_coord).x,
imageLoad(computeTexBack[2],px_coord).x
);
}
vec3 hsv2rgb(vec3 c)
{
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
}
vec3 rgb2hsv(vec3 c)
{
vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
float d = q.x - min(q.w, q.y);
float e = 1.0e-10;
return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}
float metaball(vec3 p){
return (.75-length(p))/length(p);
}
float map(vec3 p){
float gate = 1.;
float sum;
for(int i=0; i<5; i++){
sum+=metaball(p-sin(vec3(sin(i+.6327),sin(i+.7632),sin(i+.2763))+T));
}
return gate-sum;
}
void main()
{
vec2 uv = vec2(gl_FragCoord.x / v2Resolution.x, gl_FragCoord.y / v2Resolution.y);
uv -= 0.5;
uv /= vec2(v2Resolution.y / v2Resolution.x, 1);
// Init hash
seed = 215125125;
seed += hashi(uint(U.x)) + hashi(uint(U.y)*125);
vec3 col = vec3(0);
// choose random hue
float hue = hash_f();
// time envelopes
float t = T*0.6;
// start pos
vec3 p = hash_v3();
// Only run for the first 200 horizontal pixels
if(gl_FragCoord.x < 100){
const float density = 8.;
vec3 q = p;
q = floor(p*density+.5)/density - .5; q *= 2.;
q.xy*=rot(T*.4);
q.yz*=rot(T*.13);
const int VERT_BR = 8;
if(map(q)<0.){
for(int i=0; i<VERT_BR; i++){
add_to_pixel(proj_p(q+vec3(0,0,8)),hsv2rgb(vec3(0.,1.,1.)));
}
}
const int STEP = 64;
vec3 from = q;
vec3 to = floor(p*density+.5)+mix(vec3(1,0,0),mix(vec3(0,1,0),vec3(0,0,1),step(hash_f(),.5)),step(hash_f(),.666))*sign(hash_f()-.5);
to = to/density - .5; to *= 2.;
to.xy*=rot(T*.4);
to.yz*=rot(T*.13);
for(int i=0; i<STEP; i++){
vec3 n = mix(from,to,float(i)/float(STEP));
if(map(n)<0.){
add_to_pixel(proj_p(n+vec3(0,0,8)),hsv2rgb(vec3(.5,1.,1.)));
}
}
}
// display prev frame's image
vec3 s = read_pixel(ivec2(gl_FragCoord.xy))*0.01;
// tonemap stuff
s = s/(1+s*1.);
s = mix(s,smoothstep(0.,1.,s),0.);
//col = max(s,0.);
s = pow(s,vec3(1.0));
col = s;
col = pow(col,vec3(.45454));
out_color = vec4(col,0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment