comfyui_pcg docs

City block#

A whole city block built only from face operations and groups, without a single hand-placed point: 81 lots with streets and sidewalks, buildings extruded by a per-lot height, setback towers on the tall ones, window grids, shopfronts, parapets, rooftop units, street trees and per-building colours.

The city block in the studio preview

Load it#

Drag example_workflows/pcg_sop_city_block.json onto the ComfyUI canvas and press Queue. Only comfyui_pcg nodes plus ComfyUI's Preview Image are used.

Step by step#

1. Lots (first column)

  1. Grid (PCG) (108 x 108 m, 10 x 10 points = 9 x 9 cells of 12 m) is the street grid.
  2. PolyExtrude (PCG) with distance 0 and inset 1.4 only insets each cell, which leaves room for the streets. Blast (PCG) keeps the inset faces (group extrudeFront): 81 lots.
  3. A Wrangle (PCG) running over primitives computes per lot height (taller towards the centre, randomised with rand(@primnum + ...); in primitive context @P is the face centre), crown (0.35 x height) and the integer lot id.
  4. Another PolyExtrude (PCG) (inset 0.9, distance 0) splits each lot into a footprint and a ring of sidewalk.

2. Buildings (second column)

  1. PolyExtrude (PCG) extrudes the group footprint by the primitive attribute height (Local Attributes on, Distance Scale height), writing the groups roof and walls.
  2. Group Create (PCG) with base @height > 28 creates the group tall; Group Combine (PCG) intersects it with the roofs (tall & roof -> setback).
  3. Those roofs are first inset (setback terrace), then extruded again by crown into towers. Two more Group Combine nodes collect all walls (walls | walls2) and all roofs ((roof - setback) | roof2).

3. Facades (third column)

  1. Divide (PCG) with Bricker Polygons cuts the walls into 1.6 m x 3.2 m window cells; floor lines line up automatically.
  2. Group Create (PCG) selects the ground floor by bounding box (y below 3.3) as ground; Group Combine gives upper = walls minus ground.
  3. PolyExtrude (PCG) recesses the ground-floor cells into shopfronts (inset 0.25, distance -0.5). A second one insets every upper cell and pushes it in (inset 0.45, distance -0.25) to make window frames and glass. Limit Insetting is on for both: the top row of cells can be only a few centimetres tall, and without the limit the inset would push points outside the cell (frames poking through the roof).
  4. A third PolyExtrude insets and sinks the roofs (inset 0.35, distance -0.8) to create parapets.

4. Colour and details (fourth and fifth columns)

  1. Wrangles over primitives pick one of three palettes per building by lot, light about 12% of the windows (rand(...) > 0.88 on the group glass), and colour shops, roofs, terraces and sidewalks; Color (PCG) nodes add the warm shop light and the sidewalk colour.
  2. Rooftop units: a Box (PCG) whose base is moved to y = 0 by Match Size (PCG), copied by Copy to Points (PCG) onto 90 points from Scatter (PCG) on the group roofin, then coloured metal grey.
  3. Street trees: a trunk (Tube (PCG)) and crown (Sphere (PCG) moved up with Transform (PCG)) are merged into one tree, then copied onto 150 points scattered on sidewalk (with relaxation so they are spaced out) and scaled by a random pscale from Attribute Randomize (PCG).
  4. A road plane, then Merge (PCG) of everything, Viewport (PCG), Geometry Preview (PCG) (1600 x 1066, Studio look) and Export Mesh (PCG) (pcg/city_block).

All colours are written on primitives (the Color nodes also use the class prim). That way every part being merged has Cd on the same class, instead of half point colour and half primitive colour.

Worth tweaking#

NodeParameterEffect
Gridsize_x, size_z, cols, rowsNumber and size of lots.
Lot WranglecodeThe height formula: how tall, how much taller in the centre.
Group Create (tall)baseWhich buildings get setback towers (@height > 28).
Dividebrick_size_x, brick_size_yWindow cell width and storey height.
Window PolyExtrudeinset, distanceFrame width and window depth.
Glass WranglecodeThe share of lit windows (> 0.8).
Scatter (roofs / sidewalks)count, rand_seedNumber of rooftop units and trees.

See also#