Skip to content

Instantly share code, notes, and snippets.

@cfstras
Last active January 30, 2018 23:17
Show Gist options
  • Save cfstras/bca1a26eb5fd1c8d0ceb92fac6b8dacc to your computer and use it in GitHub Desktop.
Save cfstras/bca1a26eb5fd1c8d0ceb92fac6b8dacc to your computer and use it in GitHub Desktop.
Variable Gradients Debayering in GLSL
#version 300 es
precision mediump float;
// https://anuejn.github.io/batic/
uniform sampler2D raw_image;
out vec4 fragColor;
float get_intensity(ivec2 pos) {
return texelFetch(raw_image, pos, 0).r;
}
ivec2 get_pos() {
ivec2 size = textureSize(raw_image, 0);
ivec2 icord = ivec2(gl_FragCoord);
return ivec2(icord.x, size.y - icord.y);
}
uniform float adjust_r;
uniform float adjust_g;
uniform float adjust_b;
// diagonal1 is lower-left<->upper-right
// diagonal2 is upper-left<->lower-right
void main(void) {
ivec2 pos = get_pos();
vec3 color = vec3(0.0, 0.0, 0.0);
mat3 neigh = mat3(
vec3(
get_intensity(ivec2(pos.x-1, pos.y-1)),
get_intensity(ivec2(pos.x, pos.y-1)),
get_intensity(ivec2(pos.x+1, pos.y-1))
),
vec3(
get_intensity(ivec2(pos.x-1, pos.y)),
get_intensity(pos),
get_intensity(ivec2(pos.x+1, pos.y))
),
vec3(
get_intensity(ivec2(pos.x-1, pos.y+1)),
get_intensity(ivec2(pos.x, pos.y+1)),
get_intensity(ivec2(pos.x+1, pos.y+1))
)
);
float grad_horizontal = abs(neigh[1][0] - neigh[1][2]);
float grad_vertical = abs(neigh[0][1] - neigh[2][1]);
float horizontal_fac = grad_horizontal / (grad_horizontal + grad_vertical);
float intensity_hor_vert = horizontal_fac * (neigh[1][0] + neigh[1][2]) / 2.0 +
(1.0 - horizontal_fac) * (neigh[0][1] + neigh[2][1]) / 2.0;
float grad_diagonal1 = abs(neigh[2][2] - neigh[0][0]);
float grad_diagonal2 = abs(neigh[2][0] - neigh[0][2]);
float diagonal1_fac = grad_diagonal1 / (grad_diagonal1 + grad_diagonal2);
float intensity_diag = diagonal1_fac * (neigh[2][2] + neigh[0][0]) / 2.0 +
(1.0 - diagonal1_fac) * (neigh[2][0] + neigh[0][2]) / 2.0;
if (pos.x%2==0 && pos.y%2==0) { // r
color.r = neigh[1][1];
color.g = intensity_hor_vert;
color.b = intensity_diag;
} else if (pos.x%2==1&&pos.y%2==1) { // b
color.b = neigh[1][1];
color.g = intensity_hor_vert;
color.r = intensity_diag;
} else if (pos.x%2==1&&pos.y%2==0) { // g-1
color.g = neigh[1][1];
color.r = (neigh[1][2] + neigh[1][0]) / 2.0;
color.b = (neigh[2][1] + neigh[0][1]) / 2.0;
} else { // g-2
color.g = neigh[1][1];
color.r = (neigh[2][1] + neigh[0][1]) / 2.0;
color.b = (neigh[1][2] + neigh[1][0]) / 2.0;
}
vec3 color_scale = vec3(adjust_r, adjust_g, adjust_b) * 2.0;
color *= color_scale;
// pack the color into the gl_FragColor without transparency
fragColor = vec4(color, 1.0);
}
#version 300 es
precision mediump float;
uniform sampler2D raw_image;
out vec4 fragColor;
float get_intensity(ivec2 pos) {
return texelFetch(raw_image, pos, 0).r;
}
ivec2 get_pos() {
ivec2 size = textureSize(raw_image, 0);
ivec2 icord = ivec2(gl_FragCoord);
return ivec2(icord.x, size.y - icord.y);
}
uniform float adjust_r;
uniform float adjust_g;
uniform float adjust_b;
void main(void) {
ivec2 pos = get_pos();
vec3 color = vec3(0.0, 0.0, 0.0);
if (pos.x%2==0 && pos.y%2==0) { // r
color.r = get_intensity(pos);
float g1_1 = get_intensity(ivec2(pos.x-1, pos.y));
float g1_2 = get_intensity(ivec2(pos.x+1, pos.y));
float grad_g1 = abs(g1_1 - g1_2);
float g2_1 = get_intensity(ivec2(pos.x, pos.y-1));
float g2_2 = get_intensity(ivec2(pos.x, pos.y+1));
float grad_g2 = abs(g2_1 - g2_2);
float grad_g_sum = grad_g1 + grad_g2;
float g1_fac = 1.0 - (grad_g1 / grad_g_sum);
float g2_fac = 1.0 - g1_fac;
color.g = g1_fac * (g1_1 + g1_2) / 2.0 +
g2_fac * (g2_1 + g2_2) / 2.0;
float b1_1 = get_intensity(ivec2(pos.x+1, pos.y+1));
float b1_2 = get_intensity(ivec2(pos.x-1, pos.y-1));
float grad_b1 = abs(b1_1 - b1_2);
float b2_1 = get_intensity(ivec2(pos.x-1, pos.y+1));
float b2_2 = get_intensity(ivec2(pos.x+1, pos.y-1));
float grad_b2 = abs(b2_1 - b2_2);
float grad_b_sum = grad_b1 + grad_b2;
float b1_fac = 1.0 - (grad_b1 / grad_b_sum);
float b2_fac = 1.0 - b1_fac;
color.b = b1_fac * (b1_1 + b1_2) / 2.0 +
b2_fac * (b2_1 + b2_2) / 2.0;
} else if (pos.x%2==1&&pos.y%2==1) { // b
color.b = get_intensity(pos);
float g1_1 = get_intensity(ivec2(pos.x-1, pos.y));
float g1_2 = get_intensity(ivec2(pos.x+1, pos.y));
float grad_g1 = abs(g1_1 - g1_2);
float g2_1 = get_intensity(ivec2(pos.x, pos.y-1));
float g2_2 = get_intensity(ivec2(pos.x, pos.y+1));
float grad_g2 = abs(g2_1 - g2_2);
float grad_g_sum = grad_g1 + grad_g2;
float g1_fac = 1.0 - (grad_g1 / grad_g_sum);
float g2_fac = 1.0 - g1_fac;
color.g = g1_fac * (g1_1 + g1_2) / 2.0 +
g2_fac * (g2_1 + g2_2) / 2.0;
float r1_1 = get_intensity(ivec2(pos.x+1, pos.y+1));
float r1_2 = get_intensity(ivec2(pos.x-1, pos.y-1));
float grad_r1 = abs(r1_1 - r1_2);
float r2_1 = get_intensity(ivec2(pos.x-1, pos.y+1));
float r2_2 = get_intensity(ivec2(pos.x+1, pos.y-1));
float grad_r2 = abs(r2_1 - r2_2);
float grad_b_sum = grad_r1 + grad_r2;
float r1_fac = 1.0 - (grad_r1 / grad_b_sum);
float r2_fac = 1.0 - r1_fac;
color.r = r1_fac * (r1_1 + r1_2) / 2.0 +
r2_fac * (r2_1 + r2_2) / 2.0;
} else if (pos.x%2==1&&pos.y%2==0) { // g-1
color.g = get_intensity(pos);
float r1 = get_intensity(ivec2(pos.x+1, pos.y));
float r2 = get_intensity(ivec2(pos.x-1, pos.y));
color.r = (r1 + r2) / 2.0;
float b1 = get_intensity(ivec2(pos.x, pos.y+1));
float b2 = get_intensity(ivec2(pos.x, pos.y-1));
color.b = (b1 + b2) / 2.0;
} else { // g-2
color.g = get_intensity(pos);
float r1 = get_intensity(ivec2(pos.x, pos.y+1));
float r2 = get_intensity(ivec2(pos.x, pos.y-1));
color.r = (r1 + r2) / 2.0;
float b1 = get_intensity(ivec2(pos.x+1, pos.y));
float b2 = get_intensity(ivec2(pos.x-1, pos.y));
color.b = (b1 + b2) / 2.0;
}
vec3 color_scale = vec3(adjust_r, adjust_g, adjust_b) * 2.0;
color *= color_scale;
// pack the color into the gl_FragColor without transparency
fragColor = vec4(color, 1.0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment