Re: [osg-users] [osgPPU] Problem Passing Lookup Table to Processing Unit
Hi Harash, Are you really using floatToRGB or it is not in use anywhere? This will never give you exact results because this will have quantization errors if you use normalized textures (so just GL_RGB). Try to use float textures directly. In your case GL_RGB32F_ARB (for three channels: min, max, and mean). Another point which one has to check: when doing mipmapping if texture coordinates to grab from the previous level are correct. This might introduce errors either because wrong pixels are grabbed or interpolation is in between (so pixels are not grabbed at their center). I must admit it was a long time ago, that I have tested the shaders if they use correct pixel coordinates. It might happen that there is still a mistake. You can see it in the code, where there is a comment "(TODO check why -1 seems to be correct)". Because to the time I wrote the shader, I was pretty sure it should be +halfTexel and not -halfTexel there. However the results seems to be correct. The shader was original taken from my other application. I have to sit down and just to recheck all that mipmap stuff, but unfortunately I have not so much time for that :( Cheers, Art -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=20840#20840 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] [osgPPU] Problem Passing Lookup Table to Processing Unit
Hi Mr. J.P. and Mr. Art Tevs, Thanks for the quick reply. Mr. J.P. the pointers you gave to image reduction are very interesting. I am going through those since they will help me in the long run, but it would take some time to get to it. Below, I am attaching the fragment shader code for the unit that accesses the mipmap: // The input image uniform sampler2DImage; // Mean and MeanSquared values uniform sampler2DMeanStdImage; vec3 floatToRGB(float Val) { float D = Val * 16777215.0; float R = floor(D / 65536.0); D = D - R * 65536.0; float G = floor(D/256.0); D = D - G*256.0; float B = floor(D); return vec3(R/255.0, G/255.0, B/255.0); } void main (void) { // get the image gray value -- C.r = C.g = C.b; vec4 C = texture2D(Image, gl_TexCoord[0].st); float Gray = C.r; // grab the image mean and std dev; vec4 Avg = texture2D(MeanStdImage, vec2(0.5,0.5), 100.0); float M = Avg.r;// Mean float M2 = Avg.g;// Mean of squares // Compute the variance & Std. Dev. float Var = clamp(M2 - M*M, 0.0, 1.0); float Std = sqrt(Var); float Factor = 0.5/Std;// Compute the scale factor // grab the pixel color Gray = (Gray - M) * Factor + 0.5; Gray = clamp(Gray, 0.0, 1.0); gl_FragColor = vec4(Gray, Gray, Gray, 1.0); } I have separately tried to convert the floating values M, M2, Std and unprocessed Gray into RGB (using floatToRGB) and grabbed using UnitCapture. Importing to Matlab revealed that the image has the following parameters: Min = 0.09, Max = 0.12, Mean ~ 0.11, std. dev = 0.01.., However, the mean and std dev as computed by Mipmapping are 0.115 and ~0.12 respectively. So it looks like the mean is more or less proper, but the std. dev. is improper. One doubt that I have is -- whether the placing of mean in red and sq. mean in green components is improper? Regards Harash From: Art Tevs To: osg-users@lists.openscenegraph.org Sent: Thu, December 3, 2009 5:55:24 PM Subject: Re: [osg-users] [osgPPU] Problem Passing Lookup Table to Processing Unit Hi Harash, J.P. J.P. Delport wrote: > > I'm not sure your shader is doing a proper mean. For the GPU to do > mean/sum you need to do what is called a reduction. Search for reduction > on www.gpgpu.org. This is different from doing per pixel operations like > changing luminance e.g. > The posted code seems to be similar to the luminance computation in the HDR example (quick overview over the code). Using mipmaps one can compute an average or arithmetic mean value, I am not aware if reduction is really needed here. Maybe reduction means exactly the same. To compute it I would do the way, you described here: using UnitInMipmapOut to crete a mipmap with the average value in the highest level. What do you mean, that the values are not the same? In order to get the computed value out of the mipmap you have to access the last mipmap level in your shader. Take a look into brightpass/tonemap shader, where the last level with scene luminance is accessed. Also make sure that in the last level you access not on (0,0) position, but on (0.5,0.5), because otherwise you will get interpolated values. It is actually better to disable GL_LINEAR filtering for the textures used by the unit. art -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=20803#20803 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] [osgPPU] Problem Passing Lookup Table to Processing Unit
Hi Harash, J.P. J.P. Delport wrote: > > I'm not sure your shader is doing a proper mean. For the GPU to do > mean/sum you need to do what is called a reduction. Search for reduction > on www.gpgpu.org. This is different from doing per pixel operations like > changing luminance e.g. > The posted code seems to be similar to the luminance computation in the HDR example (quick overview over the code). Using mipmaps one can compute an average or arithmetic mean value, I am not aware if reduction is really needed here. Maybe reduction means exactly the same. To compute it I would do the way, you described here: using UnitInMipmapOut to crete a mipmap with the average value in the highest level. What do you mean, that the values are not the same? In order to get the computed value out of the mipmap you have to access the last mipmap level in your shader. Take a look into brightpass/tonemap shader, where the last level with scene luminance is accessed. Also make sure that in the last level you access not on (0,0) position, but on (0.5,0.5), because otherwise you will get interpolated values. It is actually better to disable GL_LINEAR filtering for the textures used by the unit. art -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=20803#20803 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] [osgPPU] Problem Passing Lookup Table to Processing Unit
Hi, Harash Sharma wrote: Hi All, First of all thanks Mr. Art Tevs for your suggestions and pointers for passing Lookup tables. And thanks again for such a fantastic library OSGPPU. Now my whole application is ported into osgPPU pipeline and it works very well. Now the only worry that remains is the linear contrast enhancement. I had posed this problem earlier but in a different way. Motivated by Mr. Art's Luminance shader, I wanted to implement the following algorithm: 1. Use a UnitInMipmapOut to compute the Mean (M) of the image gray values and the mean of image squared gray levels 2. Read these values in the child unit shader, compute the image std. deviation, from the image gray value (G), compute the new gray levels as (G-M) * (0.5/S) + 0.5; 3. However, this doesn't give any contrast improvent 4. I have tried to capture the Mean and Std. Dev. by converting them to RGB and storing using UnitCapture. 5. The rendered image statistics and GPU computed statistics (std. dev.) don't match I have used the following fragment shader attached to UnitInMipmapOut to compute Mean and Mean (Image squared) void main(void) { // get texture sizes of the previous level vec2 size = vec2(osgppu_ViewportWidth, osgppu_ViewportHeight) * 2.0; // this is our starting sampling coordinate vec2 iCoord = gl_TexCoord[0].st; // this represent the step size to sample the pixels from previous mipmap level vec2 texel = vec2(1.0, 1.0) / (size); vec2 halftexel = vec2(0.5, 0.5) / size; // create offset for the texel sampling (TODO check why -1 seems to be correct) vec2 st[4]; st[0] = iCoord - halftexel + vec2(0,0); st[1] = iCoord - halftexel + vec2(texel.x,0); st[2] = iCoord - halftexel + vec2(0,texel.y); st[3] = iCoord - halftexel + vec2(texel.x,texel.y); // retrieve 4 texels from the previous mipmap level float c[4]; float Avg = 0.0; float Avg2 = 0.0; for (int i=0; i < 4; i++) { // map texels coordinates, such that they do stay in defined space st[i] = clamp(st[i], vec2(0,0), vec2(1,1)); // get texel from the previous mipmap level vec4 V = texture2D(texUnit0, st[i], osgppu_MipmapLevel - 1.0); Avg = Avg + V.r; // for the first mipmap level, just compute the squared // gray values from red component if (abs(osgppu_MipmapLevel - 1.0) < 0.1) Avg2 = Avg2 + V.r*V.r; // for the rest of the levels, simply add the green component else Avg2 = Avg2 + V.g; } Avg *= 0.25;Avg2 *= 0.25; // place the computed mean values in R component // place the computed mean2 values in G component gl_FragData[0].rgba = vec4(Avg, Avg2, 0.0, 1.0); } Am I making some conceptual mistake in the calculation of std. deviation. Please suggest. Thanks in advance. I'm not sure your shader is doing a proper mean. For the GPU to do mean/sum you need to do what is called a reduction. Search for reduction on www.gpgpu.org. This is different from doing per pixel operations like changing luminance e.g. jp regards Harash *From:* Art Tevs *To:* osg-users@lists.openscenegraph.org *Sent:* Tue, November 17, 2009 8:03:17 PM *Subject:* Re: [osg-users] [osgPPU] Problem Passing Lookup Table to Processing Unit Hi Harash, First take a look into documentation of osgPPU. osgPPU is very well documented, look here (http://projects.tevs.eu/osgppu and http://www.tevs.eu/doc/osgPPU/namespaceosgPPU.html) If this does not help you, then take a look into examples. Every example has tons of comments to help new users to understand how certain things works. Harash Sharma wrote: > > ...However when I attach the shader to the processing unit, the results are unexpected and I see the openGL warning. > > Do I have to use UnitTexture to pass the lookup table? I am totally stuck in dark. Please help. > Attaching a shader to a unit does works fine. In every example you can see this behaviour. So it might be that you are doing something wrong with the setup of your shader. If you want to have a texture as input to any unit, then you have to use UnitTexture instead. You just put a UnitTexture under the processor and call unitTexture::setTexture(_myTexture) with your texture. Then any unit which is a child of that unit texture will have this texture as input. Regards, art -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=19734#19734 ___ osg-users mailing list osg-users@lists.openscenegraph.org <mailto:osg-users@lists.openscenegraph.org> http://lists.openscenegrap
Re: [osg-users] [osgPPU] Problem Passing Lookup Table to Processing Unit
Hi All, First of all thanks Mr. Art Tevs for your suggestions and pointers for passing Lookup tables. And thanks again for such a fantastic library OSGPPU. Now my whole application is ported into osgPPU pipeline and it works very well. Now the only worry that remains is the linear contrast enhancement. I had posed this problem earlier but in a different way. Motivated by Mr. Art's Luminance shader, I wanted to implement the following algorithm: 1. Use a UnitInMipmapOut to compute the Mean (M) of the image gray values and the mean of image squared gray levels 2. Read these values in the child unit shader, compute the image std. deviation, from the image gray value (G), compute the new gray levels as (G-M) * (0.5/S) + 0.5; 3. However, this doesn't give any contrast improvent 4. I have tried to capture the Mean and Std. Dev. by converting them to RGB and storing using UnitCapture. 5. The rendered image statistics and GPU computed statistics (std. dev.) don't match I have used the following fragment shader attached to UnitInMipmapOut to compute Mean and Mean (Image squared) void { // get texture sizes of the previous level vec2 size = vec2(osgppu_ViewportWidth, osgppu_ViewportHeight) * 2.0; // this is our starting sampling coordinate vec2 iCoord = gl_TexCoord[0].st; // this represent the step size to sample the pixels from previous mipmap level vec2 texel = vec2(1.0, 1.0) / (size); vec2 halftexel = vec2(0.5, 0.5) / size; // create offset for the texel sampling (TODO check why -1 seems to be correct) vec2 st[4]; st[0] = iCoord - halftexel + vec2(0,0); st[1] = iCoord - halftexel + vec2(texel.x,0); st[2] = iCoord - halftexel + vec2(0,texel.y); st[3] = iCoord - halftexel + vec2(texel.x,texel.y); // retrieve 4 texels from the previous mipmap level float c[4]; float Avg = 0.0; float Avg2 = 0.0; for (int i=0; i < 4; i++) { // map texels coordinates, such that they do stay in defined space st[i] = clamp(st[i], vec2(0,0), vec2(1,1)); // get texel from the previous mipmap level vec4 V = texture2D(texUnit0, st[i], osgppu_MipmapLevel - 1.0); Avg = Avg + V.r; // for the first mipmap level, just compute the squared // gray values from red component if (abs(osgppu_MipmapLevel - 1.0) < 0.1) Avg2 = Avg2 + V.r*V.r; // for the rest of the levels, simply add the green component else Avg2 = Avg2 + V.g; } Avg *= 0.25; Avg2 *= 0.25; // place the computed mean values in R component // place the computed mean2 values in G component gl_FragData[0].rgba = vec4(Avg, Avg2, 0.0, 1.0); main(void) } Am I making some conceptual mistake in the calculation of std. deviation. Please suggest. Thanks in advance. regards Harash Hi Harash, First take a look into documentation of osgPPU. osgPPU is very well documented, look here (http://projects.tevs.eu/osgppu and http://www.tevs.eu/doc/osgPPU/namespaceosgPPU.html) If this does not help you, then take a look into examples. Every example has tons of comments to help new users to understand how certain things works. Harash Sharma wrote: > > ...However when I attach the shader to the processing unit, the results are > unexpected and I see the openGL warning. > > Do I have to use UnitTexture to pass the lookup table? I am totally stuck in > dark. Please help. > Attaching a shader to a unit does works fine. In every example you can see this behaviour. So it might be that you are doing something wrong with the setup of your shader. If you want to have a texture as input to any unit, then you have to use UnitTexture instead. You just put a UnitTexture under the processor and call unitTexture::setTexture(_myTexture) with your texture. Then any unit which is a child of that unit texture will have this texture as input. Regards, art -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=19734#19734 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org From: Art Tevs To: osg-users@lists.openscenegraph.org Sent: Tue, November 17, 2009 8:03:17 PM Subject: Re: [osg-users] [osgPPU] Problem Passing Lookup Table to Processing Unit ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Re: [osg-users] [osgPPU] Problem Passing Lookup Table to Processing Unit
Hi Harash, First take a look into documentation of osgPPU. osgPPU is very well documented, look here (http://projects.tevs.eu/osgppu and http://www.tevs.eu/doc/osgPPU/namespaceosgPPU.html) If this does not help you, then take a look into examples. Every example has tons of comments to help new users to understand how certain things works. Harash Sharma wrote: > > ...However when I attach the shader to the processing unit, the results are > unexpected and I see the openGL warning. > > Do I have to use UnitTexture to pass the lookup table? I am totally stuck in > dark. Please help. > Attaching a shader to a unit does works fine. In every example you can see this behaviour. So it might be that you are doing something wrong with the setup of your shader. If you want to have a texture as input to any unit, then you have to use UnitTexture instead. You just put a UnitTexture under the processor and call unitTexture::setTexture(_myTexture) with your texture. Then any unit which is a child of that unit texture will have this texture as input. Regards, art -- Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=19734#19734 ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
[osg-users] [osgPPU] Problem Passing Lookup Table to Processing Unit
Dear Mr. Art Tevs, I am trying to pass a GL_RGB texture to one of the Proceessing units for Lookup table. I attach a shader to the processing unit to compute the final color. The scheme works when I attach the shader to the scenegraph and access the lookup texture thererin. However when I attach the shader to the processing unit, the results are unexpected and I see the openGL warning. Do I have to use UnitTexture to pass the lookup table? I am totally stuck in dark. Please help. Thanks Regards Harash ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org