Muli3D Calculate vertex tangent

记录一下:

// Calculate triangle normal ...
	vector3 v01 = pDest[1].vPosition - pDest[0].vPosition;
	vector3 v02 = pDest[2].vPosition - pDest[0].vPosition;
	vector3 vNormal; vVector3Cross( vNormal, v01, v02 );
	// all vertex normal is same
	pDest[0].vNormal = pDest[1].vNormal = pDest[2].vNormal = vNormal;

	// Calculate triangle tangent ...
	float32 fDeltaV[2] = {
		pDest[1].vTexCoord0.y - pDest[0].vTexCoord0.y,
		pDest[2].vTexCoord0.y - pDest[0].vTexCoord0.y };
	vector3 vTangent = (v01 * fDeltaV[1]) - (v02 * fDeltaV[0]);
	pDest[0].vTangent = pDest[1].vTangent = pDest[2].vTangent = vTangent.normalize();


以上的代码是主要的目的就是计算 顶点的法线与切线,法线就比较好理解,切线就需要点数学基础了。下面就记录一下切线的数学基础。


******************************************************************************

转载:

http://blog.csdn.net/bonchoix/article/details/8619624

参考:

Mathematics for 3D Game Programming and Computer Graphics-3rd edition

P180


已知该三角形三个顶点的位置坐标:P0, P1,P2, 以及对应的纹理坐标:(u0,v0,), (u1, v1), (u2, v2)。 定义三角形的两条边为E0 = P1 –P0E1= P2 –P0,对应的纹理坐标差值:(t1,  b1) = (u1 – u0, v1– v0), (t2,  b2) = (u2 – u0, v2– v0)。 我们有如下关系式:

E0 =t1Tb1B

E1 = t2Tb2B


有了以上纹理坐标与位置坐标的关系,我们便可以根据已知的信息,自己来求得任一三角形的切线坐标系了。在3D模型文件中,所有顶点的位置坐标、纹理坐标、法线等信息一般都会提供的,但却缺少切线坐标系相关信息。而在应用Normal Mapping等技术时,切线空间又是必不可少的,因此就需要我们自己手动来获取切线坐标系了。很多读取模型的库都提供了生成切线空间的功能,不过了解一下其是如何生成还是很有必要的。下面我们就来一步步地推导下切线空间的求法:

       继续从上面的纹理坐标与位置坐标的关系公式出发,把它表示成矩阵形式为:

        

把E0,E1,T,B拆成分量形式,即:

移到另一边,有:

根据矩阵知识,对于矩阵, 其逆矩阵为:

因此以上公式可以进一步表示为:





******************************************************************************


对比代码与公式:


公式:

Tx = b2 * E0x - b1 * E1x


     =   ( (v2– v0) * (p1 - p0) - (v1 - v0) * (p2 - p0)  )  *  1 /  (t1b2 - b1t2)



代码:


vector3 vTangent = (v01 * fDeltaV[1]) - (v02 * fDeltaV[0]);


                            =   (p1 - p0) * (v2 - v0) - (p2 - p0) * (v1 - v0)



对比之后,发现公式多了  1 /  (t1b2 - b1t2),而代码是没有的,

个人理解,由于之后要正规化 vTangent (vTangent.normalize();) ,那么  1 /  (t1b2 - b1t2) 乘不乘已经没有所谓了,代码就可以直接使用  (p1 - p0) * (v2 - v0) - (p2 - p0) * (v1 - v0)。










你可能感兴趣的:(光栅渲染器)