Mr Jox Mr Jox - 1 year ago 53
C# Question

Vertex normal from byte to float

I have 1 byte of vertex normal (X,Y and Z for each). How can I translate the value from byte to float?
For examples, bytes in hex:

0x81 0xEE 0BF (129 238 191 in bytes)

And here's the output in float (used software to calculate):

0.382027 0.718028 0.5818

Does anyone know how can I make a calculation formula?
I thought it's simply a division of value on 255 (129/255, 238/255 and 191/255), but it didn't work.

Tried to make a calculation on c#

normX = rawNormX * (1.0f / 255.0f);

But the formula is not correct.
I'd love to read about packing normals, tangents and binormals from float to bytes if there are anything to read.

Answer Source

I am not convinced that the input you describe, (129, 238, 191), is in fact the same vector as the output you desire, (0.382027, 0.718028, 0.5818).

The output vector is a unit vector. I.e. it's been "normalized" and so it has length 1. In theory, you should be able to convert the input vector to the normalized format simply by dividing the components of the input vector by that vector's length (which is 331.3095). Doing so, I get a normalized vector of (0.389363997, 0.718361482, 0.576500181).

The important thing to note about this vector is that the X and Y components are larger than in your desired output, while the Z component is smaller. I.e. this vector simply does not point in the same direction as your desired output.

It is possible that in your example system, there is some rounding error that accounts for this discrepancy, either in the conversion to the byte format or even possibly in the reference output value. There's not enough information in your question to explain the difference.

Regardless, it seems clear to me that the basic conversion requires nothing more than to convert from the input vector to its normalized form:

byte bx = 129, by = 238, bz = 191;
double length = Math.Sqrt((bx * bx) + (by * by) + (bz * bz));
double dx = bx / length, dy = by / length, dz = bz / length;

Where bx, by, and bz are your input values, and dx, dy, and dz are your outputs. This doesn't produce precisely the values you expected, but I'm reasonably confident it produces the values that you should expect.

If you need anything more specific than that, you'll have to improve your question so that it includes more specifics about where the numbers your example uses come from and why you believe they should represent the same vector.