0% found this document useful (0 votes)
96 views11 pages

Generating Lust City

Uploaded by

ergasca2025
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
96 views11 pages

Generating Lust City

Uploaded by

ergasca2025
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 11

Generating Lust City

“Lust wasn’t built in a day.”


Actually, it was.

The Full Graph - Cleaned so I don’t get made fun of

The approach to making Lust City was inspired by the city generations made by Jan Trubač. For a deeper
dive into the Substance side of this technique, see https://www.exp-points.com/jan-trubac-creating-a-metropolis
Substance Insanity - Creating a Metropolis

Lust, being an oppressive city filled with only skyscrapers, and the artstyle of ULTRAKILL reflecting a more
retro vibe, my Substance graph is very parred down. The unique contribution of this work is the process
of converting the output of this graph to a mesh.

Why not use Houdini or Geometry Nodes or whatever else? I’m good at Substance.
01
Road Generation

In the first node group, roads are initialized with a Voronoi pattern. To create a more natural structure
with bends in the roads (as if routing around an underlying landscape), a simple blurred box shape is
used to Directional Warp some of them upwards. It also makes it look less like Voronoi without much
effort. I don’t know why I made a single box with a Tile Generator, imagine I used a Shape.

A Flood Fill to Index, then Distance are used to inflate the cells. To clean up the warp, this is followed by
an Edge Detect. This step ensures all roads are of even thickness.

The second node group manually adds a few roads to slice up the city in more plausible and interesting
ways. The Bevel -> Histogram Scan is used to create roundings at road intersections.

Building Clusters

The buildings are generated in 3 steps. The first Tile Random node is used as a mask for where buildings
should not be generated. The Tile Random 2 takes in this mask and generates dense and uneven city
blocks. The Flood Fill Mapper then splats this texture, rotating it randomly for each “district” of the city.

The last step in this process is to get a binary mask of the resulting city, then calculate the minimum
BBox size of the buildings. A histogram scan is used to mask out the smallest buildings which tend to be
awkwardly sliced by the roads. An Auto Levels of the BBox minimum is multiplied with that.
02
Building Generation

This is the real meat and potatoes of the graph. I wanted a natural variation in heights, with a concept of
“districts”.

Under the assumption that things like financial/business sectors are usually smaller in landmass, but taller
in height, I used an inverted BBox size of the city districts to boost building height in smaller districts.

For the base height variation, I used a blending of Flood Fill to Random, the BBox sizes of the buildings,
and a Perlin Noise sampled such that there are smooth undulations from building to building.

The Perlin is likely the most interesting, and very simple. The Flood Fill to Position node basically spits out
the texture coordinate of the center of each building. In a Pixel Processor I use those same coordinates as
the texture coordinates with which to sample the Perlin. The result is a Perlin texture that’s spatially
quantized to the buildings.

As a last step, random buildings were given extra boosts in height. Care was taken at this step so that
only larger buildings could be made randomly taller, as tiny or thin buildings looked strange. Denser
districts also have a higher chance to create larger buildings.

In the making of the city, I previewed my graph on a subdivided plane, with normals and AO to aid the
visualization.
03
Color Temperature - A trick for later

This part of the graph was made after creating the city mesh, but is key to giving a lifelike look to the city.

Originally the city had a uniform color to all of the lights. This felt very flat, not giving a sense of depth or
purpose to the space. Building on the concept of districts, I assumed that the taller the building, the more
it should have the cool tones of commercial space lighting. Residential areas got nice oranges and reds.

To make this effect, I pass an adjusted heightmap into a Pixel Processor. It simply lerps between in two
color temperatures and produces the blackbody spectrum that would be emitted. I do a few additional
things to get the colors into a range that I like. Later, we’ll see how this texture gets used!

“Pixel Processors, for Fun and Profit” - Quark, Deep Space 9


04

Blender Decimation - A Better Way


A friend of mine, https:
Katja Linssen,
//www.artstati on.com/rhebko reviewed this document. She informed me that there’s a
better way to do what I’ll be describing in the following pages. I’m not a Blender user, so I
didn’t know about this at the time. Oops!

Basically, the steps I showcase will involve repeated decimations of a displaced mesh. The
idea here is that small decimation passes will act to preserve detail, while a single
aggressive decimation will quickly destroy a mesh. This is true across pretty much every
program, including the one I’m most familiar with (3ds Max). So it’s still a good tip!

Her advice was - after the displacement - to remove everything but the building rooftops,
then do a Limited Dissolve to remove everything but their border edges. Finally, run series
of limited dissolves with small angle values to slowly remove the jaggedness of the
buildings, resulting in clean shapes. I didn’t know Limited Dissolve could be used to clean
up borders like that, but I tried it out and it’s pretty cool!

This is in essence the same approach as mine, but is easier to work with and doesn’t
require the repeated “rebuilding” of the building sides that my process needed. I’ve left
the following part of the guide as is to reflect how I approached this model.

Enjoy!
05
Blender Decimation - Part 1
I experimented with a few ways to mesh the city:
Generate an SVG from the heightmap, Geometry
Nodes and data embedded in the texture to
generate from the texture. None were very good.

Given the simplicity of the city, I took the simplest


approach - Decimate a displaced mesh.

The first step was to displace a very subdivided


plane. If this crashes your computer, simply
download more RAM.

A first decimation step with triangulation is used


to remove the bulk of the polygons. This takes a
while to process.

We’re not trying to remove too aggressively here.


Just get it to something manageable.

Select Similar - Normal is used to keep only


rooftops. The ground is deleted. Small buildings
are removed with Select Similar - Area.
The roofs are extruded back down to create new,
clean walls.

Decimation is repeated over and over with small,


granular steps. Basically, single aggressive
decimation will completely destroy features that
matter. Small incremental ones will stack in a way
that actually preserve detail better!

The walls are needed to allow decimation of the


edges, but they occasionally will need rebuilds in
between the repeated decimations. Attention to
the mesh integrity is important at this stage.
06
Blender Decimation - Part 2
At a certain point, the mesh is looking very clean!

The volume of the buildings are well preserved,


lines are nice and consistent.

Some problem areas remain. A few rooftops have


stray extra verts, and some shapes feel “off”.
At this stage, I hid every rooftop that doesn't have
4 edges and got to cleaning by hand.

Embrace the incredible magic of manual cleanup. Don’t overthink it.

“Nothing wastes time like trying to save time.”


I don’t know who said this. Hopefully they weren’t a Milkshake Duck.
07
Texturing - It’s just Hotspot, but Vertex Colors too

The textures are just hotspot textures. Virtually everyone knows about them thanks to Source 2.
Credit where credit is due though, they didn’t create the technique!

The modern approach, using 45 degree normal map edges was actually made for Sunset Overdrive.
This isn’t part of the breakdown. I just wanted to shout out some inventive people.

Really, we’re all just using trim textures, a technique as old as time, with fancy tools to automate the
process a bit.

Here’s the 3 textures I use. Rooftops Color, Windows Color, and Windows Emission.
They're not too interesting, just simple graphs made in Designer. They’re not tidy either, so I won’t show
them outright. Sorry!

There are a couple cool things to touch on though!


08
Texturing Breakdowns
The Window Emission uses the same blackbody
radiator node shown previously.

To give more dimension, I multiply it with an RT


Shadows. It creates a natural directionality to the
window glows. HBAO was also used to soften it
further.

A common Designer trick is to use Directional


Warp on a texture to produce uniqueness per
“cell”.

I convert this Perlin to normals, giving each


window a unique and uneven reflection direction.

Some filters that come prepackaged with Substance


Painter are very useful in Designer.
For retro work I used Baked Lighting Stylized.

Dig around in Painter\resources\starter_assets

My Pixel8r filter is always the last stop for my


work. It’s used very simply on ULTRAKILL assets,
but is extremely powerful for any retro artstyle.

A bit of grain via Blue Noise dither, with Nearest


Softer sampling, goes a long way.
09
Applying Hotspots

I used DreamUV to apply the hotspot textures. Give it an Atlas Object, and just hit “Hotspot” for the faces
you want to map. The tool unwraps them to the most similar match in the Atlas. It would hang the
process if I tried to use it on the entire mesh at once, so be careful!

If you need a more complicated Atlas, they can be quads of all sorts of shapes. The only important thing
is that the Atlas Object and its UVs match.
For more detail see: https://www.artstation.com/artwork/oA55G4
Hotspot Materials: and you can too by Dave Face.

Vertex Colors

This is my favorite part. Remember that District Color Temperature map that was made back in Designer?

Top-down UVs are created, and the texture is sampled with them to produce the above image. It’s then
baked down into the mesh vertex colors. In ULTRAKILL, we use my new Master Shader which has a
feature to tint the emissive map with vertex colors. The shader has a number of controls for the blending,
intensity, and saturation of the effect.
Wrapping Up

With this approach, the Lust City took something like 8 hours to make, including fumbling around with
the failed approaches for meshing the Substance maps, questioning if I should have just used Houdini,
and a tasteful amount of watching YouTube slop with the Dev team.

Not bad!

Dillon Rogers made me write this breakdown.

- Victoria Holland

Check out my cool store where I make Substance plugins, including


Pixel8r, the thing we use for everything in ULTRAKILL.

https://actiondawg.itch.io/
https://actiondawg.itch.io/

You might also like