Pages: 1
  Print  
Author Topic: Packing bits  (Read 1569 times)
Offline (Unknown gender) TheExDeus
Posted on: October 05, 2014, 11:35:21 AM

Developer
Joined: Apr 2008
Posts: 1872

View Profile
I am looking into packing some stuff more compactly for OpenGL, but I have some problems coding that.
For normals, it's recomended to use GL_INT_2_10_10_10_REV​ format, which is basically 10bits per normal (x,y,z) and 2 bits left over. Right now all normals are floats, 32bit per normal. This packing would reduce the size by 2/3. This is how I tried it:
Code: (C) [Select]
normal_t val = 0.0f;
val = val | (0 << 30);
val = val | ((unsigned int)((nz+1.0f)*0.5f*1023) << 20);
val = val | ((unsigned int)((ny+1.0f)*0.5f*1023) << 10);
val = val | ((unsigned int)((nx+1.0f)*0.5f*1023) << 0);
Where normal_t is just a 32bit structure like color_t is right now:
Code: (C) [Select]
template<int x> struct intmatch { };
template<int x> struct uintmatch { };
template<> struct intmatch<1>   { typedef int8_t type;  };
template<> struct intmatch<2>   { typedef int16_t type; };
template<> struct intmatch<4>   { typedef int32_t type; };
template<> struct intmatch<8>   { typedef int64_t type; };
template<> struct uintmatch<1>  { typedef uint8_t type;  };
template<> struct uintmatch<2>  { typedef uint16_t type; };
template<> struct uintmatch<4>  { typedef uint32_t type; };
template<> struct uintmatch<8>  { typedef uint64_t type; };
typedef uintmatch<sizeof(gs_scalar)>::type color_t;
typedef intmatch<sizeof(gs_scalar)>::type uv_t;
typedef intmatch<sizeof(gs_scalar)>::type normal_t;
I use 1023, because that is the biggest number you can hold it 10bits. All normals are from -1 to +1, so what I do is offset it (add +1.0) and scale (multiply by 0.5), then I multiply by 1023 and move the bits in place. I don't know how to really unpack it to see if it's correct though. I tried this:
Code: (C) [Select]
    printf("Normal before packing %f, %f, %f after unpacking %f, %f, %f\n", nx,ny,nz,(double)(val & 1023)/1023.0-1.0,(double)((val & 1023)>>10)/1023.0-1.0,(double)((val & 1023)>>20)/1023.0-1.0);But it shows 1.0 for ny and nz when it shouldn't. nx is also incorrect. I know there will be a slight loss of precision, but it shouldn't matter for normals.

The second thing that is encouraged to pack is UV coordinates. I see recommendations for them being SHORT. I can't seem to pack them either. Then there is the problem that UV's are not limited to +-1.0. Normally they are, but if you want the texture to repeat, you give values out of this range. If we pack SHORT as in integer, then we cannot have that (as it will normalize and change to +-1.0 when sending to GPU). A half-float could work though. But I don't know how to pack half-floats either.

tl;dr - How to pack 3 floats in 1 float by having 10bit integer each?
How to pack 2 floats in 1 float having 16bit float each?
Logged
Offline (Male) Goombert
Reply #1 Posted on: October 05, 2014, 05:00:29 PM

Developer
Location: Cappuccino, CA
Joined: Jan 2013
Posts: 3110

View Profile
Did you look at how we pack color_t? You would also have to change the stride any everything Harri, did you change and fix all of that?
Logged
I think it was Leonardo da Vinci who once said something along the lines of "If you build the robots, they will make games." or something to that effect.

Offline (Unknown gender) TheExDeus
Reply #2 Posted on: October 06, 2014, 04:40:45 AM

Developer
Joined: Apr 2008
Posts: 1872

View Profile
It's a lot easier to pack color_t as they are integers. Here I need to pack half floats, which require a lot more magic. And 10bit integers, which are also "non standard" in C++. I know everything about strides and GL side. The problem is only packing. Making a "float floatToHalfFloatPacked(float u, float v)" function and "float floatTo10bitPacked(float nx, float ny, float nz)". I will figure it out eventually, but I just know people like Josh are really good with bit arithmetic, which I'm not.
Logged
Offline (Male) Goombert
Reply #3 Posted on: October 06, 2014, 05:30:00 AM

Developer
Location: Cappuccino, CA
Joined: Jan 2013
Posts: 3110

View Profile
Heh, me neither Harri, I'll try to call this to his attention.
Logged
I think it was Leonardo da Vinci who once said something along the lines of "If you build the robots, they will make games." or something to that effect.

Pages: 1
  Print