Jump to content
  • Advertisement
Sign in to follow this  
Slather

Tangent troubles (solved)

This topic is 3960 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello, I having problems trying to implement Eric Lengyel's tangent generation code. I'm using my own model format, and I can successfully bump-map a quad because the tangents behave when its just a quad facing the positive-z direction. In the lower-left of the image is an isolated quad facing the positive z direction, and to the right of that is a tri-strip that curves. You can see the funky rotated tangents on that curve. By the way, my coord system is [x:right, y:up, z:facing camera]. I'd appreciate any suggestions and can provide more screenshots/code if it helps. If you'd like to see the problem in any kind of test model let me know!! I'm a 3d artist, so creating test models is no issue. Below is my tangent generation code. I'd be happy to answer any questions.
        num_vertex = vertex_vector.size() / const_vertex_floats;	// get the actual number of vertices
	vec3df *tan1 = new vec3df[num_index];
	vec3df *tan2 = new vec3df[num_index];
	uint cur_tan = 0;

	for(uint j=0; j<num_vertex-3; j+=3)		//// ***** j<num_vertex caused a vector bounds error
	{
		const vec3df v1( vertex_vector[j*const_vertex_floats], vertex_vector[j*const_vertex_floats+1], vertex_vector[j*const_vertex_floats+2]);
		const vec3df v2( vertex_vector[(j+1)*const_vertex_floats], vertex_vector[(j+1)*const_vertex_floats+1], vertex_vector[(j+1)*const_vertex_floats+2]);
		const vec3df v3( vertex_vector[(j+2)*const_vertex_floats], vertex_vector[(j+2)*const_vertex_floats+1], vertex_vector[(j+2)*const_vertex_floats+2]);
        
		const vec2df w1( vertex_vector[j*const_vertex_floats+6], vertex_vector[j*const_vertex_floats+7]);
		const vec2df w2( vertex_vector[(j+1)*const_vertex_floats+6], vertex_vector[(j+1)*const_vertex_floats+7]);
		const vec2df w3( vertex_vector[(j+2)*const_vertex_floats+6], vertex_vector[(j+2)*const_vertex_floats+7]);

		float x1 = v2.x - v1.x;
		float x2 = v3.x - v1.x;
		float y1 = v2.y - v1.y;
		float y2 = v3.y - v1.y;
		float z1 = v2.z - v1.z;
		float z2 = v3.z - v1.z;
        
		float s1 = w2.x - w1.x;
		float s2 = w3.x - w1.x;
		float t1 = w2.y - w1.y;
		float t2 = w3.y - w1.y;
        
		float r = 1.0f / (s1 * t2 - s2 * t1);
		vec3df sdir((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r);
		vec3df tdir((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, (s1 * z2 - s2 * z1) * r);
        
		tan1[cur_tan]   += sdir.normalize();
		tan1[cur_tan+1] += sdir.normalize();
		tan1[cur_tan+2] += sdir.normalize();
        
		tan2[cur_tan]	+= tdir.normalize();
		tan2[cur_tan+1] += tdir.normalize();
		tan2[cur_tan+2] += tdir.normalize();

		cur_tan += 3;
	}
	
	
    vec3df n;
    vec3df t;
    vec3df temp;
    float sign;

    for (uint c = 0; c < num_vertex; c++)
    {
	t = tan1[c];
        n = vec3df( vertex_vector[c*const_vertex_floats+3], 
		vertex_vector[c*const_vertex_floats+4], 
		vertex_vector[c*const_vertex_floats+5] );

	// Gram-Schmidt orthogonalize
        temp = (t - n * n.dot(t)).normalize();
        
        // Calculate handedness of the bitangent
		sign = ( (n.cross(t)).dot(tan2[c]) < 0.0f ) ? -1.0f : 1.0f;

		vertex_vector[c*const_vertex_floats+8] = temp.x;
		vertex_vector[c*const_vertex_floats+9] = temp.y;
		vertex_vector[c*const_vertex_floats+10] = temp.z;
		vertex_vector[c*const_vertex_floats+11] = sign;
/*
		log_write("tangent[%d]: [%f, %f, %f]", c, 
			vertex_vector[c*const_vertex_floats+8],
			vertex_vector[c*const_vertex_floats+9], 
			vertex_vector[c*const_vertex_floats+10]);*/
     }


Thank you [Edited by - sneakyrobot on February 6, 2008 4:37:11 PM]

Share this post


Link to post
Share on other sites
Advertisement
Thanks for the reply, but I don't think its the way the triangles are wound because no matter how the triangles are tessellated, Max will export the indices in CCW order. I've checked this in the exporter and my app when importing. Your suggestion has made me think about what the tangent code assumes about the mesh. Before calculating the tangents, it collects the s and t direction vectors, and my mesh is split into render-ready form (uv edges create additional verts) when this happens, so nothing is really being added together! I'm going to change it and see if that's the problem...

Share this post


Link to post
Share on other sites
That was it! I just needed to change how the mesh was iterated when adding the s and t direction vectors to the tangent array. Thank you Mars, your comment made me think about the problem a little differently.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!