GAME JOBS
Contents
Sponsored: The World of Just Cause 2 - Using Creative Technology to Build Huge Open Landscapes
 
 
Printer-Friendly VersionPrinter-Friendly Version
 
Latest Jobs
spacer View All     Post a Job     RSS spacer
 
June 6, 2013
 
Wargaming.net
Build Engineer
 
Gameloft - New York
Programmer
 
Wargaming.net
Build Engineer
 
Virdyne Technologies
Unity Programmer
 
Wargaming.net
Quality Assurance Analyst
 
Wargaming.net
Python Developer
spacer
Latest Blogs
spacer View All     Post     RSS spacer
 
June 6, 2013
 
Free to Play: A Call for Games Lacking Challenge
 
Cracking the Touchscreen Code [1]
 
10 Business Law and Tax Law Steps to Improve the Chance of Crowdfunding Success
 
Deep Plaid Games, one year later
 
The Competition of Sportsmanship in Online Games
spacer
About
spacer Editor-In-Chief:
Kris Graft
Blog Director:
Christian Nutt
Senior Contributing Editor:
Brandon Sheffield
News Editors:
Mike Rose, Kris Ligman
Editors-At-Large:
Leigh Alexander, Chris Morris
Advertising:
Jennifer Sulik
Recruitment:
Gina Gross
Education:
Gillian Crowley
 
Contact Gamasutra
 
Report a Problem
 
Submit News
 
Comment Guidelines
 
Blogging Guidelines
Sponsor
Features
  Sponsored: The World of Just Cause 2 - Using Creative Technology to Build Huge Open Landscapes
by Linus Blomberg [Programming, Art, Game Developer Magazine, Console/PC, Sponsored Feature, GD Mag, GD Mag Exclusive]
6 comments Share on Twitter Share on Facebook RSS
 
 
May 16, 2013 Article Start Previous Page 4 of 6 Next
 

Compile-Time Mesh Construction

Each terrain patch contains a mesh representing the terrain in that area. The resolution of this mesh is not uniform. The complexity of the landscape in the Just Cause series varies a lot from one location to another, so the number of triangles required to accurately represent the terrain varies greatly too -- therefore we didn't want a uniform terrain mesh resolution since that would mean a lot of unnecessary vertices, which would cost both vertex performance and memory. Also, small triangles are more expensive per pixel to render than large triangles, so we only want to use small triangles where they really make a visual difference. However, this is just for the graphical representation. For the underlying physical representation we used the fixed-size height maps described above.

There are a number of adaptive-resolution mesh schemes that take the viewpoint into consideration and adjust the resolution in real-time, like "real-time optimally adapting mesh" (ROAM), for instance. One problem with these is that they often introduce "popping" artifacts when changing the viewpoint, but more importantly that the vertex count can vary from frame to frame. Particularly on older hardware this is a very bad thing, since this would mean uploading new vertex data each frame.



With that in mind, one of our requirements was to have a fixed static vertex buffer for the life-time of the terrain patch. Basically this meant that we disregard the viewpoint and focus only on terrain complexity and distance from the camera for determining the resolution. For the terrain complexity part we went with an offline mesh construction solution, and for the distance part we used run-time selection of different LOD representations of the same data.

For the mesh data representation we came up with an adaptive scheme based on binary triangle trees. Although we came up with it independently, there are now several references to binary triangle trees on the internet, and one that closely matches our approach is described in a Gamasutra article from 2006 written by Chris Dallaire. A binary triangle tree is simply a tree in which a node defines a triangle and where two child nodes define a uniform subdivision of the parent triangle (see Figure 3). So to represent a rectangular patch of terrain, two triangle trees are needed. The rectangular patch is split along the diagonal, and the two resulting triangles are the root nodes of the two triangle trees.

Figure 3: The same triangle tree in three different representations: Mesh, tree, and bit stream

An offline process in the terrain compiler generates these triangle trees by iterating over the terrain and measuring the topographic complexity. The more complex the terrain is, the deeper the resulting triangle trees are.

We also had heuristics other than complexity that influenced the tree depth. For instance, we always wanted maximum resolution along shorelines to get smooth looking island contours. The analysis works by starting with the root node and traversing over the height map within that triangle and summing up the differences between the triangle plane and height map samples. The tree is subdivided if this sum is above a specific threshold, and the process repeated for the child nodes. The resulting tree is stored as a bit-stream, where "1" indicates a node and "0" a leaf. This is an extremely compact representation of the terrain mesh. The X and Z positions are implicit by the tree structure, and the height value for each node is sampled from the height map in run time when the vertex buffers are generated.

In the original Just Cause game we actually stored the heights at each node in this structure too, and used planar interpolation to generate the height map values within a triangle. This was of course a very compact way to store the height map but we abandoned that in favor of simplicity with Just Cause 2, since we no longer supported PlayStation 2 and the original Xbox, and thus had higher memory budgets.

So, in essence, what's stored in each stream patch with regards to the terrain mesh is simply a bit-stream for each triangle tree. To make matter slightly more complex however, we actually do this process once for each patch size in the terrain patch maps. We basically store the terrain mesh twelve times over, with different resolutions, since there are twelve patch maps in the terrain patch system. The meshes that correspond to patch sizes that are smaller or equal to the stream patch size are stored in the stream patch and streamed in as part of the stream patch map, but the meshes that correspond to patch sizes larger than the stream patch are stored in an "always loaded" global repository. 

 
Article Start Previous Page 4 of 6 Next
 
Top Stories

image
Keeping the simulation dream alive
image
A 15-year-old critique of the game industry that's still relevant today
image
Advanced audio streaming in Unity
image
Amazon launches dedicated indie games storefront
Comments

Mark DeLoura
profile image
This was a great article, thanks!

Linus Blomberg
profile image
Glad you liked it!

/Linus

Twitter: @BlombergLinus

Chris Birke
profile image
I second Mark's opinion, and I especially liked the bit on storing the x/z z/x pair.

Ferruccio Cinquemani
profile image
I didn't understand most of it and still liked it. :)

Nick Harris
profile image
I very much enjoyed Just Cause 2 and found this article to be invaluable, despite only understanding about half of it. Hopefully, when I eventually come to program my own terrain generation system I won't face the same awkward memory and DVD seek speed constraints that you overcame. I too was amazed by Elite's enormous scope back in '84, but in truth I found it to be too hard and lacking in the ability to colonize other star systems: whether it be building a moonbase, or a home inside an asteroid, or a city on a planet with an atmosphere. Orbiting space stations weren't enough for me and I quickly became frustrated that I couldn't walk around in them, shopping for cheap parts to fix my ship up with. It had Commerce and Combat, but the addition of Colonization would lead to both Culture (Colonization via Commerce) and Conquest (Colonisation via Combat). Anyway, not bad for 20KB.

Indeed, the game that inspired me at this time was Paul Woakes' Mercenary a year later in which you crash land on a planet and then have a number of adventures within that city as you seek a way to escape. This type of open world gameplay was new to me back then and may well have invented the genre - certainly, more so than Grand Theft Auto. The later sequel Damocles had you flying from planet to planet within a star system, giving a sense of enormous empowerment. This predates Frontier: Elite II by several years, which struck me as being too big, dry and purposeless. Flavien Brebion's Infinity (The Quest for Earth) is technically impressive - but ultimately as cold and detached as Space Engine or the Universe Sandbox. At times EVE Online veers too close to being as boring as a spreadsheet with a fancy sit-back-and-watch screensaver attached. The launch of Dust 514 for the PS3 just highlights the lack of cohesion in the game - you really ought to be able to land on a planet in your own ship rather than delegate the fun to some mercs and pay for the priviledge in the process. For a long time space games were out of vogue and it is interesting to see so many get funded through recent Kickstarter appeals, including Elite: Dangerous - which, in later versions, promises to let you land on planets.

However, as someone keen on this genre and finding nothing in the market since the release of Damocles, my yearnings for an adventure game set as much on the surfaces of astral bodies and inside spacecraft as much as between the stars drove me to work on the tools I thought I would need if I were to attempt to write such a big game by myself. Suffice to say I have put decades of research into boosting my productivity. C++ horrifies me: such an awful mish-mash of poorly concieved features wrapped in an error-prone syntax. Substantial use will need to be made of both kitbashing (assembling complex models from phasing the geometry of "prefabs") and the procedural generation of those prefabs. Miguel Cepero's work Procedural World looks a lot better than I need my game 'Universe' to look. Indeed, I would happily accept the rudimentary charm of Damocles if that was all I could manage, after all there are a lot of other aspects to the game that I think are more important than its presentation... I don't like this modern trend of squandering computational resources on special effects that have no impact on gameplay, whilst physics and AI get short-shrift again.

So, finally I wend my way around to my question. How would I apply a terrain solution like yours that depends on square tiles to a spherical planet? I don't think Latitude and Longitude will work as that will stretch stuff too much and result in awkward triangles at the poles. An isocahedron-sphere is nice, but relies on triangles. Is a (bloated) spherified cube the correct approach? What happens to the horizon? Will it appear to curve with more altitude? Should I trust my instincts and just use polar coordinates and a heightmap centred on the core of the planet? Any advice or pointers to research papers would be appreciated. I'd like to read up on this subject now whilst I'm implementing my programming language.

Robert Schmidt
profile image
Reminds me of Thatcher Ulrich's work with Chunked LOD. I was hoping someone would implement something like that. I was never a fan of ambient occlusion. The first open world game I played was Operation Flashpoint and I was a bit disappointed that I could only see about 1km. I wanted to see to the horizon. I'll have to get your game to check it out. Now, could you create something like this for Unity?


none
 
Comment:
 




UBM Tech