Chapter 1 generating complex procedural terrains using the GPU
利用GPU产生复杂的程序地形
1.1 导言
传统上,CPU生成并由GPU渲染的程序地形仅限于高度网格(height fields)。然而,CPU的串行处理特性并不适合于生成极度复杂地形——一个高度平行的任务。加之,CPU能处理的简单高度网格并不能提供有趣的地形特征(如洞穴或悬崖)。
在交互式帧率下生成高度复杂性的程序地形,我们指望GPU。通过利用几个新的DX10能力,如GS、stream output,和3D纹理渲染,我们能利用GPU快速生成复杂程序地形的大块(large blocks),集合起这些大块建立一个大的、细化的多边形模型,并在当前视口中显示这一地形。
1.2 边界立方体和密度函数(Marching Cubes and the Density Function)
概念上,地形表面可以利用称为“密度函数”的单一函数完全描述。在3D空间(x,y,x)内的任意点,本函数表示为单一的浮点值。这些值在空间内变化——时而为正,时而为负。如果值为正,这点在空间中位于实体地形内部。
如果值为负,这点位于空空间(empty space)(如空气或水)。在负值和正值之间的边界——密度值为零——是地形的表面。沿着这个表面,我们想要构造一个多边形网格。
我们利用GPU每次生成地形的一“块”多边形,但我们进一步细分这块为32×32×32的小单元,或三维象素。图1-2展示这一坐标系统。在这些三维象素内部,我们构建多边形(三角形)来表现地形表面。这一边界立方体运算法则允许我们在单一三维象素内生成正确的多边形,赋于,作为输入,其八个顶点的密度值。作为输出,其产生0-5间的任意个多边形。如果一个单元的八个顶点的密度值具有相同的正负,那么该单元完全在地形内部或外部,因此没有多边形输出。在所有其他情况下,该单元在岩石和空气之间,会有0-5间的任意个多边形产生。
1.2.1 在一个单元内部生成多边形
在一个单元内部生成多边形的工作如下:如图1-3获得八个顶点的密度值,确定每一个值是否为正或负。对于每一个值我们设置一位。如果密度为负,我们设该位为0;如果密度为正,我们设该位为1。
Figure 1-3. A Single Voxel with Known Density Values at Its Eight Corners
A solid dot indicates a positive density value at that corner. Each corner becomes a "bit" in determining the 8-bit case.
然后我们逻辑连接(接位取或)这八位以产生一个字节——也称为CASE——在所0~255范围内。如果CASE为0或255,那么这个单元全部在地形内部或外部,如前面描述的,没有多边形会生成。然而,如果CASE在范围[1,254]之间,会有不同数量的多边形生成。
如果CASE不是0或255,其通常在样式查找表[various loolup tables](在GPU上,使用constant buffers)中索引以确定基于这个CASE有多少个多边形输出,同时如何建立它们。每一个多边形通过连接位于此单元12条边的不同位置的三个点(顶点)加以建立。
Figure 1-4. The 14 Fundamental Cases for Marching Cubes
The other 240 cases are just rotations or inversions of these base cases. Image courtesy of Martin Franc.
正确的,一个顶点沿边放置的位置由插值决定。该顶点置于密度值大约为0的位置。例如,一个边的终点A的密度值为0.1,终点B的密度值为-0.3,则顶点位于从A到B的25%位置。
图1-5展示一个CASE。当这个CASE索引查找表后,蓝色的点表明顶点位于哪个边上。灰色区域显示这些顶点如何连接以构成三角形。注意蓝色点沿边实际出现的位置取决于此边终点的密度值。
Figure 1-5. Implicit Surface to Polygon Conversion
1.2.2 查找表[Lookup Tables]
两个主要的查找表在此工作。第一个,当通过索引CASE数值,告诉我们此CASE有多少个多边形要建立:
int case_to_numpolys[256];
第二个查找表要大得多。一旦其接收CASE值,该表提供在单元内部建立5个多边形的必须信息。这五个多边形均通过一个INT3值(3个整数值)加以描述;这三个值是必须连接以建立三角形的立方体边的编码[0~11]。图1-6显示边编码的方案。
int3 edge_connect_list[256][5];
Figure 1-6. The Edge Numbers Assigned to the 12 Edges of a Voxel