Friday, August 21, 2020

Procedural Buildings: More Room Details

This post continues my work on procedural room object placement from the previous few posts. I don't have too much new technical content to show this time since most of the work was in the details of room classification, room partitioning, object selection, and model placement. This is easiest shown with images. If you want to see the details, have a look at the 3DWorld buildings code on GitHub.

Here is an overview of the recent changes I've made. Office building bathrooms now have multiple bathroom stalls and sinks. Large office rooms are sometimes divided into rows of cubicles. Some office buildings have illuminated exit signs, and some houses have welcome signs above their doors. I assigned a room in some of the larger houses to be the library. I added kitchen sinks, and cabinets and counters with doors and handles. I added nightstands and dressers to bedrooms. I also finally started implementing interiors for the office buildings within city blocks, which is incomplete and not shown here.

I put a lot of time and effort into populating houses while leaving other types of buildings somewhat neglected. To start off, I decided that having a single toilet and sink in an office building bathroom was too little. We don't want to see the employees lining up in the hallways! These rooms often have a large amount of space, enough to fit several stalls and sinks. Each bathroom above a minimum size is now assigned a row of stalls with toilets and a row of sinks along one or both walls. I even had to add interior room occlusion culling to avoid drawing the hundreds of toilets and sinks in a large office building.

Office building bathroom with three stalls, two sinks, and a trashcan in the back corner. Yes, I need to change the floor from carpet to tile.

Some office buildings contain very large open rooms. It seems odd to place only a single table with chairs in the center of the room, or a pair of desks with chairs along one wall. The building where I work has many of the large rooms filled with rows of cubicles, and offices in the central area of the building. I modified the room population algorithm to divide some of the rooms above a minimum size into multiple rows and columns of cubicles, as many as could be fit while allowing all of them to be accessible through the aisles. Cubicles near windows have shorter walls to let in more sunlight.

Large office room divided into cubicles, some of them against the windows.

Very large office room with a center row of cubicles. Maybe it should have more than one light?


What else do buildings have? How about signs, both on the interior and the exterior. I added illuminated "Exit" signs, "Women" and "Men" restroom signs, and "Welcome" signs to some houses. Exit signs are visible in dark rooms and can be either red or green. I plan to add more types of signs to the exterior walls and roofs of buildings eventually.

This office has a green illuminated exit sign above the door. Others have red exit signs.


Office buildings look much more interesting now, though there's still plenty of work to be done. It's time to move back to houses. I really like the look of bookcases filled with books, and I put quite a bit of time into this feature. Up until this point, a room could contain at most one of these. I added a new room of type "library" to upper floors of houses that have a table with chairs and as many as five bookcases. The bookcases are currently all randomly sized and placed. Maybe later I'll go back and make their sizes and spacing more consistent with an organized home library.

Some houses have an upper floor library, basically a room with lots of books on shelves.


Kitchens with only a table, chairs, refrigerator, and stove seem too bare. Most kitchens have counters with cabinets above and below. Also, don't forget the kitchen sink! I added code to attempt to place counters and cabinets around the walls of the kitchen wherever there's space. Cabinets have upper and lower rows with many doors, each with a handle. Everything is formed from simple cubes, which makes it a lot easier to create these objects and fit them into the gaps in the room. Then I choose a location to cut a cubic hole into the counter to make the bowl of the kitchen sink. Sorry, no faucet yet.

A kitchen with table, refrigerator, stove, sink, counters, and cabinets. The sink is the hole in the far counter to the right of the stove.


Bedrooms were next. At this point they only contained a bed and possibly a bookshelf and/or trashcan. Bedrooms are the most common room in a house, accounting for nearly half the total rooms. Many of them are large and have plenty of space for additional furniture. I placed dressers and nightstands in bedrooms using code similar to kitchen cabinets. Each object has between two and three rows of drawers, with 2-4 drawers in each row for dressers.

I used the same rough wood texture as most of the other furniture. At some point I'll need to go back and add a larger variety of high quality wood textures that vary by house or room. Or at least vary the color and texture scale a bit.

Here are some example screenshots of bedrooms.

Bedroom with bed, dresser, and nightstand. These use similar code to kitchen cabinets.

Bedroom with bed, dresser, nightstand, bookshelf, and picture

A different bedroom with bed, dresser, and nightstand. The dresser has multiple drawer sizes.

I also attempted to add potted plants to living and dining rooms. The pots looked fine, but the plant leaves didn't work out well. I tried to reuse my procedural plant generation code that creates landscape vegetation, which was using a different shader from building interiors. Building shaders don't yet support full alpha testing and alpha blending. It's easy to enable, but will result in early Z (depth) testing getting disabled, which hurts the frame rate. Buildings have very high depth complexity when considering all of the walls and ceilings, and the fragment shader is heavy with lighting and shadow calculations.

After adding all of these new room objects, I found that it was easier for the player to get stuck. Some rooms had furniture placed close enough together that the player couldn't cross from one side to the other. My solution was to ensure there was a player diameter of clearance in front of most objects, meaning the side facing away from the nearest wall. This seemed to work very well. I can no longer find a room that can't be crossed. I wonder if the AI people can also navigate these rooms?