Ive been trying to make a 3Dmodel parser, on one hand to understand the process better, and on the other hand to be able to make formats that I can call my own, but the result creates seams once I introduce normal mapping. Maybe somebody can explain what is happening, and/or what I should be doing different.
What I do is make an object in maya (in this a case a cube-sphere), export as obj and then try to parse it. My problem is: how do I handle shared vertices and edges for tangents? When it comes to vertex_normals this is fairly straight forward:
vector <vec3>normalref(normalsize, vec3(0)); //normalsize, amount of vn, fill with 0
//fill normalref with calculated normals
vec3 normalbuffer;
//i=vert1, i+1=uv1, i+2 vn1
//i+3=vert2,i+4=uv2,i+5=vn2
//i+6=vert3, i+7=uv3, i+8=vn3
for (size_t i = 0; i < totalrefs.size(); i += 9) {
normalbuffer = cross(
vref[totalrefs[i + 3] - 1] - vref[totalrefs[i] - 1],
vref[totalrefs[i + 6] - 1] - vref[totalrefs[i] - 1]);
normalref[totalrefs[i + 2] - 1] += normalbuffer;
normalref[totalrefs[i + 5] - 1] += normalbuffer;
normalref[totalrefs[i + 8] - 1] += normalbuffer;
}
for (auto&x : normalref)x = normalize(x); //and normalize
For each face, add the cross (plane angle) to each vn connected, then after, normalize each of the vns, And you will have a vertex_normal that will work with a seamless phong shader.
But when It comes to tangent values, this is not as straight forward. The idea is that you convert the tangent on gpu, alongside with the normal for that vertice/corner, and make a bitangent, and tbn matrix, that you use for further calculations. But what I cant figure out is: How do you balance the tangent values for each side?
I keep getting edges that overlap and shadows that do not make any sense. Calculating the tangents themselves for each face is not very hard:
for (size_t i = 0; i < totalrefs.size(); i += 9)
{
edge1 = vref[totalrefs[i + 3] - 1] - vref[totalrefs[i] - 1];
edge2 = vref[totalrefs[i + 6] - 1] - vref[totalrefs[i] - 1];
deltaUV1 = uvref[totalrefs[i + 4] - 1] - uvref[totalrefs[i + 1] - 1];
deltaUV2 = uvref[totalrefs[i + 7] - 1] - uvref[totalrefs[i + 1] - 1];
f = 1.0f / (deltaUV1.x * deltaUV2.y - deltaUV2.x * deltaUV1.y);
tangentbuf = normalize(f*vec3(
(deltaUV2.y * edge1.x - deltaUV1.y * edge2.x),
(deltaUV2.y * edge1.y - deltaUV1.y * edge2.y),
(deltaUV2.y * edge1.z - deltaUV1.y * edge2.z)));
tangents[tangcount++] = tangentbuf;
tangents[tangcount++] = tangentbuf;
tangents[tangcount++] = tangentbuf;
}
But this approach that works with vertex_normals, does not work for tangents. Even if i map them per vertex, per uv, or per vn. I get the same poor result showing seams. As far as I can gather, the problem is shared vertex/corner balancing, and I do not know how to do that correctly.
Somebody help!
this is what it currently looks like:
Where the specular value is turned up, to make out the seam more clearly. This seam is not there when I use normals to do the shading, and, each face isnt square-ish either, but interpolated properly. Im pretty certain this is caused by the way I either calculate the tangents, or how I index them, can somebody explain to me how this should be done?