我正在使用Assimp资产导入器(http://assimp.sourceforge.net/lib_html/index.html)来解析3d模型。
到目前为止,我已经简单地提取了为网格中每个顶点定义的法线向量。但是我还在法线贴图上找到了各种教程...
据我了解,对于法线贴图,法线矢量存储在法线贴图的每个纹理元素中,您可以将它们从着色器的法线纹理中拉出。
为什么有两种获取法线的方法,一种被认为是最佳实践,为什么呢?
我正在使用Assimp资产导入器(http://assimp.sourceforge.net/lib_html/index.html)来解析3d模型。
到目前为止,我已经简单地提取了为网格中每个顶点定义的法线向量。但是我还在法线贴图上找到了各种教程...
据我了解,对于法线贴图,法线矢量存储在法线贴图的每个纹理元素中,您可以将它们从着色器的法线纹理中拉出。
为什么有两种获取法线的方法,一种被认为是最佳实践,为什么呢?
Answers:
简短答案
法线贴图和法线是两个不同的东西:法线是任何网格/曲面的几何属性,其用途并非仅用于阴影和光照计算,而实际上在物理上还有许多其他用途。法线贴图是对可替代法线矢量进行编码的纹理,该替代法线矢量用于计算机图形中以模拟颠簸。
长答案
几何中的法线法线是垂直于给定对象的矢量或线(例如,平面法线,顶点法线)。图形中的法线通常用于光线计算,例如通过获取光方向和曲面法线之间的点积来计算整个表面的漫反射。通常通过获取位于同一平面上的任意两个非平行边的叉积,基于网格的几何特性(面/顶点)来计算法线。
在OpenGL中,为每个顶点指定法线(因此称为顶点属性),即使在这种情况下可能仅针对每个面进行计算,也需要为一个面中的每个顶点指定相同的法线。OpenGL可以在一个面(三角形)的每个顶点上插入法线,因此您可以计算每个像素而不是每个顶点的反射光,从而获得更准确的结果。
法线贴图:另一方面,这是计算机图形学中的一种技术,可在纹理贴图中对法线进行编码,因此每个法线均按纹理素编码。它通常用于伪造凹凸点和凹痕的照明(例如凹凸贴图,视差贴图)。
由于法线是根据网格/曲面的几何属性计算的,因此“法线贴图”将为您提供替代法线,该法线可以模拟凹凸以在不添加更多多边形的情况下向表面添加细节。
通常使用更详细的3D模型生成法线贴图,然后根据该模型计算法线并将其编码为法线贴图。
为什么我们都需要?
只谈论渲染,法线和法线贴图通常一起使用以达到最终的照明效果,一个很好的例子可能是凹凸着色器,您需要法线贴图法线来达到凹凸照明效果,而您仍然需要几何法线以计算所谓的切空间。切线空间通常用于提供法线贴图的可重用性。
请记住,法线被认为是表面的几何属性,其用途远不止光计算。另一方面,法线贴图通常用于表面效果。
扩展答案以解释为什么切线空间很重要:
简短答案: 切线空间用于制作独立于基础几何的法线贴图。
[编辑]添加了图像,以表示切线空间中的法线贴图和世界空间中的法线贴图。
长答案: 下图显示了UV平面和定义切线空间的法线,在生成法线贴图时,我们已经知道所使用的空间将始终在Z方向上具有法线指向(这就是法线贴图看上去偏蓝的原因) ,这将有助于我们忽略表面曲率** ,。
切线空间为我们提供的优势是,我们的法线贴图编码不绑定到特定的网格法线。假设我们在世界或对象空间中对法线贴图进行编码,那么我们所编码的每个法线将具有基于原始网格法线在世界空间中如何变化的方向,更不用说您的法线贴图将受到模型转换的影响。
在上面的两张图片中,很明显,切线空间使法线贴图(右)与基础几何图形无关,因为所有法线都在几乎相同的方向上进行编码,并且变化很小,以模拟凹凸效果。
**表面曲率由几何对象偏离平面或直线的偏离量定义,但这取决于上下文以不同的方式定义。