I’m trying to create a color filter array demosaicing fragment shader for raw capture from a color camera with color bayer filter. In order to properly decode the image, I require acces to clean neighboring texels without any averaging from neighboring texels. Since I’m not using TEXTURE_RECTANGLE textures, I’m a little nervous. I also have to know the exact x/y offset of the main pixel in the shader.
Here is a partial simple shader that implements the RGB values from a red pixel of the color bayer filter array:
#extension GL_EXT_gpu_shader4 : enable [SIZE=2]//Required For Integer Modulus Operation (%)
uniform sampler2D BayerCaptureSampler;
uniform [/SIZE][SIZE=2]float[/SIZE] captureImageWidth;
uniform [SIZE=2]float[/SIZE] captureImageHeight;
[SIZE=2]void[/SIZE] main([SIZE=2]void[/SIZE])
{
[SIZE=2]float[/SIZE] step_w;
[SIZE=2]float[/SIZE] step_h;
[SIZE=2]float[/SIZE] fragOffsetFloatX;
[SIZE=2]float[/SIZE] fragOffsetFloatY
[SIZE=2]int[/SIZE] fragOffsetIntX;
[SIZE=2]int[/SIZE] fragOffsetIntY;
vec2 redOffset[4];
vec2 greenOffset[4];
vec2 blueOffset[4];
[SIZE=2]int[/SIZE] evenOddX;
[SIZE=2]int[/SIZE] evenOddY;
[SIZE=2]float[/SIZE] Sum;
[SIZE=2]//Example: ASSUME ORIGINAL SOURCE BUFFER OF 2048 x 1536
[/SIZE][SIZE=2]//Calculate Single Texel Normalized Offset From Original capture buffer resolution
[/SIZE]step_w = 1.0/captureImageWidth; [SIZE=2]//Should return 1.0/2048.0 = 0.00048828125
[/SIZE]step_h = 1.0/captureImageHeigh; [SIZE=2]//Should return 1.0/1536.0 = 0.00065104166
[/SIZE][SIZE=2]//Retrieve the Current Texel Offset (In Host Buffer Integer Coordinates From Corner (0,0)
[/SIZE]fragOffsetIntX = gl_FragCoord.x; [SIZE=2]//Should Return Integer Value 0 to 2047
[/SIZE]fragOffsetIntY = gl_FragCoord.y; [SIZE=2]//Should Return Integer Value 0 to 1535
[/SIZE][SIZE=2]//Determine if this is an even or odd pixel on horizontal and vertical offsets from bottom right corner texel
[/SIZE]evenOddX = fragOffsetIntX%2; [SIZE=2]//Should Return 0 for even, or 1 for odd
[/SIZE]evenOddY = fagOffsetIntY%2; [SIZE=2]//Should Return 0 for even, or 1 for odd
[/SIZE][SIZE=2]//*************************Sample Code For A Red Pixel Decocing******************//
[/SIZE][SIZE=2]if[/SIZE](evenOddX==0) [SIZE=2]//Width Offset = Even Texel
[/SIZE]{
[SIZE=2]if[/SIZE] {evenOddY==0) [SIZE=2]//Height Offset = Even Texel
[/SIZE]{
[SIZE=2]//Retrieve Red Texel
[/SIZE]glFragColor.r = texture2D(BayerCaptureSampler,vec(gl_TextCoord[0].st)).r;
[SIZE=2]//Calculate Green Pixel Offsets
[/SIZE][SIZE=2]//THESE NEED TO BE IDENTICAL PIXEL VALUE FROM THE ORIGINAL BUFFER THAT WAS LOADED INTO
[/SIZE][SIZE=2]//TEXTURE WIHTOUT ANY MIXTURE OR AVERAGING OF PIXELS ONCE INSIDE THE TEXTURE
[/SIZE] greenOffset[0] = vec2(step_w,step_h);
greenOffset[1] = vec2(0.0,step_h);
greenOffset[2] = vec2(-step_w,0.0);
greenOffset[3] = vec2(0.0,-step_h);
[SIZE=2]//Retrieve and Average Neighboring Green Pixels
[/SIZE] sum = 0.0;
sum += texture2D(BayerCaptureSampler,vec2(gl_TexCoord[0].st + greenOffset[0];
sum += texture2D(BayerCaptureSampler,vec2(gl_TexCoord[0].st + greenOffset[1];
sum += texture2D(BayerCaptureSampler,vec2(gl_TexCoord[0].st + greenOffset[2];
sum += texture2D(BayerCaptureSampler,vec2(gl_TexCoord[0].st + greenOffset[3];
[SIZE=2]//Assign Final Calculated Green Texel
[/SIZE]glFragColor.g = sum/4.0;
[SIZE=2]//Calculate Blue Pixel Offsets
[/SIZE][SIZE=2]//THESE NEED TO BE IDENTICAL PIXEL VALUE AS DESCRIBED ABOVE
[/SIZE] greenOffset[0] = vec2(step_w,step_h);
greenOffset[1] = vec2(-step_w,step_h);
greenOffset[2] = vec2(step_w,-step_h);
greenOffset[3] = vec2(-step_w,-step_h);
[SIZE=2]//Retrieve and Average Neighboring Blue Pixels
[/SIZE] sum = 0.0;
sum += texture2D(BayerCaptureSampler,vec2(gl_TexCoord[0].st + blueOffset[0];
sum += texture2D(BayerCaptureSampler,vec2(gl_TexCoord[0].st + blueOffset[1];
sum += texture2D(BayerCaptureSampler,vec2(gl_TexCoord[0].st + blueOffset[2];
sum += texture2D(BayerCaptureSampler,vec2(gl_TexCoord[0].st + blueOffset[3];
[SIZE=2]//Assign Final Calculated Blue Texel
[/SIZE]glFragColor.b = sum/4.0;
}
}
[SIZE=2]//Assign 1 to Alpha Channel
[/SIZE]glFragColor.a = 1.0
}
My questions are:
-
How do I implement the layout qualifier “pixel_center_integer” with this version of OpenGL? I need the offsets to be the actual integer values, not with 0.5 offsets.
-
Will my greenOffset[] and blueOffset[] texel offsets return me the original buffer pixels without any sub-pixel neighbor averaging? The color demosaicing will not work if the pixel values are in any way mixed.
Thanks for your help!