一尘不染

渲染大量立方体的剔除技术

algorithm

我正在做一个个人学习项目来制作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);
                    }
                }

            }
        }

}

阅读 202

收藏
2020-07-28

共1个答案

一尘不染

前后渲染。为此,您不需要排序,请使用八叉树。叶子不会是单个的立方体,而是更大的一组。

每个这样的叶子的网格都应该缓存在显示列表中(如Bobmitch所建议的那样),或者甚至更好地缓存在顶​​点缓冲区中(更便宜)。生成此网格时, 请勿
以蛮力方式生成所有多维数据集。相反,对于每个多维数据集面,请检查其在同一叶中是否具有不透明的邻居,如果是,则根本不需要生成此面。您也可以将具有相同材质的相邻面统一为一个长矩形。您还可以将网格划分为六组,每个主方向一组:+/-
XYZ面。仅绘制可能面对相机的那组面孔。

前后渲染本身无济于事。但是,您可以使用现代硬件提供的遮挡剔除来受益于此排序。在渲染八叉树叶子之前,请检查其bbox是否通过遮挡查询。如果没有通过,则根本不需要绘制。

遮挡查询的替代方法可以是光线跟踪。光线追踪非常适合渲染这样的环境。您可以投射一组稀疏的光线以近似可见的叶子并仅绘制那些叶子。但是,这将低估可见性集。

2020-07-28