Tuesday, March 17, 2015

Environment in Savage Lands: Part 3 - Vegetation and Chopping Down Trees

Deer feasting on polygonal sprites in Savage Lands
screenshot from Savage Lands

In the previous post, I went through the process of applying textures to the terrain. Next I will be talking about nature content like trees, grass, & rock. Also, how content was made for the tree & bush destruction in our game.

Finding the Right Look

When I first set out to do an arctic tundra environment, I erred on the side of happy. In the first revisions of the world, I put a lot of green in to break up the snow and create an appealing look. But it wasn't harsh enough, and didn't differentiate us enough from other games.

Here's a screen from a very early prototype of the game:

early test environment
early test environment
I needed to go with a more hardcore, brutal look instead. Less Canadian Rockies, more desolate Siberia. Time was a major factor, we were hoping to get early alpha versions up & running within a month.

Almost everything we bought from the Unity asset store over the course of the project turned out to be disappointing, whether it was tech or art content. What often looks good in the store window turns out to be less than promised when implemented. But the exception to this rule (besides Terrain Composer) was finding the Winter Pack from Manufactura K4.

They did a fantastic job of bundling together a balanced content assortment of trees, bushes, rocks, and other winter environment elements. Everything is very high quality, aesthetically strong, and completely finished to work in Unity seamlessly. As an indie developer I greatly appreciate the promise of the asset store occasionally coming true, and saving a ton of content development time.

Populating the World

In Terrain Composer there are 3 layers of scattered content for the game:

- Trees (this includes bushes) essentially large plants
- Grasses (polygonal sprites) for small plants
- Rocks (objects) for obstacles & breaking up the player flow

For each layer I needed to create a custom mask to control the distribution of objects throughout the environment. These nature objects need to appear only on the flatter ground areas, and have varying falloff as they get closer to the ocean. The steepness mask is generated in World Machine, then post-processed to accommodate the water line.

Additionally, we need to prevent these objects from appearing on paths, or inside structures and other placed game objects. For this we can generate an Objects Mask in Terrain Composer, a fantastic time saver. The trick here is precisely registering this mask with the World Machine output. For this I created a node in the world at 0,0,0, and parent the game objects to this node so they are all considered in the mask.

Here you can see how this is all used:

Vegetation masks at work
Vegetation masks at work
An important note: Having grass displayed in Unity's editor completely kills performance. And by kills, I mean utterly smashes into oblivion. Fortunately Terrain Composer lets you set draw distances for trees & grass separately between the editor & run-time. Setting the grass distance to 0 makes the editor useable again.

For nature objects, the filters & masks in Terrain Composer work just like what I showed in the previous post on texturing. Here is the set up for the trees:

Tree distribution - filter & mask
Tree distribution - filter & mask
Chopping Down Trees

After the world was populated with natural objects, we proceeded to tackle the issue of chopping down trees. This was tricky, first because one of our talented programmers at Digital DNA needed to write a new collision system that would support the huge number of trees on the map. This made it possible work around some classic memory limit issues. A system also was required to remove trees from the world (leaving behind stumps), and making the tree top fall over.

The next challenge was getting the tree prefabs out of Unity 3D and into a 3D editor so I could create the destruction models. The best tool for this turned out the be Export2Maya, a package from Michael Cook available on the Unity asset store. It's a simple and clean interface that exports the geometry & UVs out into OBJ format. Just make sure that in Unity you center the model in the world before hitting export.

Tree testing scene in Unity 3D
Tree testing scene in Unity 3D
Once I had a tree outside of Unity, I proceeded to cut it up into pieces:

- Trunk
- Chunks (removed while chopping)
- Tree Top (part that falls over)

The hardest part of this was dealing with what happens when you cut apart a model with existing UVs. If the are any un-welded vertices or geometry wierdness, the UV's break and you have to redo them. This ended up being the case on most of the tree trunks. The challenge here is, when the trees are swapped between intact & destructable, you want zero change in appearance that would give away the switch. So new UVs have to perfectly match the original ones.

Also, a texture representing the tree interior needed to be added. Here is an exploded view of the destructable tree:

chop-able tree exploded view
chop-able tree exploded view
This had to be repeated for every tree & bush in the game, which ended up being a fair amount of work. For the smaller bushes I simplified this setup so that whacking away at it just removes partial chunks until it's gone.

I still have a problem to solve, which is a slight brightness pop when the trees swap states. Terrain Composer is set up to do some random tinting of vegetation, this makes the intact tree appear darker than the destructable tree. People see this as a lighting change, but it's most likely just the tint going away.

Thoughts & Lessons

It's worth mentioning that we apply wind to all the vegetation, but it's nowhere near the look I want yet. The trees sort of "shake & shimmy" instead of showing larger scale motion. And the grasses all move in unison, and could use more variation of motion. Both are issues I'm looking to solve in the near future.

Once again, none of this cool stuff would have seen the light of day without the incredible support & amazing minds at Digital DNA Games.

-H



Monday, March 16, 2015

Environment in Savage Lands: Part 2 - Terrain Composer & Splat Textures in Unity 3D

Outside the village Argo
screnshot from Savage Lands

In my last post I talked about the concept phase, and the tools & procedural sculpting of our height map.

Moving to the next step of the pipeline, I will attempt to describe how we established the environment in Unity using Terrain Composer. The first stage is the terrain texture application.

Booting Up

Unity 4 already has built-in terrain & tree systems, but we were looking for a way to really maximize the treatment & organic feel of the environment space. Terrain Composer was recommended by a colleague who showed me it's unified interface that manages a complex application of textures, vegetation, and objects scattered on the terrain.

Actually using TC was quite another thing. The tool is exceptionally deep & powerful, but the majority of it is undocumented. The videos help a little, but don't go into much depth on the specifics of what every control in the interface actually does. And the interface itself isn't the pinnacle of "artist-friendly".

Here is the setup for the displacement of the terrain mesh:

Height Map setup in Terrain Composer
Height Map setup in Terrain Composer

Generating the terrain mesh was straight forward. You apply the height map texture (16-bit) to a new terrain mesh, the adjust scale and resolution. We experimented with multi-mesh (tiled) terrains for a while, but couldn't really see any advantage to that approach, in fact it made the data more complicated to manage. So we settled on one terrain mesh for the whole world.

Base Texturing

So, it took weeks of experimenting to arrive at a point where I felt I could control the output when it came to splat maps, texture blending, and layer controls. Eventually I went back and started with a stripped down scene in unity, and applying a set of test textures that were color coded and labeled with a unique number.

Then, many knobs were twiddled. Over & over again to understand filters, curves, masks, blend ranges, and how all these things interact. This really helped to see what the tool was actually doing.

The result of this research phase was the decision to use 8 texture sets for the terrain, consisting of 5 snow textures distributed by altitude (ranging from muddy snow to grassy snow to pure snow), 2 rock textures on cliffs, and 1 muddy ground texture that goes underneath villages and the water.

In each texture slot you can set the tile amount & offset under Settings. You can input a diffuse and normal texture map for each channel. I found out much later that you can put a Specular texture into the alpha of the diffuse! Never saw that in the documentation, and it made a huge difference.

Main texture index for terrain
Main texture index for terrain

Splat Maps

A "splat" map is usually an RBGA image, you store one mask into each channel for a total of 4 masks in a splat. These masks control where each texture channel is applied on the terrain. This is how Unity likes the data. Terrain Composer generates these in the final step.

But the layers are where the real power is. They let you reference a single mask texture for a given feature, and you can use 16-bit textures for this. Here are each of the layer & filter setups for our terrain textures in TC:

Snow Layer Height Curve & Mask
Snow Layer Height Curve & Mask
Cliffs with Steepness Curve
Cliffs with Steepness Curve
Paths with Mask Only
Paths with Mask Only

In the above images you can see 3 layers of application:

1) Snow - curve based on height (altitude). A filter is added with a mask to put snow only on flatter areas of the terrain.

2) Cliffs - curve based on slope steepness. The curve represents degrees, so you have to arrange your index or do some crafty curve editing to get the right texture on the right angle.

3) Paths - no curve variation, just straight application with a filter mask that was painted to localize application to village areas.

For the first layer (snow), it's important to note that the "height" curve represents the full range of a height map, so if the highest point in your height map is 0.5 luminance, you need to adjust the curve max point accordingly.

For each layer you specify the index of textures used, and set a "mix rate" which is the overlap area where two textures are blended together. This really helps provide more variation. You can also set sliders for each texture channel to bias it against the curve.

In this image you can see the Snow textures, and how the mud is pushed down to the lowest altitude so it appears only under the water.

Snow layer blending & bias
Snow layer blending & bias

Go Time

Once you've defined your textures, layers, and filters, you can generate the final splat maps and TC will apply all this to your terrain. After that we apply the global normal map which adds a lot of nice shading detail. It's crucial to bake the normals from the height map using the same overall terrain height you set in Terrain Composer.

Here is a screenshot showing how the filter masks create nice smooth blends between texture areas.



Lessons and Thoughts

Once you decode the Rubik's cube that is Terrain Composer, it becomes a really great way to manage your terrain features across a huge play area. I would love to contribute to a documentation effort that would save others the countless hours I spent arriving at sane baselines for this part of the pipeline.

There are other tools like Relief Terrain Pack (RTP) that add another level of realism to the terrain shaders & textures. We gave it a try early on, but abandoned it because the added complexity made it tough to get predictable results. Like TC, it's a powerful set of tools that require loads of time to really understand. I may revisit it at a later date, as I've seen some people get amazing results with RTP.

Next, time to fill the world with vegetation!

Part 3 - Vegetation and Chopping Down Trees

Thanks for reading!!
-H

Saturday, March 14, 2015

Environment in Savage Lands: Part 1 - Concept & Sculpting

screenshot from Savage Lands
screenshot from Savage Lands

In my last post I talked about a recent project I'm working on called Savage Lands. Following is the first in a series on how the environment was created.

Concept Phase

Back when we started the project, there were several ideas on the table for what our world should look like. What I was hoping to do was differentiate our world from numerous other survival games, and present a harsh unforgiving climate for a grittier survival experience.

It's funny, I've never been a player of medieval games, or watched Game of Thrones. Most every game I've worked on previously was current, near-future, or futuristic in setting. But as I started to research I became very interested in how GoT treated a setting called "The North", blending both brutal realism and mythical elements in the world.

This research produced our "key" image, the reference that would set the tone for the environment.

key inspirational reference image
The North from GoT, a key inspirational reference image

From there, I made a visual style guide for for the World elements. On large studio games I've worked on, we would typically go way deeper and into greater detail with concept drawings, etc.. But this being an indie project and working with experienced artists, I made a 'lite' style document that provided a broad visual overview.

You can download the style guide here: [zipped Word doc 8mb]

That's a key phrase to remember in all of this: Indie Game. Our hope was to have the core of everything up & running in 3 months. That proved to be wildly optimistic, but the essence of the development process was to move as efficiently as possible, and not rat-hole on anything too specific.

We would start with this direction, then shape it and make it our own interpretation.

Scale & Topology

A lot of discussion ensued about the size of the world. This decision is driven by a variety of factors like the number of players, the speed of player movement, and what the balance is between exploration and player constructed content.

But the reality is, you don't get a true sense of scale until you can actually run around on a map and measure commute times through the space. Some early test maps were experimented with, and the general feeling was that we'd need at least 2x2 km and maybe as much as 8x8 km.

Another classic issue is boundaries, and we decided to go with an island to solve a host of potential issues. Players hate invisible walls, and creating a steep terrain wall around the space makes the world look like a bowl. An island would create interesting water/land interaction spaces, and offer variety to the landscape. If players decided to run into the water, they would die quickly of hypothermia.

So at that point I knew I had to build a big honkin' arctic island. In my head I saw a design that transitioned from sea level up eroded slopes, leading to rolling hills on a broad plateau in the higher elevations.

Crafting the Height Map - Tools

I've been building height map terrains since the first days of KPT Bryce, but it's been a while since setting out to create a game world this way. We needed a tool that would allow iterative design, and generate elements like splat maps, normal maps, and other terrain data.

A colleague of mine had been checking out World Machine, a stand-alone package that uses a node-based interface, and offers a good low-level control for sculpting. It also is designed to work well with Unity 3D, the engine we selected for the game.

Another tool called Terrain Composer seemed like a good fit for texturing & vegetation, and works with World Machine. So the environment pipeline became World Machine -> Terrain Composer -> Unity 3D.

Sculpting the Island

It was very important to me to create a natural, realistic terrain that didn't feel contrived or "gamey". Knowing the play area would be vast, I also wanted as much variation as possible in the topology while keeping things procedural.

After a fair amount of experimentation, I started to envision a 'dual-peak' design. If you only have a single peak, players would just make a beeline straight up the hill to find the highest point. Breaking it into two or more peaks would make the island feel bigger.

In the graphic below, you see the node construction and shaping that takes place in this first stage:

First stage shaping of terrain
Defining the initial shape of the terrain

It starts with a blend of 4 radial gradient peaks, smooshed together then limited using a Constant node. Next we need to add natural break-up to the slopes and some terracing. So we start with the always-magical Perlin noise, and feed that to a Terrace node while using a second Perlin node to modulate it.

Here is the node flow for this stage:

Noise, erosion, and terracing
Breaking up the terrain with organic features

After the Terrace node, we add Erosion and Coastal erosion to emulate the natural flow of water down the slopes. Erosion is brutally expensive in World Composer, it can take up to 10 minutes to calculate the final height map even on a fast system. But it is crucial to providing organic feel and effects of gravity on the terrain.

Adding Game Features

Natural feel is great, but you also need to allow for specific game play features in the design of the terrain. Our designer asked for flat areas to place buildings and other content that would make up abandoned villages and ruins sites. This was partially necessary since the structures were not modeled with "skirts" that would let us sink them into uneven ground.

In the above graphic you may have noticed a node called Layout Generator. This lets you draw spline shapes, then essentially boolean them into the height map. It's pretty tricky to make this feel organic, even with some of the tools they provide to soften the transition of the shapes into the landscape.

Here is a look at a sample shape and it's properties:

Layout Generator & Game Features
Carving features into the terrain

You can see in the above image that the shape cuts into the slope, creating a ridge above and a dropoff below. The area has a roughly 50-75m footprint, with a 10m falloff. The spline shape is easily modifiable, and can be locked when design is complete.

This process was repeated for each village & ruins site on the map. The same technique can be used to create other features like roads, troughs, etc..

Ultimately this tool didn't provide enough true flatness to make the structure placement consistent, so some post-processing was needed on the height & normal maps to ensure we were truly flat in these areas.

The exact issue here is whether you place these features before or after the Erosion passes. You want natural erosion to break up the shape, but it's hard to control how much break up actually gets applied by the erosion. If you place the feature after, you get a really inorganic look with a perfect shape cut into an eroded hill.

Output Stage

The final nodes in the graph create the bitmap output for the main height map, global normal, and masks for defining areas like cliffs.

final output from World Machine
final output from World Machine

The masks are used to limit vegetation, so for example trees & grass don't appear on really steep slopes. They are also used to specify where certain texture maps are applied, ie. steep slopes get rock, flat get snow, etc..

It's important to note that these bitmaps are the starting point for a lot of downstream work. I create many additional masks for things like meadows and clearings, as well as accommodating game objects like large rocks and structures. For example, you don't want grass growing inside houses.

I will go into more detail on masks and splat maps in the next post.

Lessons & Thoughts

It took a lot of iteration to decide just how tall the island is. In the examples shown above, the terrain is MUCH steeper and more vertical than we ultimately settled on.

I like extreme terrain, but early on it became clear that people didn't enjoy running around on 45-degree slopes. It left many people disoriented, and pushed them to keep moving until finding flatter ground. This is an interesting psychological phenomenon, but it also makes a lot of sense for things like situational awareness.

None of my work would have seen the light of day without the outstanding support of my colleagues at Digital DNA Games, an exceptional group of experienced game developers.

Next up, how we displace & texture the terrain:

Part 2 - Terrain Composer & Splat Textures in Unity 3D

Cheers, -H

Thursday, March 12, 2015

Update: Blood is Still Circulating

So one day you wake up and realize you haven't touched your blog for six months.

Life happens. Since my last post I joined the art faculty at DePaul School of Cinematic Arts. After a few years of adjunct teaching I really was enjoying myself, and when the opportunity came along I applied for it. I was honored when they decided to extend an offer.

At that time I was also well into my next indie game project called Savage Lands. It has since been released to Steam Early Access on March 5. The game is a collaboration between two great indie game studios, Digital DNA and Signal Studios.

My part has been creating the environment, lighting , and special effects. In addition, I created the visual branding for the game. I've been working closely with the talented artists at Signal, who created the characters, creatures, weapons, structures, and user interface.

Here is the trailer I cut together over the holiday break:



In the next several days I will be posting a series of articles describing the environment creation process in Savage Lands. My plan is to take you through the entire sequence from designing the height map, to final polish details.

It's been an amazing education in Unity 3D, procedural art creation, and medieval fantasy genre. All areas I had not spent significant time with before.

On to Part 1 - Concept & Sculpting!