Voxel Space:Comanche的地形渲染在少于20行代码(2020)

2021-04-01 20:02:37

让我们回到1992年。CPU比今天慢1000倍,通过GPU的加速度未知或不适算。 3D游戏专门计算在CPU上,渲染引擎呈现填充的多边形,具有单色。

图形是令人叹为观止的时间,并在我的意见前3年提前。您在山脉和山谷上看到了更多细节,如纹理,并且第一次是一个整洁的着色甚至阴影。当然,它的像素化,但这些年份的所有游戏都是像素化的。

Comanche使用一种名为Voxel Space的技术,这是基于与Ray Casting的相同想法。因此,体素空间引擎是2.5D发动机,它没有常规3D发动机提供的所有自由度。

代表地形的最简单方法是通过高度地图和彩色地图。对于游戏Comanche A 1024 * 1024一个字节高度映射和1024 * 1024您可以在本网站上下载一个字节的颜色图。这些地图是定期的:

这样的地图将地形限制在地图上的一个高度。地图" - 诸如建筑物或树等复杂的几何形状不可能表示。然而,Colormap的一个很大的优点是它已经包含着色和阴影。 Voxel Space Engine只取出颜色,也不需要在渲染过程中计算照明。

对于3D引擎,渲染算法非常简单。 Voxel Space Engine将高度和颜色图绘制并绘制垂直线路。下图展示了这种技术。

保证遮挡从后面开始并渲染到前面。这称为画家算法。

确定地图上的线,其对应于与观察者相同的光学距离。考虑视野和透视投影(物体越远较小)

从相对应的2D地图检索高度和颜色。

使用相应的颜色绘制垂直线,从透视投影中检索的高度。

核心算法以最简单的形式包含几行代码(Python语法):

def渲染(p,高度,地平线,scale_height,距离,screen_width,screen_height):#从回到前面(高z坐标为低z坐标),在范围内(距离,1, - 1):#查找行在地图上。该计算对应于90°PLEFT = Point( - Z + P. x, - z + p.y)prilight = point(z + p.x, - z + p.y)#段的视野DX =(X-PLEFT. x)/ screen_width#栅格线并为每个段的垂直线绘制IN范围(0,屏幕_WIDTH):height_on_screen =(高度 - 高度图[Pleft。x,pleft。y]) / z * scale_height。 + Horizo​​ n DrawVerticalline(i,height_on_screen,screen_height,colormap [pleft。x,pleft。y])pleft。 x + = dx#用相机参数调用渲染功能:#位置,高度,地平线位置,#高度的缩放系数,最大距离,#屏幕宽度和屏幕高度参数渲染(点(0,0) ,50,120,120,300,800,600)

通过上面的算法,我们只能查看到北方。不同的角度需要更多的代码行来旋转坐标。

def渲染(p,phi,高度,地平线,scale_height,距离,screen_width,screen_height):#预先平衡视角参数var sinphi = math。罪(PHI); var cosphi =数学。 cos(phi); #从返回到前部(高Z坐标为低Z坐标),在z范围内(距离,1, - 1):#在地图上查找线。该计算对应于90°PLEFT =点的视场( - ( - COSPI * Z - SINPHI * Z)+ P. x,(SINPHI * Z - COSPI * Z)+ P.Y)PRIGHT = POINT((Cashi * z - sinphi * z)+ p。x,( - sinphi * z - cashi * z)+ p。y)#段线dx =(斜视。x - pleft。x)/ screen_width dy =(pr。y - pleft。y)/ screen_width#栅格线并为i的每个段绘制一个垂直线(0,screen_width):height_on_screen =(高度 - 高度图[pleft。x,pleft。y])/ z * scale_height。 + Horizo​​ n DrawVerticalline(i,height_on_screen,screen_height,colormap [pleft。x,pleft。y])pleft。 x + = dx pleft。 y + = dy#用相机参数呼叫渲染功能:#位置,查看角度,高度,地平线位置,#高度的缩放系数,最大距离,#屏幕宽度和屏幕高度参数呈现(点(0 ,0),0,50,120,120,300,800,600)

而不是从背面绘制我们可以从前面绘制。优点是,我们不必每次由于遮挡时向屏幕底部绘制线条。但是,为了保证闭塞,我们需要额外的Y缓冲液。对于每个列,存储最高的y位置。因为我们从前到后面绘制,所以下一行的可见部分只能较大,然后绘制的最高线。

def渲染(p,phi,高度,地平线,scale_height,距离,screen_width,screen_height):#预先平衡视角参数var sinphi = math。罪(PHI); var cosphi =数学。 cos(phi); #初始化可见性阵列。 Ybuffer = np上的每列的y位置。 Zeros(screen_width)在范围内(0,screen_width):Ybuffer [i] =屏幕xheight#从前面绘制到后面(低z坐标为高z坐标)dz = 1. z = 1.而z<距离#在地图上查找行。该计算对应于90°PLEFT =点的视场( - ( - COSPI * Z - SINPHI * Z)+ P. x,(SINPHI * Z - COSPI * Z)+ P.Y)PRIGHT = POINT((Cashi * z - sinphi * z)+ p。x,( - sinphi * z - cashi * z)+ p。y)#段线dx =(斜视。x - pleft。x)/ screen_width dy =(pr。y - pleft。y)/ screen_width#栅格线并为i的每个段绘制一个垂直线(0,screen_width):height_on_screen =(高度 - 高度图[pleft。x,pleft。y])/ z * scale_height。 + Horizo​​ n DrawVerticalline(I,Height_on_screen,Ybuffer [I],ColorMap [Pleft.X,Pleft.y])如果height_on_screen< YBUFFER [I]:YBUFFER [I] = HEIGHT_ON_SCREEN PLEFT。 x + = dx pleft。 y + = dy#转到下一行,增加步长z + = dz dz + = 0.2#呼叫渲染功能与相机参数:#位置,观察角度,高度,地平线位置,#缩放适用于高度,最大距离,#屏幕宽度和屏幕高度参数渲染(点(0,0),0,50,120,120,300,800,600)

存储库的软件部分在MIT许可证下。请阅读许可证文件以获取更多信息。请记住,Voxel Space技术可能在一些国家仍然专利。颜色和高度图是从游戏Comanche的反向设计,因此被排除在许可证之外。