Saturday, June 13, 2020

Procedural City: Furniture for Building Interiors

I'm continuing to work on object placement within the rooms of 3DWorld's procedural buildings. First I need to show some updates to the furniture I added in the previous post. Then I'll get into the fun topic of toilets.

Books

The books in my bookcases looked pretty plain because they were nothing more than colored cubes. I've changed them into several cubes representing the front and back covers, pages, and spine. Pages are white and the rest of the book is colored. Now they look more like books and less like colorful boxes.


Bookcase containing colorful books with covers and pages.


Next, I added pictures to the front covers of some books. This applies to books in bookcases and individual books placed on desks and tables. These are the same set of pictures/images that are hanging on the walls of rooms. Maybe at some point I can find more book-like pictures online. Not all books have cover images.


Bookcase containing books with images on some of their covers.


A book on a table with an image on its cover.


The final step was to add titles to the spines of books. I should be able to use the existing text drawing system in 3DWorld to add titles. This is the same system I use for drawing text message overlays, the framerate counter, game stats, debug visuals, etc. Text is drawn one character at a time using a font texture atlas and and array of adjacent textured quads, one per character. That leads to a ton of geometry, but I only need to generate text for books in the nearest building.

The only question is where to get the book titles from. I did a lot of online research into text generation, but it doesn't look easy to create reasonable sounding book titles. The best I could come up with was a website listing 1000 (actually 997) must-read books. I used this list of book titles as a pool of available text labels for adding to the spines of books placed on bookcases, desks, and tables. Extra long titles are wrapped onto two lines of text. Titles use colors opposite on the spectrum from the book cover's color.


Books on a bookcase with titles randomly selected from 1000 real book titles found online.

Beds

I added beds to building interiors a few weeks ago. The first version of beds used textured cubes for everything, including the pillows. As someone pointed out, these made beds look like they were made out of Legos. I went back and replaced these 5 sided (bottom not visible) shapes with something rounder with more triangles. I used a 2D, fifth root power falloff for the edges with 25 square root (nonlinear) spaced samples in each dimension. This is more expensive to draw, but looks much better. Pillows now have a smooth curve that blends into the bed sheets below rather than having hard edges.


The pillows on beds are now rounded shapes rather than cubes.

Toilets

I finally got around to adding true instanced 3D models to 3DWorld's procedural building interiors. Up until now, all of the building interior models were procedurally generated on-the-fly when needed. (I don't count people and cars in this category because they're dynamic and not part of building interiors.) The main difference between room models and dynamic models is that the room models are generated as needed when the player is near a building, compared to people and cars which are all placed at scene load time.

I've been working on adding specific rooms to houses, starting with bedrooms in the previous post. Next on my list was bathrooms, which at the very least need a toilet. That's not something I can easily generate with code because toilets have too many complex curves. I downloaded a 3D toilet model online and got to work. I tried various experiments with this toilet model, some of which were interesting. I suppose the remainder of this post is going to be mostly about silly things I did with toilets.

First up, what happens if I use a toilet model for cars and pedestrians, and have 3DWorld attempt to animate the toilet as a person? Since the animation is procedural, it should in theory apply to any 3D model. Well, it did pretty much exactly what I expected, with hilarious results!



Are toilets furniture? I'm not sure, but it's time to add them to my procedural buildings. For now they're only added to houses. Maybe sometime later I can add office bathrooms. I'm categorizing them as "room objects" in the code, along with tables, chairs, bookcases, desks, beds, and lights. Toilets are placed in rooms categorized as bathrooms. Once again there are a large number of constraints on which rooms can be used as bathrooms. In fact, there may be more constraints for bathrooms than for bedrooms. Some of them are demonstrated below for amusement.

1. A room can't be both a bathroom and a bedroom:

The bedside toilet, for those who prefer not to leave the bedroom to use the bathroom. (The toilet is also probably too large and has been reduced in size after the screenshot was taken.)


2. A bathroom can only have one door, and it can't have stairs or an elevator in it:

All the privacy of having the bathroom at the center of the house and containing the stairs. At least the opaque windows give some privacy, right? (More on them below.)


3. Bookcases shouldn't be placed in bathrooms:

A bookcase strategically placed to allow for some light bathroom reading. Well, maybe it could be in reaching distance from the toilet.


4. Bathrooms shouldn't have an exterior door. We don't want visitors entering the house through the bathroom. (Sorry, I don't have an image for this one.)

There are also constraints on room sizes, number of bathrooms in a house, etc. I won't list everything because I don't have nice pictures of the other items.

Once all of these conditions are checked, it's time to place a toilet in a corner of the bathroom away from the door. This exposes another problem though. The toilet is often placed near a window, and can be easily seen through the window from outside the building. That certainly doesn't look right!


A properly placed toilet, except for the fact that it's next to a big transparent window.


Something must be done to address the lack of privacy when the toilet is placed near a window. So, what can we do about this? Real bathrooms use windows with frosted glass, swirly patterns, or glass blocks to prevent people from looking in but still allow the light to enter from outside. These windows have glass that refracts light in a complex way, distorting the light pattern to prevent people from seeing through them. They're often smaller than regular house windows as well.

I can't easily vary the size of windows per-room, and it's too expensive to create a proper refractive material. I'm not sure exactly how to do this in a way that looks right for all indoor and outdoor lighting conditions either. For example, the window should be bright in the day time when the sun is out and dark at night. I don't really want to have to regenerate the window when the room lights are turned on or the time of day is changed. I also can't make it partially transparent because then people can still see though the window. The best I came up with was adding a generic texture of an array of glass blocks.


I replaced the window with some frosted glass blocks to give the bathroom more privacy.


There are some minor issues here. The lighting/color is fixed, independent of time of day. It's that sort-of-light-but-not-bright color in between what you would get at night and what you would get during the day. The window is probably larger than it should be. Also, the blocks don't align with the corners of the window. Fixing the alignment is very difficult. The glass block texture is actually slightly behind the wall and covers the entire wall, which avoids having to figure out how many windows there actually are in this room and where they're located. It's also more efficient to draw one quad per wall rather than one per window, though there is often only one window in a bathroom. This is good enough for now.

I suppose I'll have to add sinks next. Maybe I can also add mirrors that have real reflections. I'm not sure what to do about the player's reflection since there's no player model, but I should be able to reflect everything else in the room.

7 comments:

  1. Funnily enough, the house I'm currently staying in has the master bathroom open into a tiny laundry room, which open onto…the back patio! So not *quite* a bathroom with an exterior door, but pretty close.

    ReplyDelete
  2. Interesting! Well, houses and buildings can really have any floorplan, so it's not all that bad when my building generator creates something odd. My usual rule is that if I've ever seen a building like that, then it's okay. The logic for placing everything is so complex! It's much more complex now than in this post from 3 months ago.

    ReplyDelete
  3. What monster puts books on the shelf without the spine showing?
    Typo: "to the pines of books"
    Have you looked at the Dwarf Fortress approach to book titles? It's a few madlib-style templates and a dictionary of vocab to choose from.
    I kinda liked the blocky beds better. The low-rez representation invites interperetation and imagination, where the smoother version, though it looks more accurate on it's own, makes everything else look worse by comparison.
    As far as "are toilets furniture", in the construction business, toilets are categorized as Plumbing Fixtures.
    The view out the window looks about the same brightness as the interior lighting. If it's day time, the exterior should be much brighter (like, a thousand times brighter, in absolute terms) than the interior. At night, it's a bit darker than what shown, depending on the phase of the moon.
    For the privacy windows, you could cheat by re-mapping the "exterior" view on to the glass blocks using the normal map. It won't be optically correct, but you'll get the light levels, and a refractive effect anyhow.

    ReplyDelete
    Replies
    1. I just wanted to add some variety to the books. Thanks for the fix, another typo that's a real word and not flagged with a squiggly red line.

      I did quite a bit of research into book titles and even posted a question on Reddit. The most difficult part is finding a good word dictionary to use. I didn't want to spend too much time manually creating one. In the end I found that using a list of actual book titles seemed like the easiest solution.

      Interesting. Someone else commented that the blocky pillow looked wrong in the previous post, so I changed them. I guess everyone has a different opinion on how these should look. Maybe I'll eventually make the bed smoother as well.

      I'm not using HDR rendering or textures, so there's a limit to the difference in brightness between outside and inside. I experimented with outdoor lighting, but then some other parts of the scene look wrong. Terrain and vegetation use different lighting systems. I suppose if I changed everything then maybe it would look better, but it's not clear exactly how to do that in a consistent way. The other problem is that increasing outdoor light levels too much will saturate the colors and look wrong. Decreasing indoor light levels instead will lead to color banding in darker areas. Maybe indoor and outdoor scenes need to be drawn to different buffers and combined at the end.

      Creating a or refraction map for bathroom windows requires an extra rendering pass, similar to mirrors. That might work, but may be too slow for rooms that have multiple windows, if they use different textures. That's a good idea though. I would have to find or generate a normal map for that window block texture. It might be something to experiment with.

      Delete
    2. I realized I can just increase the sunlight intensity to improve outdoor lighting. When I bump it to 2x it definitely looks better, with brighter building exteriors. If I make it much larger than 2x then everything looks washed out, so I guess that's about as good as I can make it with minimal work.

      I tried to make bathroom windows partially transparent, but that doesn't work. The draw order is wrong for proper alpha blending. I'll have to do some sort of render-to-texture or screen space postprocessing if I want that proper refractive glass block effect. I may be able to draw everything very low resolution, so maybe the performance won't be so bad.

      Delete
  4. Oh, also, if you stick with the super-low-poly aesthetic (like the blocky pillows) you could feasibly generate toilets parametrically.

    ReplyDelete
    Replies
    1. The pillows were only a placeholder. I've replaced them with curved pillows, which are generated using math. It was complex enough that I decided to use 3D models for nontrivial curved geometry.

      Delete