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:
Code :[SIZE=2] #extension GL_EXT_gpu_shader4 : enable [SIZE=2][COLOR=#008000]//Required For Integer Modulus Operation (%)[/COLOR][/SIZE] uniform sampler2D BayerCaptureSampler; uniform [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]float[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] captureImageWidth; uniform [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]float[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] captureImageHeight; [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]void[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#000000] main([/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]void[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#000000])[/COLOR] { [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]float[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] step_w; [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]float[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] step_h; [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]float[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] fragOffsetFloatX; [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]float[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] fragOffsetFloatY [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]int[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] fragOffsetIntX; [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]int[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] fragOffsetIntY; vec2 redOffset[4]; vec2 greenOffset[4]; vec2 blueOffset[4]; [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]int[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] evenOddX; [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]int[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] evenOddY; [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]float[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] Sum;[/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]//Example: ASSUME ORIGINAL SOURCE BUFFER OF 2048 x 1536 [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]//Calculate Single Texel Normalized Offset From Original capture buffer resolution [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]step_w = 1.0/captureImageWidth; [/SIZE][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]//Should return 1.0/2048.0 = 0.00048828125 [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]step_h = 1.0/captureImageHeigh; [/SIZE][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]//Should return 1.0/1536.0 = 0.00065104166 [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]//Retrieve the Current Texel Offset (In Host Buffer Integer Coordinates From Corner (0,0) [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]fragOffsetIntX = gl_FragCoord.x; [/SIZE][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]//Should Return Integer Value 0 to 2047 [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]fragOffsetIntY = gl_FragCoord.y; [/SIZE][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]//Should Return Integer Value 0 to 1535 [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]//Determine if this is an even or odd pixel on horizontal and vertical offsets from bottom right corner texel [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]evenOddX = fragOffsetIntX%2; [/SIZE][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]//Should Return 0 for even, or 1 for odd [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]evenOddY = fagOffsetIntY%2; [/SIZE][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]//Should Return 0 for even, or 1 for odd [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]//*************************Sample Code For A Red Pixel Decocing******************// [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]if[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2](evenOddX==0) [/SIZE][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]//Width Offset = Even Texel [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]{ [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]if[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] {evenOddY==0) [/SIZE][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]//Height Offset = Even Texel [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]{ [/SIZE][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]//Retrieve Red Texel [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]glFragColor.r = texture2D(BayerCaptureSampler,vec(gl_TextCoord[0].st)).r; [/SIZE][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]//Calculate Green Pixel Offsets [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]//THESE NEED TO BE IDENTICAL PIXEL VALUE FROM THE ORIGINAL BUFFER THAT WAS LOADED INTO [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]//TEXTURE WIHTOUT ANY MIXTURE OR AVERAGING OF PIXELS ONCE INSIDE THE TEXTURE [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] 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][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]//Retrieve and Average Neighboring Green Pixels [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] 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][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]//Assign Final Calculated Green Texel [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]glFragColor.g = sum/4.0; [/SIZE][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]//Calculate Blue Pixel Offsets [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]//THESE NEED TO BE IDENTICAL PIXEL VALUE AS DESCRIBED ABOVE [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] 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][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]//Retrieve and Average Neighboring Blue Pixels [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] 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][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]//Assign Final Calculated Blue Texel [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]glFragColor.b = sum/4.0; } } [/SIZE][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]//Assign 1 to Alpha Channel [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]glFragColor.a = 1.0 } [/SIZE]
My questions are:
1) 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.
2) 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!