Gameres上有强人给出算法,用角度做权重,这样共面的面权重和就是不变的了,就不用排除共面的面了贴在这里,供又需要的朋友参考 作者:clayman something like this, but i'm not very sure :) denote triange vertex as a,b,c, we have: v1 = normalize(a-b); v2 = normalize(a-c); normalWeight = acos(dot(v1,v2)); normal = 0,0,0 totalWeight = 0 foreach triangle connect to vertex a normal += trangleNormal * normalWeight; totalWeight += normalWeight;finalNormal = normal/totalWeight;
normal = (v1 - v0) cross (v2 - v0)
每个顶点的法向量就是这个向量normal.
我在渲染时是这样处理的.
v3
|\
| \
| \ v2
| / \
| / \
v0 -----\v1
对于面(vo,v1,v2),顶点法线是 N1 = (v1 - v0) cross (v2 - v0),此时v0的法线是N1
对于面(vo,v1,v3),顶点法线是 N2 = (v1 - v0) cross (v3 - v0),此时v0的法线是N2
N1 != N2
我在渲染画面时,就是用这个方法来做的.
//叉积(vPolygon:3角形的点)
D3DXVECTOR3 vPolygon[3];
//起始点
vPolygon[0]=MapOb1[0].LHxx3DMVertex[2].LHxxMP;
//第一条线的终点
vPolygon[1]=MapOb1[0].LHxx3DMVertex[0].LHxxMP;
//第一条线的终点
vPolygon[2]=MapOb1[0].LHxx3DMVertex[3].LHxxMP;// Get 2 vectors from the polygon (2 sides), Remember the order!
D3DXVECTOR3 vVector1 = vPolygon[2] - vPolygon[0];//第一条线向量
D3DXVECTOR3 vVector2 = vPolygon[1] - vPolygon[0];//第二条线向量//计算出第3条,垂直线的向量(求出叉积)
D3DXVECTOR3 vNormal;
D3DXVec3Cross(&vNormal,&vVector1,&vVector2);//标准化(0-1)
D3DXVec3Normalize(&vNormal,&vNormal);float range=50;//长度
//设置第3条线的起始点//求得发线长度为50*百分比.
//-D3DXVECTOR3(2.5,2.5,2.5):将终点偏移到左下角
ViewLine10[3].LHxxLP=(vNormal*range)+MapOb1[0].LHxxMove-D3DXVECTOR3(2.5,2.5,2.5);
你代入,测试一下就行了,我前一阵子做的.
如果只是计算面法线只能做Flat着色
如果要做Gouraud或Phone着色,就要计算顶点法线。
通常计算顶点法线是将公用该顶点的各个面法线相加后再归一化
vo的发现就是 Normalize(N1 + N2)
但这个式子成立的前提条件是 面(v0, v2, v3)不能和面(v0, v1, v2)共面我能想出的做法就只是排除掉所有共面的面。但是逐个顶点这么做,计算量实在太大了。
有没有什么别的快点的方法。
然后记录下在模型局部空间中法线方向,所以只在第一次跑流水线才计算法线。然后每次流水线都将局部空间中的法线转换到世界空间中,用作光照。
这样可以缓解每次都计算法线的压力了。
但是如果模拟海浪之类的,顶点相对位置会改变的模型,还是需要实时的计算法线方向。
2.一般顶点法向量都是做模型的时候美工调的,程序生成的法向量其实是不够准确的,只是程序所以然认为的,真正符合美工意图的算法是没有的而且一般像MAX这种东西实际上看着顶点是被多个面共用的,动一个点共用的3个面一起变化,其实内部数据上每个三角形都有独立的3个顶点描述,只不过在动的时候共用的顶点一起动而已,这样再计算顶点法向量的时候就不用现插值每个面的Normal了
作者:clayman
something like this, but i'm not very sure :)
denote triange vertex as a,b,c, we have:
v1 = normalize(a-b);
v2 = normalize(a-c);
normalWeight = acos(dot(v1,v2)); normal = 0,0,0
totalWeight = 0
foreach triangle connect to vertex a
normal += trangleNormal * normalWeight;
totalWeight += normalWeight;finalNormal = normal/totalWeight;