前腐后继 发表于 2006-12-18 20:19:00

Half Life2 Displacement Terrain System

<table cellspacing="0" cellpadding="0" width="100%" align="left"><tbody><tr><td class="f" valign="top" width="100%"><table cellspacing="0" cellpadding="2" width="100%"><tbody><tr><td valign="bottom" align="left"><span class="txt5"><br/></span></td><td class="txt4" valign="top" nowrap="nowrap" align="right"><a href="javascript:__doPostBack('_ctl0$MainContent$PostFlatView$_ctl0$PostRepeater$_ctl0$_ctl12','')"></a>&nbsp; </td></tr></tbody></table></td></tr><!--Element not supported - Type: 8 Name: #comment--><!--Element not supported - Type: 8 Name: #comment--><tr><td class="fh3a" valign="top" height="100"><table cellspacing="2" cellpadding="0" width="100%" align="left" border="0"><tbody><tr><td width="1" rowspan="1"><img height="250" src="http://bbs.gamedev.csdn.net/Web/Themes/default/images/spacer.gif" width="1" alt=""/>
                                                                </td><td class="txt4" valign="top" style="PADDING-TOP: 4px;"><table cellspacing="0" cellpadding="4" width="90%" align="left"><tbody><tr><td class="txt4" valign="top" align="left">Half Life2 Displacement Terrain System<br/>HL2的地形系统是一个另类的地形系统,它没有使用当前流行的heightmap技术,而是完全使用displacement map技术来进行处理,使用displacement map技术的初衷是为了在框架中和BSP技术保持一致,这是因为在BSP中最小的渲染图元是surface,surface的限制是所有的顶点必须位于同一个平面上,实际上从理论上来说在HL2这样的引擎中也可以使用heightmap来构造地形,那就是将heightmap数据也分块保存,但是当前流行的地形技术使用的都是一个整张heightmap,而且大量的LOD算法都是基于这个基础上的。使用displacement map的另外一个好处是可以构造更加复杂的地形,这是因为它存在法线的缘故。同时使用displacement map还有一个好处是在将来,因为当前MS已经对displacement map技术进行了支持,现在的问题是GPU在硬件上还不支持,如果一旦硬件支持的话,就有可能将整个地形由GPU来处理,那么对地形渲染的速度和精度会有非常大的提高。<br/>1、what’s Displacement Map<br/>displacemtn map技术是最近几年才出现的一个技术,它出现的初衷是为了解决内存和GPU之间的带宽问题,它开始主要用于高poly角色模型的渲染,由于模型的高数据量会使内存和GPU之间的传输成为瓶颈,因此将其转换为低poly模型和一张displacement传送到GPU中,在GPU中转换为高poly模型进行渲染,可以大大减轻传送的数据量。<br/>但是当前这项技术已经获得非常大的发展,它使用的范围非常大,从室外地形、水面、海洋到室内场景的渲染,它为提高场景的真实度提供了一个有力的工具。一个displacement map通常包含两部分:一张normal map用来保存法线,另一张height map用来保存顶点的偏移。当需要从低poly模型转换为高poly模型时很简单,首先从模型的一个face上获得一个插值点P1,然后从displacement map中获得相应位置的normal和distance,那么新的顶点P2为:<br/>P2 = P1 + normal*distance<br/>关于displacement map的参考文章请看shaderX2中的Displacement Mapping。<br/>2、HL2 Displacement Map Rule<br/>在HL2中displacement map信息被保存在BSP文件中,它有以下几个数据块:<br/>LUMP_DISP_VERTS 保存displacement真实顶点信息<br/>LUMP_DISP_TRIS 保存displacement三角形标识符信息(walkable or buildable)<br/>LUMP_DISPINF 保存displacement 的连接信息<br/>它们保持的信息结构如下:<br/>LUMP_DISP_VERTS:<br/>class CDispVert<br/>{<br/>public:<br/>Vector m_vVector;// Vector field defining displacement volume.<br/>float m_flDist; // Displacement distances.<br/>float m_flAlpha;// "per vertex" alpha values.<br/>};<br/>LUMP_DISP_TRIS:<br/>class CDispTri<br/>{<br/>public:<br/>unsigned short m_uiTags; // Displacement triangle tags.<br/>};<br/>LUMP_DISPINF:<br/>class ddispinfo_t<br/>{<br/>public:<br/>int NumVerts() const{ return NUM_DISP_POWER_VERTS(power); }<br/>intNumTris() const{ return NUM_DISP_POWER_TRIS(power); }<br/><br/>public:<br/>Vector startPosition;// start position used for //orientation -- (added BSPVERSION 6)<br/>int m_iDispVertStart;// Index into LUMP_DISP_VERTS.<br/>int m_iDispTriStart;// Index into LUMP_DISP_TRIS.<br/><br/>int power; // power - indicates size of map //(2^power + 1)<br/>int minTess; // minimum tesselation allowed<br/>float smoothingAngle; // lighting smoothing angle<br/>int contents; // surface contents<br/>unsigned short m_iMapFace; // Which map face this<br/>//displacement comes from.<br/>int m_iLightmapAlphaStart;// Index into ddisplightmapalpha.<br/><br/>int m_iLightmapSamplePositionStart;// Index into.<br/>// LUMP_DISP_LIGHTMAP_SAMPLE_POSITIONS <br/>CDispNeighbor m_EdgeNeighbors;// Indexed by NEIGHBOREDGE_ defines.<br/>CDispCornerNeighbors m_CornerNeighbors; // Indexed by CORNER_ defines.<br/><br/>enum { ALLOWEDVERTS_SIZE = PAD_NUMBER( MAX_DISPVERTS, 32 ) / 32 };<br/>unsigned long m_AllowedVerts; //<br/>// This is built based on the layout and <br/>//sizes of our neighbors<br/>// and tells us which<br/>//vertices are allowed to be active.<br/>};<br/><br/>在HL2中规定一个displacement最大由17*17个顶点组成,每一个displacement都将左下角看作是自身坐标系的原点,并按照顺时针方向进行记数。如下:<br/>http://www.valve-erc.com/srcsdk/Levels/images/displacement_02.png <br/><br/>在ddispinfo_t类中我们可以看到为了记录displacement的邻接关系,它使用了两个数组,m_EdgeNeighbors记录四条边的邻接关系,而m_CornerNeighbors记录了四个角的邻接关系。必须注意的是在HL2中邻接的displacement并不一定都是一样大的,也就是说邻接的displacement不一定是一个,也可以是两个,如果邻接的为两个的话那么邻接的displacement的大小必须小一倍。如下:<br/>http://www.valve-erc.com/srcsdk/Levels/images/disp_sew_04.png <br/><br/>在displacement和surface中都有一个变量来指定它们相互之间的对应关系,你可以这样认为,如果一个surface是一个displacement surface的话,那么在surface所保存的顶点信息就是displacement所在的基准面信息,实际上就是记录基准面的四角坐标,当产生实际顶点时过程如下:通过这四角的坐标和displacement的power信息可以插值获得每一个真实顶点的基准点坐标,然后通过CdispVert所保存的信息获得真实的顶点坐标。<br/>3、如何处理地形系统<br/>在HL2中为了高效的渲染地形定义了大量的类,其中最重要的为CdispInfo,它几乎包含了地形的大部分处理,还有一个类CpowerInfo,这是一个予计算的模版类,它预先计算了每一种大小displacement的信息,这样做是为了加速地形的渲染,而类CcoreDispInfo只用来载入数据时使用,它的功能就是将BSP文件中的信息转换为程序可以处理数据。其实在HL2中比较难懂的是它的LOD算法,下面是它具体的算法:<br/>首先是它的更新策略,在正常情况下(LOD的控制台变量为默认值)对displacement的更新有两种情况,它规定了一个更新半径(由控制台变量r_DispFullRadius指定)凡是位于此半径内的displacement的LOD等级都为最大。另外在每次更新时每一个displacement内部都记录了更新时camera的位置,如果当前camera的位置减去上一次更新时camera位置的大小大于一个规定值(由控制台变量r_DispRadius指定),对其进行更新,必须注意的是此时更新的是位于更新半径外的displacement。<br/>下面是它的LOD算法,还是要提醒此时是对更新半径外的displacement进行处理。通常现在LOD算法都是基于距离进行计算的,但是HL2中没有采用这种方法,而是使用一种称为屏幕误差的方法进行。具体方法如下:<br/>首先假设将要更新的displacement位于屏幕的中心,然后求出此时的camera变换矩阵,遍历displacement中的所有顶点(不包含当前displacement的中心点和四个角上的点),对于每一个顶点,用它的坐标和它所在error edge的算术中点坐标相减,然后用这个值和当前displacement的AABB中心点相加,结果通过camera矩阵进行变换然后将X,Y部分分别除以Z值得到的就是这个顶点在屏幕上的视觉误差了。这是一个非常不容易理解的部分,尤其是除以Z值的部分,其实这样做是为了将其投影到Z为1.0的平面上,省略了进行投影变换的过程,提高了效率。当这个误差大于预定义值就将这个顶点渲染出来。<br/>通过上面的介绍可以看出在HL2中并没有象其它LOD算法一样对每一个displacement硬性的规定一个LOD级别,而是通过每一个顶点的屏幕误差来确定它是否可以被渲染,这样做在渲染非常大的地形时效率不会太好,但是在处理HL2这样的小场景时效率确实非常不错。同时也要注意这种地形方法的优点,它非常适合处理落差非常大的室外场景,如地牢围攻这样比较夸张的地形,不过此时就需要对它的LOD算法进行一下改进,另外在HL2中地形一般都比较小,如果地图设计良好的话基本上很少会渲染hidden surface,因此上不需要做地形tile的HSR,而将这种地形系统扩展到无限地形系统时,必然需要使用一定OC算法来做HSR的工作,这可能是将其扩展到无限地形系统的一个非常具有挑战性的工作了。</td></tr></tbody></table></td></tr></tbody></table></td></tr></tbody></table>

lovemaxmax 发表于 2007-5-5 06:20:00

慢慢看~~

cheneboy 发表于 2007-5-17 10:11:00

good 1
页: [1]
查看完整版本: Half Life2 Displacement Terrain System