113 lines
No EOL
3.5 KiB
Text
113 lines
No EOL
3.5 KiB
Text
vertex_shader [[
|
|
out vec2 v_uv;
|
|
void main() {
|
|
v_uv = vec2(gl_VertexID & 1, (gl_VertexID & 2) * 0.5);
|
|
vec4 pos = vec4((gl_VertexID & 1) * 2 - 1, (gl_VertexID & 2) - 1, 0, 1);
|
|
gl_Position = pos;
|
|
}
|
|
]]
|
|
|
|
|
|
fragment_shader [[
|
|
#define timer u_time.x * 0.01
|
|
vec2 coordRot(vec2 tex_coord, float angle, vec2 tex_size)
|
|
{
|
|
float aspect = tex_size.x / tex_size.y;
|
|
float s = sin(angle);
|
|
float c = cos(angle);
|
|
vec2 tc = tex_coord * 2.0 - 1.0;
|
|
float rotX = (tc.x * aspect * c) - (tc.y * s);
|
|
float rotY = (tc.y * c) + (tc.x * aspect * s);
|
|
rotX = rotX / aspect;
|
|
rotY = rotY;
|
|
return vec2(rotX, rotY) * 0.5 + 0.5;
|
|
}
|
|
|
|
vec3 luma(vec3 _rgb)
|
|
{
|
|
float yy = dot(vec3(0.2126729, 0.7151522, 0.0721750), _rgb);
|
|
return vec3(yy);
|
|
}
|
|
|
|
vec4 rnm(in vec2 tc)
|
|
{
|
|
float noise = sin(dot(tc + vec2(timer,timer),vec2(12.9898,78.233))) * 43758.5453;
|
|
|
|
float noiseR = fract(noise)*2.0-1.0;
|
|
float noiseG = fract(noise*1.2154)*2.0-1.0;
|
|
float noiseB = fract(noise*1.3453)*2.0-1.0;
|
|
float noiseA = fract(noise*1.3647)*2.0-1.0;
|
|
|
|
return vec4(noiseR,noiseG,noiseB,noiseA);
|
|
}
|
|
|
|
float fade(float t) {
|
|
return t*t*t*(t*(t*6.0-15.0)+10.0);
|
|
}
|
|
|
|
float pnoise3D(vec3 p)
|
|
{
|
|
const float permTexUnit = 1.0 / 256.0;
|
|
const float permTexUnitHalf = 0.5 / 256.0;
|
|
|
|
vec3 pi = permTexUnit * floor(p) + permTexUnitHalf; // Integer part, scaled so +1 moves permTexUnit texel
|
|
vec3 pf = fract(p); // Fractional part for interpolation
|
|
|
|
float perm00 = rnm(pi.xy).a;
|
|
vec3 grad000 = rnm(vec2(perm00, pi.z)).rgb * 4.0 - 1.0;
|
|
float n000 = dot(grad000, pf);
|
|
vec3 grad001 = rnm(vec2(perm00, pi.z + permTexUnit)).rgb * 4.0 - 1.0;
|
|
float n001 = dot(grad001, pf - vec3(0.0, 0.0, 1.0));
|
|
|
|
float perm01 = rnm(pi.xy + vec2(0.0, permTexUnit)).a;
|
|
vec3 grad010 = rnm(vec2(perm01, pi.z)).rgb * 4.0 - 1.0;
|
|
float n010 = dot(grad010, pf - vec3(0.0, 1.0, 0.0));
|
|
vec3 grad011 = rnm(vec2(perm01, pi.z + permTexUnit)).rgb * 4.0 - 1.0;
|
|
float n011 = dot(grad011, pf - vec3(0.0, 1.0, 1.0));
|
|
|
|
float perm10 = rnm(pi.xy + vec2(permTexUnit, 0.0)).a;
|
|
vec3 grad100 = rnm(vec2(perm10, pi.z)).rgb * 4.0 - 1.0;
|
|
float n100 = dot(grad100, pf - vec3(1.0, 0.0, 0.0));
|
|
vec3 grad101 = rnm(vec2(perm10, pi.z + permTexUnit)).rgb * 4.0 - 1.0;
|
|
float n101 = dot(grad101, pf - vec3(1.0, 0.0, 1.0));
|
|
|
|
float perm11 = rnm(pi.xy + vec2(permTexUnit, permTexUnit)).a;
|
|
vec3 grad110 = rnm(vec2(perm11, pi.z)).rgb * 4.0 - 1.0;
|
|
float n110 = dot(grad110, pf - vec3(1.0, 1.0, 0.0));
|
|
vec3 grad111 = rnm(vec2(perm11, pi.z + permTexUnit)).rgb * 4.0 - 1.0;
|
|
float n111 = dot(grad111, pf - vec3(1.0, 1.0, 1.0));
|
|
|
|
vec4 n_x = mix(vec4(n000, n001, n010, n011), vec4(n100, n101, n110, n111), fade(pf.x));
|
|
|
|
vec2 n_xy = mix(n_x.xy, n_x.zw, fade(pf.y));
|
|
|
|
float n_xyz = mix(n_xy.x, n_xy.y, fade(pf.z));
|
|
|
|
return n_xyz;
|
|
}
|
|
|
|
vec3 filmGrain(vec2 tex_coord, vec2 tex_size, vec3 in_color)
|
|
{
|
|
const float grainsize = 1;
|
|
const float grainamount = 0.02;
|
|
const float lumamount = 0.1;
|
|
vec2 rotCoordsR = coordRot(tex_coord, timer, tex_size);
|
|
vec3 noise = vec3(pnoise3D(vec3(rotCoordsR * vec2(tex_size.xy / grainsize),0.0)));
|
|
float luminance = mix(0.0, luma(in_color).x, lumamount);
|
|
float lum = smoothstep(0.2, 0.0, luminance);
|
|
lum += luminance;
|
|
|
|
noise = mix(vec3(0.0), vec3(pow(lum, 4.0)), noise);
|
|
return in_color + noise * grainamount;
|
|
}
|
|
|
|
layout (binding=0) uniform sampler2D u_source;
|
|
in vec2 v_uv;
|
|
out vec4 o_color;
|
|
void main() {
|
|
vec3 c = texture(u_source, v_uv).rgb;
|
|
vec2 tex_size = textureSize(u_source, 0);
|
|
o_color.rgb = filmGrain(v_uv, tex_size, c);
|
|
o_color.w = 1;
|
|
}
|
|
]] |