我正在做一个个人学习项目来制作Minecraft克隆。除了一件事,它运行得很好。与Minecraft类似,我的地形在Y轴上堆积了很多立方体,因此您可以进行挖掘。尽管我进行了平截头体剔除,但这仍然意味着我无用地绘制了我下面的所有多维数据集层。多维数据集按X,Y和Z顺序排列(尽管仅在1个方向上排列,所以从技术上讲,它不是按Z顺序排列到相机)。我基本上从玩家的位置开始仅将指针添加到玩家周围的多维数据集。然后,我针对这些进行了平截头寸淘汰。我不做八叉树细分。我想到的是根本不渲染播放器下面的图层,除非如果播放器往下看,这是行不通的。鉴于此,我如何避免在我下面呈现我看不见的多维数据集,或者避免被其他多维数据集隐藏的多维数据集。
谢谢
void CCubeGame::SetPlayerPosition() { PlayerPosition.x = Camera.x / 3; PlayerPosition.y = ((Camera.y - 2.9) / 3) - 1; PlayerPosition.z = Camera.z / 3; } void CCubeGame::SetCollids() { SetPlayerPosition(); int xamount = 70; int zamount = 70; int yamount = 17; int xamountd = xamount * 2; int zamountd = zamount * 2; int yamountd = yamount * 2; PlayerPosition.x -= xamount; PlayerPosition.y -= yamount; PlayerPosition.z -= zamount; collids.clear(); CBox* tmp; for(int i = 0; i < xamountd; ++i) { for(int j = yamountd; j > 0; --j) { for(int k = zamountd; k > 0; --k) { tmp = GetCube(PlayerPosition.x + i, PlayerPosition.y + j, PlayerPosition.z + k); if(tmp != 0) { if(frustum.sphereInFrustum(tmp->center,25) != NULL) { collids.push_back(tmp); } } } } }
前后渲染。为此,您不需要排序,请使用八叉树。叶子不会是单个的立方体,而是更大的一组。
每个这样的叶子的网格都应该缓存在显示列表中(如Bobmitch所建议的那样),或者甚至更好地缓存在顶点缓冲区中(更便宜)。生成此网格时, 请勿 以蛮力方式生成所有多维数据集。相反,对于每个多维数据集面,请检查其在同一叶中是否具有不透明的邻居,如果是,则根本不需要生成此面。您也可以将具有相同材质的相邻面统一为一个长矩形。您还可以将网格划分为六组,每个主方向一组:+/- XYZ面。仅绘制可能面对相机的那组面孔。
前后渲染本身无济于事。但是,您可以使用现代硬件提供的遮挡剔除来受益于此排序。在渲染八叉树叶子之前,请检查其bbox是否通过遮挡查询。如果没有通过,则根本不需要绘制。
遮挡查询的替代方法可以是光线跟踪。光线追踪非常适合渲染这样的环境。您可以投射一组稀疏的光线以近似可见的叶子并仅绘制那些叶子。但是,这将低估可见性集。