Added shader packs
This commit is contained in:
8
tools/packsrc/Blueprint/shaders/Buffer A.frag
Normal file
8
tools/packsrc/Blueprint/shaders/Buffer A.frag
Normal file
@@ -0,0 +1,8 @@
|
||||
// the purpose of this buffer is too smooth out the sudden changes in the fft
|
||||
void mainImage( out vec4 fragColor, in vec2 fragCoord )
|
||||
{
|
||||
vec2 uv = fragCoord.xy / iResolution.xy;
|
||||
float old = texture(iChannel1, uv).x;
|
||||
float new = texture(iChannel0, uv).x;
|
||||
fragColor = vec4(mix(old, new, new > old ? .4 : .04));
|
||||
}
|
||||
356
tools/packsrc/Blueprint/shaders/Image.frag
Normal file
356
tools/packsrc/Blueprint/shaders/Image.frag
Normal file
@@ -0,0 +1,356 @@
|
||||
#define SPEED .1
|
||||
#define FOV 3.
|
||||
|
||||
#define MAX_STEPS 80
|
||||
#define EPS .001
|
||||
#define RENDER_DIST 5.
|
||||
#define AO_SAMPLES 4.
|
||||
#define AO_RANGE 100.
|
||||
|
||||
#define PI 3.14159265359
|
||||
#define saturate(x) clamp(x, 0., 1.)
|
||||
|
||||
// precomputed globals
|
||||
float _house = 0.;
|
||||
float _boat = 0.;
|
||||
float _spaceship = 0.;
|
||||
float _atmosphere = 0.;
|
||||
mat3 _kifsRot = mat3(1, 0, 0, 0, 1, 0, 0, 0, 1);
|
||||
float _kifsOffset = 0.;
|
||||
|
||||
// rotate 2d space with given angle
|
||||
void tRotate(inout vec2 p, float angel) {
|
||||
float s = sin(angel), c = cos(angel);
|
||||
p *= mat2(c, -s, s, c);
|
||||
}
|
||||
|
||||
// divide 2d space into s chunks around the center
|
||||
void tFan(inout vec2 p, float s) {
|
||||
float k = s / PI / 2.;
|
||||
tRotate(p, -floor((atan(p.y, p.x)) * k + .5) / k);
|
||||
}
|
||||
|
||||
// rectangle distance
|
||||
float sdRect(vec2 p, vec2 r) {
|
||||
p = abs(p) - r;
|
||||
return min(max(p.x, p.y), 0.) + length(max(p, 0.));
|
||||
}
|
||||
|
||||
// box distance
|
||||
float sdBox(vec3 p, vec3 r) {
|
||||
p = abs(p) - r;
|
||||
return min(max(p.x, max(p.y, p.z)), 0.) + length(max(p, 0.));
|
||||
}
|
||||
|
||||
// sphere distance
|
||||
float sdSphere(vec3 p, float r) {
|
||||
return length(p) - r;
|
||||
}
|
||||
|
||||
// 3d cross distance
|
||||
float sdCross(vec3 p, vec3 r) {
|
||||
p =abs(p) - r;
|
||||
p.xy = p.x < p.y ? p.xy : p.yx;
|
||||
p.yz = p.y < p.z ? p.yz : p.zy;
|
||||
p.xy = p.x < p.y ? p.xy : p.yx;
|
||||
return length(min(p.yz, 0.)) - max(p.y, 0.);
|
||||
}
|
||||
|
||||
// union
|
||||
float opU(float a, float b) {
|
||||
return min(a, b);
|
||||
}
|
||||
|
||||
// intersection
|
||||
float opI(float a, float b) {
|
||||
return max(a, b);
|
||||
}
|
||||
|
||||
// substraction
|
||||
float opS(float a, float b) {
|
||||
return max(a, -b);
|
||||
}
|
||||
|
||||
// smooth union
|
||||
float opSU(float a, float b, float k)
|
||||
{
|
||||
float h = clamp(.5 + .5 * (b - a) / k, 0., 1.);
|
||||
return mix(b, a, h) - k * h * (1. - h);
|
||||
}
|
||||
|
||||
// house distance
|
||||
float sdHouse(vec3 p) {
|
||||
p.y += .075;
|
||||
vec3 boxDim = vec3(.2, .15, .2);
|
||||
|
||||
// add the walls
|
||||
float d = sdBox(p, boxDim);
|
||||
|
||||
// add the windows
|
||||
vec3 q = abs(p);
|
||||
vec3 windSize = vec3(.04, .04, .06);
|
||||
q -= windSize + vec3(.005);
|
||||
d = opI(d, opU(sdCross(q, windSize), .11 - abs(p.y)));
|
||||
|
||||
// add the roof
|
||||
q = p;
|
||||
q.y -= .38;
|
||||
tFan(q.xz, 4.);
|
||||
tRotate(q.xy, PI/4.);
|
||||
d = opU(d, sdBox(q, vec3(.35, .01, .35)));
|
||||
|
||||
// make it hollow
|
||||
d = opS(d, sdBox(p, boxDim - vec3(.02)));
|
||||
return d;
|
||||
}
|
||||
|
||||
// boat distance
|
||||
float sdBoat(vec3 p) {
|
||||
|
||||
// add the mast (a word I learned today :P)
|
||||
float d = sdBox(p + vec3(0, .05, 0), vec3(.01, .2, .01));
|
||||
|
||||
// add the sail
|
||||
vec3 q = p + vec3(0, -.05, .12);
|
||||
float a = sdSphere(q, .2);
|
||||
a = opS(a, sdSphere(q, .195));
|
||||
q.x = abs(q.x);
|
||||
tRotate(q.yx, .1);
|
||||
a = opI(a, sdBox(q - vec3(0, 0, .1), vec3(.1)));
|
||||
d = opU(d, a);
|
||||
|
||||
// add the body of the boat
|
||||
p.x = abs(p.x);
|
||||
p.x += .1;
|
||||
a = sdSphere(p, .3);
|
||||
a = opS(a, sdSphere(p, .29));
|
||||
a = opI(a, p.y + .15);
|
||||
d = opU(d,a);
|
||||
return d;
|
||||
}
|
||||
|
||||
// spaceship distance
|
||||
float sdSpaceship(vec3 p) {
|
||||
tFan(p.xz, 6.);
|
||||
p.x += .3;
|
||||
|
||||
// add the cap
|
||||
float d = sdSphere(p, .4);
|
||||
d = opS(d, p.y - .12);
|
||||
|
||||
// add the body
|
||||
d = opU(d, sdSphere(p, .39));
|
||||
|
||||
// add the fins (another word I learned, thanks google :P)
|
||||
d = opU(d, opI(sdSphere(p + vec3(0, .24, 0), .41), sdRect(p.zx, vec2(.005, .5))));
|
||||
d = opS(d, sdSphere(p + vec3(0, .3, 0), .37));
|
||||
d = opS(d, p.y + .25);
|
||||
return d;
|
||||
}
|
||||
|
||||
// atmosphere distance
|
||||
float sdAtmosphere(vec3 p) {
|
||||
float time = iTime;
|
||||
tRotate(p.yz, time);
|
||||
vec3 q = p;
|
||||
tFan(q.xz, 12.);
|
||||
float d = sdBox(q - vec3(.3, 0, 0), vec3(.01));
|
||||
tRotate(p.yx, time);
|
||||
q = p;
|
||||
tFan(q.yz, 12.);
|
||||
d = opU(d, sdBox(q - vec3(0, .23, 0), vec3(.01)));
|
||||
tRotate(p.xz, time);
|
||||
q = p;
|
||||
tFan(q.yx, 12.);
|
||||
d = opU(d, sdBox(q - vec3(0, .16, 0), vec3(.01)));
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
// distance estimation of everything together
|
||||
float map(vec3 p) {
|
||||
float d = _house <= 0. ? 5. : sdHouse(p) + .1 - _house * .1;
|
||||
if (_boat > 0.) d = opU(d, sdBoat(p) + .1 - _boat * .1);
|
||||
if (_spaceship > 0.) d = opU(d, sdSpaceship(p) + .1 - _spaceship * .1);
|
||||
if (_atmosphere > 0.) d = opU(d, sdAtmosphere(p) + .1 - _atmosphere * .1);
|
||||
|
||||
//return d;
|
||||
float s = 1.;
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
tFan(p.xz, 10.);
|
||||
p = abs(p);
|
||||
p -= _kifsOffset;
|
||||
|
||||
p *= _kifsRot;
|
||||
s *= 2.;
|
||||
}
|
||||
|
||||
return opSU(d, sdBox(p * s, vec3(s / 17.)) / s, .1);
|
||||
}
|
||||
|
||||
// trace the scene from ro (origin) to rd (direction, normalized)
|
||||
// until hit or reached maxDist, outputs distance traveled, the number of steps
|
||||
// and the closest distance achieved during marching (used of cheap edge detection)
|
||||
float trace(vec3 ro, vec3 rd, float maxDist, out float steps, out float nt) {
|
||||
float total = 0.;
|
||||
steps = 0.;
|
||||
nt = 100.;
|
||||
|
||||
for (int i = 0; i < MAX_STEPS; ++i) {
|
||||
++steps;
|
||||
float d = map(ro + rd * total);
|
||||
nt = min(d, nt);
|
||||
total += d;
|
||||
if (d < EPS || maxDist < total) break;
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
// calculate the normal vector
|
||||
vec3 getNormal(vec3 p) {
|
||||
vec2 e = vec2(.0001, 0);
|
||||
return normalize(vec3(
|
||||
map(p + e.xyy) - map(p - e.xyy),
|
||||
map(p + e.yxy) - map(p - e.yxy),
|
||||
map(p + e.yyx) - map(p - e.yyx)
|
||||
));
|
||||
}
|
||||
|
||||
// ambient occlusion
|
||||
float calculateAO(vec3 p, vec3 n) {
|
||||
|
||||
float r = 0., w = 1., d;
|
||||
|
||||
for (float i = 1.; i <= AO_SAMPLES; i++){
|
||||
d = i / AO_SAMPLES / AO_RANGE;
|
||||
r += w * (d - map(p + n * d));
|
||||
w *= .5;
|
||||
}
|
||||
|
||||
return 1.-saturate(r * AO_RANGE);
|
||||
}
|
||||
|
||||
// a lovely function that goes up and down periodically between 0 and 1, pausing at the extremes
|
||||
float pausingWave(float x, float a, float b) {
|
||||
x = abs(fract(x) - .5) * 1. - .5 + a;
|
||||
return smoothstep(0., a - b, x);
|
||||
}
|
||||
|
||||
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
|
||||
// transform screen coordinates
|
||||
vec2 uv = fragCoord.xy / iResolution.xy;
|
||||
uv = uv * 2. - 1.;
|
||||
uv.x *= iResolution.x / iResolution.y;
|
||||
|
||||
// transform mouse coordinates
|
||||
vec2 mouse = iMouse.xy / iResolution.xy * 2. - 1.;
|
||||
mouse.x *= iResolution.x / iResolution.y;
|
||||
mouse *= 2.;
|
||||
|
||||
// set time dependent constants
|
||||
float speed = .25 / 10.5;
|
||||
float time = mod(iTime, 290.);
|
||||
time -= 10.5;
|
||||
if (time > 167.) time -= 167.; else
|
||||
if (time > 63.) time -= 63.;
|
||||
time -= 5.25;
|
||||
time *= speed;
|
||||
|
||||
// these determine which object to show
|
||||
_house = pausingWave(time, .15, .125);
|
||||
_boat = pausingWave(time - .125 / .1, .15, .125);
|
||||
_spaceship = pausingWave(time - .25 / .1, .15, .125);
|
||||
_atmosphere = pausingWave(time - .375 / .1, .15, .125) * step(10., iTime);
|
||||
|
||||
// set up kifs rotation matrix
|
||||
float a = -texture(iChannel0, vec2(.5, .25)).x + sin(iTime) * .2 + .9;
|
||||
float s = sin(a), c = cos(a);
|
||||
_kifsRot *= mat3(c, -s, 0, s, c, 0, 0, 0, 1);
|
||||
_kifsRot *= mat3(1, 0, 0, 0, c, -s, 0, s, c);
|
||||
_kifsRot *= mat3(c, 0, s, 0, 1, 0, -s, 0, c);
|
||||
|
||||
// set up kifs offset
|
||||
_kifsOffset = .07 + texture(iChannel0, vec2(.1, .25)).x * .06;
|
||||
|
||||
// set up camera position
|
||||
vec3 rd = normalize(vec3(uv, FOV));
|
||||
vec3 ro = vec3(0, 0, -2);
|
||||
|
||||
// light is relative to the camera
|
||||
vec3 light = vec3(-1., .5, 0);
|
||||
|
||||
vec2 rot = vec2(0);
|
||||
if (iMouse.z > 0. && iMouse.x > 0. && iMouse.y > 0.) {
|
||||
// rotate the scene using the mouse
|
||||
rot = -mouse;
|
||||
} else {
|
||||
// otherwise rotate constantly as time passes
|
||||
rot = vec2(
|
||||
iTime * SPEED * PI,//had to slightly modify \/ this value due to an issue reported by Fabrice
|
||||
mix(sin(iTime * SPEED) * PI / 8., PI / 2. - 1e-5, saturate(exp(-iTime + 10.5))));
|
||||
}
|
||||
|
||||
tRotate(rd.yz, rot.y);
|
||||
tRotate(rd.xz, rot.x);
|
||||
tRotate(light.xz, rot.x);
|
||||
tRotate(ro.yz, rot.y);
|
||||
tRotate(ro.xz, rot.x);
|
||||
|
||||
// march
|
||||
float steps, outline, dist = trace(ro, rd, RENDER_DIST, steps, outline);
|
||||
|
||||
// calculate hit point coordinates
|
||||
vec3 p = ro + rd * dist;
|
||||
|
||||
// calculate normal
|
||||
vec3 normal = getNormal(p);
|
||||
|
||||
// light direction
|
||||
vec3 l = normalize(light - p);
|
||||
|
||||
// ambient light
|
||||
float ambient = .1;
|
||||
|
||||
// diffuse light
|
||||
float diffuse = max(0., dot(l, normal));
|
||||
|
||||
// specular light
|
||||
float specular = pow(max(0., dot(reflect(-l, normal), -rd)), 4.);
|
||||
|
||||
// "ambient occlusion"
|
||||
float ao = calculateAO(p, normal);
|
||||
|
||||
// create the background grid
|
||||
vec2 gridUv = fragCoord.xy - iResolution.xy / 2.;
|
||||
float grid = dot(step(mod(gridUv.xyxy, vec4(20, 20, 100, 100)), vec4(1)), vec4(.1, .1, .2, .2));
|
||||
|
||||
// create blue background
|
||||
vec3 bg = vec3(0, .1, .3) * saturate(1.5 - length(uv) * .5);
|
||||
|
||||
// find the edges in the geometry
|
||||
float edgeWidth = .0015;
|
||||
float edge = smoothstep(1., .0, dot(normal, getNormal(p - normal * edgeWidth))) * step(length(p), 1.);
|
||||
|
||||
// get the outline of the shapes
|
||||
outline = smoothstep(.005, .0, outline) * step(1., length(p));
|
||||
|
||||
// diagonal strokes used for shading
|
||||
vec2 strokes = sin(vec2(uv.x + uv.y, uv.x - uv.y) * iResolution.y * PI / 4.) * .5 - .5;
|
||||
|
||||
// first part of the shading: ao + marching steps
|
||||
float highlights = (steps / float(MAX_STEPS) + sqrt(1. - ao)) * step(length(p), 1.) * .5;
|
||||
highlights = floor(highlights * 5.) / 10.;
|
||||
|
||||
// second part of the shading: ambient + diffuse + specular light
|
||||
float fog = saturate(length(ro) - dist * dist * .25);
|
||||
float lightValue = (ambient + diffuse + specular) * fog;
|
||||
lightValue = floor(lightValue * 5.) / 10.;
|
||||
|
||||
fragColor.rgb = mix(bg, vec3(1., .9, .7),
|
||||
max(max(max(saturate(highlights + strokes.x), saturate(lightValue + strokes.y)) * fog,
|
||||
(edge + outline) * 2. + strokes.y), grid));
|
||||
|
||||
// gamma correction
|
||||
fragColor = pow(saturate(fragColor), vec4(1. / 2.2)) * step(abs(uv.y), 1.);
|
||||
}
|
||||
Reference in New Issue
Block a user