Rennie Johnson

10-05-2012, 03:47 PM

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 //Required For Integer Modulus Operation (%)

uniform sampler2D BayerCaptureSampler;

uniform float captureImageWidth;

uniform float captureImageHeight;

void main(void)

{

float step_w;

float step_h;

float fragOffsetFloatX;

float fragOffsetFloatY

int fragOffsetIntX;

int fragOffsetIntY;

vec2 redOffset[4];

vec2 greenOffset[4];

vec2 blueOffset[4];

int evenOddX;

int evenOddY;

float Sum;

//Example: ASSUME ORIGINAL SOURCE BUFFER OF 2048 x 1536

//Calculate Single Texel Normalized Offset From Original capture buffer resolution

step_w = 1.0/captureImageWidth; //Should return 1.0/2048.0 = 0.00048828125

step_h = 1.0/captureImageHeigh; //Should return 1.0/1536.0 = 0.00065104166

//Retrieve the Current Texel Offset (In Host Buffer Integer Coordinates From Corner (0,0)

fragOffsetIntX = gl_FragCoord.x; //Should Return Integer Value 0 to 2047

fragOffsetIntY = gl_FragCoord.y; //Should Return Integer Value 0 to 1535

//Determine if this is an even or odd pixel on horizontal and vertical offsets from bottom right corner texel

evenOddX = fragOffsetIntX%2; //Should Return 0 for even, or 1 for odd

evenOddY = fagOffsetIntY%2; //Should Return 0 for even, or 1 for odd

//*************************Sample Code For A Red Pixel Decocing******************//

if(evenOddX==0) //Width Offset = Even Texel

{

if {evenOddY==0) //Height Offset = Even Texel

{

//Retrieve Red Texel

glFragColor.r = texture2D(BayerCaptureSampler,vec(gl_TextCoord[0].st)).r;

//Calculate Green Pixel Offsets

//THESE NEED TO BE IDENTICAL PIXEL VALUE FROM THE ORIGINAL BUFFER THAT WAS LOADED INTO

//TEXTURE WIHTOUT ANY MIXTURE OR AVERAGING OF PIXELS ONCE INSIDE THE TEXTURE

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);

//Retrieve and Average Neighboring Green Pixels

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];

//Assign Final Calculated Green Texel

glFragColor.g = sum/4.0;

//Calculate Blue Pixel Offsets

//THESE NEED TO BE IDENTICAL PIXEL VALUE AS DESCRIBED ABOVE

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);

//Retrieve and Average Neighboring Blue Pixels

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];

//Assign Final Calculated Blue Texel

glFragColor.b = sum/4.0;

}

}

//Assign 1 to Alpha Channel

glFragColor.a = 1.0

}

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!

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 //Required For Integer Modulus Operation (%)

uniform sampler2D BayerCaptureSampler;

uniform float captureImageWidth;

uniform float captureImageHeight;

void main(void)

{

float step_w;

float step_h;

float fragOffsetFloatX;

float fragOffsetFloatY

int fragOffsetIntX;

int fragOffsetIntY;

vec2 redOffset[4];

vec2 greenOffset[4];

vec2 blueOffset[4];

int evenOddX;

int evenOddY;

float Sum;

//Example: ASSUME ORIGINAL SOURCE BUFFER OF 2048 x 1536

//Calculate Single Texel Normalized Offset From Original capture buffer resolution

step_w = 1.0/captureImageWidth; //Should return 1.0/2048.0 = 0.00048828125

step_h = 1.0/captureImageHeigh; //Should return 1.0/1536.0 = 0.00065104166

//Retrieve the Current Texel Offset (In Host Buffer Integer Coordinates From Corner (0,0)

fragOffsetIntX = gl_FragCoord.x; //Should Return Integer Value 0 to 2047

fragOffsetIntY = gl_FragCoord.y; //Should Return Integer Value 0 to 1535

//Determine if this is an even or odd pixel on horizontal and vertical offsets from bottom right corner texel

evenOddX = fragOffsetIntX%2; //Should Return 0 for even, or 1 for odd

evenOddY = fagOffsetIntY%2; //Should Return 0 for even, or 1 for odd

//*************************Sample Code For A Red Pixel Decocing******************//

if(evenOddX==0) //Width Offset = Even Texel

{

if {evenOddY==0) //Height Offset = Even Texel

{

//Retrieve Red Texel

glFragColor.r = texture2D(BayerCaptureSampler,vec(gl_TextCoord[0].st)).r;

//Calculate Green Pixel Offsets

//THESE NEED TO BE IDENTICAL PIXEL VALUE FROM THE ORIGINAL BUFFER THAT WAS LOADED INTO

//TEXTURE WIHTOUT ANY MIXTURE OR AVERAGING OF PIXELS ONCE INSIDE THE TEXTURE

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);

//Retrieve and Average Neighboring Green Pixels

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];

//Assign Final Calculated Green Texel

glFragColor.g = sum/4.0;

//Calculate Blue Pixel Offsets

//THESE NEED TO BE IDENTICAL PIXEL VALUE AS DESCRIBED ABOVE

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);

//Retrieve and Average Neighboring Blue Pixels

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];

//Assign Final Calculated Blue Texel

glFragColor.b = sum/4.0;

}

}

//Assign 1 to Alpha Channel

glFragColor.a = 1.0

}

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!