The Great War - Recreating the Western Front from the air - Part 2

Following on from the previous blog post, this one covers how I used Houdini to generate all the fields and crop distributions that cover the majority of the terrain.

Houdini ?

If you are not familiar with what Houdini is, it is 3D content creation package, known for it's powerful procedural tool-set. It's probably better described as a tool that lets you build other 3D tools. By wiring together nodes that perform very specific tasks, you can build up a chain of processes that crunch data and spit out pretty pictures, simulations and models that would often be impossible to make manually. If I was to sit and try and paint all the natural looking divisions and distributions of fields that cover my terrain it would never get done. Using Houdini I can churn out revisions in a couple of hours by focusing on defining the "rules" that lead to the fields being where they are.

PIXELS TO GEO

So I had the image I had assembled of all the roads covering my terrain in Photoshop. It was a simple black and white mask. Houdini has a handy node called "Trace" that reads in an image and cuts up a piece of geo based on the image. So I dropped down a simple grid, cut it up with a trace node and then I was left with a single polygon for each "field" area between my roads. All in all there are about 19,000 of them. From here I did some simple edge re-sampling and clean up.

USING ROADS TO DEFINE FIELD ALIGNMENTS

It's important to note that in the previous step, I'm basically getting 1 field = 1 polygon. This make it easier to set up an operation that loops over each input polygon 1 at a time. The polygon by itself is a bit messy, it has too many edges and is non-triangulated but it doesn't matter right now, the 1:1 relationship is the important bit.

Looking at real maps, I decided that it would be logical for fields to be aligned to the main direction of the fields shape, or perpendicular to that direction. It's not a random distribution, but it does appear to be different field to field. So, I had to work out a way to calculate the main "direction" of each field.

Roads, and the 19,000+ "fields" between them

Roads, and the 19,000+ "fields" between them

The basic method was this

  • Get the normal of each point along the polygon border. Re-sampling the edges from before gives me more points to work with
  • Make the normal point towards the neighbouring point
  • Convert the point normal direction value to a rotation value
  • Down sample the potential rotation values into a smaller range of options (15 degree increments for example)
  • Tally up the rotation values rounded up to sit within the smaller range of increments
  • The rotation value with the highest number of points rotated in that direction is the dominant direction for the field
  • Finally, store that rotation as a colour value in the blue channel of the per polygon colour attribute

Now I'm not totally sure how sound that logic is but it seemed to work pretty well. I'm sure in the real world the rules that govern how any one field is planted are more complex. Sun direction, slope of the terrain, wind etc I'm sure are all factored in. They are things I could work out but for now, this will do. I made a loop that does that calculation for every single polygon, and stores the resulting direction value as a custom attribute on the polygon.

The field "direction" mask. The texture itself probably isnt that useful, but the attribute it represents is used for rotating UV coordinates per polygon

The field "direction" mask. The texture itself probably isnt that useful, but the attribute it represents is used for rotating UV coordinates per polygon

Roads and Field rotations together

Roads and Field rotations together

Now, originally I planned to render out a texture map with this blue value stored, and use it to rotate the UV's inside my material in Unreal. This was a bad idea from the get go, because texture compression was always going to corrupt the rotation values per pixel. 

In the end, doing the same kind of operation, rotating the UV's in Houdini was the way to go, and it simplifies the Unreal material anyway. Win win.

 

FIELD & FIELD CLUSTER GENERATION

So now I have each polygon UV mapped and its rotation calculated. Time to generate some crop patterns! This was a pretty simple process, but it did go through a few revisions to get the right kind of look. The beauty of doing it in Houdini is that it's super simple to experiment without breaking anything.

Always work with reference! Here is a small patch taken from Google maps, sized to fit a stretch of the Somme river on my map. It shows a tiny sample of the field complexity I need to create.

Always work with reference! Here is a small patch taken from Google maps, sized to fit a stretch of the Somme river on my map. It shows a tiny sample of the field complexity I need to create.

The idea was to make a square image, rendered as an RGB mask, with a unique field arangement on it. Then I would render out 500 or so variations, and assemble them again into a cluster of combined field arangements giving another level of complex variation. Then in turn I rendered out 1000 of those combinations.

Generating the patterns simply involved mixing and merging simple grids with randomly generated numbers of rows and columns. Then I might rotate the whole grid 90 degrees. This maybe/maybe not switching was controlled by switch nodes that picked a stream at random. Then, a range of red colour values were assigned per primitive, so each polygon in the grid got a random colour. Then, I resampled the polygon edges to get some more detail and applied a very subtle amount of noise, just to break up te straight lines.  Then, I looped through each polygon again and applied a tiny amount of jitter to its position and rotation. I also added a variable amount of smoothing to the edges of each polygon, so the fields had slightly rounded corners. Last thing to do then was to stick a flat grid colour under the whole thing to fill any gaps, and when you render it out you get these kind of random combinations. This was all super quick and dirty, I didnt care about geo overlap, or nicely fused edges, non of that mattered. I just wanted random shape arrangements.

A small snippet of a typical, all be it messy Houdini graph. The blue nodes are switches that randomly pick which chain of the graph above to read in as data flows down the chain. 

A small snippet of a typical, all be it messy Houdini graph. The blue nodes are switches that randomly pick which chain of the graph above to read in as data flows down the chain. 

So here is the kind of thing I would get back from the first pass of just creating field patterns

Field patterns

Field patterns

Then I read them in as textures and further combine them to create field clusters

The first pass of field patterns applied per polygon to another grid

The first pass of field patterns applied per polygon to another grid

Now for the fun bit - I apply the cluster textures WITH the rotation values from the first step to each polygon field. It gives me something like this:

A bit of a jumbled mess, but it's promising

A bit of a jumbled mess, but it's promising

RENDERING AND PHOTOSHOP ASSEMBLY

I render out the entire terrain covered with these field patterns as 4 x 16k tiles. I then have a single 32k Photoshop file where I'm assembling all the layers. It's a massive document, but I have some Photoshop actions that cut the layers into 8k tiles that fit together as described in my last blog entry. There are lots of layers including roads, trees, waterways, height and slope masks, city and town placements, various noise textures etc. All of these will get mixed and enhanced with hand painted details at some point.

MASK AND GRADIENT MAPPING

Now that I have this field texture made up of shades of red, it's time to do some gradient mapping. I took a screenshot from good maps and sampled it to make a new gradient in Photoshop. Remapping the reds to match this new gradient, and then pasting the google screengrab on top looks a bit like this.

The google screengrab in the middle almost melts away as it mixes with the surrounding Houdini generated fields. Pretty cool! Still needs some colour tweaks and noises mixed in but it's a good result I think. 

The google screengrab in the middle almost melts away as it mixes with the surrounding Houdini generated fields. Pretty cool! Still needs some colour tweaks and noises mixed in but it's a good result I think. 

That's it for now, next post will cover tree distribution, detailing the colour maps, normal map generation, and other good stuff. Stay tuned!

Previous
Previous

The Great War - Recreating the Western Front from the air - Part 3

Next
Next

The Great War - Recreating the Western Front from the air - Part 1