Skip to content

Instantly share code, notes, and snippets.

@wrightwriter
Created November 19, 2023 13:55
Show Gist options
  • Save wrightwriter/53395a7a50f38eb5079cce80306360e3 to your computer and use it in GitHub Desktop.
Save wrightwriter/53395a7a50f38eb5079cce80306360e3 to your computer and use it in GitHub Desktop.
#version 420 core
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 restrict uimage2D[3] computeTex;
layout(r32ui) uniform coherent restrict 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, float t){
p *= 0.6;
// depth of field
//p.xy += sample_disk() * abs(p.z - 5. + sin(T))*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);
}
void main(void){
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();
vec3 att = hsv2rgb(vec3(hue*1,1,1));
// time envelopes
float t = T*0.6;
float env_a = floor(t) + pow(fract(t),2);
t*=0.5;
float env_b = floor(t) + pow(fract(t),2);
// start pos
vec3 p = hash_v3();
// Only run for the first 200 horizontal pixels
if(gl_FragCoord.x < 200){
for(float i = 0.; i < 100; i++){
// just totally random transforms. (can be anything)
// p/=dot(p,p) is used a lot in fractals
p/= dot(p,p);
float r = hash_f();
if(r < 0.3){
p -= vec3(0.1,0.4,0.2)*3.7 + sin((T+sin(T))*0.3)*0.2;
p /= dot(p,p);
p.xz *= rot(0.3 + env_a);
} else if(r < 0.7){
p *= vec3(23,1,1);
p -= 2.;
//p = sin(p);
} else{
p = -p;
p.xy *= rot(0.5 + (sin(env_b)*1.7));
}
// draw point
ivec2 q = proj_p(p, T);
if(q.x >= 0){
add_to_pixel(q, 0.5 + 0.5*sin(vec3(3.,2,1)*(1+p.z*.5) + p.z));
}
}
}
// 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