图1-1.png重点:计算法线向量是使用光照的必要步骤
1.什么叫做法向量?
法向量与几何学中的法线有点类似;
如上图1-1,我们已知三个顶点:
A:(0.0,0.0,0.0)
B:(0.0,1.0,0.0)
C:(0.0,0.0,1.0)
那么平面ABC的发线是垂直于这个面的;
我们又知道两个向量是可以确定一个面的;
那么向量Vab 与向量Vac 的法向量 normal1 也是同事垂直于这两个向量的;
2.法线数据是如何与顶点数据匹配的?
typedef struct {
GLKVector3 position; //顶点向量
GLKVector3 normal; //法线向量
GLKVector2 texture; //纹理坐标
}
SceneVertex;
从上面这个数据结构的定义我们可以了解到,法线量与顶点数据是一一对应的;
3.GLKit提供的计算方法:
//已知两个点,求两点组成的向量;
GLKVector3 v = GLKVector3Subtract(GLKVector3 point1, GLKVector3 point2);
// 已知两个向量 Vab ,Vca, 求着两个向量的法向量
GLKVector3 normal = GLKVector3Normalize(GLKVector3CrossProduct(Vab, Vac));
//根据这个方法,我们可以求图1-1中的normal1
GLKVector3 normal = GLKVector3Normalize(GLKVector3CrossProduct(Vab, Vca));
//normal1的最终结果应该是等于{0.0,1.0,0.0}
//因为三角形的三个顶点都是属于一个平面的,所以它三个顶点对应的法向量都是相等的
//再结合上文中的内容2:法线数据是如何与顶点数据匹配的
//我们就可以直接把求得的normal配置给三角形的每一个顶点就可以了.
代码测试结果.png
4.自定义方法修改三角形顶点数据的法向量数据
//顶点数据结构
typedef struct {
GLKVector3 position; //顶点向量
GLKVector3 normal; //法线向量
GLKVector2 texture; //纹理坐标
}
SceneVertex;
//三角形数据结构
typedef struct {
SceneVertex vertices[3];
}
SceneTriangle;
//NUM_FACES 表示有多少个三角形 是一个常量 根据实际开发情况设定.
//录入一个正方形,就有两个三角形,那么NUM_FACES = 2;
//在传参数的时候,这个数不用管,因为传入的是数据的地址;
void SceneTrianglesUpdateFaceNormals(SceneTriangle someTriangles[NUM_FACES])
{
int I;
for (i=0; i<NUM_FACES; I++)
{
//计算平面法向量
GLKVector3 faceNormal = SceneTriangleFaceNormal(someTriangles[I]);
//更新每个点的平面法向量
someTriangles[i].vertices[0].normal = faceNormal;
someTriangles[i].vertices[1].normal = faceNormal;
someTriangles[i].vertices[2].normal = faceNormal;
}
}
GLKVector3 SceneTriangleFaceNormal(const SceneTriangle triangle)
{
//vectorA = v1 - v0
GLKVector3 vectorA = GLKVector3Subtract(triangle.vertices[1].position,
triangle.vertices[0].position);
//vectorB = v2 - v0
GLKVector3 vectorB = GLKVector3Subtract(triangle.vertices[2].position,
triangle.vertices[0].position);
GLKVector3 normal = GLKVector3Normalize(GLKVector3CrossProduct(vectorA, vectorB));
//通过 向量A和向量B的叉积求出平面法向量,单元化后返回
// return SceneVector3UnitNormal(vectorA,vectorB);
return normal;
}
网友评论