3D地图渲染在游戏中

时间:2015-01-14 15:10:26

标签: opengl directx textures shader terrain

我对3D游戏中的地图(即“魔兽世界”)以及程序员如何渲染它们有一些疑问,所以我不应该为每个人打开一个帖子,我认为我应该在一个地方询问所有这些。

  1. 是否可以通过某种技术“平滑”山脉的边缘,或者唯一可能的解决方案是在高度图中使用更多顶点? enter image description here 我错了,并认为他们使用某种技术,因为它们只为每座山提供了相当数量的顶点?

  2. 看看这张图片: http://wow.gamona.de/wp-content/gallery/dun-morogh/dun_morogh_008.jpg 关于如何渲染这种场景的一些问题:

    1. 正如我被告知像WoW这样的开放世界游戏使用高度图进行地形渲染时,他们如何知道在哪里绘制所有其他东西? (树木,房屋,栅栏,水等)。
    2. 他们如何渲染地下区域? (山里面有一座巨大的城堡)
    3. 请注意,每个凹凸使用大约2个纹理作为其显示(雪和岩石)。他们用什么算法来知道何时采样每个纹理?它看起来不像它取决于法线。 (我认为他们甚至不会为他们的地形生成法线。)
    4. 它们看起来也不像是天空盒用于地平线。它可以是什么技术?
    5. 你能说出你注意到我可以探索的其他有趣技巧吗?
  3. 我目前正在学习OpenGL,但我也标记了DirectX,因为这些问题并非真正针对API。

4 个答案:

答案 0 :(得分:5)

很难从你的身高地图上看出来(主要是因为你没有任何照明)但是我已经说明了它在你的例子中他们正在使用高分辨率基础高度图比你好。

现在不像其他一些海报所说的那样,在3D建模包中建模的可能性非常小。他们极不可能使用B样条来渲染景观。

使用更高分辨率的高度图的一个大问题是内存要求。为此,有多种不同的解决方案可以优化"存储在内存中的高度图数据。附近的景观不需要远处的景观细节。

用于渲染大量高度详细的景观几何的非常好的技术是geometry clipmaps。虽然这很复杂。我过去曾经取得巨大成功的另一个计划是Geo-Mipmapping。它非常简单,非常快。如果您将三线性过滤技术应用于Geo-mipmap,它也会产生出色的效果。为这样的场景编写异步块加载器以提供大型景观的良好流式传输也是相当简单的。

无论如何,我会回答你的其他问题。

  1. 正如hbdavehb所建议的,他们将有一个加载景观的编辑器,然后他们可以在地图上放置项目(最有可能的是,编辑景观)。模型将在3DS Max或Maya中创建,然后加载到编辑器中进行放置。

  2. 它们使用其他形式的渲染器进行渲染。通常是portal rendererBSP renderer

  3. 此技术称为texture splatting

  4. 看起来像天空盒给我。我可以猜测它是一个动态渲染ONTO天空盒。

  5. 名单很大。但我建议调查各种图像映射技术,例如bump mapping(特别是normal mapping),cube mappingParallax mappingDisplacement mapping。然后会有照明技术,例如global illuminationPhong illumination(与Phong shading不同),bidirectional reflectance distribution functionsprecomputed radiance transfer。这只是表面上的瑕疵。我强烈建议你好好阅读。 Computer Graphics: Principles and Practice by Foley et al.是一本关于渲染的优秀书籍。 GPU Gems series也非常好。有关3D渲染技术的历史,在我看来,它仍然是一本非常有用的书,值得看Michael Abrash's Black Book

  6. 祝你好运!

答案 1 :(得分:2)

除了Tyler Durdens的回答,我想谈谈你的一些观点。

  1. 他们可能已经开发了自己的编辑器,然后将其导出并传递给渲染器。因此,开发人员可以进入并在点放置树,然后渲染器知道在该点绘制树模型。或者他们按照以下方式做一些事情:http://mollyrocket.com/casey/stream_0017.html,他们在其中填充"带有东西的空白区域,如草(如本例所示),树木等

  2. 他们渲染外部区域的方式相同:p

  3. 可以通过链接dari发布作为对帖子的回复来实现该效果,或者覆盖像您提到的高度图中的一些纹理。

  4. 我对天空盒不太确定。

  5. 看一下已发布的一些链接,你肯定可以花很多时间研究:)

答案 2 :(得分:1)

我发现平滑地形的最简单方法是,在转换为浮点数后,将convolution滤镜应用于顶点。它是一种来自图像处理的技术,但也可以很好地处理来自8位高度图的数据。

这是几年前我用过的C ++源代码。

void CGround::CHeightmap::_SmoothTerrain(int passes)
{
   float* NewHeightData;

   while (passes--)
   {
       // Note: m_Size.X and m_Size.Y should be equal and power-of-two values 
       NewHeightData = new float[m_Size.X * m_Size.Y];

       for (int x = 0; x < m_Size.X; x++)
       {
          for (int y = 0; y < m_Size.Y; y++)
          {
              int adjacentSections = 0;
              float sectionsTotal = 0.0f;

              if ((x - 1) > 0) // Check to left
              {
                 sectionsTotal += m_Heights[(x - 1)*m_Size.Y + y];
                 adjacentSections++;

                 if ((y - 1) > 0) // Check up and to the left
                 {
                    sectionsTotal += m_Heights[(x - 1)*m_Size.Y + y - 1];
                    adjacentSections++;
                 }

                 if ((y + 1) < m_Size.Y) // Check down and to the left
                 {
                    sectionsTotal += m_Heights[(x - 1)*m_Size.Y + y + 1];
                    adjacentSections++;
                 }
              }

              if ((x + 1) < m_Size.X) // Check to right
              {
                 sectionsTotal += m_Heights[(x + 1)*m_Size.Y + y];
                 adjacentSections++;

                 if ((y - 1) > 0) // Check up and to the right
                 {
                     sectionsTotal += m_Heights[(x + 1) * m_Size.Y + y - 1];
                     adjacentSections++;
                 }

                 if ((y + 1) < m_Size.Y) // Check down and to the right
                 {
                     sectionsTotal += m_Heights[(x + 1)*m_Size.Y + y + 1];
                     adjacentSections++;
                 }
              }

              if ((y - 1) > 0) // Check above
              {
                 sectionsTotal += m_Heights[x*m_Size.Y + y - 1];
                 adjacentSections++;
              }

              if ((y + 1) < m_Size.Y) // Check below
              {
                 sectionsTotal += m_Heights[x*m_Size.Y + y + 1];
                 adjacentSections++;
              }

              NewHeightData[x*m_Size.Y + y] = (m_Heights[x*m_Size.Y + y] + (sectionsTotal / adjacentSections)) * 0.5f;
           }
       }
       delete m_Heights;
       m_Heights = NewHeightData;
   }
}

增加passes的值以获得更多平滑效果。

单独回答1) - 。如果是对象,它们会有一个列表,只需将它们放在高度图的顶部即可。

2) - 以不同的方式。地下城通常是常规网格。

3)您可以使用法线,高度,不同解释的附加纹理数据或上述

的任意组合

答案 3 :(得分:0)

暴雪建模者使用Autodesk's 3ds max来创建模型。如果您研究该软件包的功能和技术,您将看到它们如何实现其效果。请注意,景观模型使用非均匀b样条(NURB),使其具有圆形外观。