Skip to content

Instantly share code, notes, and snippets.

@CharStiles
Last active March 16, 2020 01:05
Show Gist options
  • Save CharStiles/fd01fb6eaaf5463e09c801825b01720f to your computer and use it in GitHub Desktop.
Save CharStiles/fd01fb6eaaf5463e09c801825b01720f to your computer and use it in GitHub Desktop.
#ifdef GL_ES
precision highp float;
#endif
uniform float time1;
uniform vec2 resolution;
uniform vec2 mouse;
uniform vec3 spectrum;
uniform sampler2D texture0;
uniform sampler2D texture1;
uniform sampler2D texture2;
uniform sampler2D texture3;
uniform sampler2D prevFrame;
uniform sampler2D prevPass;
uniform int frame;
varying vec3 v_normal;
varying vec2 v_texcoord;
#ifdef GL_ES
precision highp float;
#endif
#define HASHSCALE1 vec3(.1031)
float time = float(frame)/100;
float PI = 3.1415;
float PHI = 1.61803398874989;
const float howMuchBlur = 7.;
float xu = 2.0/resolution.x;
float yu = 2.0/resolution.y;
const int steps = 166;
//float time = time1/20.;
// 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);
// }
vec4 permute(vec4 x) { return mod(((x*34.0)+1.0)*x, 289.0); }
vec4 taylorInvSqrt(vec4 r) { return 1.79284291400159 - 0.85373472095314 * r; }
float snoise(vec3 v){
const vec2 C = vec2(1.0/6.0, 1.0/3.0) ;
const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);
vec3 i = floor(v + dot(v, C.yyy) );
vec3 x0 = v - i + dot(i, C.xxx) ;
vec3 g = step(x0.yzx, x0.xyz);
vec3 l = 1.0 - g;
vec3 i1 = min( g.xyz, l.zxy );
vec3 i2 = max( g.xyz, l.zxy );
vec3 x1 = x0 - i1 + 1.0 * C.xxx;
vec3 x2 = x0 - i2 + 2.0 * C.xxx;
vec3 x3 = x0 - 1. + 3.0 * C.xxx;
i = mod(i, 289.0 );
vec4 p = permute( permute( permute( i.z + vec4(0.0, i1.z, i2.z, 1.0 )) + i.y + vec4(0.0, i1.y, i2.y, 1.0 )) + i.x + vec4(0.0, i1.x, i2.x, 1.0 ));
float n_ = 1.0/7.0;
vec3 ns = n_ * D.wyz - D.xzx;
vec4 j = p - 49.0 * floor(p * ns.z *ns.z);
vec4 x_ = floor(j * ns.z);
vec4 y_ = floor(j - 7.0 * x_ );
vec4 x = x_ *ns.x + ns.yyyy;
vec4 y = y_ *ns.x + ns.yyyy;
vec4 h = 1.0 - abs(x) - abs(y);
vec4 b0 = vec4( x.xy, y.xy );
vec4 b1 = vec4( x.zw, y.zw );
vec4 s0 = floor(b0)*2.0 + 1.0;
vec4 s1 = floor(b1)*2.0 + 1.0;
vec4 sh = -step(h, vec4(0.0));
vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ;
vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ;
vec3 p0 = vec3(a0.xy,h.x);
vec3 p1 = vec3(a0.zw,h.y);
vec3 p2 = vec3(a1.xy,h.z);
vec3 p3 = vec3(a1.zw,h.w);
vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));
p0 *= norm.x;
p1 *= norm.y;
p2 *= norm.z;
p3 *= norm.w;
vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);
m = m * m;
return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1), dot(p2,x2), dot(p3,x3) ) );
}
float snoise(float x, float y, float z){
return snoise(vec3(x, y, z));
}
float random (in vec2 _st) {
return fract(sin(dot(_st.xy,
vec2(12.9898,78.233)))*
43758.5453123);
}
const mat2 myt = mat2(.12121212, .13131313, -.13131313, .12121212);
const vec2 mys = vec2(1e4, 1e6);
vec2 rhash(vec2 uv) {
uv *= myt;
uv *= mys;
return fract(fract(uv / mys) * uv);
}
vec3 hash(vec3 p) {
return fract(
sin(vec3(dot(p, vec3(1.0, 57.0, 113.0)), dot(p, vec3(57.0, 113.0, 1.0)),
dot(p, vec3(113.0, 1.0, 57.0)))) *
43758.5453);
}
vec3 voronoi(const in vec3 x) {
vec3 p = floor(x);
vec3 f = fract(x);
float id = 0.0;
vec2 res = vec2(100.0);
for (int k = -1; k <= 1; k++) {
for (int j = -1; j <= 1; j++) {
for (int i = -1; i <= 1; i++) {
vec3 b = vec3(float(i), float(j), float(k));
vec3 r = vec3(b) - f + hash(p + b);
float d = dot(r, r);
float cond = max(sign(res.x - d), 0.0);
float nCond = 1.0 - cond;
float cond2 = nCond * max(sign(res.y - d), 0.0);
float nCond2 = 1.0 - cond2;
id = (dot(p + b, vec3(1.0, 57.0, 113.0)) * cond) + (id * nCond);
res = vec2(d, res.x) * cond + res * nCond;
res.y = cond2 * d + nCond2 * res.y;
}
}
}
return vec3(sqrt(res), abs(id));
}
// Based on Morgan McGuire @morgan3d
// https://www.shadertoy.com/view/4dS3Wd
float noise (in vec2 _st) {
vec2 i = floor(_st);
vec2 f = fract(_st);
// Four corners in 2D of a tile
float a = random(i);
float b = random(i + vec2(1.0, 0.0));
float c = random(i + vec2(0.0, 1.0));
float d = random(i + vec2(1.0, 1.0));
vec2 u = f * f * (3.0 - 2.0 * f);
return mix(a, b, u.x) +
(c - a)* u.y * (1.0 - u.x) +
(d - b) * u.x * u.y;
}
//vec3 hash(vec3 p3)
//{
// p3 = fract(p3 * HASHSCALE1);
// p3 += dot(p3, p3.yxz+19.19);
// return fract((p3.xxy + p3.yxx)*p3.zyx);
//}
vec3 noise( in vec3 x )
{
vec3 p = floor(x);
vec3 f = fract(x);
f = f*f*(3.0-2.0*f);
return mix( mix(mix( hash(p+vec3(0,0,0)),
hash(p+vec3(1,0,0)),f.x),
mix( hash(p+vec3(0,1,0)),
hash(p+vec3(1,1,0)),f.x),f.y),
mix(mix( hash(p+vec3(0,0,1)),
hash(p+vec3(1,0,1)),f.x),
mix( hash(p+vec3(0,1,1)),
hash(p+vec3(1,1,1)),f.x),f.y),f.z);
}
float fbm ( in vec2 _st ) {
float v = 0.0;
float a = 0.5;
vec2 shift = vec2(100.0);
// Rotate to reduce axial bias
mat2 rot = mat2(cos(0.5), sin(0.5),
-sin(0.5), cos(0.50));
for (int i = 0; i < 4; ++i) {
v += a * noise(_st);
_st = rot * _st * 2.0 + shift;
a *= 0.5;
}
return v;
}
float fbm ( in vec2 _st, int no ) {
float v = 0.0;
float a = 0.5;
vec2 shift = vec2(100.0);
// Rotate to reduce axial bias
mat2 rot = mat2(cos(0.5), sin(0.5),
-sin(0.5), cos(0.50));
for (int i = 0; i < no; ++i) {
v += a * noise(_st);
_st = rot * _st * 2.0 + shift;
a *= 0.5;
}
return v;
}
const mat3 m3 = mat3( 0.00, 0.80, 0.60,
-0.80, 0.36, -0.48,
-0.60, -0.48, 0.64 );
vec3 fbm(in vec3 q,int i)
{
vec3 f = 0.5000*noise( q ); q = m3*q*2.01;
f += 0.2500*noise( q ); q = m3*q*2.02;
f += 0.1250*noise( q ); q = m3*q*2.03;
f += 0.0625*noise( q ); q = m3*q*2.04;
#if 1
f += 0.03125*noise( q ); q = m3*q*2.05;
f += 0.015625*noise( q ); q = m3*q*2.06;
f += 0.0078125*noise( q ); q = m3*q*2.07;
f += 0.00390625*noise( q ); q = m3*q*2.08;
#endif
return vec3(f);
}
float smin( float a, float b, float k )
{
float h = clamp( 0.5+0.5*(b-a)/k, 0.0, 1.0 );
return mix( b, a, h ) - k*h*(1.0-h);
}
// The "Round" variant uses a quarter-circle to join the two objects smoothly:
float fOpUnionRound(float a, float b, float r) {
vec2 u = max(vec2(r - a,r - b), vec2(0));
return max(r, min (a, b)) - length(u);
}
float fOpIntersectionRound(float a, float b, float r) {
vec2 u = max(vec2(r + a,r + b), vec2(0));
return min(-r, max (a, b)) + length(u);
}
float fOpDifferenceRound (float a, float b, float r) {
return fOpIntersectionRound(a, -b, r);
}
float virusHead (float p){
return cos(p);//+ noise(abs(p));
}
float modBlob(inout vec3 p){
float sz = 0.;
if (p.x < max(p.y, p.z)){
p = p.yzx;
//sz+=.007;
}
if (p.x < max(p.y, p.z)){
// sz-=0.05;
p = p.yzx;}
//PHI = 0.;
return sz;
}
float bFunct(vec3 p, vec3 savedP){ // this function places nubs around sphere
return max(max(max(
dot(p, normalize(vec3(1., 1, 1))),
dot(p.xz, normalize(vec2(PHI+1., 1.)))),
dot(p.yx, normalize(vec2(1., PHI )))),
dot(p.xz, normalize(vec2(1., PHI ))));
}
float fBlob(vec3 p) {
p = abs(p);
vec3 savedP = p;
float sz = 1.3;
sz += modBlob(p);
float b = bFunct(p,savedP);
float l = length(p);
float nub =(1.01 - b / l)*(PI / .04) - fbm(savedP*20.,20).x;
// float nub =(1.01 - b / l)*(PI / .04) - snoise(savedP*20.);
float sploops = l - sz - 0.09 * cos(min(nub, (PI)));
return fOpDifferenceRound (sploops,l-1.38, 0.15); // just ge tthe nubs
}
float virus(vec3 p) {
vec3 savedP = p;
p = abs(p);
float sz = 1.2;
sz += modBlob(p);
float b = bFunct(p,savedP);
float l = length(p);
return l - sz - 0.3 * (3. / 2.)* cos(min(sqrt(1.01 - b / l)*(PI / 0.15), PI )) +( noise(savedP.xy*20.) *0.01)+ noise(savedP.zy*17.) *0.03;
}
void pR(inout vec2 p, float a) {
p = cos(a)*p + sin(a)*vec2(p.y, -p.x);
}
float scene(vec3 ray){
float floor = (ray.y + 1.2) -
cos(ray.x * 10.)* 0.2 - sin(ray.y* 10.);
float radius = 0.5;
// ray = mod(ray, modSpace) - 0.5*modSpace;
ray = ray - vec3(0.,0.,2.0);
vec3 ray2 = ray;
vec3 ray3 = ray;
pR(ray2.yz,time/3. + fbm((vec2(time/3. ) / 2.),2) * 0.2);
pR(ray3.yz,time/3.);
vec3 ray4 = mix(ray2,ray3,(sin(time)/5.) + 1.);
pR(ray4.xz, noise(vec3(time/4.) ).x );
pR(ray4.xy, 0.2*noise(vec3(time) ).x );
float blob = fBlob(ray4);
float virus = virus(ray4);
return smin(blob,virus,.8 + (0.08* sin(time)));//smin(smin(blob, sphere,0.6), sphere2,0.6) ;
}
vec3 estimateNormal(vec3 p) {
float smallNumber = 0.002;
vec3 n = vec3(
scene(vec3(p.x + smallNumber, p.yz)) -
scene(vec3(p.x - smallNumber, p.yz)),
scene(vec3(p.x, p.y + smallNumber, p.z)) -
scene(vec3(p.x, p.y - smallNumber, p.z)),
scene(vec3(p.xy, p.z + smallNumber)) -
scene(vec3(p.xy, p.z - smallNumber))
);
return normalize(n);
}
float lighting(vec3 origin, vec3 dir, vec3 normal) {
vec3 lightPos = vec3(12,12,1);//vec3(cos(time) +12., sin(time), 12.);
vec3 light = normalize(lightPos - origin);
float diffuse = max(0., dot(light, normal));
vec3 reflectedRay = 2.2 * dot(light, normal) * normal - light;
float specular = max(0., (pow(dot(reflectedRay, light),5.)));
float ambient = 0.03;
return ambient + diffuse + specular;
}
float hex(vec2 p) {
p.x *= 0.57735*2.;
p.y += mod(floor(p.x), 2.)*.5;
p = abs((mod(p, 1.) - .5));
return abs(max(p.x*1.5 + p.y, p.y*2.) - 1.);
}
// the following function is from https://www.shadertoy.com/view/llScR1
float celli(in vec3 p){ p = fract(p)-.5; return dot(p, p); }
float cellTile2(in vec3 p){
vec4 d;
d.x = celli(p - vec3(.81, .62, .53));
p.xy = vec2(p.y-p.x, p.y + p.x)+hex(p.xy*0.2);
d.y = celli(p - vec3(.39, .2, .11));
p.yz = vec2(p.z-p.y, p.z + p.y)+hex(p.yz*0.2);
d.z = celli(p - vec3(.62, .24, .06));
p.xz = vec2(p.z-p.x, p.z + p.x)+hex(p.xz*0.2);
d.w = celli(p - vec3(.2, .82, .64));
d.xy = min(d.xz, d.yw);
return min(d.x, d.y)*.5;
}
// cosine based palette, 4 vec3 params
vec3 palette( in float t, in vec3 a, in vec3 b, in vec3 c, in vec3 d )
{
return a + b*cos( 6.28318*(c*t+d) );
}
vec4 trace(vec3 rayOrigin, vec3 dir){
vec3 ray = rayOrigin;
float dist = 0.;
float totalDist = 0.;
float maxDist = 3.;
for (int i = 0; i < steps ; i++){
dist = scene(ray);
if(dist < 00.04){
vec4 distCol = vec4(1. - vec4(totalDist/maxDist));
vec4 lightingCol = vec4(lighting(rayOrigin,dir,estimateNormal(ray)));
vec4 col = lightingCol;//mix(lightingCol , vec4(distCol),distCol.x);
return col;
}
totalDist += dist;
ray += dist * dir;
if (totalDist > maxDist){
break;
}
}
return vec4(0);
}
int howMuchFocus(float d){
float p = 1.46;// this is the focus point, make bigger for farther away
float fo = 0.7;// this is the fall off make bigger for slower fall off and smaller for more sharp
float fin= abs(d-p)/fo;
return int(fin* howMuchBlur);
}
vec4 blur(vec4 startCol, vec3 rayOrigin, vec3 dir, int howMuch){
if (mod(float(frame),2.) == 0.){
vec4 col = vec4(0);//startCol; // TODO figure out how to recalculate the dir
int div = 0;
for (int i = 1 ; i < int(howMuchBlur); i ++){
if (i > howMuch){
break;
}
float x = (xu * float(i))/2.0;
float y = (yu * float(i))/2.0;
col += texture2D(prevFrame, v_texcoord + vec2(x,0.));
col += texture2D(prevFrame, v_texcoord + vec2(x,-y));
col += texture2D(prevFrame,v_texcoord + vec2(0,-y));
col += texture2D(prevFrame,v_texcoord + vec2(-x,-y));
col += texture2D(prevFrame,v_texcoord + vec2(-x,0.));
col += texture2D(prevFrame, v_texcoord + vec2(-x,y));
col += texture2D(prevFrame, v_texcoord + vec2(0,y));
col += texture2D(prevFrame, v_texcoord + vec2(x,y));
div +=8;
}
return max(col/ vec4(div), vec4(0));
}
vec4 col = vec4(0);//startCol; // TODO figure out how to recalculate the dir
int div = 0;
for (int i = 1 ; i < int(howMuchBlur); i ++){
if (i > howMuch){
break;
}
float x = (xu * float(i));
float y = (yu * float(i));
col += trace(rayOrigin + vec3(x,0.,0.),dir);
col += trace(rayOrigin + vec3(x,-y,0.),dir);
col += trace(rayOrigin + vec3(0,-y,0.),dir);
col += trace(rayOrigin + vec3(-x,-y,0.),dir);
col += trace(rayOrigin + vec3(-x,0.,0.),dir);
col += trace(rayOrigin + vec3(-x,y,0.),dir);
col += trace(rayOrigin + vec3(0,y,0.),dir);
col += trace(rayOrigin + vec3(x,y,0.),dir);
div +=8;
}
return max(col/ vec4(div), vec4(0));
}
vec4 traceWithBlur(vec3 rayOrigin, vec3 dir){
vec3 ray = rayOrigin;
float dist = 0.;
float totalDist = 0.;
float maxDist = 3.;
vec4 edgeBlur = vec4(0);
vec4 someC = vec4( voronoi(vec3(rayOrigin.xy*4., time)),1. ).rrrr * vec4(0.1);
for (int i = 0; i < steps ; i++){
dist = scene(ray);
if (dist < 0.04 * 2.){
int f = howMuchFocus(totalDist);
vec4 col = someC;
//edgeBlur = blur(col,rayOrigin, dir,f);
// break;
if(dist < 0.04 ){
if (f == 0){
vec4 distCol = vec4(1. - vec4(totalDist/maxDist));
vec4 lightingCol = vec4(lighting(rayOrigin,dir,estimateNormal(ray)));
col = lightingCol;
return col ;//+ edgeBlur;
}
edgeBlur = blur(col,rayOrigin, dir,f);
return edgeBlur;
//break;
}
//dfdsf
}
totalDist += dist;
ray += dist * dir;
if (totalDist > maxDist){
break;
}
}
vec4 someC2 = vec4( voronoi(vec3(ray.xyz)),1. ).rrrr * vec4(0.23);
someC = mix(someC,someC2,(sin(time/13.) /2.) + .5) ;
// return vec4(cellTile2(vec3(rayOrigin.xyz)));
vec4 lilD = (vec4( fbm(vec2(snoise(vec3(rayOrigin.xy*1.3,time/10.))),2)) - vec4(cellTile2(vec3(rayOrigin.xy, time))) -0.012341) * 0.764;
// vec4(vrmf(vec2(rayOrigin.y,time/10.),int(floor(sin(time) + 3.)*20.))) +
vec4 bkg = mix(lilD,someC2,0.);
return (bkg * (1.6-length(rayOrigin.xy))) + edgeBlur;
}
vec3 lookAt(vec2 uv, vec3 camOrigin, vec3 camTarget){
vec3 zAxis = normalize(camTarget - camOrigin);
vec3 up = vec3(0,1,0);
vec3 xAxis = normalize(cross(up, zAxis));
vec3 yAxis = normalize(cross(zAxis, xAxis));
float fov = 2.;
vec3 dir = (normalize(uv.x * xAxis + uv.y * yAxis + zAxis * fov));
return dir;
}
void main() {
vec2 uv = -1. + 2.3 * v_texcoord;
uv.x *= resolution.x/resolution.y;
vec3 rayOrigin = vec3(uv.x + fbm(vec2(time),4)*0.05,uv.y + fbm(vec2(time/3.))*0.03, 0.); // TODO make it so that the bg moves more than the foreground so it looks like the fbm is far away
vec3 camOrigin = vec3(0, 0., -1.);
vec3 camTarget = camOrigin+ vec3(sin(time/10.),cos(time/10.), 2);
vec3 direction = lookAt(uv, camOrigin, camTarget);
// vec3 camOrigin = vec3(0.,0.,sin(u_time)-1.);
// vec3 rayOrigin = vec3(camOrigin.xy +
// uv, camOrigin.z + 1.);
// vec3 dir = normalize(rayOrigin-camOrigin);
gl_FragColor = (traceWithBlur(rayOrigin, direction));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment