法线映射基本原理和相关的顶点数据压缩

原创 2006年05月22日 02:40:00

法线映射我也是刚学会的,呵呵

输入到固定渲染管线的顶点结构虽然可以定制,但也不是完全自由的,比如顶点位置必须是float3,纹理坐标float2,法线float3等等。如果使用可编程管线,由于VS的输入可以自由解析,所以相对来说就增加了很多灵活性。

在使用切线空间的法线映射(normalmap)时,一般来说顶点数据中除了法线向量外还需要加入tangent向量和binormal向量信息,以便在VS中计算切线空间变换矩阵。其中tangent是切平面上纹理坐标u的正方向,binormal是切平面上纹理坐标v的正方向。normal,tangent和binormal三者互相垂直,构成了切线空间坐标系,于是切线空间到世界空间的变换矩阵就是 float3x3( tangent, binormal, normal )

法线映射的实现一般来说有两种:

1。在vertex shader中计算出切线空间变换矩阵(如上文所述),并将该矩阵输出。在pixel shader中用得到的矩阵将法线图中采样得到的切线空间的法向量变换到世界空间,然后再进行后续的光照计算。

2。同样在vertex shader中计算出切线变换矩阵,但不输出,而是在VS中将光线方向逆向变换到切线空间,将切线空间的光线方向输出。在PS中所有的计算都在切线空间进行。

上述两种方法本人都试过,得到的画面有些微差异,但很难说哪一种是“正确”的,因为都涉及到象素对顶点信息的插值,只不过一个是对矩阵的插值,一个是对向量的插值。但是从效率上考虑,一般来说PS的压力会比VS大,而第二种方法把一个向量/矩阵乘法从PS端提前到了VS端,所以速度会更快一些。要注意的是如果采用第二种方法并且需要实现基于法线映射的高光的话,视线向量也必须在VS中转换到切线空间并输出到PS。

另外,由于normal,tangent和binormal是正交的,实际上三者中的任何一个都可以通过另外两个向量的叉乘得到,所以实际上顶点数据只需要提供normal和tangent,binormal可以在VS中通过计算得到。这样能节省宝贵的显存带宽,而显卡瓶颈一般会在PS,VS中增加一些计算不会降低帧率(不要相信我,自己去试验一下^^)

现在计算一下顶点结构大小。顶点坐标float3,纹理坐标float2,法线向量float3,tangent向量float3,一共要44个字节。如果要节省的话,实际上normal和tangent向量可以从float3压缩到byte3,当然显卡不会支持byte3这种格式,浪费一个字节就DWORD(也就是COLOR)吧,这样顶点结构就一下减到28字节了。有些情况下这是很有意义的,在处理象地形这种包含大量顶点并且需要每帧生成顶点缓冲的情况下,缩减顶点结构大小就意味着节省大量内存,减小CPU复制顶点的开销,减小显存带宽的占用真是一举数得嘿嘿……当然,代价是降低了切线空间的精度,但是考虑到最多会引入1/256的误差,而且本来法线图的精度也只有0~255(单分量),而且还经过了象素插值,最终的画面对比用肉眼几乎看不出差别。

还有更厉害的。如果正好是用在地形渲染,并且一次渲染的地形块尺寸小于256(均匀网格的情况下),甚至顶点位置和纹理坐标也可以压缩,能再节省12个字节!声明一下这个我还没有试过是否真正可行,不知道是否允许pos不是float3的。。。

再次抱歉,没有图

顶点法线和面法线

一、问题描述: 当几个面共享了一个顶点时,该如何设置这个顶点的法线呢? 二、下面是参考 Max Wagner 的 文章 《Generating Vertex Normals》,记的笔记。 ...
  • zhw_giser
  • zhw_giser
  • 2013年09月24日 09:36
  • 1770

OpenGL中求顶点的法线

在opengl中为了模拟光线或进行光照计算,我们往往需要首先计算法线。法线是一个向量定义了表面对光照的响应。例如,如何去照亮它。表面的光照强度(即反射光量)是和光线方向与法线方向的夹角成正比的,夹角越...
  • zhw_giser
  • zhw_giser
  • 2013年09月30日 11:02
  • 5427

Face Normals & Vertex Normals(面法线跟顶点法线的区别)

What is a face normal? A face normal is a vector that describesthe direction a polygon is facin...
  • fox64194167
  • fox64194167
  • 2013年03月03日 15:47
  • 3040

自动计算顶点缓冲中所有顶点的法线

问题 当绘制自定义的结构时,你会发现光照不正确。 这是因为你没有指定正确的法线向量,显卡要求每个顶点都有法线信息,这样它才可以决定每个三角形获得多少光照,详细信息可见第六章。 为每个...
  • smbluesky
  • smbluesky
  • 2015年01月24日 16:35
  • 831

Unity Shader:Unity网格(1)---顶点,三角形朝向,法线,uv,以及双面渲染三角形

1,顶点顶点是网格最基础的组成部分,可通过mesh.vertices获取和赋值。mesh.vertices是一个Vector3的数组,每个Vector3代表了此顶点在世界空间中的位置。顶点的位置,数量...
  • liu_if_else
  • liu_if_else
  • 2017年06月15日 17:33
  • 1354

顶点的法线计算方式

如果一个顶点的法线共享多个三角形,我们还需要对此法线进行均值计算,如下伪代码 void CalculationNormalVector() { for(int i=0;i...
  • mengzhisuoliu
  • mengzhisuoliu
  • 2018年01月11日 20:08
  • 52

3ds max 中平滑组顶点法线的导出

3ds max中导出顶点的法线看似很容易,直接通过mesh->getNormal(i);可以获取,但实际上这样获取的法线不一定对。 实际在3ds max中会常常使用平滑组来对面法线进行指定。这样...
  • honghaier
  • honghaier
  • 2011年08月16日 10:17
  • 3824

世界空间的法线映射

一看今天还挺早的(对于正常作息来说,也很“早”^^),再写点东西。最近一直在研究地形相关的东西,其中一个问题就是地形在经过了LOD处理之后,顶点光照变得不再适用。因为patch的LOD级别变化时,一些...
  • ZERO2046
  • ZERO2046
  • 2006年05月22日 03:23
  • 1849

对于法线映射(Normal Map) 的深入研究

前几篇文章写过有关法线贴图的内容,这次文章将讨论其原理及相关优化。回过头来看一下原来的文章真有种想删掉的感觉。。。 为什么叫法线贴图,我们知道法线(Normal)是垂直于一个面的直线...
  • huang9012
  • huang9012
  • 2014年03月22日 15:14
  • 1071

Mesh 顶点的Normal

美术经常找程序撕逼,我做的顶点在max里面只有xxx那么少,但是程序说我再unity看到的就是有XXX那么多。为什么? 因为有些公共顶点直观感受是一个,实际上是应该按照三角面的个数来计数的。...
  • baidu_16312167
  • baidu_16312167
  • 2017年07月18日 17:09
  • 465
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:法线映射基本原理和相关的顶点数据压缩
举报原因:
原因补充:

(最多只允许输入30个字)