PDA

View Full Version : HDR cube maps & OpenEXR



dletozeun
03-07-2008, 11:05 AM
Hello,

I need to load vertical cross cube maps from openEXR pictures to use it as an environment in an OpenGL scene.
I load 48 bits openexr files using the code provided in the documentation.
the loaded data is stored in a Rgba array where Rgba is this structure:

struct Rgba{
half r; // red
half g; // green
half b; // blue
half a; // alpha (opacity)
};

I would know for those who used (or are using) the file format how they adapt this data to the gl representation.

As far as I am concerned, I convert data in a rgb array removing the useless alpha component...
I use GL_RGB16F_ARB internal format and GL_HALF_FLOAT_ARB data type.

But looking at r, g, b, a components in the data, what I see is values between around 0.02 and 0.2 not more than a 10 factor between the smallest and greatest values. Astonishing with a HDR cube map no?
What do you think about it for those who use openEXR?

Thank you.

-NiCo-
03-07-2008, 11:25 AM
Haven't used the OpenEXR format myself, but I seriously doubt that removing the alpha component will help. My guess is that it's being converted to a GL_RGBA16F_ARB internally anyway.

RGHP
03-07-2008, 02:57 PM
I use RGBA images:

glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RGBA16F_ARB,
width,
height,
0,
GL_RGBA,
GL_HALF_FLOAT_ARB,
(GLvoid*)pixeles

);

Can you post some of your code for loading into memory, crop alpha component and uploading to OpenGL?.

dletozeun
03-08-2008, 06:23 AM
Thank you both for your replies.

Nico> I can keep the alpha component but it is the same. The alpha component is always 1 so I thought that it is useless if I do not need transparency. At the beginning I thought that the alpha component would have been like the color "module" but it is always 1.
The point is why the data values are so small?

RGHP> I do the same for glTexImage2D or this:

glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RGB16F_ARB,
width,
height,
0,
GL_RGB,
GL_HALF_FLOAT_ARB,
(GLvoid*)pixeles
);

if I don't want the alpha component.

Removing the alpha component works well because I see exactly the same thing with or without it.

This is the function that loads OpenEXR pictures and extracts the alpha component:



/**

* @brief loads a 48 bits openEXR picture in memory

* @param filename file path

* @param width address of a Texture.width
* @param height address of a Texture.height

* @return Timage the picture data

*/
GLubyte* loadEXR48(char* filename, GLuint* width, GLuint* height)
{
GLubyte*Timage=NULL;
Imf::Array2D<Imf::Rgba> pixels;

const int bulkSize=6;

Imf::RgbaInputFile file (filename);
Imath::Box2i dw = file.dataWindow();
*width = dw.max.x - dw.min.x + 1;
*height = dw.max.y - dw.min.y + 1;
pixels.resizeErase ((long int)*height, (long int)*width);
file.setFrameBuffer (&amp;pixels[0][0] - dw.min.x - dw.min.y *(*width), 1, (*width));
file.readPixels (dw.min.y, dw.max.y);

int size=(*width)*(*height);

Timage=new GLubyte[size*bulkSize];

for(int i=0;i<(int)(*height);i++)
{
for(int j=0;j<(int)(*width);j++)
{
memcpy(Timage+bulkSize*(i*(*width)+j), &amp;pixels[i][j], bulkSize*sizeof(char));
//cout<<"R="<<pixels[i][j].r<<" G="<<pixels[i][j].g<<" B="<<pixels[i][j].b<<" A="<<pixels[i][j].a<<endl;
}
}

return Timage;
}


You just have to change bulkSize by 8 to keep the alpha component . bulkSize is the pixel byte size.

thanks

-NiCo-
03-08-2008, 06:30 AM
My point was that if your card does not support GL_RGB16F_ARB natively (which is most likely the case), your data will have to be converted to GL_RGBA16F_ARB before it is downloaded to the GPU. So if it's not supported natively you'd be better off sticking to GL_RGBA16F_ARB value even if the alpha is always 1 because you will get accelerated data transfer to GPU without conversion.

Don't know why the range is so small, haven't used HDR textures myself.

dletozeun
03-08-2008, 06:38 AM
Thank you nico.

I let the GL_RGBA16F_ARB and I have the same thing. I think that both are supported by my cg. It is ATI mobility X1600.


I have projected the loaded cube map on a quad (You must reconize the famous uffizi picture).

http://img187.imageshack.us/img187/5120/uffiziuj4.th.png (http://img187.imageshack.us/my.php?image=uffiziuj4.png)

There is another problem, as you can see, the texture is very pixelated as if I let the GL_NEAREST filter. But even if I put the GL_LINEAR filter I see the same thing.
I don't understand because it worked with a LDR cube map...

for information the size of the loaded cube map is 64

thanks

-NiCo-
03-08-2008, 06:42 AM
Did you use GL_LINEAR for both the minification and magnification filters? What graphics card hardware are you using?

dletozeun
03-08-2008, 06:46 AM
lol you post so quickly that in my last post I did not take into account your post before this last one ^^ (So I have tried to adapt it after...)

So, yes I use GL_LINEAR filter for minification and magnification filters like I did for LDR cube maps.
My graphic card is ATI mobility X1600.

thanks

-NiCo-
03-08-2008, 07:00 AM
Probably a hardware limitation. My guess is that 16 bit floating point textures are not supported natively on ATi X1k hardware so it uses 32 bit floating point substitution, which in turn does not support linear filtering.

I'd be happy to try out the code if I can compile it for linux.

dletozeun
03-08-2008, 07:34 AM
Yes it could...
Actually I work on linux. I checked the presence of GL_ARB_half_float_pixel with glxinfo and I found nothing. But when I do that with glew in my code, glew seems to have found this extension! Maybe it is because of 16 bits floating point -> 32 bits floating points replacement mechanism...

If you want to compile my code on your linux you have to be brave ^^.
actually it is a school project to demonstrate HDR rendering and I don't know for now how to create configure files. So you will need to install manually the ilmbase and openexr libraries and maybe modify the Makefile to make it works.

But if it is your wish I can do that.
On my side, I will find out about how to make easier my project compilation.

-NiCo-
03-08-2008, 08:14 AM
Try this code to see if it supports 16bit fp filtering:



#include <GL/glew.h>
#include <GL/glut.h>

int ww,hh;
GLuint tex;

void changeSize(int w, int h) {
ww=w;
hh=h;
glViewport(0,0,ww,hh);
}

void renderScene(void) {

glClearColor(0.0,0.0,0.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);

glEnable(GL_TEXTURE_2D);

glBegin(GL_QUADS);
glTexCoord2f(0.0f,0.0f);
glVertex2f(-1.0f,-1.0f);
glTexCoord2f(1.0f,0.0f);
glVertex2f( 1.0f,-1.0f);
glTexCoord2f(1.0f,1.0f);
glVertex2f(1.0f,1.0f);
glTexCoord2f(0.0f,1.0f);
glVertex2f(-1.0f,1.0f);
glEnd();

glutSwapBuffers();
}

void initTex() {

float texdata[] = { 0.0f,0.0f,0.0f,1.0f,
1.0f,0.0f,0.0f,1.0f,
0.0f,1.0f,0.0f,1.0f,
0.0f,0.0f,1.0f,1.0f};

glGenTextures(1,&amp;tex);
glBindTexture(GL_TEXTURE_2D,tex);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA16F_ARB,2,2,0, GL_RGBA,GL_FLOAT,&amp;texdata[0]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTE R,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTE R,GL_LINEAR);

}

int main(int argc, char **argv) {
glutInit(&amp;argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(100,100);
glutInitWindowSize(512,512);
glutCreateWindow("HDR");

glutDisplayFunc(renderScene);
glutReshapeFunc(changeSize);

glewInit();

initTex();

glutMainLoop();

return 0;
}



Here's my output:

http://i28.tinypic.com/2gx1kqc.jpg

dletozeun
03-08-2008, 02:10 PM
I tried your code and this is what I obtain:


http://img137.imageshack.us/img137/4536/16fpfilteringcd4.th.png (http://img137.imageshack.us/my.php?image=16fpfilteringcd4.png)

It looks like 16 fp linear filtering do not work with my current cg...

dletozeun
03-08-2008, 02:28 PM
I forgot something,
I don't understand why in your code you use float data and GL_FLOAT in glTexImage2D if you want to test if 16 fp filtering works ?

-NiCo-
03-08-2008, 02:52 PM
GL_FLOAT only indicates the data type of the client (CPU) side texture. By specifying GL_RGBA16F_ARB, the driver will convert it to 16bit fp and then upload it to the server (GPU) side. I could just as easily have specified GL_UNSIGNED_BYTE and still get the same result.

PS. I just tried your program code and I get linear filtering.

dletozeun
03-08-2008, 03:43 PM
Ok I understand.



PS. I just tried your program code and I get linear filtering.

Cool! ^^

Thank for your help, I think I will do the linear filtering manually in the fragment shader.

RGHP
03-09-2008, 06:05 PM
Just pass us the code ;).

In this page says that your card model support half textures(and acelerated tone mapping, how? ) :

http://ati.amd.com/products/mobilityradeonx1600/specs.html

which drivers are you using? maybe ypu are working with Mesa and you have no access to all the features opf your card.

RGHP
03-09-2008, 06:08 PM
Just pass us the code ;).

In this page says that your card model support half textures(and acelerated tone mapping, how? ) :

http://ati.amd.com/products/mobilityradeonx1600/specs.html

which drivers are you using? maybe ypu are working with Mesa and you have no access to all the features opf your card.

RGHP
03-09-2008, 06:08 PM
Just pass us the code ;).

In this page says that your card model support half textures(and acelerated tone mapping, how? ) :

http://ati.amd.com/products/mobilityradeonx1600/specs.html

which drivers are you using? maybe ypu are working with Mesa and you have no access to all the features opf your card.

RGHP
03-09-2008, 06:10 PM
Just pass us the code ;).

In this page says that your card model support half textures(and acelerated tone mapping, how? ) :

http://ati.amd.com/products/mobilityradeonx1600/specs.html

which drivers are you using? maybe ypu are working with Mesa and you have no access to all the features opf your card.

RGHP
03-09-2008, 06:11 PM
Just pass us the code ;).

In this page says that your card model support half textures(and acelerated tone mapping, how? ) :

http://ati.amd.com/products/mobilityradeonx1600/specs.html

which drivers are you using? maybe ypu are working with Mesa and you have no access to all the features opf your card.

RGHP
03-09-2008, 06:12 PM
sorry :S

dletozeun
03-10-2008, 11:56 AM
Hi RGHP,

"16 bit per channel floating point HDR and 10 bit per channel DVI output"

Yes they speak about 16 bits fp in Avivo™ Video and Display Platform section but I clearly do not understand this sentence...it is about video and they do not mention filtering.

On Linux my ATI driver version is 8.47.3, I look for windows.

dletozeun
03-10-2008, 12:35 PM
On Widows it is the same, but I am confused. Until now I did not read tightly ARB_texture_float and ARB_half_float_pixel extensions specs.

This is what I have found on ARB_texture_float spec:

"This extension adds texture internal formats with 16- and 32-bit
floating-point components"

I have this extension on my graphic card and it seems to be sufficient to support hardware linear filtering because it is about internal format, isn't it? But 16 bits fp linear filtering is not supported on my GC.

Moreover, on ARB_half_float_pixel spec:

" This extension allows applications to use half-precision floating-point data when specifying pixel data."

This last one just allow the application to give half float data to opengl when specifying texture data.

So why with the code that posted Nico, I have don't have linear filtering whereas texture data type is float ( on application side) ? It is the same problem if data is given with GLubyte type.

Thanks.