Calculate tangents for ObjMesh
This commit is contained in:
parent
4951ad3b04
commit
fd9317a5f5
@ -33,17 +33,25 @@ struct Mesh {
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
|
||||
|
||||
// position attribute
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 14 * sizeof(float), (void*)0);
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
// Normal attribute
|
||||
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
|
||||
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 14 * sizeof(float), (void*)(3 * sizeof(float)));
|
||||
glEnableVertexAttribArray(1);
|
||||
|
||||
// texture coord attribute
|
||||
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
|
||||
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 14 * sizeof(float), (void*)(6 * sizeof(float)));
|
||||
glEnableVertexAttribArray(2);
|
||||
|
||||
// Tangent attribute
|
||||
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 14 * sizeof(float), (void*)(8 * sizeof(float)));
|
||||
glEnableVertexAttribArray(3);
|
||||
|
||||
// Bitangent attribute
|
||||
glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, 14 * sizeof(float), (void*)(11 * sizeof(float)));
|
||||
glEnableVertexAttribArray(4);
|
||||
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
|
@ -39,16 +39,27 @@ private:
|
||||
|
||||
std::vector<float> vertexData = std::vector<float>();
|
||||
|
||||
// Go through each vertex
|
||||
for (auto &Vertice : curMesh.Vertices) {
|
||||
vertexData.emplace_back(Vertice.Position.X);
|
||||
vertexData.emplace_back(Vertice.Position.Y);
|
||||
vertexData.emplace_back(Vertice.Position.Z);
|
||||
vertexData.emplace_back(Vertice.Normal.X);
|
||||
vertexData.emplace_back(Vertice.Normal.Y);
|
||||
vertexData.emplace_back(Vertice.Normal.Z);
|
||||
vertexData.emplace_back(Vertice.TextureCoordinate.X);
|
||||
vertexData.emplace_back(Vertice.TextureCoordinate.Y);
|
||||
auto tangents = getTangentsFromVertices(curMesh.Vertices, getIndicesFromFile(path));
|
||||
|
||||
for (int i = 0; i <= curMesh.Vertices.size(); i++) {
|
||||
auto vertex = curMesh.Vertices[i];
|
||||
auto tangent = tangents.first[i];
|
||||
auto bitangent = tangents.second[i];
|
||||
|
||||
vertexData.emplace_back(vertex.Position.X);
|
||||
vertexData.emplace_back(vertex.Position.Y);
|
||||
vertexData.emplace_back(vertex.Position.Z);
|
||||
vertexData.emplace_back(vertex.Normal.X);
|
||||
vertexData.emplace_back(vertex.Normal.Y);
|
||||
vertexData.emplace_back(vertex.Normal.Z);
|
||||
vertexData.emplace_back(vertex.TextureCoordinate.X);
|
||||
vertexData.emplace_back(vertex.TextureCoordinate.Y);
|
||||
vertexData.emplace_back(tangent.x);
|
||||
vertexData.emplace_back(tangent.y);
|
||||
vertexData.emplace_back(tangent.z);
|
||||
vertexData.emplace_back(bitangent.x);
|
||||
vertexData.emplace_back(bitangent.y);
|
||||
vertexData.emplace_back(bitangent.z);
|
||||
}
|
||||
|
||||
return vertexData;
|
||||
@ -58,6 +69,58 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
static std::pair<std::vector<glm::vec3>, std::vector<glm::vec3>> getTangentsFromVertices(const std::vector<objl::Vertex> &vertices, const std::vector<unsigned int> indices) {
|
||||
// These vectors hold tangents and bitangents in the same way in which the vertices vectors holds vertices:
|
||||
// Their index in the vector corresponds to indices in the indices vector.
|
||||
std::vector<glm::vec3> tangents(vertices.size());
|
||||
std::vector<glm::vec3> bitangents(vertices.size());
|
||||
|
||||
// Iterate over all triangles
|
||||
for (uint index = 0; index < indices.size(); index += 3) {
|
||||
// Index in vertex buffer
|
||||
uint i0 = indices[index];
|
||||
uint i1 = indices[index + 1];
|
||||
uint i2 = indices[index + 2];
|
||||
|
||||
// Inputs
|
||||
glm::vec3 vertex0 = glm::vec3(vertices[i0].Position.X, vertices[i0].Position.Y, vertices[i0].Position.Z);
|
||||
glm::vec3 vertex1 = glm::vec3(vertices[i1].Position.X, vertices[i1].Position.Y, vertices[i1].Position.Z);
|
||||
glm::vec3 vertex2 = glm::vec3(vertices[i2].Position.X, vertices[i2].Position.Y, vertices[i2].Position.Z);
|
||||
|
||||
glm::vec2 uv0 = glm::vec2(vertices[i0].TextureCoordinate.X, vertices[i0].TextureCoordinate.Y);
|
||||
glm::vec2 uv1 = glm::vec2(vertices[i1].TextureCoordinate.X, vertices[i1].TextureCoordinate.Y);
|
||||
glm::vec2 uv2 = glm::vec2(vertices[i2].TextureCoordinate.X, vertices[i2].TextureCoordinate.Y);
|
||||
|
||||
glm::vec3 normal0 = glm::vec3(vertices[i0].Normal.X, vertices[i0].Normal.Y, vertices[i0].Normal.Z);
|
||||
glm::vec3 normal1 = glm::vec3(vertices[i1].Normal.X, vertices[i1].Normal.Y, vertices[i1].Normal.Z);
|
||||
glm::vec3 normal2 = glm::vec3(vertices[i2].Normal.X, vertices[i2].Normal.Y, vertices[i2].Normal.Z);
|
||||
|
||||
// Edges of the triangle : position delta
|
||||
glm::vec3 deltaPos1 = vertex1 - vertex0;
|
||||
glm::vec3 deltaPos2 = vertex2 - vertex0;
|
||||
|
||||
// UV delta
|
||||
glm::vec2 deltaUV1 = uv1 - uv0;
|
||||
glm::vec2 deltaUV2 = uv2 - uv0;
|
||||
|
||||
float r = 1.0f / (deltaUV1.x * deltaUV2.y - deltaUV1.y * deltaUV2.x);
|
||||
glm::vec3 tangent = (deltaPos1 * deltaUV2.y - deltaPos2 * deltaUV1.y)*r;
|
||||
glm::vec3 bitangent = (deltaPos2 * deltaUV1.x - deltaPos1 * deltaUV2.x)*r;
|
||||
|
||||
// Add the tangent and bitangent to the current value in the array.
|
||||
// This is done to get an average in the end.
|
||||
tangents[i0] += tangent;
|
||||
tangents[i1] += tangent;
|
||||
tangents[i2] += tangent;
|
||||
|
||||
bitangents[i0] += bitangent;
|
||||
bitangents[i1] += bitangent;
|
||||
bitangents[i2] += bitangent;
|
||||
}
|
||||
|
||||
return std::pair<std::vector<glm::vec3>, std::vector<glm::vec3>>(tangents, bitangents);
|
||||
}
|
||||
|
||||
static std::vector<unsigned int> getIndicesFromFile(const std::string &path) {
|
||||
objl::Loader loader;
|
||||
|
||||
|
@ -2,6 +2,8 @@
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 1) in vec3 NORMAL;
|
||||
layout (location = 2) in vec2 UV;
|
||||
layout (location = 3) in vec3 TANGENT;
|
||||
layout (location = 4) in vec3 BITANGENT;
|
||||
|
||||
out vec2 TexCoord;
|
||||
out vec3 Normal;
|
||||
|
Loading…
x
Reference in New Issue
Block a user