Sign in to follow this  
Relfos

Tangent calculation

Recommended Posts

Relfos    349
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
ArKano22    650
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
Relfos    349
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

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