Half Life2 Displacement Terrain System HL2的地形系统是一个另类的地形系统,它没有使用当前流行的heightmap技术,而是完全使用displacement map技术来进行处理,使用displacement map技术的初衷是为了在框架中和BSP技术保持一致,这是因为在BSP中最小的渲染图元是surface,surface的限制是所有的顶点必须位于同一个平面上,实际上从理论上来说在HL2这样的引擎中也可以使用heightmap来构造地形,那就是将heightmap数据也分块保存,但是当前流行的地形技术使用的都是一个整张heightmap,而且大量的LOD算法都是基于这个基础上的。使用displacement map的另外一个好处是可以构造更加复杂的地形,这是因为它存在法线的缘故。同时使用displacement map还有一个好处是在将来,因为当前MS已经对displacement map技术进行了支持,现在的问题是GPU在硬件上还不支持,如果一旦硬件支持的话,就有可能将整个地形由GPU来处理,那么对地形渲染的速度和精度会有非常大的提高。 1、what’s Displacement Map displacemtn map技术是最近几年才出现的一个技术,它出现的初衷是为了解决内存和GPU之间的带宽问题,它开始主要用于高poly角色模型的渲染,由于模型的高数据量会使内存和GPU之间的传输成为瓶颈,因此将其转换为低poly模型和一张displacement传送到GPU中,在GPU中转换为高poly模型进行渲染,可以大大减轻传送的数据量。 但是当前这项技术已经获得非常大的发展,它使用的范围非常大,从室外地形、水面、海洋到室内场景的渲染,它为提高场景的真实度提供了一个有力的工具。一个displacement map通常包含两部分:一张normal map用来保存法线,另一张height map用来保存顶点的偏移。当需要从低poly模型转换为高poly模型时很简单,首先从模型的一个face上获得一个插值点P1,然后从displacement map中获得相应位置的normal和distance,那么新的顶点P2为: P2 = P1 + normal*distance 关于displacement map的参考文章请看shaderX2中的Displacement Mapping。 2、HL2 Displacement Map Rule 在HL2中displacement map信息被保存在BSP文件中,它有以下几个数据块: LUMP_DISP_VERTS 保存displacement真实顶点信息 LUMP_DISP_TRIS 保存displacement三角形标识符信息(walkable or buildable) LUMP_DISPINF 保存displacement 的连接信息 它们保持的信息结构如下: LUMP_DISP_VERTS: class CDispVert { public: Vector m_vVector;// Vector field defining displacement volume. float m_flDist; // Displacement distances. float m_flAlpha;// "per vertex" alpha values. }; LUMP_DISP_TRIS: class CDispTri { public: unsigned short m_uiTags; // Displacement triangle tags. }; LUMP_DISPINF: class ddispinfo_t { public: int NumVerts() const{ return NUM_DISP_POWER_VERTS(power); } intNumTris() const{ return NUM_DISP_POWER_TRIS(power); } public: int power; // power - indicates size of map //(2^power + 1) int m_iLightmapSamplePositionStart;// Index into. enum { ALLOWEDVERTS_SIZE = PAD_NUMBER( MAX_DISPVERTS, 32 ) / 32 }; 在HL2中规定一个displacement最大由17*17个顶点组成,每一个displacement都将左下角看作是自身坐标系的原点,并按照顺时针方向进行记数。如下: 在ddispinfo_t类中我们可以看到为了记录displacement的邻接关系,它使用了两个数组,m_EdgeNeighbors记录四条边的邻接关系,而m_CornerNeighbors记录了四个角的邻接关系。必须注意的是在HL2中邻接的displacement并不一定都是一样大的,也就是说邻接的displacement不一定是一个,也可以是两个,如果邻接的为两个的话那么邻接的displacement的大小必须小一倍。如下: 在displacement和surface中都有一个变量来指定它们相互之间的对应关系,你可以这样认为,如果一个surface是一个displacement surface的话,那么在surface所保存的顶点信息就是displacement所在的基准面信息,实际上就是记录基准面的四角坐标,当产生实际顶点时过程如下:通过这四角的坐标和displacement的power信息可以插值获得每一个真实顶点的基准点坐标,然后通过CdispVert所保存的信息获得真实的顶点坐标。 |
-
2007-04-22
-
2007-04-15
-
2007-04-10