summaryrefslogtreecommitdiff
path: root/debayer.fs.glsl
diff options
context:
space:
mode:
Diffstat (limited to 'debayer.fs.glsl')
-rw-r--r--debayer.fs.glsl41
1 files changed, 41 insertions, 0 deletions
diff --git a/debayer.fs.glsl b/debayer.fs.glsl
new file mode 100644
index 0000000..e6eace4
--- /dev/null
+++ b/debayer.fs.glsl
@@ -0,0 +1,41 @@
+uniform sampler2D u_sampler;
+uniform highp mat4 u_coef_r;
+uniform highp mat4 u_coef_g;
+uniform highp mat4 u_coef_b;
+varying highp vec2 v_position;
+
+/* Evaluate power serial polynomial of degree 16, with 0-th order term 0 */
+highp float polyeval(highp mat4 c, highp float x){
+ highp float y = c[3][3];
+ for(int i=4, j=3; 0<i; --i, j=4){ for(; 0<j; --j){
+ y = y*x + c[i-1][j-1];
+ }}
+ return y*x;
+}
+
+void main(){
+ /* Even and odd rows each contain alternating primitives of the
+ * Bayer pattern;
+ * RGRGRGRGRG
+ * GBGBGBGBGB
+ * RGRGRGRGRG
+ * GBGBGBGBGB
+ * ...
+ *
+ * The pixel data was uploaded to the texture in
+ * a way, that the even rows are in 0<x<0.5 and the odd rows
+ * in 0.5<x<1, i.e. we end up with
+ * RGRGRGRGRG GBGBGBGBGB
+ * RGRGRGRGRG GBGBGBGBGB
+ * ...
+ *
+ * Also OpenGL assumes texture origin lower left, so flip y here */
+ lowp vec2 v_pos_even = vec2(0.5*( v_position.x), 1.-v_position.y);
+ lowp vec2 v_pos_odd = vec2(0.5*(1.+v_position.x), 1.-v_position.y);
+ highp vec4 rggb = vec4(texture2D(u_sampler, v_pos_even).wx, texture2D(u_sampler, v_pos_odd ).wx);
+ highp vec3 rgb = vec3(
+ polyeval(u_coef_r, rggb[0]),
+ mix(polyeval(u_coef_g, rggb[1]), polyeval(u_coef_g, rggb[2]), 0.5),
+ polyeval(u_coef_b, rggb[3]) );
+ gl_FragColor = vec4(rgb, 1.);
+}