OpenGL中求顶点的法线
来源:互联网 发布:古木夕羊淘宝代购 编辑:程序博客网 时间:2024/09/21 08:56
在opengl中为了模拟光线或进行光照计算和阴影计算,我们往往需要首先计算法线。法线是一个向量,顶点法线(Vertex Normal)是过顶点的一个矢量,用于在高洛德着色(Gouraud Shading)中的计算光照和纹理效果。在生成曲面时,通常令顶点法线和相邻平面的法线保持等角,这样进行渲染时,会在平面接缝处产生一种平滑过渡的效果。表面的光照强度(即反射光量)是和光线方向与法线方向的夹角成正比的,夹角越小表面就会看起来越亮(具体可以参考http://blog.csdn.net/racehorse/article/details/6641623)。
我们知道求一个面的法线,但是一个顶点的法线怎么求呢?其实求出来的也是一种大概的法线。我们根据这个顶点旁边的点,每三个点确定一个平面,用这个点和其他点,每三个组合一个平面,分别求出每个平面法线后,把所有平面的法线叠加在一起,然后再单位化即是该点的法线。关于顶点和面的法线相关内容,请参考我转载的另一篇文章(顶点法线和面法线)
如上图所示,根据V0,V1和V2确定的平面(每个顶点Vi有x,y和z),我们可以求出这个平面的法线:
va = V1 - V0
vb = V2 - V0
根据向量求法线的公式我们可以得出,向量va和vb的叉乘 ,即为所求法向量。
即为:法线 norm = va X vb(向量叉乘) norm(x, y, z)
具体为:norm.x = va.y * vb.z - va.z * vb.y
norm.y = va.z * vb.x - va.x * vb.z
norm.z = va.x * vb.y - va.y * vb.x
或者我们可以用一些第三方计算几何数学库来处理向量的计算,例如glm库(OpenGL Mathematics几何数学库),另一个类似的数学库是:Shading Language Math for C++。使用glm库的计算如下:
glm::Vec3 va, vb, norm;
norm = glm::Cross(va, vb); //直接利用叉乘函数即可计算
上述讲了怎么求一个面的法线,那么如何求一个顶点的法线就很容易了,下面是分别针对格网数据和三角网数据求顶点法线的情况。
1)格网数据
*以下内容源自http://www.cppblog.com/flashboy/archive/2008/09/19/62263.html,包括图片。
为地形使用面法线最大的问题就是它看起来一块一块的, 因为每个面的亮度都是恒定的,并且每个方向的面上的亮度都有明显的区别。为了看起来更加的光滑,我们必须为每个顶点计算法线,而不是每个面计算法线。当计算顶点法线的时候,我们有必要考虑到此顶点共享的所有面,所以我们用方形举例,每个顶点(排除掉角落和边缘的顶点)被四个多边形共享。这个顶点的法线就应该是所有共享面法线的和在归一化的结果。
有了前面求法线的公式,现在我们求图中中间顶点的法线就比较方便了。在上面的图里,v1,v2,v3和v4是向量,v代表了中心顶点的法线,每个vij表示每个共享面的法线,所以例如v12是右下方面的单位长度的法线。那么法线 v = v12 + v23 + v34 + v41
为了使表面看起来更加光滑,有两种方法,第一种我们可以采用计算8个相邻顶点的法线,具体做法与计算四个顶点类似。第二种方法是对法线进行插值,具体是在着色器中完成,由于现在大多使用可编程管线,我们可以采用Phong光照模型,把顶点法线传到顶点着色器中,然后在片段着色器中对法线进行插值,使之看起来更光滑,但这种方法做出来的效果并不适合所有模型,看起来太鲜亮,有的模型需要偏暗色彩。如下图为phong光照模型下绘制的茶壶。图片源自:http://blog.csdn.net/xiajun07061225/article/details/7729871
2)三角网
如上图所示,为三角网中的四个三角形,中间的顶点共享四个三角形,我们也是采取跟格网数据同样的方法来求中间顶点的法线,即 v = v12 + v23 + v34 + v41
最后,另一个必要的步骤获得正确的光照是归一化这个向量,就是让它是单位长度,OpenGL在计算光照的时候需要考虑归一化的法向量。归一化的过程意味着第一步首先计算向量的长度,然后向量的每个部分除以此长度。具体可以参考http://www.cppblog.com/flashboy/archive/2008/09/19/62263.html。
如果使用glm库的话,直接可以使用glm::Normalize()这个函数归一化。
References:
http://blog.csdn.net/racehorse/article/details/6658731
http://blog.csdn.net/racehorse/article/details/6662540
http://www.cnblogs.com/flying_bat/archive/2007/10/13/923286.html
http://blog.csdn.net/sophistcxf/article/details/9095911
- OpenGL中求顶点的法线
- 自动计算顶点缓冲中所有顶点的法线
- 自动计算顶点缓冲中所有顶点的法线
- 3ds max 中平滑组顶点法线的导出
- D3D中光照,顶点法线,顶点结构,顶点颜色
- 顶点法线
- 顶点法线和面法线
- 顶点法线和面法线
- opengl中使用顶点数组的方法
- 求三角形的法线
- 在Blender中通过法线贴图和顶点位移实现石块地面的凹凸感
- OpenGL法线
- 法线映射基本原理和相关的顶点数据压缩
- 基于平均法线实现顶点网格变形控制的总结
- 基于平均法线实现顶点网格变形控制的总结
- 基于平均法线实现顶点网格变形控制的总结
- 基于平均法线实现顶点网格变形控制的总结
- 根据模型的顶点位置坐标和纹理坐标计算顶点的法线、切线和副法线
- VtigerCRM 点击拨号和来电弹屏 PBX Manager Module
- [各种面试题] N皇后问题非递归版
- nyoj79-拦截导弹
- 计算几何札记-高斯消元
- 同余定理
- OpenGL中求顶点的法线
- 压力测试工具Ab简介
- remove函数的实现
- android简单布局素材(2)—渐出底部标题栏
- CF - 244B - Undoubtedly Lucky Numbers
- jquery学习 小作品《我的日记本》
- ACM进阶计划
- Android 本机号码的获取
- HTML5 Canvas选择形状的名字与KineticJS,我喜欢的一个知识点!