Important information: this site is currently scheduled to go offline indefinitely by end of the year.

Figuring out encoded vertex normal vector

Post questions about game models here, or help out others!
Post Reply
Sectus
veteran
Posts: 98
Joined: Tue Sep 15, 2009 5:47 pm
Has thanked: 12 times
Been thanked: 20 times
Contact:

Figuring out encoded vertex normal vector

Post 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?
chrrox
Moderator
Posts: 2602
Joined: Sun May 18, 2008 3:01 pm
Has thanked: 57 times
Been thanked: 1422 times

Re: Figuring out encoded vertex normal vector

Post by chrrox »

most likely something like this
https://www.opengl.org/discussion_board ... tex-Arrays
noesis supports decoding normals like these
User avatar
Wobble
ultra-veteran
ultra-veteran
Posts: 584
Joined: Tue Jan 04, 2005 9:47 pm
Has thanked: 43 times
Been thanked: 112 times

Re: Figuring out encoded vertex normal vector

Post by Wobble »

[out]
Last edited by Wobble on Sun Mar 12, 2017 10:38 am, edited 1 time in total.
daemon1
MEGAVETERAN
MEGAVETERAN
Posts: 2647
Joined: Tue Mar 24, 2015 8:12 pm
Has thanked: 65 times
Been thanked: 2871 times

Re: Figuring out encoded vertex normal vector

Post by daemon1 »

Can you upload the actual FILES?
Sectus
veteran
Posts: 98
Joined: Tue Sep 15, 2009 5:47 pm
Has thanked: 12 times
Been thanked: 20 times
Contact:

Re: Figuring out encoded vertex normal vector

Post 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).
You do not have the required permissions to view the files attached to this post.
Sir Kane
veteran
Posts: 104
Joined: Mon Aug 06, 2012 4:14 am
Been thanked: 96 times

Re: Figuring out encoded vertex normal vector

Post 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);
}
Last edited by Sir Kane on Sun Sep 11, 2016 8:10 pm, edited 1 time in total.
Sectus
veteran
Posts: 98
Joined: Tue Sep 15, 2009 5:47 pm
Has thanked: 12 times
Been thanked: 20 times
Contact:

Re: Figuring out encoded vertex normal vector

Post 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.
daemon1
MEGAVETERAN
MEGAVETERAN
Posts: 2647
Joined: Tue Mar 24, 2015 8:12 pm
Has thanked: 65 times
Been thanked: 2871 times

Re: Figuring out encoded vertex normal vector

Post 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.
Sir Kane
veteran
Posts: 104
Joined: Mon Aug 06, 2012 4:14 am
Been thanked: 96 times

Re: Figuring out encoded vertex normal vector

Post 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.
Sectus
veteran
Posts: 98
Joined: Tue Sep 15, 2009 5:47 pm
Has thanked: 12 times
Been thanked: 20 times
Contact:

Re: Figuring out encoded vertex normal vector

Post by Sectus »

Good work, Sir Kane! That solves the entire mystery.
Post Reply