@@ -65,6 +65,10 @@ uniform vec2 tex_step;
uniform vec2 tex_bayer_first_red;
uniform sampler2D tex_y;
+uniform sampler2D red_param;
+uniform sampler2D green_param;
+uniform sampler2D blue_param;
+uniform mat3 ccm;
void main(void)
{
@@ -212,5 +216,57 @@ void main(void)
vec3(patterns.y, C, patterns.x) :
vec3(patterns.wz, C));
+#if defined(APPLY_CCM_PARAMETERS)
+ /*
+ * CCM is a 3x3 in the format
+ *
+ * +--------------+----------------+---------------+
+ * | RedRedGain | RedGreenGain | RedBlueGain |
+ * +--------------+----------------+---------------+
+ * | GreenRedGain | GreenGreenGain | GreenBlueGain |
+ * +--------------+----------------+---------------+
+ * | BlueRedGain | BlueGreenGain | BlueBlueGain |
+ * +--------------+----------------+---------------+
+ *
+ * Rout = RedRedGain * Rin + RedGreenGain * Gin + RedBlueGain * Bin
+ * Gout = GreenRedGain * Rin + GreenGreenGain * Gin + GreenBlueGain * Bin
+ * Bout = BlueRedGain * Rin + BlueGreenGain * Gin + BlueBlueGain * Bin
+ *
+ * We upload to the GPU without transposition glUniformMatrix3f(.., .., GL_FALSE, ccm);
+ *
+ * CPU
+ * float ccm [] = {
+ * RedRedGain, RedGreenGain, RedBlueGain,
+ * GreenRedGain, GreenGreenGain, GreenBlueGain,
+ * BlueRedGain, BlueGreenGain, BlueBlueGain,
+ * };
+ *
+ * GPU
+ * ccm = {
+ * RedRedGain, GreenRedGain, BlueRedGain,
+ * RedGreenGain, GreenGreenGain, BlueGreenGain,
+ * RedBlueGain, GreenBlueGain, BlueBlueGain,
+ * }
+ *
+ * However the indexing for the mat data-type is column major hence
+ * ccm[0][0] = RedRedGain, ccm[0][1] = RedGreenGain, ccm[0][2] = RedBlueGain
+ *
+ */
+ float rin, gin, bin;
+ rin = rgb.r;
+ gin = rgb.g;
+ bin = rgb.b;
+
+ rgb.r = (rin * ccm[0][0]) + (gin * ccm[0][1]) + (bin * ccm[0][2]);
+ rgb.g = (rin * ccm[1][0]) + (gin * ccm[1][1]) + (bin * ccm[1][2]);
+ rgb.b = (rin * ccm[2][0]) + (gin * ccm[2][1]) + (bin * ccm[2][2]);
+
+#elif defined(APPLY_RGB_PARAMETERS)
+ /* Apply bayer params */
+ rgb.r = texture2D(red_param, vec2(rgb.r, 0.5)).r;
+ rgb.g = texture2D(green_param, vec2(rgb.g, 0.5)).g;
+ rgb.b = texture2D(blue_param, vec2(rgb.b, 0.5)).b;
+#endif
+
gl_FragColor = vec4(rgb, 1.0);
}
@@ -21,11 +21,17 @@ precision highp float;
/** Monochrome RGBA or GL_LUMINANCE Bayer encoded texture.*/
uniform sampler2D tex_y;
+uniform sampler2D red_param;
+uniform sampler2D green_param;
+uniform sampler2D blue_param;
varying vec4 center;
varying vec4 yCoord;
varying vec4 xCoord;
+uniform mat3 ccm;
void main(void) {
+ vec3 rgb;
+
#define fetch(x, y) texture2D(tex_y, vec2(x, y)).r
float C = texture2D(tex_y, center.xy).r; // ( 0, 0)
@@ -97,11 +103,65 @@ void main(void) {
PATTERN.xw += kB.xw * B;
PATTERN.xz += kF.xz * F;
- gl_FragColor.rgb = (alternate.y == 0.0) ?
+ rgb = (alternate.y == 0.0) ?
((alternate.x == 0.0) ?
vec3(C, PATTERN.xy) :
vec3(PATTERN.z, C, PATTERN.w)) :
((alternate.x == 0.0) ?
vec3(PATTERN.w, C, PATTERN.z) :
vec3(PATTERN.yx, C));
+
+#if defined(APPLY_CCM_PARAMETERS)
+ /*
+ * CCM is a 3x3 in the format
+ *
+ * +--------------+----------------+---------------+
+ * | RedRedGain | RedGreenGain | RedBlueGain |
+ * +--------------+----------------+---------------+
+ * | GreenRedGain | GreenGreenGain | GreenBlueGain |
+ * +--------------+----------------+---------------+
+ * | BlueRedGain | BlueGreenGain | BlueBlueGain |
+ * +--------------+----------------+---------------+
+ *
+ * Rout = RedRedGain * Rin + RedGreenGain * Gin + RedBlueGain * Bin
+ * Gout = GreenRedGain * Rin + GreenGreenGain * Gin + GreenBlueGain * Bin
+ * Bout = BlueRedGain * Rin + BlueGreenGain * Gin + BlueBlueGain * Bin
+ *
+ * We upload to the GPU without transposition glUniformMatrix3f(.., .., GL_FALSE, ccm);
+ *
+ * CPU
+ * float ccm [] = {
+ * RedRedGain, RedGreenGain, RedBlueGain,
+ * GreenRedGain, GreenGreenGain, GreenBlueGain,
+ * BlueRedGain, BlueGreenGain, BlueBlueGain,
+ * };
+ *
+ * GPU
+ * ccm = {
+ * RedRedGain, GreenRedGain, BlueRedGain,
+ * RedGreenGain, GreenGreenGain, BlueGreenGain,
+ * RedBlueGain, GreenBlueGain, BlueBlueGain,
+ * }
+ *
+ * However the indexing for the mat data-type is column major hence
+ * ccm[0][0] = RedRedGain, ccm[0][1] = RedGreenGain, ccm[0][2] = RedBlueGain
+ *
+ */
+ float rin, gin, bin;
+ rin = rgb.r;
+ gin = rgb.g;
+ bin = rgb.b;
+
+ rgb.r = (rin * ccm[0][0]) + (gin * ccm[0][1]) + (bin * ccm[0][2]);
+ rgb.g = (rin * ccm[1][0]) + (gin * ccm[1][1]) + (bin * ccm[1][2]);
+ rgb.b = (rin * ccm[2][0]) + (gin * ccm[2][1]) + (bin * ccm[2][2]);
+
+#elif defined(APPLY_RGB_PARAMETERS)
+ /* Apply bayer params */
+ rgb.r = texture2D(red_param, vec2(rgb.r, 0.5)).r;
+ rgb.g = texture2D(red_param, vec2(rgb.g, 0.5)).g;
+ rgb.b = texture2D(red_param, vec2(rgb.b, 0.5)).b;
+#endif
+
+ gl_FragColor.rgb = rgb;
}
Extend out the bayer fragment shaders to take 3 x 256 byte inputs as textures from the CPU. We then use an index to the table to recover the colour-corrected values provided by the SoftIPA thread. Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> --- .../internal/shaders/bayer_1x_packed.frag | 56 +++++++++++++++++++ include/libcamera/internal/shaders/bayer_8.frag | 62 +++++++++++++++++++++- 2 files changed, 117 insertions(+), 1 deletion(-)