UDN
Search public documentation:
ProceduralBuildings
日本語訳
中国翻译
한국어
Interested in the Unreal Engine?
Visit the Unreal Technology site.
Looking for jobs and company info?
Check out the Epic games site.
Questions about support via UDN?
Contact the UDN Staff
中国翻译
한국어
Interested in the Unreal Engine?
Visit the Unreal Technology site.
Looking for jobs and company info?
Check out the Epic games site.
Questions about support via UDN?
Contact the UDN Staff
UE3 Home > Static Meshes > Procedural Buildings
UE3 Home > Environment Artist > Procedural Buildings
UE3 Home > Environment Artist > Procedural Buildings
Procedural Buildings
Overview
Defining Buildings
Building Groups
When working with a building that is not just a simple shape, it usually desirable to use multiple volumes. For performance reasons though, you should group these volumes together. This is done by choosing one volume to be the 'Base' volume, and then attaching other volumes to it using the 'Base' property. This can be made a lot easier using the Attachments Editor, or the 'ProcBuilding -> Group Buildings' option in the context menu. The 'Prefab Lock' button on the editor toolbar (the letter P) is also used to choose whether you are selecting entire ProcBuilding 'groups' or individual ProcBuilding volumes within a group. The 'Base' ProcBuilding volume in a group will show its wireframe in light green instead of the usual yellow, and can be quickly selected using 'ProcBuilding -> Select Base Building'. You only need to set the Ruleset on the Base building, as child buildings will inherit this. You can set it on child Procbuilding volumes if you wish though, to override certain areas of the same ProcBuilding grouping. Note that all meshes that are used for a single building 'group' are owned by the 'Base' ProcBuilding volume, so if you click on them in the editor, you will find yourself selecting that volume.Building Properties
The properties of a ProcBuilding volume are described below - more details on many of these are given later in this document.Ruleset | The ProcBuildingRuleset that should be applied to this volume |
---|---|
bGenerateRoofMesh | Whether a roof polygon should be generated for this building |
bGenerateFloorMesh | whether a floor polygon should be generated for this building |
bApplyRulesToRoof | If the Ruleset should be run on the roof of a building as well as the walls |
bApplyRulesToFloor | If the Ruleset should be run on the floor of a building as well as the walls |
bSplitWallsAtRoofLevels | If entire building group should be split horizontally at each roof level |
bSplitWallsAtWallEdges | If building faces should be split vertically when another face intersects it |
SimpleMeshMassiveLODDistance | How far away the building should transition to the low-LOD version |
RenderToTexturePullBackAmount | When generating the render-to-texture for LOD, how far to pull back from building (and clip detail) |
RoofLightmapRes | What resolution to use for lighting on the roof of the building |
NonRectWallLightmapRes | What resolution to use for lighting on the non-rectangular wall polys |
LODRenderToTextureScale | Controls the resolution of the LOD render-to-texture |
BuildingMaterialParams | Additional parameters that are set on MaterialInstances applied to meshes in particular building. Can be used for tinting walls etc. |
bBuildingBrushCollision | If collision should be enabled on the building volume itself |
Rulesets

- Break a scope into smaller scopes
- Place a mesh that takes up the space of the scope

Ruleset Properties
Once you have created a new Ruleset (in the normal way, using the Content Browser), you can open it in the Facade editor. With no rule nodes selected, the property window will show the properties of the Ruleset itself:DefaultRoofMaterial | The material that should be applied to the roof polygon of the building |
---|---|
DefaultFloorMaterial | The material that should be applied to the floor polygon of the building |
DefaultNonRectWallMaterial | The material that should be used on polygons created to fill in holes around wall scopes |
RoofZOffset | Offset applied to the roof (at top of entire building) polygon along Z. Note that RoofEdgeScopeRaise is usually a better way to form walls around the roof. |
NotRoofZOffset | Offset applied to roof (of any volume other than top of entire building) polygon along Z. Note that RoofEdgeScopeRaise is usually a better way to form walls around the roof. |
FloorZOffset | Offset applied to the floor (at bottom of entire building) polygon along Z. |
NotFloorZOffset | Offset applied to the floor (of any volume other than bottom of entire building) polygon along Z. |
RoofPolyInset | How far to pull 'in' the vertices of the roof polygon |
FloorPolyInset | How far to pull 'in' the vertices of the floor polygon |
BuildingLODSpecular | Controls overall specular of the building low-LOD version |
RoofEdgeScopeRaise | Extend any scopes that touch a roof up by this amount, forming short walls around the roof of the building |
LODCubemap | Cubemap texture to use for cubemaps areas (normally glass) on the low-LOD version of the building |
bLODOnlyRoof | If TRUE, a roof poly is only created for the low-LOD version of the building |
Mesh Rule
This is a very important rule, and actually adds a mesh to the building, using the size and location of the scope passed in. Meshes should always be authored so that the bottom-left corner is the origin, Z is up and X is right. You must specify how large a space you expect the mesh to take up. This is then used to adjust the size of the mesh to fill in the space that is provided for it. This allows you to have features (such as railings or trim) that extend outside the scope region that is passed in. Each mesh node supports an array of specified StaticMeshes called BuildingMeshes, and it will pick randomly from that list. The following settings are available for each mesh in the array.Mesh | The StaticMesh to use |
---|---|
DimX | The X dimension (width) of Mesh |
DimZ | The Z dimension (height) of Mesh |
Chance | How likely this mesh is to be picked from the array. |
Translation | An optional translation (or translation range) to apply to the mesh when placing |
Rotation | An option rotation (or rotation range) in degrees to apply to the mesh when placing |
bMeshScaleTranslation | If TRUE, the Translation specified is scaled by any scaling applied to the mesh |
bOverrideMeshLightMapRes | If TRUE, use OverriddenLightMapRes instead of resolution set on the mesh |
OverriddenMeshLightMapRes | Resolution to use for lighting on this mesh, if bOverrideMeshLightMapRes is TRUE |
SectionOverrides | Allows you specify, for each section of this mesh, a range of possible materials to apply as random overrides |
Occlusion Test
Another important feature that a Mesh Rule performs is to test if the scope passed in is intersecting another part of the building. Consider the image below:

Collision
By default, meshes used as part of a ProcBuilding do not have non-zero extent player collision (only zero-extent weapon collision). Player collision only happens with the volume itself (like a blocking volume) which has several advantages:- Collision is smooth and fast
- Collision does not change when the ProcBuilding's ruleset changes
Repeat Rule
This rule takes a scope and breaks it into a number of smaller scopes along an axis.

Split Rule
This node is similar to the Repeat Rule, as it takes a scope and breaks it into smaller scopes based on the defined SplitAxis. However, the Repeat Rule will generate a varying number of scopes depending on the input scope size, whereas the Split Rule will always (unless the input is too small) generate the same number of output scopes.
bFixSize | If TRUE, this output will be fixed to FixedSize. If FALSE, this output will expand as the input scope does. |
---|---|
FixedSize | Only used if bFixSize is TRUE, to define exactly how big the output scope should be |
ExpandRatio | When multiple entries have bFixSize set to FALSE, this controls how they stretch. A larger number means more stretching as the input gets bigger |
SplitName | This is used to label the output created on the rule node |
Alternate Rule
Some areas of buildings always start and end with the same feature, with another type of feature placed between. This is not easy to do with just Repeat and Split rules, so the Alternate Rule can be used.

bInvertPatternOrder | This option lets you start and end with a variable size B, instead of the fixed size A (ie. changing it from ABABA to BABAB) |
---|---|
bEqualSizeAB | If TRUE, forces A and B to be the same size |
Occlusion Rule
As was mentioned in the Mesh Rule node, it is sometimes desirable to perform an occlusion test on a scope. This Rule Node allows you to perform this test on any scope, rather than just before placing a mesh. You may want to, for example, test a floor of a building before splitting it up to make room for a central door.Top/Bottom Rule
Because each scope extracted from the building volume is processed by the same set of rules, you can sometimes get odd-looking features on more complicated buildings. If your ruleset put shops in at the bottom of each scope for example, upper areas of the building may end up with shop fronts, when that does not make any sense. To fix this, the Top/Bottom Rule Node allows you to test whether the top or bottom of the scope is the same as the top or bottom of the entire ProcBuilding volume group. The example below helps illustrate this:
Random Rule
The Mesh Rule already allows you to select one mesh from a set, but sometimes you want control earlier on in your ruleset, for example choosing a totally different look for a particular floor or face of the building. In addition, you might sometimes want to choose more than one option from a set. The Random Rule lets you do this. You first indicate how many outputs you would like using the NumOutputs property. Then you decide how many of those outputs may fire using the MinNumExecuted and MaxNumExecuted properties. Using this rule you can 'stack' meshes on top of each other in random ways, for example choosing a different A/C unit, sign and light for a particular area of the building. The pictures below show an example of this:


Quad Rule
Sometimes there are areas of a building where a flat quad mesh with a tiling material is the best solution, and this rule node allows you to do that. As well as adding a 2-triangle quad mesh to the building, this rule will also adjust the UVs to allow you to do tiling based on the size of the scope. This is controlled with the RepeatMaxSizeX and RepeatMaxSizeZ parameters, in a similar way to the Repeat Rule. Note that there is only one copy of the quad mesh in memory, and per-instance UV adjustment is performed using material instances. This is done automatically, but you must ensure that your base Material applied to the quad (using the Material parameter) supports 4 material instance parameters: U_Scale, U_Offset, V_Scale, V_Offset. There is a master material you can use as the basis for material instances applied to quad's called EngineBuildings.BuildingQuadMaterial. Below is an example of using a quad rule for one side of a building:
Sub Ruleset
When working with Rulesets, it is possible to create some quite complicated graphs. Also, you sometimes create parts of a Ruleset that you wish to use in multiple other Rulesets (for example, a particularly detailed shop-front area). The help with this, it is possible to create a SubRuleset Node, and use the SubRuleset property to point to another Ruleset. Whatever scope is passed into the node will then be passed into the start of that Ruleset. In this way you can keep each Ruleset small, and avoid some unnecessary duplication. Note that you should be careful not to create 'cycles', where Rulesets refer to each other.Size Rule
This offers you a simple choice based on the dimensions of a scope. You first pick the axis that you are interested in with the SizeAxis property, and then the size at which the decision will be made. If the scope dimension is small than this, then it will be passed out of the 'Less' output, otherwise it will be passed out of the 'Greater/Equal' output. The bUseTopLevelScopeSize option let you make this decision based on the 'top level' scope (ie. the entire building face size) instead of the scope passed in. The Size Rule can be used to avoid meshes becoming too squished. In the example below, the 3-window mesh is being squished and does not look good. The designer then uses a Size rule to use a 2 or 1 window version of the mesh when the space is small. The same is done with the trim work.
Comment
This special node does not perform any action, but allows you to put a box around areas of the Ruleset and comment them, in the same way as Kismet.Variation Rule
By default the Ruleset applied to a ProcBuilding is applied to all faces. However, it is sometimes desirable to have a different appearance on different faces. To support this, you can use a Variation Rule. To add a 'variation' to a Ruleset, you first have to select the Ruleset itself in Facade (you do this by deselecting all nodes). Then you can add an element to the Variations array, giving a name for that variation (for example 'PlainBrickSide'). Then, whenever you place a Variation Rule node in Facade, it will have one output for each new variation you created for the Ruleset, plus a 'default' output at the top. When the level designer wishes to use a particular variation on a face of the building, they simply do the following:- Go into geometry editing mode
- Select the face(s) of the building volume you wish to change
- Right click and choose the ProcBuilding menu
- Select the desired variation name from the list


Edge Mesh Rule
Is it sometimes possible to create a ruleset where the edges of each face are flat, and so corners just work naturally. An example of this is below:

Corner Rule
To get the best looking corners on buildings, it is often desirable to create a custom corner mesh to handle different angles between faces. The Corner Rule node was designed to make this easy. When using the Corner Rule, each scope is designated as 'owning' its left-hand edge. It will split off a portion on the left and right of the scope passed in, and pass the scope it makes on the left out of the output that most closely matches the angle between faces. On the right it will just leave a gap, expecting that area to be filled in by the scope around the building to the right.
FlatThreshold | If the angle between two scopes is less than this amount (in degrees), no mesh is added. |
---|---|
bNoMeshForConcaveCorners | If TRUE, no space is left or mesh inserted for concave corners |

Roof Corners
One problem that you run into when using curved or beveled corners is that the roof polygon (generated based on the ProcBuilding volume faces) does not match the actual shape of the roof. The fix this, you can specify some additional information in the corner node, and this will be used to reshape the corners of the roof poly. Note that the system finds the highest corner node to get this information.

CornerType | The shape of the corner - this can be EPBC_Default (the standard square corner), EPBC_Chamfer (diagonally cut corner) or EPBC_Round (rounded corner) |
---|---|
RoundTesselation | If the corner shape is EPBC_Round, this controls how much tessellation is used to round the corner |
RoundCurvature | This controls the shape of the rounded corner |
CornerShapeOffset | How far from start of curve mesh region to actually chamfer/round adjust roof poly corner |
Horizontal Splitting
In order to process a building, the system has to find which top-level scopes meet at each edge. This can be difficult when more than 2 edges meet at a single edge, as shown in the image below:


LOD

Windows
Buildings usually have glass windows, and this usually done with reflective cubemaps. As a result, the LOD needs a mask for the reflective windows or this will lose the reflection and create a very noticeable pop when transitioning. This is done automatically, but does require some setup on the meshes. The generate the low LOD textures, 3 rendering passes are made on the building. They are:- Unlit, to gather diffuse color
- Lighting Only, to gather lighting information
- Window Mode, where all windows are white and non-window areas are black


Streaming
It is often desirable to have the high-detail building (made from many mesh instances) in a different sub-level from the low-LOD, single section mesh. This is automatically supported by the system. When you add a ProcBuilding to a streaming sub-level, it will automatically generate a new sublevel, with the same name as the 'high detail' level, but with the '_LOD' suffix. For example, if you add a ProcBuilding to CityBlock_01, a new streaming level called CityBlock_01_LOD will automatically be created and a ProcBuilding_SimpleLODActor (which is just a subclass of StaticMeshActor) will be added to it. The reason for having the low-LOD in its own sublevel instead of in the _P map is so that areas of the city can be worked on without requiring the _P map to be checked out. As you edit the high-detail ProcBuilding, the low detail is automatically updated. It is usually a good idea to check both the high and low detail version of a city block Note that when adding a ProcBuilding to a map without sublevels, no LOD map will be added - the ProcBuilding itself will own the low-detail mesh.Attachments
When you attach a StaticMeshActor to a ProcBuilding (using the usual Base property), it will cause that mesh to be hidden when the building switches to its low-LOD version. This is usually desirable, as the low-LOD version will probably have a version of that static mesh rendered into its texture. When you place a StaticMeshActor (eg. an A/C unit) on top of a ProcBuilding, it will automatically attach itself to the building. This behavior can be disabled with the bDisableAutoBaseOnProcBuilding property on the StaticMeshActor.Transitions
Unreal Engine uses a dither approach to transitions/LOD. In order for this to function, however, you need to set the bUsedWithScreenDoorFade property to TRUE on any materials applied to building meshes (or meshes used on StaticMeshActors attached to the building).Other Features
Building Stats
There is a new tab in the editor which allows you to see stats for buildings in your city. There is one row for each building, and you can see stats for components, triangles and lighting and LOD texture memory usage. This can be very useful for spotting buildings that might need a simpler ruleset because they are very large, or Rulesets that may need their lighting settings adjusted or meshes simplified. Double-clicking on a row will take you to that building.
Material Parameters
It is possible to set parameters that you have exposed in the building mesh Materials on a per-building basis. To do this, add elements to the BuildingMaterialParams array on the ProcBuilding, and fill in the name and desired color for that parameter. This can be a good way to add visual variety to a city without creating a large number of unique rulesets. Below is an example of a row of buildings using the same rulesets, but with the wall color changed using this feature.
Overriding Materials
You can override the material used on the generated roof, floor or non-rectangular wall polys on a per-ProcBuilding basis. To do this, enter geometry mode, select the Material you want to use instead, select the face(s), right click and choose 'ProcBuilding -> Apply Material (MaterialName) To Face'. You can clear all per-face Material overrides by right-clicking on a building and selecting 'ProcBuilding -> Clear Material Face Assignments'.Meshing Roof & Floor
As mentioned earlier, by default meshing rules are not applied to roofs or floors of buildings. However, there are some cases where this is desirable (for example, adding supporting beams under a bridge-like building). There are two modes of doing this. Setting bApplyRulesToFloor or bApplyRulesToRoof on the ProcBuilding will actually enable a scope being extracted and rules being run on the roof and/or floor area. There is an additional option within the Ruleset variation settings called bMeshOnTopOfFacePoly. Enabling this will make the system generate the usual floor or roof poly, and then apply rules on top of this. An example of this can be seen here, on the underside of the walkway: