记录一下:
// 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 –P0,E1= P2 –P0,对应的纹理坐标差值:(t1, b1) = (u1 – u0, v1– v0), (t2, b2) = (u2 – u0, v2– v0)。 我们有如下关系式:
E0 =t1T+ b1B
E1 = t2T+ b2B
有了以上纹理坐标与位置坐标的关系,我们便可以根据已知的信息,自己来求得任一三角形的切线坐标系了。在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)。