Monday 12 September 2016

Future City: Update 4 - Down To Business

This week I've been developing the business district layout a bit, dealing with a few bugs, experimenting with gradients, optimising the rendering, and adding a few features and fixes to help diagnose problems.  Oh, and it was my birthday too :)


The business district is going to be lots of tall, close-packed skyscrapers with occasional open spaces amongst them.  With the area we are covering there are going to be a lot of buildings, and a lot of geometry.  To deal with this we have to introduce the buildings (and gradually higher detailed versions of them) progressively as we get closer.  Since a 'Manhattan skyline' area of a city tends to be visible from a long way off we are going to have to introduce buildings from quite a distance away.  We can do this gradually, and as long as there are some of the tallest ones appearing early on we should get a good impression of a distant city.
Distant 'Manhattan skyline' effect from larger buildings
At the moment we will just use a simple boxy model for the buildings, which should suffice for distant buildings, but will need to be replaced for the closer ones.  The detail testing/switching logic for the skyscraper uses the building height to judge which detail band they should go in.  I set it up to introduce the tallest ones in a large/distant range, the mid-height ones in the next one and the smallest ones in the closer range.  The small ones can be left until quite close before we even fade them in.  Once the viewpoint is within the city, most of what you should be able to see has been faded in.
Inner city, all building proxies faded in.
Most business district blocks are of a size suitable to house a single building.  If they are a bit long or large still we sub-divide a little more and instantiate a couple of similar buildings.
At the moment we will ignore the connectivity and access situation at the periphery of each block that we saw set up in previous posts.  It's not that we aren't going to use this information eventually, but barriers and division are probably not a big features in a business area.  To postpone this for now I added a periphery clearance space around the edge of each block.  This can be later be filled with open-space furniture (benches, water features, trees, etc).  These will carry the open space blocks in the city in amongst the buildings too.
Clearance around buildings connects with open areas.

Detail Comparison

It proved quite tricky to get my head around how to get the building reveal/distance calculations to work in such a way that it was clear what the effects of the control parameters were.  Sometimes it's very easy to set something up like this and then just 'give up' by randomly fiddling with values until it seems to be working well enough.  The first attempt was like this; the values were too arbitrary and I wasn't sure what effect they were actually having.  By stepping back, thinking about the problem in a slightly different way I ended up with a system that works.  The problem was that we have two values with different meanings to compare; the height of the building and the size of the block they are being instantiated into.  Instead of trying to massage one into the 'space' of the other it is easier to convert both into an intermediate, neutral range.  Turning both into a normalised 0 to 1 range and then comparing them seems easier to calculate and balance.
When should we introduce a distance building?
Since the block size are powers of two, it also seemed a good idea to changing them to a linear value for the purposes of comparison too.  This produced the following stages of building reveal.
Stages of distance skyscraper population, far to near.

Gradient Surfaces

Using a simple box for each building quickly blocked refinement as a geometry from a normal box primitive can't be sub-divided automatically.  This has been fixed before by using the generic rectangular patch procedure (see previous post) which sub-divides and adds some interesting extra surface detail.  Since this is a bit 'blocky' I decided to try to implement a smoother version.
Block vs. Smooth surface patch procedure
Until now, all modelling primitives have only supported painting in a single flat colour (all models use vertex colour to drive their diffuse appearance), so to introduce smoother, gradient based surfaces we need another primitive or paint operator.  I decided that a flat rectangular sheet primitive with corner colour inputs would serve best to keep the amount of pre-processing and complex painting around it in the procedure to a minimum.
Coloured Sheet primitive for creating smooth gradient surfaces
Similar to the generic patch, we will be introducing variations in the colouring as the sub-division happens to add detail.  This time however, it's a bit more complicated as the adjacent pieces need to share colours along their boundaries.  Also, we aren't going to vary a single colour, we are going to blend between two main colours as this helps keep the colours consistent as we divide deeper.  By carrying both a blend factor and a seed value with each corner vertex down through the sub-division process we can ensure that as each edge is divided up and perturbed by the same amount from each side.  We end up with a variation on the mid-point noise algorithm and build up a nice surface detail as we get close.
Increasing sub-divisions of smooth patch procedure (high contrast detail setting)
This provides us with a couple of nice features when applied to the buildings:
  • More interesting surfaces (not just flat).
  • Fewer edges visible, less blocky
  • Even the lowest detail buildings have gentle gradients across them.
Smooth patch applied to low-detail skyscrapers in business district.


This gives us low-ish detail city buildings, which we will re-visit in the future to fully detail and flesh out.  For now though we are going to look at other district types and get them up to a similar level of detail.
This example demonstrates a couple of significant advantage of the procedural approach to modelling:
  1. Re-visiting models to add detail later is a normal part of the process.
  2. Upgrading fundamental elements used across your environment will automatically be applied everywhere it is used.
  3. Building up your scene breadth first instead of having to work depth first means your scene builds up as a whole, and not piece by piece.
  4. You get a working environment sooner, game-play and other disciplines can get to work earlier while the detail is added in parallel.
We shall see these points come up again and again.  They are some of the reasons I like this approach to content creation.


I might do a side-post on the debugging and diagnosis issues I've had this week, but then it's on to the industrial zone!  ..which sounds like something from the Crystal Maze :D

P.S. Cake

Since it was my birthday I thought I'd build some procedural cakes to celebrate.  I'm quite pleased with the result of a day of 'baking'.
Procedural cakes to celebrate.

No comments:

Post a Comment