Grid cities

Detailed explanations

For an easier start, you should read the introduction to grid cities first.

The screenshots are to be updated for the current version of SceneCity, and may not always show the current state exactly, but they are correct nonetheless. The text is up-to-date.

Generate a random grid map

The foundation of a non-overlapping city is a grid. Everything will be placed on the cells of that grid. However you are in charge of the size of the grid, what you store in that grid, and how the generator should use it to place different things on it, such as the roads and the buildings.

Create a new city graph, call it something like Tutorial city. Add and connect the following nodes:

  • Grids ==> grid

  • City layouts ==> non-overlapping boxes

  • Textures and images ==> grid to blender image

You now have a blank grid. You give it to a new layout which will put values inside that grid. Then the last node will draw that grid based on the values inside, to have an overview.

Before explaining in more details the options of each node, click Add new color on the last node, four times, then set it like below. Then click on Create / update image and display the image that has just been created. You should have something like this.

The exact colors you choose don’t matter, use any you like, BUT the texts of the key/value fields do matter!

The resulting image is a map of your city, of where the roads and buildings will be. Each pixel is 10 meters wide, and the colors represent roads for black pixels, residential districts for green pixels, industrial districts for yellow pixels, and commercial districts for blue pixels. Note that the types of districts are just those by default, they are simply names, and you can have as few as one district type to as many as you need.

Let’s see in more detail the important stuff here.

What is the grid

Let’s talk about the grid node first. You can set two important values: the overall size of the grid, which is how many cells it has on each side. And the size of each cell, in meters or blender units (I consider 1 meter equals 1 Blender unit, by convention). Each cell is a portion of land in your city, onto which you’ll put things. Therefore in this example a grid of 100 by 100 cells, with a cell size of 10 meters, represents a land of 1km by 1km.

How do you choose the size of the cells? A cell is the smallest unit when you layout your city. You will define the size of your assets (roads and buildings) in terms of cells, so for instance you could make (or have) a building 2 cells wide by 4 cells long. Which means 20m wide by 40m long if a cell is 10m wide. However it’s most important for the roads. Currently the road portions can only be exactly 1 cell wide by 1 cell long. So if you want your roads to be 20 meters wide, you should set your cell size to 20 meters. And obviously a too small cell size would not make much sense if the roads are then only a few meters wide, like 2 meters. In future versions the roads will be much more flexible. Also the included library of assets is built for a cell size of 10m, which is the default, so leave it at 10 meters.

What is IN the grid

Each cell of the grid contains key / value pairs. The keys and values can be any text that you choose. For example it can be district = residential, road = any, blender = awesome. Each cell can also have multiple key / value pairs. Each key can only have one value, so you cannot have in the same cell district = residential and district = commercial, it’s either one or the other.

Here is an example of what a grid might contain:

The layout

The layout node generates boxes separated by separators. You can control their size. You can also tell what key / value pairs to store in the grid cells of the boxes and separators. This effectively creates districts and roads, and those key / value pairs will be used in the next steps to control where to put the buildings and the roads.

For the roads their key / value do not matter because there’s no way for now to have different road types in the same city (in future versions it’ll be possible). For the buildings however it is possible to have different districts, so decide how many district types you need, then give them a name, for example commercial, residential, industrial. In this tutorial we’ll keep everything at their default values.

An example of a larger city layout of 300x300. But for yours don’t make it too large to begin with, 100x100 is very large already.

Congratulations, you have the map of a city now. If you don’t understand a concept such as the grid, what it contains or what the layout does, you should read this section again. Otherwise this section is completed and you can keep reading below, you’ll add the roads in the 3d scene.

Adding the roads from the library

Let’s put the road models where they should be. We’ll use the ones that come bundled with SceneCity. Later in this tutorial you’ll see how to use your own.

Import the pre-made assets as explained in the fundamentals.

A common mistake at this step is to move the imported assets around in 3d space (if you make them visible first). Those props are made of several objects grouped together (for most of them) to form collections. If you’re not familiar with object collections in Blender, know that a collection has an origin that is set in the collection setting, found in the object tab of the properties panel, when you select any object part of that collection. Moving the objects of the collection around, without setting the collection's origin again accordingly, is like moving a whole mesh in edit mode: visually you have moved things around, but for Blender the collection is still at the same location. Its center or origin hasn’t moved. If you do that, later in your city you’ll see buildings and roads that look out of place. But actually they’re not, their centers are correctly placed, it’s the objects within those collection that are misplaced, because you forgot to set the origin of the collections back to the actual, real center of the buildings/roads when you moved them.

In the outliner, look for a collection with a name like assets instances, where all the buildings and road portions object collections are already instanced for you. Activate it to see all the models inside.

The road portions are complex models, each made of several objects. One way to let SceneCity instantiate them is to input an instance object of each portion into the graph (in the objects getter nodes). Another way is to input the parent objects for each portion, so they must form a hierarchy for that second method.

In the city graph, add the following nodes and connect them like below:

  • Objects ==> objects getter

  • City roads ==> static road portion

Fill the name of the straight road portion object instance, look for the exact name of the object, it may be different from the one in the picture (likely something such as SC road 1x1 1 straight instance). And make sure the road type is set to straight.

The first node converts a Blender object to a SceneCity object (or several if the object has children, but this feature is not ready yet). The second node converts a SceneCity object into a road portion. So what you just did is tell SceneCity that the object road_1x1_1_straight is a straight road portion, and it is now ready to be used, but before that…

Select the nodes and duplicate them twice, for the other two portion types: intersection-3 (or T-crossing), and intersection-4 (or X-crossing).

To instantiate those road portions and put them at the correct location, add the following two nodes, and connect them like below:

  • City roads ==> road portions collection

  • City roads ==> road portions instancer

Add three input socket to the collection by clicking on Add road portions, and fill the Place on grid value field with road = all.

The collection node is used to group several road portions together (of the same or different types), and let other nodes use them as a whole. When several portions of the same type are available in the group (eg 2 different straight portions) they are chosen randomly. When that happens, you can favor one over the others by setting different probability weight: a portion with a weight of 2 is twice as likely to be chosen as a portion with a weight of one.

The road instancer node will place the portions where they should be, and rotate them accordingly also. But you have to tell it what parts of the grid contain the roads. It will check all the cells of the grid, and each time it finds a cell with a key road with the associated value all, it will place a road portion there. The output of this node is a bunch of SceneCity objects, so you need one last node to transform those objects back into Blender objects.

Finally add the last node: objects ==> objects instancer.

Set the name prefix of the future objects to Road, set the instance method to Dupli verts, and click the Create objects button. You should have something like this appear:

The creation of the instances should be almost instantaneous, but for larger cities it’ll take more time. In that case Blender will freeze while SceneCity works in the background. The only way to see the progress is to open Blender’s console (on Windows it’s in the window menu -> toggle system console) and watch the progress report. You must open it before clicking the button to create the roads.

The last node created “virtual” instances of the road portions because we set it to dupli verts. So here is what it created in the scene

Under a parent named like the name prefix you set (Roads), you have all the different objects that make all the road portions, which in that case are the three object collections. The created object hierarchy setup is for dupli verts, a method of object duplication in Blender: it places a virtual copy of the same object at each vertex of a mesh (note that duplication and instantiation are interchangeable terms). By virtual I mean that the copy only exists for rendering, and cannot be manipulated like a regular object in the scene. It’s the most efficient duplication method Blender has, performance-wise and memory-wise. On the other hand each instance cannot be manipulated individually. For that you need the second instantiation method: individual objects.

The second instantiation method, individual objects, creates objects sharing the same datablock. It has the advantage that you can do much more with an object than with the dupli vert method: transform them (move, scale, rotate), change their datablock, apply modifiers etc… It is however a much much less efficient method, it cannot scale at all beyond a few hundred objects, so in practice it should not be used or only for a limited set of object instances.

DO NOT enter edit mode for the meshes used to place the instances (they have dupli positions for in their name). Doing so will reset the rotation of all their vertices, and therefore of all the associated instances.

There are additional instances that look out of place, at the origin of the roads. DO NOT delete them, they are necessary and part of the dupli verts setups. They won’t appear in the renders, only in the viewport, that’s the way dupli verts works in Blender.

Adding the buildings

This step is a lot similar to the roads.

In the previously imported collection having a name like asset instances, look for the buildings instances, already created for you.

The buildings are complex models, each made of several objects. One way to let SceneCity instantiate them is to input an instance object of each building into the graph (in the objects getter nodes). Another way is to input the parent objects for each building, so they must form a hierarchy for that second method.

In the city graph, add two new nodes:

  • Objects ==> objects getter

  • City buildings ==> static building

Then copy/paste the name of the first small building, and set its size to 1 grid cell by 1 grid cell. Remember that our grid is set to 10 meters per grid cell, and the included buildings, just like for the roads, have been modeled in increment of 10 meters for their X and Y sizes.

With these two nodes you have just described a building of 1 cell on X by 1 cell on Y, from an existing Blender object. Do the same for all the other buildings. Don’t forget to set their size correctly. You should have something like this:

When extending the graph, copy and paste the existing nodes (and the object names from the properties panel, when object names are needed), it’ll be much faster.

Just like for the roads, add the following nodes:

  • City buildings ==> buildings collection

  • City buildings ==> buildings instancer

Connect all the buildings to the collection node. This will allow them to be used as a group. It’s very similar to the collection of roads.

On the instancer set the district to comm (short for commercial) because that’s the kind of district the included buildings are made for. If you changed, or will change, the key and/or value for the districts, don’t forget to set it here also. For instance, if on the layout node, instead of district you set block_type as the key, and instead of comm you set commercial as the value, then enter block_type = commercial on the instancer node.

By default the buildings will orient to the roads. Again if you changed the key / value pair of the roads, you must set it here as well, otherwise the buildings will have random rotations, and not be facing the roads.

Finally we just need to add an object instancer node:

Set it to dupli verts as well, and specify the name prefix of the future objects. Create the objects.

Your viewport may be slow at that point, when there are too many objects visible in the scene. Even with dupli verts, Blender is not optimized to efficiently draw lots of objects in the viewport. Fortunately this is not the case when rendering with Cycles, it is extremely optimized and won’t break a sweat even with buildings stretching to the horizon. To fix the slow viewport issue, you can simply hide the objects in the viewport, from the outliner.

Only the commercial buildings are present. The other districts (residential and industrial) are missing because we haven’t specified any buildings for them yet.

Congratulations, you have roads and buildings! All fitting together nicely. But wait a minute, there are holes in the city, empty districts. That’s where the other district types are: residential and industrial. We haven’t taken care of them yet, and that’s what we’re going to do next.

Using / creating your own buildings

Up to this point you have been using the assets included with SceneCity. Now you’ll learn how to create and use your own. There are a few easy conventions to follow for SceneCity to use your assets. The hard part is in making great asset though ;)

First, a building can be a mesh or an object collection. But in both cases, in the end it has to be in the form of a Blender object, so you can feed it to the Objects getter node we saw earlier.

Secondly, you have to decide what size it is, in terms of grid cells and so in Blender units. The smallest building in this tutorial is 1 cell wide by 1 cell long, which is equivalent to 10m by 10m (1 meter equals 1 blender unit by convention) because the grid node is set to 1 cell = 10 meters. A building can be of any size: 1x1 cells, or 2x2, 4x2, 10x20, etc…

Thirdly the mesh or collection origin must be at the exact center of the building on the XY (horizontal) plane. For instance a 10mx10m building should have its bounding box from -5m to +5m on both X and Y. A 20mx40m building would have its bounding box from -10m to +10m on X, and -20m to +20m on Y. On Z, zero is the ground so you shouldn’t model anything below it, though you can if your city has no ground or if you need underground details. In all cases the buildings can be as short or as high as you want.

And lastly the building’s front side must be facing its local positive x.

Start modeling it if it’s a mesh, or arranging the objects together if it’s a collection.

Here are 2 simple example buildings, as object collections, I modeled for the sake of this tutorial:

First I modeled a simple base mesh. Notice that the centers (the two little dots) are at the center of the houses, this is crucial! Then I modeled a fence mesh, duplicated and placed several instances all around the houses.

Finally I grouped the objects together into collections. One collection for the small house, and another for the larger one.

A common mistake with collections is to move the objects of the collection around, as a whole, but forgetting to also change the collection's origin. The typical symptom, if you forget to do that, will be buildings that look out of place in the city. Although the buildings instances’ origins will be correctly placed in the city, the objects inside the collection are not correctly centered around their collection’s origin.

Make sure that the collection's origin is set to the center of the building. And this must be done each time you move around the objects of the building, as a whole. Of course simply moving props inside the collection, like a fence object, does not change the center of the building, so in that case the group origin stays the same.

You’re not limited to buildings with the same dimension on both axes. You can have a 20 by 40 mansion for instance:

Once you have your residential buildings models ready, you add them to your city graph, just like you did before in this tutorial.

At this stage you have two objects instancer nodes: one for the commercial buildings, and one for the residential buildings. You can keep the graph like this if you want, so you can create / delete each district type separately and use different instantiation method if you need.

Another option is to have only one instancer node no matter how many districts you have. This is useful to create or delete them in a single action. It’s done with the Objects add node (found in the City objects category), like this:

Either way, create the buildings instances in the city, and you should have something like this:

The residential districts added, with simple houses modeled for this tutorial. The industrial buildings are still missing.

You know how to make and use your own buildings with SceneCity. An exercise you can do is to model your own residential and industrial buildings, then add them to the city, or create entirely new district types of your own.

Using / creating your own road portions

Two types of Blender entities can be used for the roads: meshes, and collections of objects.

There are 3 road portion types you must create. Just like Lego blocks, the road portions must fit together to give the illusion of continuity from a portion to another. To achieve this, you must follow certain conventions when creating your models. SceneCity will then instantiate (meaning creating copies) and place the instances in the scene to form the entire network. It will assume you follow the conventions properly. If you don’t, the network will look odd.

The portions must follow a few conventions common to all of them, and some specific to each.

Common conventions:

  • A portion is 1 grid cell wide by 1 grid cell long. (In future versions this limit will be lifted)

  • Just like for the buildings, the model or collection origin must be at the center on the XY plane.

  • Local Z=0 is the ground level.

Conventions specific to each road block type:

  • Straight: portion of a straight road along the local X axis.

  • T crossing: when 3 directions meet: along Y (+Y and -Y) and +X.

  • X crossing: when all 4 directions meet: along X and Y.

The number of lanes is your choice, but the more lanes you want, the bigger you must make the cells of the grid (again because a road potion can only be 1x1 grid cell), see the section above about the grid.

Completed

Bravo! You’ve been through major city-construction concepts. If you feel you don’t fully grasp everything, that’s okay. It may be a lot to swallow, especially in one session, and even more if you’re not a regular Blender user. What you need now is practice, if you haven’t done it along the way. So what you should do is to try and make your own city, and use this page as reference. And once it is done you’ll have all the knowledge necessary to use grid cities in your own projects.