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?
Important information: this site is currently scheduled to go offline indefinitely by end of the year.
Figuring out encoded vertex normal vector
-
- 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
most likely something like this
https://www.opengl.org/discussion_board ... tex-Arrays
noesis supports decoding normals like these
https://www.opengl.org/discussion_board ... tex-Arrays
noesis supports decoding normals like these
-
- MEGAVETERAN
- Posts: 2647
- Joined: Tue Mar 24, 2015 8:12 pm
- Has thanked: 65 times
- Been thanked: 2870 times
-
- 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
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).
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.
Re: Figuring out encoded vertex normal vector
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.
-
- 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
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.
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.
-
- MEGAVETERAN
- Posts: 2647
- Joined: Tue Mar 24, 2015 8:12 pm
- Has thanked: 65 times
- Been thanked: 2870 times
Re: Figuring out encoded vertex normal vector
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 wrote:BDOGetTangentSpaceVectors
...
Re: Figuring out encoded vertex normal vector
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.