Page 1 of 1

Figuring out encoded vertex normal vector

Posted: Tue Sep 06, 2016 5:33 pm
by Sectus
I'm trying to figure out how the normal vector for vertices is encoded for a game, and I'm having a bit of trouble with it. It's with the PAC format from the game Black Desert (various format specifications can be found here: viewtopic.php?f=16&t=11849).

I'm rather new to 3D model formats, but as far as I know, this normal would usually be represented as a position in 3D space using 3 floats. But in this case, it's just 4 bytes. Here's a couple of examples (listing the unsigned bytes alongside the normal auto generated by 3DS Max for each vertex):

A simple box mesh:
https://abload.de/img/t0054_trade_box_0001_jrqyh.png
http://pastebin.com/raw/SQqR0deU

A much more complex mesh (a cape):
https://abload.de/img/phm_00_cloak_0073_cdgpd8.png
http://pastebin.com/raw/hR61SLfx

I've noticed the second byte is never lower than 128 in value. I've written code which outputs the bytes as ints of various bit sizes (with or without sign bit, and of different endian), but I don't get anything which makes sense.

Anyone got any clever idea how to approach this? Or does anyone have examples of documented 3D model formats with vertex normal vectors represented in unusual ways?

Re: Figuring out encoded vertex normal vector

Posted: Wed Sep 07, 2016 10:03 pm
by chrrox
most likely something like this
https://www.opengl.org/discussion_board ... tex-Arrays
noesis supports decoding normals like these

Re: Figuring out encoded vertex normal vector

Posted: Thu Sep 08, 2016 3:18 pm
by Wobble
[out]

Re: Figuring out encoded vertex normal vector

Posted: Fri Sep 09, 2016 4:56 pm
by daemon1
Can you upload the actual FILES?

Re: Figuring out encoded vertex normal vector

Posted: Fri Sep 09, 2016 11:30 pm
by Sectus
Thanks for the replies.

I added conversion of some common data types used for vertices in shaders. Here's the new list of values (also attached the actual model files):

A simple box mesh:
http://pastebin.com/raw/33JeEBaa

A much more complex mesh (a cape):
http://pastebin.com/raw/3wHadTC2

I don't think I can see anything obvious popping out. I've been reading about various methods on storing normal and tangent vectors for vertices, and there's some developers who's used some very creative solutions out there, so maybe the developer here has used an unusual way of storing the normal vector (and maybe tangent).

Re: Figuring out encoded vertex normal vector

Posted: Sun Sep 11, 2016 2:06 am
by Sir Kane

Code: Select all

inline CVec2f SinCos(float f){
	return CVec2f(cosf(f), sinf(f));
}

void BDOGetTangentSpaceVectors(const CVec4f &input, CVec3f &Normal, CVec3f &Tangent, CVec3f &Binormal){
	CVec2f bxy, bzs, txy, tzs;

	CVec4f scaled = input * (M_PI * 2.0f) - M_PI; //Rescale from 0.0 - 1.0 to -PI - +PI

	txy = SinCos(scaled.x);
	tzs = SinCos(scaled.y);

	bxy = SinCos(scaled.z);
	bzs = SinCos(scaled.w);

	txy *= fabs(tzs.y);
	bxy *= fabs(bzs.y);

	Tangent = CVec3f(txy.x, txy.y, tzs.x);
	Binormal = CVec3f(bxy.x, bxy.y, bzs.x);
	Normal = CVec3f::Cross(Tangent, Binormal) * (scaled.w >= 0.0f ? 1 : -1.0f);
}

Re: Figuring out encoded vertex normal vector

Posted: Sun Sep 11, 2016 7:09 pm
by Sectus
Calculating normal, tangent, and bitangent vectors for each vertex to see if they'll give any hints.

A simple box mesh:
http://pastebin.com/raw/E0EghAbW

A much more complex mesh (a cape):
http://pastebin.com/raw/kXHsRv2e

It would definitely make sense that UBYTE4N is the data type being used. Still not sure how the data is stored though. I've been reading up on various methods developers have used to store normal (and sometimes tangent) vertex vectors, but this doesn't really look like any other implementation I've seen.

Re: Figuring out encoded vertex normal vector

Posted: Sun Sep 11, 2016 8:14 pm
by daemon1
Sir Kane wrote:BDOGetTangentSpaceVectors
...
So they actually saved 2 angles packed as bytes for tangent and binormal, because you only need 2 angles to make a vector.

Re: Figuring out encoded vertex normal vector

Posted: Sun Sep 11, 2016 8:46 pm
by Sir Kane
Yeah. I've never seen it done like this before, but it certainly saves space and it doesn't take too many instruction to decode in the shader.

Re: Figuring out encoded vertex normal vector

Posted: Sun Sep 11, 2016 9:34 pm
by Sectus
Good work, Sir Kane! That solves the entire mystery.