#version 300 es
// ╔═════════════╦════════════════╗
// ║ Marco Gomez ║ https://mgz.me ║
// ╚═════════════╩════════════════╝
precision highp float;
#define inputTexture prgm5Texture
uniform sampler2D prgm5Texture;
uniform vec2 resolution;
out vec4 fragColor;
void main(void) {
vec2 uv = gl_FragCoord.xy / resolution.xy;
vec4 tex = texture(inputTexture, uv);
fragColor = tex;
}
#version 300 es
// ╔═════════════╦════════════════╗
// ║ Marco Gomez ║ https://mgz.me ║
// ╚═════════════╩════════════════╝
precision highp float;
#define InOutTexture prgm1Texture
uniform sampler2D prgm1Texture;
uniform vec2 resolution;
uniform vec2 mouse;
uniform float time;
uniform float deltatime;
uniform int frame;
uniform bool mousedown;
out vec4 fragColor;
const ivec2 texelPlayerPos = ivec2(0, 0);
const ivec2 texelGPUPos = ivec2(1, 0);
const ivec2 texelBallPosDir = ivec2(2, 0);
const ivec2 texelScore = ivec2(3, 0);
const ivec2 texelState = ivec2(4, 0);
const vec2 paddleSize = vec2(0.03, 0.16);
const float ballSize = 0.015;
const float wallWidth = 0.02;
const float fieldHeight = 1.05;
const float playerXPos = -0.95;
const float gpuXPos = 0.95;
const float ballSpeed = 1.5;
const float ballAccel = 0.2;
const float speedLimit = 3.0;
vec4 readTexel(sampler2D tex, ivec2 pos) {
return texelFetch(tex, pos, 0);
}
void writeTexel(in ivec2 pos, in vec4 val, in ivec2 fragPos, inout vec4 fragColor) {
fragColor = (fragPos == pos) ? val : fragColor;
}
float Hash(in float n) {
return fract(sin(n) * 138.5453123);
}
float GetSpeed(float startTime) {
return clamp(0.0, speedLimit, ballSpeed + (time - startTime) * ballAccel);
}
void main(void) {
ivec2 iCurPixel = ivec2(gl_FragCoord.xy - 0.5);
if (gl_FragCoord.x > 5.0 || gl_FragCoord.y > 1.0 ) discard;
vec2 playerPaddlePos = readTexel(InOutTexture, texelPlayerPos).xy;
vec2 gpuPaddlePos = readTexel(InOutTexture, texelGPUPos).xy;
vec4 ballPosDir = readTexel(InOutTexture, texelBallPosDir);
vec2 score = readTexel(InOutTexture, texelScore).xy;
vec3 state = readTexel(InOutTexture, texelState).xyz;
bool reset = (gpuPaddlePos == vec2(0.0));
if (frame == 0 || state.x == 1.0 || reset) {
ballPosDir = vec4(0.0, 0.0, 0.0, 0.0);
playerPaddlePos = vec2(playerXPos, playerPaddlePos.y);
gpuPaddlePos = vec2(gpuXPos, gpuPaddlePos.y);
state.x = -1.0;
state.z = 1.0;
score = vec2(0, 0);
}
if (state.x == -1.0) {
if (mousedown) {
ballPosDir.xy = vec2(0.0, 0.0);
ballPosDir.zw = normalize(vec2(state.z, Hash(float(frame) * 1.5) * 0.25));
state.x = 0.0;
state.y = time;
gpuPaddlePos.y = 0.0;
playerPaddlePos.y = 0.0;
}
} else {
float limits = (fieldHeight * 0.5) - (wallWidth * 0.5);
float paddleHalfHeight = paddleSize.y * 0.5;
float paddleHalfWidth = paddleSize.x * 0.5;
playerPaddlePos.y = clamp(mouse.y, -limits + paddleHalfHeight, limits - paddleHalfHeight);
float gpuUp = step(0.0, ballPosDir.y - (gpuPaddlePos.y + paddleHalfHeight));
float gpuDown = step(0.0, (gpuPaddlePos.y - paddleHalfHeight) - ballPosDir.y);
gpuPaddlePos.y += (deltatime / 1000.0) * (gpuUp - gpuDown);
gpuPaddlePos.y = clamp(gpuPaddlePos.y, -limits + paddleHalfHeight, limits - paddleHalfHeight);
ballPosDir.xy += ballPosDir.zw * GetSpeed(state.y) * (deltatime / 1000.0);
if (ballPosDir.y + ballSize >= limits) {
ballPosDir.y = limits - ballSize;
ballPosDir.w *= -1.0;
} else if (ballPosDir.y - ballSize <= -limits) {
ballPosDir.y = ballSize - limits;
ballPosDir.w *= -1.0;
}
if (ballPosDir.x + ballSize >= (gpuPaddlePos.x - paddleHalfWidth)) {
if (abs(ballPosDir.y - gpuPaddlePos.y) <= paddleHalfHeight + ballSize) {
ballPosDir.x = gpuPaddlePos.x - paddleHalfWidth - ballSize;
ballPosDir.z *= -1.0;
ballPosDir.w += (ballPosDir.y - gpuPaddlePos.y) * 5.0;
ballPosDir.zw = normalize(ballPosDir.zw);
}
} else if (ballPosDir.x - ballSize <= playerPaddlePos.x + paddleHalfWidth) {
if(abs(ballPosDir.y - playerPaddlePos.y) <= paddleHalfHeight + ballSize) {
ballPosDir.x = playerPaddlePos.x + paddleHalfWidth + ballSize;
ballPosDir.z *= -1.0;
ballPosDir.w += (ballPosDir.y - playerPaddlePos.y) * 5.0;
ballPosDir.zw = normalize(ballPosDir.zw);
}
}
if (ballPosDir.x - ballSize > gpuPaddlePos.x + paddleHalfWidth - 1e-4) {
score.x += 1.0; state.x = -1.0; state.z = -1.0;
} else if (ballPosDir.x + ballSize < playerPaddlePos.x - paddleHalfWidth + 1e-4) {
score.y += 1.0; state.x = -1.0; state.z = 1.0;
}
if (score.x >= 10.0 || score.y >= 10.0) { state.x = 1.0; }
}
fragColor = vec4(0.0);
writeTexel(texelPlayerPos, vec4(playerPaddlePos, 0.0, 0.0), iCurPixel, fragColor);
writeTexel(texelGPUPos, vec4(gpuPaddlePos, 0.0, 0.0), iCurPixel, fragColor);
writeTexel(texelBallPosDir, ballPosDir, iCurPixel, fragColor);
writeTexel(texelScore, vec4(score, 0.0, 0.0), iCurPixel, fragColor);
writeTexel(texelState, vec4(state, 0.0), iCurPixel, fragColor);
}
#version 300 es
// ╔═════════════╦════════════════╗
// ║ Marco Gomez ║ https://mgz.me ║
// ╚═════════════╩════════════════╝
precision highp float;
#define inputTexture prgm1Texture
uniform sampler2D prgm1Texture;
uniform vec2 resolution;
uniform float time;
out vec4 fragColor;
const ivec2 texelPlayerPos = ivec2(0, 0);
const ivec2 texelGPUPos = ivec2(1, 0);
const ivec2 texelBallPosDir = ivec2(2, 0);
const ivec2 texelScore = ivec2(3, 0);
const ivec2 texelState = ivec2(4, 0);
const float drawSS = 0.01;
const vec2 paddleSize = vec2(0.03, 0.16);
const float wallWidth = 0.01;
const float ballSize = 0.015;
const float fieldHeight = 1.05;
const vec3 ballColor = vec3(2.0);
const vec3 paddleColor = vec3(0.6, 0.7, 0.8);
const vec3 borderColor = vec3(0.7, 0.8, 0.7);
const vec3 scoreColor = vec3(0.3);
vec4 readTexel(sampler2D tex, ivec2 pos) {
return texelFetch(tex, pos, 0);
}
float osc(float s, float e, float t, float ts) {
return (e - s) / 2.0 + s + sin(t * ts) * (e - s) * 0.5;
}
const int[] font = int[](0x75557, 0x22222, 0x74717, 0x74747, 0x11574, 0x71747, 0x71757, 0x74444, 0x75757, 0x75747);
const int[] powers = int[](1, 10, 100, 1000, 10000);
float printInt(vec2 uv, int value ) {
const int maxDigits = 2;
if (abs(uv.y - 0.5) < 0.5) {
int iu = int(floor(uv.x));
if (iu >= 0 && iu < maxDigits) {
int n = (value / powers[maxDigits - iu - 1]) % 10;
uv.x = fract(uv.x);
ivec2 p = ivec2(floor(uv*vec2(4.0, 5.0)));
return float((font[n] >> (p.x + p.y * 4)) & 1);
}
}
return 0.0;
}
float squareSDF(vec2 p, vec2 pos, vec2 size) {
vec2 d = abs(p - pos) - size;
return length(max(d, 0.0));
}
vec3 drawBall(vec2 pos, vec2 ballPos, vec3 col) {
float t = squareSDF(pos, ballPos, vec2(ballSize, ballSize));
return mix(ballColor, col, smoothstep(0.0, drawSS, t));
}
vec3 drawPaddle(vec2 pos, vec2 paddlePos, vec3 col) {
float t = squareSDF(pos, paddlePos, paddleSize * 0.5);
return mix(paddleColor, col, smoothstep(0.0, drawSS, t));
}
vec3 drawWalls(vec2 pos, float distToCenter, vec3 col, bool point) {
float t = (point) ? 0.25 * time : 0.0625 * time;
float p = abs(abs(pos.y) - distToCenter) / (wallWidth * 0.5);
return mix(
borderColor,
col,
smoothstep(
0.0,
drawSS,
clamp(
sin((sign(pos.y) * t + pos.x) * 64.0),
(point) ? 0.0 : 0.0,
(point) ? 0.5 : 0.0
) + p - 1.0
)
);
}
vec3 drawDashedLine(vec2 pos, float opacity, float thickness, vec3 col) {
float t = abs(pos.x) - thickness;
float dashT = step(0.0, sin(pos.y * 220.0 + 1.5));
float limitsT = (abs(pos.y) - (fieldHeight * 0.5));
col = mix(vec3(opacity), col, smoothstep(0.0, thickness, max(t, limitsT) + dashT));
return col;
}
vec3 drawScore(vec2 score, vec2 coord, vec3 col, bool point, vec3 state) {
float blinkPlayer = 1.0;
float blinkGPU = 1.0;
float o = osc(-0.25, 1.0, time, 8.0);
if (point && (score.x > 0.0 || score.y > 0.0)) {
if (state.z == -1.0) { blinkPlayer += o; }
if (state.z == +1.0) { blinkGPU += o; }
}
const vec2 displacement = vec2(0.3, -0.65);
vec2 uv = (2.0 * coord.xy - resolution.xy) / resolution.y;
col = mix(col, scoreColor * blinkPlayer, printInt((uv + displacement) * vec2(10.0, 7.0), int(score.x)));
col = mix(col, scoreColor * blinkGPU, printInt((uv + displacement * vec2(-0.4, 1.0)) * vec2(10.0, 7.0), int(score.y)));
return col;
}
void main(void) {
vec2 uv = ((gl_FragCoord.xy / resolution.xy) * 2.0 - 1.0);
uv = uv * vec2(1.15, 1.15 * (resolution.y / resolution.x));
vec2 playerPos = readTexel(inputTexture, texelPlayerPos).xy;
vec2 gpuPos = readTexel(inputTexture, texelGPUPos).xy;
vec2 ballPos = readTexel(inputTexture, texelBallPosDir).xy;
vec2 score = readTexel(inputTexture, texelScore).xy;
vec3 state = readTexel(inputTexture, texelState).xyz;
bool point = (state.x == -1.0);
vec3 col = vec3(0.02);
col = drawDashedLine(uv, 0.4, 0.003, col);
col = drawDashedLine(vec2(uv.x + 1.0, uv.y), 0.3, 0.002, col);
col = drawDashedLine(vec2(uv.x - 1.0, uv.y), 0.3, 0.002, col);
col = drawBall(uv, ballPos, col);
col = drawPaddle(uv, playerPos, col);
col = drawPaddle(uv, gpuPos, col);
col = drawWalls(uv, (fieldHeight * 0.5), col, point);
col = drawScore(score, gl_FragCoord.xy, col, point, state);
fragColor = vec4(col, 1.0);
}
#version 300 es
// ╔═════════════╦════════════════╗
// ║ Marco Gomez ║ https://mgz.me ║
// ╚═════════════╩════════════════╝
precision highp float;
#define inputTexture prgm2Texture
#define statesTexture prgm1Texture
uniform sampler2D prgm1Texture;
uniform sampler2D prgm2Texture;
uniform sampler2D prgm3Texture;
uniform sampler2D textTexture;
uniform vec2 resolution;
uniform vec2 mouselerp;
uniform float time;
uniform int frame;
uniform float fftNormalized;
out vec4 fragColor;
const ivec2 texelScore = ivec2(3, 0);
const ivec2 texelState = ivec2(4, 0);
const float h = 0.003;
const float v = 0.012;
const float scrollSpeed = 3.0;
const float fontSize = 0.4;
const float sinAmplitude = 0.6;
const float sinFrequency = 0.4;
const float sinSpeed = 3.0;
const float scrollLength = 50.0;
const vec4 baseColor = vec4(0.0, 0.0, 1.0, 0.0);
#define SS(a) c += char(u, a); u.x -= 0.5;
vec4 char(vec2 pos, float c) {
vec4 o = texture(
textTexture,
clamp(pos, 0.0, 1.0) / 16.0 + fract(floor(vec2(c, 15.999 - c / 16.0)) / 16.0)
);
return(
(o.r > 0.0) ? baseColor * smoothstep(0.0, 0.5, o.r - o.a * 0.2) : vec4(0.0)
);
}
#define _spc SS(32.);
#define _A SS(65.);
#define _B SS(66.);
#define _C SS(67.);
#define _D SS(68.);
#define _E SS(69.);
#define _F SS(70.);
#define _G SS(71.);
#define _H SS(72.);
#define _I SS(73.);
#define _J SS(74.);
#define _K SS(75.);
#define _L SS(76.);
#define _M SS(77.);
#define _N SS(78.);
#define _O SS(79.);
#define _P SS(80.);
#define _Q SS(81.);
#define _R SS(82.);
#define _S SS(83.);
#define _T SS(84.);
#define _U SS(85.);
#define _V SS(86.);
#define _W SS(87.);
#define _X SS(88.);
#define _Y SS(89.);
#define _Z SS(90.);
#define _a SS(97.);
#define _b SS(98.);
#define _c SS(99.);
#define _d SS(100.);
#define _e SS(101.);
#define _f SS(102.);
#define _g SS(103.);
#define _h SS(104.);
#define _i SS(105.);
#define _j SS(106.);
#define _k SS(107.);
#define _l SS(108.);
#define _m SS(109.);
#define _n SS(110.);
#define _o SS(111.);
#define _p SS(112.);
#define _q SS(113.);
#define _r SS(114.);
#define _s SS(115.);
#define _t SS(116.);
#define _u SS(117.);
#define _v SS(118.);
#define _w SS(119.);
#define _x SS(120.);
#define _y SS(121.);
#define _z SS(122.);
#define _or SS(33.);
#define _dot SS(46.);
vec4 scroll(vec2 u) {
vec4 c = vec4(0.0);
_spc _spc _spc _spc _spc _spc _spc _spc _spc _spc _spc _spc _spc _spc _spc _spc _spc _spc _spc _spc;
_spc _spc _spc _spc _spc _spc _spc _spc _spc _spc _spc _spc _spc _spc _spc _spc _spc _spc _spc _spc;
_C _L _I _C _K _spc _T _O _spc _P _L _A _Y;
return c;
}
vec4 readTexel(sampler2D tex, ivec2 pos) {
return texelFetch(tex, pos, 0);
}
float stepm(float a, float b, float c) {
return step(c, sin(time + a * cos(time * b)));
}
vec3 badVHS(sampler2D tex, vec2 uv, vec3 state, vec2 score) {
vec2 suv = gl_FragCoord.xy / resolution.xy;
float tmod = mod(time * 0.25, 3.0);
float lookyMod = uv.y - tmod;
float window = 1.0 / (1.0 + 20.0 * lookyMod * lookyMod);
float lookyStep = stepm(4.0, 4.0, 0.3) * 0.5;
uv.x = uv.x + sin(uv.y * 10.0 + time) / 100.0 * lookyStep * (1.0 + cos(time * 80.0)) * window * 0.25;
float vShift = v * stepm(2.0, 3.0, 0.9) * (sin(time) * sin(time * 20.0) + (0.5 + 0.1 * sin(time * 200.0) * cos(time)));
uv.y = mod(uv.y + vShift, 5.0);
vec3 desatColor;
float r, g, b;
float x = sin(0.3 * time + uv.y * 21.0) * sin(0.7 * time + uv.y * 29.0) * sin(0.3 + 0.33 * time + uv.y * 31.0) * h;
r = texture(tex, vec2(x + uv.x + 0.001, uv.y + 0.001)).x + 0.007;
g = texture(tex, vec2(x + uv.x + 0.000, uv.y - 0.002)).y + 0.007;
b = texture(tex, vec2(x + uv.x - 0.002, uv.y + 0.000)).z + 0.007;
r += 0.08 * texture(tex, 0.75 * vec2(x + 0.012, -0.013) + vec2(uv.x + 0.001, uv.y + 0.001)).x;
g += 0.05 * texture(tex, 0.75 * vec2(x + -0.011, -0.010) + vec2(uv.x + 0.000, uv.y - 0.002)).y;
b += 0.08 * texture(tex, 0.75 * vec2(x + -0.010, -0.009) + vec2(uv.x - 0.002, uv.y + 0.000)).z;
float luma = 0.3 * r + 0.6 * g + 0.1 * b;
float desat = 0.3;
desatColor = vec3(
r + desat * (luma - r),
g + desat * (luma - g),
b + desat * (luma - b)
);
if (state.x == -1.0 && (score.x < 1.0 && score.y < 1.0)) {
desatColor *= (1.0 + state.x * 0.9) * clamp((suv.y - 0.35), 0.0, 1.0);
float yMod = 64.0;
float yRes = resolution.y / yMod;
vec2 suv = (gl_FragCoord.xy / resolution.y * 2.0 - 1.0) / fontSize;
suv.x += -4.0 + mod(time * scrollSpeed, scrollLength);
suv.y += floor((0.5 + sinAmplitude * sin(suv.x * sinFrequency + time * sinSpeed)) * yMod * 0.42) / (yMod * 0.42);
suv = floor(suv * yRes) / yRes;
desatColor = (scroll(vec2(suv.x, suv.y + 1.2)) == baseColor)
? vec3(0.7, 0.8, 0.7)
: desatColor;
}
return desatColor;
}
vec3 hash33(vec3 p3) {
p3 = fract(p3 * vec3(0.1031, 0.1030, 0.0973));
p3 += dot(p3, p3.yxz + 19.19);
return fract((p3.xxy + p3.yxx) * p3.zyx);
}
void main(void) {
vec2 uv = gl_FragCoord.xy / resolution.xy;
vec3 state = readTexel(statesTexture, texelState).xyz;
vec2 score = readTexel(statesTexture, texelScore).xy;
vec4 tex = texture(inputTexture, uv);
vec3 vhs = badVHS(inputTexture, uv, state, score);
float vhsGlitches = state.x + 1.0;
vec4 col = mix(vec4(vhs, 1.0), tex, vhsGlitches);
float w = 0.1;
vec2 a = vec2(uv.x - 0.5, uv.y - 0.66);
vec2 b = a * 0.15 / float(10.0);
vec3 h = hash33(vec3(gl_FragCoord.xy, frame));
uv += b * h.x;
for (float i = 1.0; i > 0.994; i-= 0.0005) {
uv -= 0.5; uv *= i; uv += 0.5;
col += texture(inputTexture, uv) * w * 1.5;
w *= 0.98;
}
col *= 0.98;
if (frame % 2 == 0) { fragColor += col; }
fragColor += texture(prgm3Texture, uv) * 0.85;
fragColor = mix(fragColor, col, 0.65);
}
#version 300 es
// ╔═════════════╦════════════════╗
// ║ Marco Gomez ║ https://mgz.me ║
// ╚═════════════╩════════════════╝
precision highp float;
#define inputTexture prgm2Texture
uniform sampler2D prgm1Texture;
uniform sampler2D prgm2Texture;
uniform sampler2D prgm3Texture;
uniform sampler2D noiseTexture;
uniform vec2 resolution;
uniform vec2 mouselerp;
uniform float time;
out vec4 fragColor;
const float amount = 1.0;
const float reinhardAmount = 0.0;
const float contrast = 1.0;
const float brightness = 1.0;
const float saturation = 1.0;
const vec2 vignetteSize = vec2(0.25, 0.25);
const float vignetteRoundness = 0.15;
const float vignetteMix = 1.0;
const float vignetteSmoothness = 0.6;
const float gaussGrainAmount = 0.3;
const float W = 1.2;
const float T = 7.5;
const float PI = acos(-1.0);
const float TAU = PI * 2.0;
const float sqrTAU = sqrt(TAU);
vec4 readTexel(sampler2D tex, ivec2 pos) {
return texelFetch(tex, pos, 0);
}
vec4 rgbShift(vec2 p , vec4 shift) {
shift *= 2.0 * shift.w - 1.0;
vec2 rs = vec2(shift.x, -shift.y);
vec2 gs = vec2(shift.y, -shift.z);
vec2 bs = vec2(shift.z, -shift.x);
float r = texture(inputTexture, p + rs, 0.0).x;
float g = texture(inputTexture, p + gs, 0.0).y;
float b = texture(inputTexture, p + bs, 0.0).z;
return vec4(r,g,b,1.0);
}
vec4 noise(vec2 uv) {
return texture(noiseTexture, uv, 0.0);
}
vec4 vec4pow(vec4 v, float p) {
return vec4(pow(v.x, p), pow(v.y, p), pow(v.z, p), v.w);
}
float filmicReinhardCurve(float x) {
float q = (T * T + 1.0) * x * x;
return q / (q + x + T * T);
}
vec3 filmicReinhard(vec3 c) {
float w = filmicReinhardCurve(W);
return vec3(
filmicReinhardCurve(c.r),
filmicReinhardCurve(c.g),
filmicReinhardCurve(c.b)
) / w;
}
vec3 contrastSaturationBrightness(vec3 color, float brt, float sat, float con) {
const float AvgLumR = 0.5;
const float AvgLumG = 0.5;
const float AvgLumB = 0.5;
const vec3 LumCoeff = vec3(0.2125, 0.7154, 0.0721);
vec3 AvgLumin = vec3(AvgLumR, AvgLumG, AvgLumB);
vec3 brtColor = color * brt;
vec3 intensity = vec3(dot(brtColor, LumCoeff));
vec3 satColor = mix(intensity, brtColor, sat);
vec3 conColor = mix(AvgLumin, satColor, con);
return conColor;
}
float sdSquare(vec2 point, float width) {
vec2 d = abs(point) - width;
return min(max(d.x, d.y), 0.0) + length(max(d, 0.0));
}
float vignette(vec2 uv, vec2 size, float roundness, float smoothness) {
uv -= 0.5;
float minWidth = min(size.x, size.y);
uv.x = sign(uv.x) * clamp(abs(uv.x) - abs(minWidth - size.x), 0.0, 1.0);
uv.y = sign(uv.y) * clamp(abs(uv.y) - abs(minWidth - size.y), 0.0, 1.0);
float boxSize = minWidth * (1.0 - roundness);
float dist = sdSquare(uv, boxSize) - (minWidth * roundness);
return 1.0 - smoothstep(0.0, smoothness, dist);
}
float gaussian(float z, float u, float o) {
return (
(1.0 / (o * sqrTAU)) *
(exp(-(((z - u) * (z - u)) / (2.0 * (o * o)))))
);
}
vec3 gaussgrain(float t) {
vec2 ps = vec2(1.0) / resolution.xy;
vec2 uv = gl_FragCoord.xy * ps;
float seed = dot(uv, vec2(12.9898, 78.233));
float noise = fract(sin(seed) * 43758.5453123 + t);
noise = gaussian(noise, 0.0, 0.5);
return vec3(noise);
}
void drawScanLines(vec2 uv, inout vec3 color) {
float scanline = clamp(0.95 + 0.05 * cos(PI * (uv.y + 0.016 * -time * 1.5) * 160.0 * 1.0 ), 0.0, 1.0);
float grille = 0.85 + 0.15 * clamp(1.5 * cos(PI * uv.x * 320.0 * 1.0), 0.0, 1.0);
color -= scanline * grille * 0.03;
}
void main(void) {
vec2 uv = gl_FragCoord.xy / resolution.xy;
vec2 mo = uv * 2.0 - 1.0;
mo *= 0.027;
float frameScale = 29.97;
float frameTime = floor(time * frameScale) / frameScale;
vec3 grain = gaussgrain(frameTime);
vec3 chromaticAberration;
chromaticAberration.r = texture(inputTexture, uv - mo * 0.05, 0.0).r;
chromaticAberration.g = texture(inputTexture, uv - mo * 0.15, 0.0).g;
chromaticAberration.b = texture(inputTexture, uv - mo * 0.25, 0.0).b;
vec4 tex = vec4(vec3(0.0), 1.0);
tex.xyz = mix(tex.xyz, chromaticAberration, 0.3);
const float speed = 0.007;
const float amplitude = 0.017;
vec4 shift = vec4pow(
noise(
vec2(speed * time, speed * time / 25.0)
), 8.0
) * vec4(vec3(amplitude), 1.0);
tex += rgbShift(uv, shift);
vec3 reinhard = filmicReinhard(tex.rgb);
vec3 color = tex.rgb;
color = mix(color, reinhard, reinhardAmount);
color = contrastSaturationBrightness(color, brightness, saturation, contrast);
float v = vignette(uv, vignetteSize, vignetteRoundness, vignetteSmoothness);
vec3 vig = color * v;
color = mix(color, vig, vignetteMix);
color = mix(tex.xyz, color, amount);
color -= grain * gaussGrainAmount;
color = clamp(color, 0.0, 1.0);
vec4 finalColor = vec4(color, 1.0);
vec4 prgm3 = texture(prgm3Texture, uv);
finalColor = mix(finalColor, prgm3, 0.5);
finalColor.rb *= 0.9;
drawScanLines(uv, finalColor.xyz);
fragColor = finalColor;
}
#version 300 es
// ╔═════════════╦════════════════╗
// ║ Marco Gomez ║ https://mgz.me ║
// ╚═════════════╩════════════════╝
precision highp float;
#define inputTexture prgm4Texture
uniform sampler2D prgm4Texture;
uniform vec2 resolution;
uniform vec2 mouselerp;
uniform float time;
out vec4 fragColor;
#define ss smoothstep
const float PI = acos(-1.0);
const float TAU = PI * 2.0;
const vec2 hashv2 = vec2(12.9898, 78.233);
const float hashS = 43758.5453123;
const int blurIter = 8;
const float blurSize = 0.07;
const float width = 0.49;
const float height = 0.3;
float gaussian(float z, float u, float o) {
return (
(1.0 / (o * sqrt(TAU))) *
(exp(-(((z - u) * (z - u)) / (2.0 * (o * o)))))
);
}
vec3 gaussgrain(float t) {
vec2 ps = vec2(1.0) / resolution.xy;
vec2 uv = gl_FragCoord.xy * ps;
float seed = dot(uv, hashv2);
float noise = fract(sin(seed) * hashS + t);
noise = gaussian(noise, 0.0, 0.5);
return vec3(noise);
}
float rand(vec2 co) {
return fract(sin(dot(co.xy, hashv2)) * hashS);
}
vec2 CurvedSurface(vec2 uv, float r) {
return r * uv / sqrt(r * r - dot(uv, uv));
}
vec2 crtCurve(vec2 uv, float r, bool content) {
uv = CurvedSurface(uv, 1.8);
if (content) { uv *= 0.5 / vec2(width, height); }
uv.x -= mouselerp.x * 0.0325;
return uv;
}
float roundSquare(vec2 p, vec2 b, float r) {
return length(max(abs(p) - b, 0.0)) - r;
}
float rs(vec2 uv, float r) {
return roundSquare(uv, vec2(width, height) + r, 0.05);
}
vec2 borderReflect(vec2 p, float r) {
float eps = 0.0001;
vec2 epsx = vec2(eps, 0.0);
vec2 epsy = vec2(0.0, eps);
vec2 b = (1.0 + vec2(r, r)) * 0.5;
r /= 3.0;
p -= 0.5;
vec2 normal = vec2(
roundSquare(p - epsx, b, r) - roundSquare(p + epsx, b, r),
roundSquare(p - epsy, b, r) - roundSquare(p + epsy, b, r)
) / eps;
float d = roundSquare(p, b, r);
p += 0.5;
return p + d * normal;
}
vec2 normalizeAndFix() {
vec2 uv = (gl_FragCoord.xy / resolution.xy) * 2.0 - 1.0;
float targetAR = 16.0 / 9.0;
float ar = resolution.x / resolution.y;
uv.x *= ar;
uv *= (
ar < targetAR &&
resolution.x < 800.0 &&
resolution.x < resolution.y
) ? 1.1 : 0.55;
return uv;
}
void main(void) {
float s = 0.0021;
vec4 color = vec4(0.02, 0.02, 0.03, 0.0);
const vec4 multColor = vec4(0.21);
const float ambient = 0.11;
vec4 bezel = vec4(0.5);
vec2 uv = normalizeAndFix();
vec2 suv = gl_FragCoord.xy / resolution.xy;
float gs = 1.0;
float grid = (
(mod(floor((suv.x) * resolution.x / gs), 2.0) == 0.0 ? 1.0 : 0.0) *
(mod(floor((suv.y) * resolution.y / gs), 2.0) == 0.0 ? 1.0 : 0.0)
);
vec2 uvC = crtCurve(uv, 1., true) + 0.5;
vec2 uvS = crtCurve(uv, 1., false);
vec2 uvE = crtCurve(uv, 1.25, false);
color += (max(0.0, ambient - 0.25 * distance(uvS, vec2(0.0))) * ss(s, -s, rs(uvS, 0.0)));
color += (bezel * ambient * 0.7 * ss(-s, s, rs(uvS, 0.0)) * ss(s, -s, rs(uvE, 0.05)));
color -= (bezel * ss(-s * 2.0, s * 10.0, rs(uvE, 0.05)) * ss(s * 2.0, -s * 2.0, rs(uvE, 0.05)));
color += (bezel * ambient * ss(-s, s, rs(uvE, 0.05)) * ss(s, -s, rs(uvE, 0.15)));
for (int i = 0; i < blurIter; i++) {
vec2 uvR = borderReflect(uvC + (vec2(rand(uvC + float(i)), rand(uvC + float(i) + 0.1)) - 0.5) * blurSize, 0.05);
color += (
(multColor - bezel * ambient) *
texture(inputTexture, uvR) / float(blurIter) *
ss(-s, s, rs(uvS, 0.0)) *
ss(s, -s, rs(uvE, 0.05))
);
}
vec4 prgmMipMaps = texture(inputTexture, uvC, 3.0) + texture(inputTexture, uvC, 4.0) + texture(inputTexture, uvC, 5.0);
color += (prgmMipMaps * ss(0.0, -s * 20.0, rs(uvS, -0.05)) * 0.5);
color += (
max(0.0, (1.0 - 2.0 * gl_FragCoord.y / resolution.y)) * vec4(0.1, 0.1, 0.1, 0.0) *
ss(-0.3, 0.3, roundSquare(uvC - vec2(0.5, 0.0), vec2(width + 0.2, height), 0.1)) *
ss(-s * 2.0, s * 2.0, roundSquare(uvE, vec2(width, height) + 0.15, 0.05))
) * 1.5;
if (
uvC.x > 0.0 &&
uvC.x < 1.0 &&
uvC.y > 0.0 &&
uvC.y < 1.0
) {
color += texture(inputTexture, uvC);
color = mix(color, color * grid, 0.35);
}
vec3 g = gaussgrain(time) * 0.015;
color.xyz += g;
fragColor = color;
fragColor.a = 1.0;
}