diff --git a/src/qcam/assets/shader/bayer_8.frag b/src/qcam/assets/shader/bayer_8.frag
index 4ece44ab..be23913b 100644
--- a/src/qcam/assets/shader/bayer_8.frag
+++ b/src/qcam/assets/shader/bayer_8.frag
@@ -10,21 +10,51 @@ This paper appears in issue Volume 13, Number 4.
 ---------------------------------------------------------
 Copyright (c) 2008, Morgan McGuire. All rights reserved.
 
-Modified by Linaro Ltd to integrate it into libcamera.
+
+Modified by Linaro Ltd to integrate it into libcamera, and to
+fix the artifacts due to pixel coordinates interpolation.
 Copyright (C) 2021, Linaro
 */
 
 //Pixel Shader
 
+varying vec2 textureOut;
+
+uniform vec2 tex_size; /* The texture size in pixels */
+uniform vec2 tex_step;
+
+/** Pixel position of the first red pixel in the */
+/**  Bayer pattern.  [{0,1}, {0, 1}]*/
+uniform vec2            tex_bayer_first_red;
+
 /** Monochrome RGBA or GL_LUMINANCE Bayer encoded texture.*/
 uniform sampler2D       tex_y;
-varying vec4            center;
-varying vec4            yCoord;
-varying vec4            xCoord;
 
 void main(void) {
     #define fetch(x, y) texture2D(tex_y, vec2(x, y)).r
 
+    /** .xy = Pixel being sampled in the fragment shader on the range [0, 1]
+        .zw = ...on the range [0, sourceSize], offset by firstRed */
+    vec4            center;
+
+    /** center.x + (-2/w, -1/w, 1/w, 2/w); These are the x-positions */
+    /** of the adjacent pixels.*/
+    vec4            xCoord;
+
+    /** center.y + (-2/h, -1/h, 1/h, 2/h); These are the y-positions */
+    /** of the adjacent pixels.*/
+    vec4            yCoord;
+
+    /* Align the center coordinates to the nearest pixel */
+    center.zw = floor(textureOut * tex_size);
+    center.xy = center.zw * tex_step;
+    center.zw += tex_bayer_first_red;
+
+    xCoord = center.x + vec4(-2.0 * tex_step.x,
+                             -tex_step.x, tex_step.x, 2.0 * tex_step.x);
+    yCoord = center.y + vec4(-2.0 * tex_step.y,
+                              -tex_step.y, tex_step.y, 2.0 * tex_step.y);
+
     float C = texture2D(tex_y, center.xy).r; // ( 0, 0)
     const vec4 kC = vec4( 4.0,  6.0,  5.0,  5.0) / 8.0;
 
diff --git a/src/qcam/viewfinder_gl.cpp b/src/qcam/viewfinder_gl.cpp
index e7c8620c..a5b1bfbe 100644
--- a/src/qcam/viewfinder_gl.cpp
+++ b/src/qcam/viewfinder_gl.cpp
@@ -231,28 +231,24 @@ bool ViewFinderGL::selectFormat(const libcamera::PixelFormat &format)
 	case libcamera::formats::SBGGR8:
 		firstRed_.setX(1.0);
 		firstRed_.setY(1.0);
-		vertexShaderFile_ = ":bayer_8.vert";
 		fragmentShaderFile_ = ":bayer_8.frag";
 		textureMinMagFilters_ = GL_NEAREST;
 		break;
 	case libcamera::formats::SGBRG8:
 		firstRed_.setX(0.0);
 		firstRed_.setY(1.0);
-		vertexShaderFile_ = ":bayer_8.vert";
 		fragmentShaderFile_ = ":bayer_8.frag";
 		textureMinMagFilters_ = GL_NEAREST;
 		break;
 	case libcamera::formats::SGRBG8:
 		firstRed_.setX(1.0);
 		firstRed_.setY(0.0);
-		vertexShaderFile_ = ":bayer_8.vert";
 		fragmentShaderFile_ = ":bayer_8.frag";
 		textureMinMagFilters_ = GL_NEAREST;
 		break;
 	case libcamera::formats::SRGGB8:
 		firstRed_.setX(0.0);
 		firstRed_.setY(0.0);
-		vertexShaderFile_ = ":bayer_8.vert";
 		fragmentShaderFile_ = ":bayer_8.frag";
 		textureMinMagFilters_ = GL_NEAREST;
 		break;
