Skip to content

Instantly share code, notes, and snippets.

@erichlof
Created September 9, 2018 05:32
Show Gist options
  • Save erichlof/7d5f2bdb81c57e79d07e05d971629368 to your computer and use it in GitHub Desktop.
Save erichlof/7d5f2bdb81c57e79d07e05d971629368 to your computer and use it in GitHub Desktop.
Original minified Antimatter glsl shader (with spaces and line returns added for readability)
const vec2 scale = vec2(0.5, 0.5);
attribute vec2 aPosition;
varying vec2 vQuadCoords;
void main()
{
vQuadCoords = aPosition * scale + scale;
gl_Position = vec4(aPosition, 0.0, 1.0);
}
precision highp float;
precision highp int;
struct TD
{
float id;
float tn;
} tds[20];
struct BN
{
vec3 min;
vec3 max;
float cha;
float chb;
};
struct LN
{
vec3 v0;
vec3 n0;
vec2 t0;
vec3 e1;
vec3 n1;
vec2 t1;
vec3 e2;
vec3 n2;
vec2 t2;
float mi;
float mk;
};
struct MT
{
vec3 kd;
vec3 ks;
vec3 kt;
vec3 ke;
float ix;
float ro;
float rv;
float op;
};
const float EPS = 0.0000001;
const float HUGE = 1000000.;
const float PI = 3.14159265358979323846;
const float U0 = 0.25 / 2048.;
const float U1 = 1. / 2048.;
const float U2 = 2. / 2048.;
const float U3 = 3. / 2048.;
const float U4 = 4. / 2048.;
const float U5 = 5. / 2048.;
const float U6 = 6. / 2048.;
const vec3 GA = vec3(2.2);
uniform bool uDoDOF;
uniform float uBounces;
uniform float uBlurRadius;
uniform float uFocalDistance;
uniform float uEnvironmentRotation;
uniform float uNormalMappingStrength;
uniform float uSamplingWeight;
uniform vec2 uResolution;
uniform vec2 uRandomSeed;
uniform vec3 uCameraOrigin;
uniform vec4 uBackgroundColor;
uniform vec4 uLightSphere;
uniform vec4 uGroundPlane;
uniform mat4 uCameraMatrix;
uniform sampler2D uBVHDataMap;
uniform sampler2D uMultipassMap;
uniform sampler2D uEnvironmentMap;
uniform sampler2D uColorMap;
uniform sampler2D uNormalMap;
varying vec2 vQuadCoords;
float rnd = 0.;
float seed = 0.;
float kit = 0.;
float rand()
{
rnd = sin(rnd + seed);
return fract(rnd * 43758.5453);
}
TD m0(const in float ix)
{
if (ix == 0.)
return tds[0];
if (ix == 1.)
return tds[1];
if (ix == 2.)
return tds[2];
if (ix == 3.)
return tds[3];
if (ix == 4.)
return tds[4];
if (ix == 5.)
return tds[5];
if (ix == 6.)
return tds[6];
if (ix == 7.)
return tds[7];
if (ix == 8.)
return tds[8];
if (ix == 9.)
return tds[9];
if (ix == 10.)
return tds[10];
if (ix == 11.)
return tds[11];
if (ix == 12.)
return tds[12];
if (ix == 13.)
return tds[13];
if (ix == 14.)
return tds[14];
if (ix == 15.)
return tds[15];
if (ix == 16.)
return tds[16];
if (ix == 17.)
return tds[17];
if (ix == 18.)
return tds[18];
return tds[19];
}
void m1(in float ix, const in TD value)
{
if (ix == 0.)
tds[0] = value;
else if (ix == 1.)
tds[1] = value;
else if (ix == 2.)
tds[2] = value;
else if (ix == 3.)
tds[3] = value;
else if (ix == 4.)
tds[4] = value;
else if (ix == 5.)
tds[5] = value;
else if (ix == 6.)
tds[6] = value;
else if (ix == 7.)
tds[7] = value;
else if (ix == 8.)
tds[8] = value;
else if (ix == 9.)
tds[9] = value;
else if (ix == 10.)
tds[10] = value;
else if (ix == 11.)
tds[11] = value;
else if (ix == 12.)
tds[12] = value;
else if (ix == 13.)
tds[13] = value;
else if (ix == 14.)
tds[14] = value;
else if (ix == 15.)
tds[15] = value;
else if (ix == 16.)
tds[16] = value;
else if (ix == 17.)
tds[17] = value;
else if (ix == 18.)
tds[18] = value;
else
tds[19] = value;
}
BN m2(const in float off)
{
float span = off * U0;
float f = floor(span);
float u = span - f;
float v = f * U1;
vec4 d0 = texture2D(uBVHDataMap, vec2(u, v));
vec4 d1 = texture2D(uBVHDataMap, vec2(u + U1, v));
return BN(d0.rgb, vec3(d0.a, d1.rg), d1.b, d1.a);
}
LN m3(const in float off)
{
float span = off * U0;
float f = floor(span);
float u = span - f;
float v = f * U1;
vec4 d0 = texture2D(uBVHDataMap, vec2(u, v));
vec4 d1 = texture2D(uBVHDataMap, vec2(u + U1, v));
vec4 d2 = texture2D(uBVHDataMap, vec2(u + U2, v));
vec4 d3 = texture2D(uBVHDataMap, vec2(u + U3, v));
vec4 d4 = texture2D(uBVHDataMap, vec2(u + U4, v));
vec4 d5 = texture2D(uBVHDataMap, vec2(u + U5, v));
vec4 d6 = texture2D(uBVHDataMap, vec2(u + U6, v));
LN ln;
ln.v0 = d0.rgb;
ln.n0 = vec3(d0.a, d1.rg);
ln.t0 = d1.ba;
ln.e1 = d2.rgb;
ln.n1 = vec3(d2.a, d3.rg);
ln.t1 = d3.ba;
ln.e2 = d4.rgb;
ln.n2 = vec3(d4.a, d5.rg);
ln.t2 = d5.ba;
ln.mi = d6.r;
ln.mk = d6.g;
return ln;
}
MT m4(const in float off)
{
float span = off * U0;
float f = floor(span);
float u = span - f;
float v = f * U1;
vec4 d0 = texture2D(uBVHDataMap, vec2(u, v));
vec4 d1 = texture2D(uBVHDataMap, vec2(u + U1, v));
vec4 d2 = texture2D(uBVHDataMap, vec2(u + U2, v));
vec4 d3 = texture2D(uBVHDataMap, vec2(u + U3, v));
MT mt;
mt.kd = pow(d0.rgb, GA);
mt.rv = d0.a;
mt.ke = d1.rgb;
mt.op = d1.a;
mt.kt = pow(d2.rgb, GA);
mt.ix = d2.a;
mt.ks = pow(d3.rgb, GA);
mt.ro = d3.a;
return mt;
}
vec3 m5(const in vec3 n)
{
float r1 = rand() * 2. * PI;
float r2 = rand();
vec3 u = normalize(abs(n.x) > 0.1 ? vec3(n.z, 0., -n.x) : vec3(0., -n.z, n.y));
vec3 v = cross(n, u);
return (u * cos(r1) + v * sin(r1)) * sqrt(r2) + n * sqrt(1. - r2);
}
vec3 m6(const in vec3 n, const float theta)
{
float r1 = rand() * 2. * PI;
float r2 = rand();
float m0 = theta * (1. - 2. * acos(r2) / PI);
vec3 w = normalize(abs(n.x) > 0.1 ? vec3(n.z, 0., -n.x) : vec3(0., -n.z, n.y));
vec3 u = cross(n, w);
vec3 v = cross(n, u);
return (u * cos(r1) + v * sin(r1)) * sin(m0) + n * cos(m0);
}
vec3 m7(const in vec3 dir)
{
if (uBackgroundColor.r == -1.)
{
vec2 coord = vec2(0.5 + uEnvironmentRotation, 0.5) - vec2(atan(dir.z, dir.x), asin(dir.y)) / vec2(2. * PI, PI);
return texture2D(uEnvironmentMap, coord).xyz * uBackgroundColor.a;
}
else
{
return pow(uBackgroundColor.rgb, GA);
}
}
float m8(const in vec3 dir, const in vec3 n, const in float n1, const in float n2)
{
float nr = n1 / n2;
float cosI = -dot(dir, n);
float sinT2 = nr * nr * (1. - cosI * cosI);
if (sinT2 > 1.)
{
return 1.;
}
float cosT = sqrt(1. - sinT2);
float rOrth = (n1 * cosI - n2 * cosT) / (n1 * cosI + n2 * cosT);
float rPar = (n2 * cosI - n1 * cosT) / (n2 * cosI + n1 * cosT);
return (rOrth * rOrth + rPar * rPar) / 2.0;
}
float m9(const in vec4 sphere, const in vec3 o, const in vec3 dir, const in float maxt)
{
vec3 L = sphere.xyz - o;
float tca = dot(L, dir);
float d2 = dot(L, L) - tca * tca;
if (d2 > sphere.w * sphere.w)
return HUGE;
float thc = sqrt(sphere.w * sphere.w - d2);
float t0 = tca - thc;
float t1 = tca + thc;
if (t0 > t1)
{
float temp = t0;
t0 = t1;
t1 = temp;
}
if (t0 < 0.)
{
t0 = t1;
}
if (t0 < 0.)
return HUGE;
return t0 < maxt ? t0 : HUGE;
}
float m10(const in vec3 boxMin, const in vec3 boxMax, const in vec3 o, const in vec3 dir, const in float maxt)
{
vec3 f = (boxMax - o) / dir;
vec3 n = (boxMin - o) / dir;
vec3 tmax = max(f, n);
vec3 tmin = min(f, n);
float t1 = min(min(tmax.x, min(tmax.y, tmax.z)), maxt);
float t0 = max(max(tmin.x, max(tmin.y, tmin.z)), EPS);
return t0 <= t1 ? t0 : HUGE;
}
bool m11(const in vec3 v0, const in vec3 e1, const in vec3 e2, const in vec3 o, const in vec3 dir, const in float maxt, out vec3 r)
{
vec3 s = o - v0;
vec3 q = cross(s, e1);
vec3 p = cross(dir, e2);
r = vec3(dot(e2, q), dot(s, p), dot(dir, q)) / vec3(dot(e1, p));
return r.x > EPS && r.x < maxt && r.y >= 0. && r.y <= 1. && r.z >= 0. && r.z + r.y <= 1.;
}
float m12(const in vec3 o, const in vec3 dir, inout vec3 result)
{
bool skip = false;
float hit = 0.;
float stackptr = 0.;
BN ne = m2(0.);
TD td = TD(0., m10(ne.min, ne.max, o, dir, result.x));
for (int g = 0; g == 0; g += 0)
{
if (td.tn < result.x)
{
if (ne.cha < 0.)
{
LN leaf;
vec3 isect;
if (-ne.cha != kit)
{
leaf = m3(-ne.cha);
if (m11(leaf.v0, leaf.e1, leaf.e2, o, dir, result.x, isect))
{
result = isect;
hit = -ne.cha;
}
}
if (-ne.chb != kit && ne.chb != ne.cha)
{
leaf = m3(-ne.chb);
if (m11(leaf.v0, leaf.e1, leaf.e2, o, dir, result.x, isect))
{
result = isect;
hit = -ne.chb;
}
}
}
else
{
BN na = m2(ne.cha);
BN nb = m2(ne.chb);
TD tva = TD(ne.cha, m10(na.min, na.max, o, dir, result.x));
TD tvb = TD(ne.chb, m10(nb.min, nb.max, o, dir, result.x));
if (tva.tn < tvb.tn)
{
TD tmp = tva;
tva = tvb;
tvb = tmp;
BN tnp = na;
na = nb;
nb = tnp;
}
if (tva.tn < result.x)
{
td = tva;
ne = na;
skip = true;
}
if (tvb.tn < result.x)
{
if (skip)
m1(stackptr++, tva);
td = tvb;
ne = nb;
skip = true;
}
}
}
if (!skip)
{
if (--stackptr < 0.)
break;
td = m0(stackptr);
ne = m2(td.id);
}
skip = false;
}
return hit;
}
bool m13(const in vec3 o, const in vec3 dir, out vec3 pos, out vec3 n, out MT ml)
{
vec3 mis = vec3(HUGE, 0., 0.);
float hit = m12(o, dir, mis);
if (hit > 0.)
{
LN ne = m3(hit);
pos = o + dir * mis.x;
float u = 1. - mis.y - mis.z;
n = normalize(u * ne.n0 + mis.y * ne.n1 + mis.z * ne.n2);
ml = m4(ne.mi);
if (ne.mk > 0.)
{
ml.kd = pow(ml.kd * texture2D(uColorMap, u * ne.t0 + mis.y * ne.t1 + mis.z * ne.t2).xyz, GA);
}
}
if (kit != -1. && uGroundPlane.y > 0.)
{
vec4 pl = uGroundPlane;
float t = -(dot(pl.xyz, o) + pl.w) / dot(pl.xyz, dir);
if (t > 0. && t < mis.x)
{
hit = -1.;
mis.x = t;
pos = o + dir * mis.x;
n = texture2D(uNormalMap, vec2(pos.x * 0.5, pos.z * 0.5)).rgb * 2.0 - 1.;
n.xy *= min(1., uNormalMappingStrength / mis.x);
n = normalize(vec3(n.x, n.z, n.y));
ml = m4(16777184.0);
}
}
if (kit != -2.0 && uLightSphere.w > 0.)
{
vec4 sphere = uLightSphere;
float t = m9(sphere, o, dir, mis.x);
if (t > 0. && t < mis.x)
{
hit = -2.0;
mis.x = t;
pos = o + dir * mis.x;
n = (o + dir * mis.x - sphere.xyz) / sphere.w;
ml = m4(16777152.0);
}
}
kit = hit;
return mis.x < HUGE;
}
void main()
{
MT ml;
vec3 o, dir, pos, n, j = vec3(0.), w = vec3(1.);
seed = dot(gl_FragCoord.xy, uRandomSeed);
vec4 p = uCameraMatrix * vec4(2. * (gl_FragCoord.xy + vec2(rand(), rand())) / uResolution - 1., 1., 1.);
dir = normalize(p.xyz / p.w);
o = uCameraOrigin;
if (uDoDOF)
{
float r1 = rand() * 2. * PI;
float r2 = rand() * uBlurRadius;
o = uCameraOrigin + r2 * (normalize(uCameraMatrix[1].xyz) * sin(r1) + normalize(uCameraMatrix[0].xyz) * cos(r1));
dir = normalize(uCameraOrigin + dir * uFocalDistance - o);
}
float dist = HUGE;
vec3 bgColor = m7(dir);
for (float depth = 0.; depth < 16.0; ++depth)
{
if (depth == uBounces)
{
break;
}
if (!m13(o, dir, pos, n, ml))
{
j += w * m7(dir);
break;
}
if (depth == 0.)
{
dist = length(pos - o);
}
else if (depth > 3.0)
{
float p = max(w.x, max(w.y, w.z));
if (rand() < p)
w *= 1. / p;
else
break;
}
o = pos;
j += w * ml.ke;
float f = rand();
if (f < ml.op)
{
float n1 = 1.;
float n2 = ml.ix;
if (dot(dir, n) > 0.)
{
n = -n;
n1 = ml.ix;
n2 = 1.;
}
if (f < m8(dir, n, n1, n2))
{
dir = m6(reflect(dir, n), ml.ro);
w *= ml.ks;
}
else
{
dir = m6(refract(dir, n, n1 / n2), ml.ro);
w *= ml.kt;
}
}
else if (f < ml.rv)
{
dir = m6(reflect(dir, n), ml.ro);
w *= ml.ks;
}
else if (f < (ml.ix > 1. ? m8(dir, n, 1., ml.ix) : 0.))
{
dir = m6(reflect(dir, n), ml.ro);
w *= ml.ks;
}
else
{
dir = m5(n);
w *= ml.kd;
}
}
j = mix(j, bgColor, clamp(pow(max(0., (dist - 20.)) / 20., 1.15), 0., 1.));
gl_FragColor = vec4(mix(j, texture2D(uMultipassMap, vQuadCoords).rgb, uSamplingWeight), dist);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment