PDA

View Full Version : Generating tangents & bitangents for triangle strip sphere?



paul_g_griffiths
01-22-2017, 03:18 AM
I'm trying to generate tangents and bitangents for a triangle strip sphere.
I have taken code off the net but I believe the generator is for triangles and not triangle strip?

Can you help?

Heres my code, thanks.


diameter /= 2.0;
numVertices = 0;
glm::vec3 vertex(0.0f, 0.0f, 0.0f);
float lonstep = (float)(M_PI / (float)stacks);
float latstep = (float)(M_PI / (float)slices);
float lon, lat;
glm::vec2 texCoord(0.0f, 0.0f);
float dstack = 1.0f / (float)stacks;
float dslice = 1.0f / (float)slices;
float texX, texY;
std::vector<glm::vec3> vertices;
std::vector<glm::vec3> normals;
std::vector<glm::vec2> uvs;
for (lon = 0.0f, texX = 0.0f; lon <= 2 * M_PI; lon += (lonstep), texX += (dstack))
{
for (lat = 0.0, texY = 0.0f; lat <= 2 * M_PI + latstep; lat += (latstep), texY += (dslice))
{
vertex[0] = diameter * cosf(lon)*sinf(lat);
vertex[1] = diameter * sinf(lon)*sinf(lat);
vertex[2] = diameter * cosf(lat);
vertices.push_back(vertex); // vertex position
texCoord[0] = texX;
texCoord[1] = texY;
uvs.push_back(texCoord); // vertex texture coordnate
vertex = glm::normalize(vertex);
normals.push_back(vertex); // vertex normal
numVertices++;

vertex[0] = diameter * cosf(lon + lonstep)*sinf(lat);
vertex[1] = diameter * sinf(lon + lonstep)*sinf(lat);
vertex[2] = diameter * cosf(lat);
vertices.push_back(vertex); // vertex position
texCoord[0] = texX + dstack;
texCoord[1] = texY;
uvs.push_back(texCoord); // vertex texture coordnate
vertex = glm::normalize(vertex);
normals.push_back(vertex); // vertex normal
numVertices++;
}
}

std::vector<glm::vec3> tangents;
std::vector<glm::vec3> bitangents;
// problem here?
for (unsigned int i = 0; i < vertices.size(); i += 3)
{
// Shortcuts for vertices
glm::vec3 & v0 = vertices[i + 0];
glm::vec3 & v1 = vertices[i + 1];
glm::vec3 & v2 = vertices[i + 2];

// Shortcuts for UVs
glm::vec2 & uv0 = uvs[i + 0];
glm::vec2 & uv1 = uvs[i + 1];
glm::vec2 & uv2 = uvs[i + 2];

// Edges of the triangle : postion delta
glm::vec3 deltaPos1 = v1 - v0;
glm::vec3 deltaPos2 = v2 - v0;

// 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;

// Set the same tangent for all three vertices of the triangle.
// They will be merged later, in vboindexer.cpp
tangents.push_back(tangent);
tangents.push_back(tangent);
tangents.push_back(tangent);
// Same thing for binormals
bitangents.push_back(bitangent);
bitangents.push_back(bitangent);
bitangents.push_back(bitangent);
}

for (unsigned int i = 0; i < vertices.size(); i += 1)
{
glm::vec3 & n = normals[i];
glm::vec3 & t = tangents[i];
glm::vec3 & b = bitangents[i];

// Gram-Schmidt orthogonalize
t = glm::normalize(t - n * glm::dot(n, t));

// Calculate handedness
if (glm::dot(glm::cross(n, t), b) < 0.0f) {
t = t * -1.0f;
}
}

paul_g_griffiths
01-22-2017, 05:09 PM
I've solved the problem, it's not in the code above, it was in my fragment shader. I was discarding fragments outside texture choords but don't want to do that for a sphere because spheres have no edges.

My engine is coming on well. It has deferred renderer, multiple lighting, multiple shadows, normal and parallax texturing and portals too.

https://s23.postimg.org/irf23xf2z/Untitled.jpg