Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

3D maps rendering in games [closed]

I have some questions about maps in 3D games (i.e. World of Warcraft) and how programmers render them:

  1. Is it possible to "smooth" the edges of mountains via some technique, or the only possible solution would be to use more vertices in a heightmap?

    enter image description here

    Am I wrong and to think that they use some kind of technique for this, as they just render a fair amount of vertices for each mountain?

  2. Take a look at this image:

    enter image description here
    (source: gamona.de)

    Some questions about how the render this kind of scene:

    1. As I've been told that open-world games like WoW use heightmaps for terrain rendering, how do they know where to draw all the other stuff? (trees, houses, fences, water etc.).
    2. How do they render underground areas? (There's a huge castle inside the mountain)
    3. Notice that every bump uses about 2 textures for its display (snow and rock). What could be the algorithm they use to know when to sample each texture? It doesn't look like it depends on normals. (I don't think they even generate normals for their terrains.)
    4. It also doesn't look like they use a skybox for the horizon. What technique could it be?
    5. Could you name other interesting techniques you noticed that I could explore?

I'm currently learning OpenGL but I tagged DirectX too as these questions aren't really API specific.

like image 346
Pilpel Avatar asked Jan 14 '15 15:01

Pilpel


3 Answers

It is quite hard to tell from your height map (primarily because you haven't got any lighting on it) but I'd say its near definite that in your examples they are using high resolution base height maps than you are.

Now unlike what some of the other posters suggest it is highly unlikely the landscape is being modelled in a 3D modelling package. It is also highly unlikely they are using B-splines to render the landscape.

The big problem with using a higher resolution height map is the memory requirements. To this end there are multiple different solutions that "optimise" the height map data that is stored in memory. Nearby landscape does not need as much details as the landscape far away.

A really good technique for rendering VAST amounts of highly detailed landscape geometry is geometry clipmaps. It's quite complicated though. Another scheme I have used to great success in the past is Geo-Mipmapping. It's very simple and very fast. It produces excellent results, too, if you apply trilinear filtering techniques to your Geo-mipmaps. It is also fairly trivial to write an asynchronous chunk loader for such a landscape to provide good streaming performance of huge landscapes.

Anyway I'll answer your other questions.

  1. As suggested by hbdavehb they will have an editor that loads the landscape and they can then place items on the map (as well, most probably, as editing the landscape). The models will be created in 3DS Max or Maya and then loaded into the editor for placing.

  2. They are rendered with some other form of renderer. Often a portal renderer or maybe a BSP renderer.

  3. This technique is known as texture splatting.

  4. Looks like a skybox to me. It could I guess be a dynamic rendering ONTO a skybox.

  5. The list is huge. But I would suggest looking into various image mapping techniques such as bump mapping (Especially normal mapping), cube mapping, Parallax mapping, Displacement mapping. Then there would be the lighting techniques such as global illumination, the Phong illumination (not the same as Phong shading), bidirectional reflectance distribution functions and precomputed radiance transfer. That's only scratching the surface. I highly recommend having a good read around. Computer Graphics: Principles and Practice by Foley et al. is an excellent book on rendering. The GPU Gems series is very good too. For a history of 3D rendering techniques and, in my opinion, still a very useful book its worth looking at Michael Abrash's Black Book as well.

Good luck!

like image 114
Goz Avatar answered Nov 08 '22 16:11

Goz


In Addition to Tyler Durdens answer I want to touch on a few of your points.

  1. They likely have developed their own editor, which they export and pass to their renderer. So developers can go in and place a tree at point and then the renderer knows to draw the tree model at that point. Or they do something along the lines of this: http://mollyrocket.com/casey/stream_0017.html, in which they "fill" the empty area with stuff, like grass (as shown in this example), trees, etc.

  2. Same way they render the outside areas :p

  3. Could achieve that effect with the link dari posted as a reply to your post, or overlay some texture from a heightmap like you mentioned.

  4. I'm not so sure about skybox.

  5. Take a look at some of the links posted already, you could surely spend a good chunk of time researching :)

like image 32
hbdavehb Avatar answered Nov 08 '22 16:11

hbdavehb


I've found out that the simplest way to smoothen out the terrain is, after conversion to floats, applying a convolution filter to the vertices. It's a technique from image processing, but works nicely with data from 8-bit heightmaps too.

Here's the C++ source I used a good few years ago.

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;
   }
}

Increase the value of passes to get more smoothing.

To answer your 1) - separately. They have a list if objects and simply place them on top of the heightmap.

2) - in a different way. Dungeons are typically regular meshes.

3) you can use the normal, the height, additional texture data interpreted differently or any combination of the above

like image 24
Bartek Banachewicz Avatar answered Nov 08 '22 18:11

Bartek Banachewicz