Learn how to add variation to a modular building. Create a procedural material in Unreal, for both static and instanced meshes
WarningThis website and its contents are work in progress. In the meantime, please visit the YouTube channel.
Constructing a building procedurally with Blueprint is a tempting idea. Using standardized modules and automatic placement makes a lot of sense. It’s architecture, after all. But how can we texture it to get a natural variation instead of repetition?
The building was made from just 1 module, copied automatically in the Construction Blueprint. The idea for the material was to require almost no manual input. There is only 1 material for the entire building (except the windows). All of its parameters are controlled within a material instance and make use of mesh’s vertex color. It has a dirt layer that covers the object only up to a certain height. The color of items is randomly chosen for every floor and segment. The position of small items is also randomized slightly. The color of walls is adjustable, as is the amount of damage.
Vertex color as data
Meshes in Unreal Engine store a color value which can be different for every vertex. When shading a triangle of a mesh, the color is interpolated between the vertices. You can either paint it in a 3D editing software or using the Paint tab in UE. The advantage of doing it in the engine is the ability to customize a single instance of a mesh. This use case is explained in the vertex painting tutorial. Here, however, I stick to the imported color. That’s because I use the RGB channels as precise masks that drive randomization.
Remember than in 3D graphics a color is just a three-component vector. Its components are the brightness of red, green and blue – but you can think of them as a collection of three numerical values. The meaning is arbitrary. As you may have noticed in Unreal Engine’s color picker, each slider sets a float number between 0 and 1 (though there is no limit for setting a higher value). So vertex color is just data. Instead of using it directly for colorizing the textures, I decided to pack masks (with value between 0 and 1) into each channel.
In the case of this material, the red channel is a mask between the primary and the secondary color of wall paint. Polygons with the zero value in this channel will be covered with the primary color only, while those with full red value will use the secondary color parameter.
The green channel is used for choosing a color from a palette. This is meant for smaller items, like the drying clothes and socks. I want the value of this channel to be random per item – so identical for an entire cloth, but different for another one.
The shader also moves vertices sideways, with different offset per segment, to add randomness to the position of items like the air conditioner. The strength of that offset is multiplied by the value of the blue vertex color channel. It means that 0 should be used for walls (no movement), while a value up to 1 can be assigned to an air conditioner or to clothes.
Assigning vertex color ( 03:34)
Every major 3D editor provides a feature for painting vertex color. You should be able to easily find instructions for your tool of choice. Just remember to tell Unreal Engine to Replace vertex color (instead of Ignore) in the mesh import window.
As I mentioned, the color in the case of this project is a collection of precise values. For a task like that – and virtually any technical task in game art – I prefer Houdini. It’s a 3D modelling and simulation package that has procedural approach at it’s core.
I split the entire process of assigning values to vertex color channels into a separate tutorial: Store data in vertex color using Houdini. In the tutorial I make use of several clever tools in Houdini to make the process efficient. However, a similar result should be possible (just with more effort) in any software. Just focus on what each color channel was supposed to mean for the shader.
WarningThe remaining sections of the tutorial are work in progress.
Construction Blueprint ( 07:57)
Material: noise, texture packing and mixing ( 14:22)
Height-based dirt. The Remap function ( 18:00)
Using vertex color to control material’s features ( 21:16)
Randomizing colors, hiding elements ( 22:55)
Applying local position offset ( 27:08)
Screenshot of the final setup:
You can download the project files for free (or a donation, if you like) from the Products page:Asset files from YouTube tutorials
- Easy Way To Pack Textures Into RGB Channels — How to save 3 grayscale textures into channels of a single RGB image, using just Photoshop. Packing allows to save space and, most importantly, retrieve 3 textures with a single read. This is worth the effort because reading textures from memory is one of the most time-consuming operations on the GPU.