作者:i_dovelemon
日期:2017-03-07
来源:CSDN
主题:Normal Map, Normal Mapping, Tangent Space
bool glb_calc_tangent_binormal_coordinates(int32_t face_num, float* vertex_buf, float* texcoord_buf, float* normal_buf, std::vector &tangents) {
bool result = true;
if (vertex_buf == NULL || texcoord_buf == NULL) {
result = false;
return result;
}
glb::Vector v0, v1, v2, t0, t1, t2, n0, n1, n2;
for (int32_t i = 0; i < face_num; i++) {
v0.x = vertex_buf[i * 3 * 3 + 0 * 3 + 0];
v0.y = vertex_buf[i * 3 * 3 + 0 * 3 + 1];
v0.z = vertex_buf[i * 3 * 3 + 0 * 3 + 2];
v1.x = vertex_buf[i * 3 * 3 + 1 * 3 + 0];
v1.y = vertex_buf[i * 3 * 3 + 1 * 3 + 1];
v1.z = vertex_buf[i * 3 * 3 + 1 * 3 + 2];
v2.x = vertex_buf[i * 3 * 3 + 2 * 3 + 0];
v2.y = vertex_buf[i * 3 * 3 + 2 * 3 + 1];
v2.z = vertex_buf[i * 3 * 3 + 2 * 3 + 2];
t0.x = texcoord_buf[i * 3 * 2 + 0 * 2 + 0];
t0.y = texcoord_buf[i * 3 * 2 + 0 * 2 + 1];
t1.x = texcoord_buf[i * 3 * 2 + 1 * 2 + 0];
t1.y = texcoord_buf[i * 3 * 2 + 1 * 2 + 1];
t2.x = texcoord_buf[i * 3 * 2 + 2 * 2 + 0];
t2.y = texcoord_buf[i * 3 * 2 + 2 * 2 + 1];
n0.x = normal_buf[i * 3 * 3 + 0 * 3 + 0];
n0.y = normal_buf[i * 3 * 3 + 0 * 3 + 1];
n0.z = normal_buf[i * 3 * 3 + 0 * 3 + 2];
n1.x = normal_buf[i * 3 * 3 + 1 * 3 + 0];
n1.y = normal_buf[i * 3 * 3 + 1 * 3 + 1];
n1.z = normal_buf[i * 3 * 3 + 1 * 3 + 2];
n2.x = normal_buf[i * 3 * 3 + 2 * 3 + 0];
n2.y = normal_buf[i * 3 * 3 + 2 * 3 + 1];
n2.z = normal_buf[i * 3 * 3 + 2 * 3 + 2];
TangentSpace space;
glb_calc_tangent_binormal(v0, v1, v2, t0, t1, t2, n0, n1, n2, space);
tangents.push_back(space);
}
return result;
}
void glb_calc_tangent_binormal(glb::Vector v0, glb::Vector v1, glb::Vector v2
, glb::Vector t0, glb::Vector t1, glb::Vector t2
, glb::Vector n0, glb::Vector n1, glb::Vector n2
, TangentSpace& space) {
glb::Vector vedge0 = v1 - v0;
glb::Vector vedge1 = v2 - v0;
glb::Vector tedge0 = t1 - t0;
glb::Vector tedge1 = t2 - t0;
float temp = 1.0f / (tedge0.x * tedge1.y - tedge0.y * tedge1.x);
glb::Vector tangent = (vedge0 * tedge1.y - vedge1 * tedge0.y) * temp;
glb::Vector binormal = (vedge1 * tedge0.x - vedge0 * tedge1.x) * temp;
tangent.Normalize();
binormal.Normalize();
// Gram-Schmidt orthogonalize
space.tangent[0] = tangent - n0 * glb::Dot(n0, tangent);
space.binormal[0] = binormal - n0 * glb::Dot(n0, binormal);
space.tangent[1] = tangent - n1 * glb::Dot(n1, tangent);
space.binormal[1] = binormal - n1 * glb::Dot(n1, binormal);
space.tangent[2] = tangent - n2 * glb::Dot(n2, tangent);
space.binormal[2] = binormal - n2 * glb::Dot(n2, binormal);
}
uber.vs
#ifdef GLB_TANGENT_IN_VERTEX
#ifdef GLB_BINORMAL_IN_VERTEX
vs_NT = cross(glb_Tangent, glb_Binormal);
vs_NT = (glb_Trans_Inv_WorldM * vec4(vs_NT, 0.0)).xyz;
#endif
#endif
#ifdef GLB_TANGENT_IN_VERTEX
vs_Tangent = (glb_Trans_Inv_WorldM * vec4(glb_Tangent, 0.0)).xyz;
#endif
#ifdef GLB_BINORMAL_IN_VERTEX
vs_Binormal = (glb_Trans_Inv_WorldM * vec4(glb_Binormal, 0.0)).xyz;
#endif
uber.ps
#ifdef GLB_ENABLE_NORMAL_MAPPING
vec3 normal = texture2D(glb_NormalTex, vs_TexCoord).xyz;
normal -= vec3(0.5, 0.5, 0.5);
normal *= 2.0;
mat3 tbn = mat3(vs_Tangent, vs_Binormal, vs_NT);
normal = tbn * normal;
normalize(normal);
#endif