PDA

View Full Version : pack/unpack half floats on 3D textures



jcabeleira
03-30-2010, 04:33 PM
Hi, guys. I need help with the following problem: I'm rendering data to a volume texture and reading it back on another pass and that works just fine. The data is generated on a GLSL program and passed as 4 coefficients encoded on the RGBA components of gl_FragData[0] (I'm rendering to multiple 3D textures at once). The format of the volume texture is GL_RGBA32F.

Now I'm trying to generate 8 coefficients, where each pair of coefficients is packed into a single float using the pack_2half() instruction, thus generating 4 floats that can also be passed as RGBA to gl_FragData[0]. But when I read the contents of that texture on the following pass, for some reason I get incorrect results.
I can read and extract the first two coefficients from the red channel of the texture, but all the other channels are wrong. The green, blue and alpha components seem to contain the same information as the red channel which is incorrect.

Here is the writting shader code:
gl_FragData[0]= vec4(pack_2half(half2(1.0, 1.0)), pack_2half(half2(0.3, 0.3)), 0.0, 0.0);

And when I extract those values from the red channel:
vec4 x= texture3D(volumeTexture0, texcoord);
half2 y= unpack_2half(x.r);

I get the correct result of (1.0, 1.0), but when I try to read from the green channel:
vec4 x= texture3D(volumeTexture0, texcoord);
half2 y= unpack_2half(x.g);

I also get (1.0, 1.0) instead of (0.3, 0.3)!

What could be causing this problem?
I know that I shouldn't use those packing/unpacking instructions because they're only supported on Nvidia hardware, but for now portability is not a concern for me.
The extension documentation about the NV_gpu_program (or whatever) mentions something about the assembly version of those packing/unpacking instructions returning unsigned ints instead of floats but they aren't clear about it. Do I need to return those packed coefficients as UINTs instead of floats and change the format of the volume texture accordingly?

Thanks in advance

jcabeleira
03-31-2010, 07:06 AM
Problem solved. I'm not sure if it's a driver/compiler bug or someking of data type casting problem but if instead of doing the data write this way:
gl_FragData[0]= vec4(pack_2half(half2(1.0, 1.0)), pack_2half(half2(0.3, 0.3)), 0.0, 0.0);

I first pack into temporary variables and then write them as the result like this:
float a= pack_2half(half2(1.0, 1.0));
float b= pack_2half(half2(0.3, 0.3));
gl_FragData[0]= vec4(a, b, 0.0, 0.0);

It works fine.