Sign in to follow this  

Tangent calculation

This topic is 2817 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

I'm having a problem calculating tangents for my models, when outputing the tangents in the pixelshader as the outputcolor, I get some areas that appear to be black. The code I'm using is this one, adapted from here http://www.terathon.com/code/tangent.html
void Model::calculateTangents()
{
    float *tan1 = new float[_vertexCount * 3];
    float *tan2 = new float[_vertexCount * 3];
    ZeroMemory(tan1, _vertexCount * sizeof(float) * 3);
	ZeroMemory(tan2, _vertexCount * sizeof(float) * 3);
    
	for (int k = 0; k < _meshCount; k++)
	{
		for (int i = 0; i < _triangleCount; i++)
		{
			int i1 = _triangleList[i]._vertexIndices[0];
			int i2 = _triangleList[i]._vertexIndices[1];
			int i3 = _triangleList[i]._vertexIndices[2];
	        
			float v1[3];
			float v2[3];
			float v3[3];
			memcpy(v1, _vertexList[i1].position, sizeof(float) * 3);
			memcpy(v2, _vertexList[i2].position, sizeof(float) * 3);
			memcpy(v3, _vertexList[i3].position, sizeof(float) * 3);
	        
			float w1[2];
			float w2[2];
			float w3[2];
			memcpy(w1, _vertexList[i1].texcoord, sizeof(float) * 2);
			memcpy(w2, _vertexList[i2].texcoord, sizeof(float) * 2);
			memcpy(w3, _vertexList[i3].texcoord, sizeof(float) * 2);
	        
			float x1 = v2[0] - v1[0];
			float x2 = v3[0] - v1[0];
			float y1 = v2[1] - v1[1];
			float y2 = v3[1] - v1[1];
			float z1 = v2[2] - v1[2];
			float z2 = v3[2] - v1[2];
	        
			float s1 = w2[0] - w1[0];
			float s2 = w3[0] - w1[0];
			float t1 = w2[1] - w1[1];
			float t2 = w3[1] - w1[1];
	        
			float r = 1.0f / (s1 * t2 - s2 * t1);
			float sdir[3];
			sdir[0] = (t2 * x1 - t1 * x2) * r;
			sdir[1] = (t2 * y1 - t1 * y2) * r;
			sdir[2] = (t2 * z1 - t1 * z2) * r;

			float tdir[3];
			tdir[0] = (s1 * x2 - s2 * x1) * r;
			tdir[1] = (s1 * y2 - s2 * y1) * r;
			tdir[2] = (s1 * z2 - s2 * z1) * r;
	        
			tan1[i1*3 + 0] += sdir[0];
			tan1[i1*3 + 1] += sdir[1];
			tan1[i1*3 + 2] += sdir[2];

			tan1[i2*3 + 0] += sdir[0];
			tan1[i2*3 + 1] += sdir[1];
			tan1[i2*3 + 2] += sdir[2];

			tan1[i3*3 + 0] += sdir[0];
			tan1[i3*3 + 1] += sdir[1];
			tan1[i3*3 + 2] += sdir[2];
	        
			tan2[i1*3 + 0] += tdir[0];
			tan2[i1*3 + 1] += tdir[1];
			tan2[i1*3 + 2] += tdir[2];

			tan2[i2*3 + 0] += tdir[0];
			tan2[i2*3 + 1] += tdir[1];
			tan2[i2*3 + 2] += tdir[2];

			tan2[i3*3 + 0] += tdir[0];
			tan2[i3*3 + 1] += tdir[1];
			tan2[i3*3 + 2] += tdir[2];
		}
	    
		for (int i = 0; i < _vertexCount; i++)
		{
			float n[3];
			memcpy(n, _vertexList[i].normal, sizeof(float)*3);
			float t[3];
			memcpy(t, &(tan1[i]), sizeof(float)*3);
	        
			// Gram-Schmidt orthogonalize
			float dot = (n[0] * t[0]) + (n[1] * t[1]) + (n[2] * t[2]);
			_vertexList[i].tangent[0] = (t[0] - n[0]) * dot;
			_vertexList[i].tangent[1] = (t[1] - n[1]) * dot;
			_vertexList[i].tangent[2] = (t[2] - n[2]) * dot;
			
			float length = sqrt((_vertexList[i].tangent[0] * _vertexList[i].tangent[0]) +
						   (_vertexList[i].tangent[1] * _vertexList[i].tangent[1]) +
						   (_vertexList[i].tangent[2] * _vertexList[i].tangent[2]));
			_vertexList[i].tangent[0] /= length;
			_vertexList[i].tangent[1] /= length;
			_vertexList[i].tangent[2] /= length;
	        
			// Calculate handedness
			float cc[3];
			cc[0] = n[1] * t[2] - t[1] * n[2];
			cc[1] = n[2] * t[0] - t[2] * n[0];
			cc[2] = n[0] * t[1] - t[0] * n[1];
			dot = (cc[0] * tan2[i*3 + 0]) + (cc[1] * tan2[i*3 + 1]) + (cc[2] * tan2[i*3 + 2]);

			if (dot<0.0f)
				_vertexList[i].tangent[3] = 1.0f;
			else
				_vertexList[i].tangent[3] = -1.0f;
		}

	}
    delete[] tan1;
	delete[] tan2;
}


Share this post


Link to post
Share on other sites
What are you outputting exactly? xyz of the tangent vector as rgb? probably some tangents have negative values, and those will show up as black in the image... i can be wrong, though. Try outputting tangent*0.5+0.5, that will bring the values to [0,1].

Share this post


Link to post
Share on other sites
Quote:
Original post by ArKano22
What are you outputting exactly? xyz of the tangent vector as rgb? probably some tangents have negative values, and those will show up as black in the image... i can be wrong, though. Try outputting tangent*0.5+0.5, that will bring the values to [0,1].


Ah, yes, I forgot that, now the output looks better, but still, in those black areas is still the same, so I think the tangent calculation is getting some zero values somewhere when it shouldn't

Share this post


Link to post
Share on other sites

This topic is 2817 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this