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

原创 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的。。。

再次抱歉,没有图

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

dx9顶点数据

  • 2008-03-31 16:54
  • 17KB
  • 下载

OpenGL顶点数据传输速度优化

前言最近在给cocos2d-x v2.x的一个项目做渲染优化,执行渲染批处理(Batch)的时候,发现顶点数据传输速度很慢,实在是颠覆了我的OpenGL认知。 常规的Batch原理: · 将...

Ogre中获取mesh顶点数据

void getMeshInfo(Entity* ent) { MeshPtr mesh = ent->getMesh(); bool added_shared = false; ...

[iTyran翻译]OpenGL ES 从零开始系列08:交叉存取顶点数据

Technote 2230提出了很多用OpenGL ES来提升iphone程序性能的建议。我们现在远远不能深刻理解OpenGL ES所以你需要学习以下内容。不信?是真的,试试看,我等着你的读后感。 ...

.obj文件中顶点数据的合并

在OpenGL中,为了减少顶点数据所占用的内存,通常会合并具有相同属性的顶点,然后使用顶点的索引进行绘制。举例来说,对于xz平面上中心在原点的的单位正方形,需要两个三角形来表示它,于是一共需要六个顶点...

Vulkan编程指南翻译 第八章 图形管线 第2节 顶点数据

8.2  顶点数据 如果你所使用的图形管线需要顶点数据,在执行任何绘制操作前,你需要绑定用来获取数据的哦缓冲区。当缓冲区被用来作为顶点数据的来源时,它们有时也被称为顶点缓冲区。把缓冲区当作顶点数据来用...

OpenGL ES八 - 交叉存取顶点数据

Technote 2230提出了很多用OpenGL ES来提升iphone程序性能的建议。我们现在远远不能深刻理解OpenGL ES所以你需要学习以下内容。不信?是真的,试试看,我等着你的读后感。 ...

用模板和基类巧妙实现类方法的回调(消息映射的基本原理)

注:本文参考一位学长的博客。用模板和基类巧妙实现类方法的回调是在这位学长的指导下完成的。他的博文链接:http://xuwenzhang.org/blog/category/c%e7%bc%96%e7...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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