This page provides a technical breakdown for a MEL script which assists in modeling when using Maya.
At first my goal was to create a general modeling suite, but the project started to focus more and more towards city environment & architectural modeling.
After completing my internship with Pixar and working on Wall-E, I was inspired by the post-apocalyptic city in Act I. When returning to SCAD,
I decided to take the project in a new direction - procedurally generating a ruined, demolished city model without resorting to dynamic simulation.
Using this script, I can generate proxy city layouts within minutes and more detailed city environments within an hour.
The 7 minute (18 MB) video to the left demonstrates some of the functionality of the v4.0 script.
Animated Short WIP
After spending signifcant time developing the MEL script, it was refreshing to use it in a production.
Using the script, I was able to create the 1 1/2 minute animation above within a month. Considering that the modeling and shading were completed quickly, particular attention was given towards lighting, shot composition, and overall visual style. In this regard,
I'm very happy with how several of the shots turned out, but the pacing needs to be slowed. Also the characters are certainly the weakest aspect of the animation so far. For now, they serve as temporary placeholders which
will be replaced before the short is submitted to 2010 festivals. I hope to collaborate with an animator to overcome this weakness.
Even though I could have used the MEL script to generate a unique city model for every shot, I preferred to make small sections and set-dress
relative to the camera on a shot-by-shot basis. This approach minimized scene geometry and render times while allowing me to edit shot composition quickly.
Rendering at HD resolution (1920x1080), each frame averaged 20 minutes and never exceeded an hour on SCAD's renderfarm. Three passes (diffuse, ambient occlusion, and toon) were rendered for each shot and then
composited in Shake to create the final, non-photorealistic style. Mental Ray was used to render motion vectors and depth maps. These passes allowed me to tweak motion blur and depth of
field in Shake, but unfortunately, the motion vectors did not consistently render correctly. As a result, several of the shots above don't have motion blur applied.
The first thing I did was search for music that would help establish a visual rhythm. I spent time sifting through
orchestral music to find something with an epic feel. It was also important to find something with a pace that would complement the destruction
and rebuilding of a city. I decided on a song called “Fight for Glory” by Immediate Music.
Next, I used some of the test models and animations to create a rough animatic as seen below.
Once I was satisfied with the state of the animatic, I created a shot
breakdown to list exactly what needed to be done for each shot. This guide was extremely
important since I had to juggle every part of production in parallel and begin rendering
as soon as possible.
Normal Building and City Models
For additional building variation, I modeled ~30 new buildings in 6 hours and added them to my existing library.
Then I created the normal city model which is seen in the last shot of the short. Parts of this city were then reused for set-dressing in 9 other shots.
I would have preferred to spend more time adding more detail to each building, but time constraints were a concern.
City Growth Shots
The 6 city growth shots were created using the expression-driven animation approach tested in version 5.0. Unfortunately, this method created unwanted
artifacts that were visible only in the diffuse pass if the geometry had a Y scale value of 0.
This problem was easily remedied by slightly lowering the scaled geometry below the ground.
Since the city block height was miniscule compared to the height of the buildings, scaling their height was hardly noticable. Instead, I decided to use an expression to toggle
the visibility of the city blocks if they were within the radius of the animated locator so that they appear ahead of the building growth. I would have preferred to develop a
special shading effect, but there is only one shot where the block "popping" is obvious.
Cracked Building Shots
After completing the city shots, I fractured a few building exteriors for the 9 "crack healing" shots.
I found this process somewhat frustrating since Maya would crash if I tried to fracture too many objects at once.
The upper limit seemed to be about 80 Boolean operations which would take about 20 seconds. As a result, I moved back and forth
between two computer stations, working on one building while waiting for the other to finish its calculations.
To prevent the entire building from healing at once, I created a keyframe offset procedure. The procedure offsets all the keyframes of a
selection by the number of frames determined by an input. This simple tool made it very easy to add a ripple-like effect to the healing process so that the
buildings would appear to heal from the ground up.
First all the fractured pieces of a building were selected. Then I deselected parts of the building (as seen to the left) and used the procedure on the remaining
selection. This process was repeated as I worked my way up the building. If I needed to retime the animation, it was a simple process of selecting all
the geometry, double-clicking the timeline, and scaling
all the keyframes until the animation played as desired.
The video below shows the result of the offset process. The building on the left has had its keyframes offset while the building on the right has not. It should
be noted that the healing aesthetic is entirely contingent on the deselection pattern so a building does not necessarily have to heal from the ground up.
Jumping Debris Shots
After the "healing" shots were finished, I moved onto the 4 shots which involved "jumping debris."
The translation and rotation values of all the pieces were keyframed. This was done at the end of
the timeline to establish the building's "restored" state. Then the building debris was crumbled and keyframed at the beginning of the
timeline. The left lower video shows the result. The building on the right has had its animation curve tangents tweaked and keyframes offset. This process
took roughly five minutes.
All the concrete geometry was procedurally shaded with simple noise patterns to add some variation. After creating the array of shaders shown above,
I wrote a procedure which randomly assigned them based on naming conventions. (Concrete shaders to objects named "concrete#"; metal shaders to "metal#" etc.) Additional
shading tweaks were performed as needed on a shot-by-shot basis.
Shake was used for compositing for its flexible node-based workflow and ability to interpret Z-Depth and motion vector information.
The depth maps were used to add depth of field and atmosphere to several of the shots. The greyscale video demonstrates how the depth map can be used. Obviously it can be
used for fog, but blurring can be isolated to white areas for depth of field.
The image below shows how the different passes were composited together to form the final images.
I created a node network for each shot as seen below. After rendering each shot out as .tga's, After Effects was used for final editing to
ensure that the visuals would follow the timing of the animatic and music. However, I felt that the timing was off in this phase and the short had too quick a pace after
adding the camera moves. As a result, two shots were cut from the animation.
Lastly, final rendered frames from each shot were brought into Photoshop as reference when painting the sky backgrounds. The matte
paintings were kept simple yet vibrant to complement the visual aesthetic of the building models. Every sky image began from a two color gradient. Next, I
layered more gradients on top with blending modes and/or painted in some clouds using custom brushes. The image below shows some of the process.
While, most of my graduate school work has revolved around programming useful modeling tools, I’ve enjoyed revisiting my animation roots recently.
Consequently, I’ve decided to spend some time developing an animated short to showcase my script’s abilities and create any useful technical solutions towards its production.
The short will have several limitations considering that it will be a solo project, the production schedule is only a few weeks, and the MEL script is still a work in progress.
To narrow in on a topic and explore animation potential, I’ve created some tests dealing with city growth and building reconstruction from debris.
A logical use of the City Generator is to show a city growing. This involves generating a city model and then using an expression to affect the scale of its geometry.
The expression increments a building’s Y scale if it is within a certain radius of a locator. By using this approach, the locator is the only object which needs to be animated instead of tediously
key-framing the individual buildings. The expression is embedded into the locator so that it can be imported and used on any city model. The video to the left shows how the locator influences surrounding geometry.
Click the image above to see a rendered result.
Building Reconstruction Test Animations
Reconstructing a building from its fractured parts also creates an interesting aesthetic. The effect will have to be done quickly as not to draw
too much attention to the large amounts of geometry interpenetration. The “healing” effect (upper-left) is particularly interesting to fuse together cracks. This technique is used in the other two tests to
subtly accentuate the primary reconstruction method. Having the debris "jump" into place (upper-right) also creates a curious effect. Adding some squash and stretch to the debris and building could make them seem alive.
Swirling the debris and adding extra motion can create an interesting visual too but probably shouldn't be used to the exaggerated degree shown to the left. Performing a combination of these techniques on an entire city
should be entertaining and add to the visual complexity of the animation.
I’ve also added an animation panel to assist in the key-framing process. I often use the “s”
hotkey shortcut to key all the attributes of an object in the channel editor. Although quick and convenient, the extraneous keys can create unnecessary work when editing an animation. The panel I’ve added
consists of translation, rotation, and scaling checkboxes for each axis. This helped make the process of creating and editing the building test animations quick and clean.
I often use the graph editor to manipulate the curves of an animated object. This is particularly useful to create easing in, easing out, and other acceleration effects such as gravity.
Unfortunately, Maya doesn’t allow the simultaneous manipulation of tangents on multiple curves. This was a considerable problem when creating the test animations since I was working with so many objects.
To reduce time spent animating, I created a procedure which goes through all the selected objects, manipulating the curve tangents for me.
Improved Wire Support Mesh Procedure
In addition to animation solutions, I’ve improved a modeling tool which creates the wire support mesh found inside concrete structures. Previously, the procedure generated a grid of cylinders
wrapped in a lattice, but this created a result that was too uniform. The new version creates a result that is more imperfect and appropriate for city ruins.
First, geometry is used to determine where wire mesh will be created. A specially named cube determines the XZ bounds and selected geometry provides height values to create the wires. Next, grids of curves are
created and extruded into cylinders. After that, the curves’ control points are randomly offset to create irregularity in the wire mesh. Lastly, deformed geometry is used to cut the wire mesh unevenly using subtraction
This approach allows me to add ruined wire mesh detail to a building in a few minutes, but it suffers from a few problems. Since the procedure relies on Boolean operations, it requires significant user feedback
for the same reasons as the fracturing procedure faults stated in the version 4.7 write-up. Currently, all the curve control points are included in the random offset process. This can cause some of the bars to poke through geometry as
see in the example above. Also the wires can only be created horizontally at this point. An option to add the wire mesh vertically would be useful. Being able to parent the wires to debris would also be useful for animation purposes.
A few improvements have been made to the crumbling tool introduced in the previous update. I have added an option which causes the target locator to act as the center point of an explosion instead of an attraction point.
The equation y = mx+b is used to determine the direction selected geometry will be placed relative to the locator. The slope is determined from the
equation m = (z2 - z1)/(x2 - x1). Since the scene is Y axis up, the selection and locator's XZ coordinates are used. A user input determines the distance from the locator per button click. This approach creates
a spread effect which was lacking in the previous 4.8 version. Factoring in falloff values adds a rounding, bubble-like aesthetic to the debris dispersal pattern.
The image to the left demonstrates how the crumbling tool works when the locator mimics the center point of an explosion instead of an attraction point. The selection consists of about 1300 objects which results in a real-time processing delay of about one second per button click on a
2.4GHz Pentium 4 machine with a 1 GB graphics card and 2 GB of RAM.
The fractured building being crumbled has a few external and internal support columns. Although it's tempting to quickly select everything, I've found that crumbling columns as a final, separate step ensures that fractured walls, floors, and ceilings
appear supported. A future update may include more selection tools to make this process easier.
A procedure has been created which helps prevent geometry from unnaturally standing upright. The procedure chooses a random rotation value and only rotates the selection if its bounding box height decreases
- equivalent to an object rotating to lie on its side. For now, the rotation value is random for procedural variation, but this sometimes results in several button clicks before a selection actually rotates in the correct direction. Rules will be implemented in a future version to fix this workflow flaw.
Also a button has been added which drops all selections vertically so manipulation of XYZ influence inputs can be bypassed if the user doesn't wish to deal with them.
The fracturing procedure has also been improved. In version 4.7, the fracturing Boolean noise planes were placed perpendicular to a selection, but random rotation was still allowed in the XYZ directions. I have added an option which limits the random rotation axis so that
the Boolean noise planes will always remain perpendicular. Also the noise planes will always make cuts across the side with the shortest width. These rules were added for cleaner cuts and to reduce the possibility of creating thin slivers or unusually small shards.
A new selection tool has also been created to help streamline the crumbling process by quickly selecting objects with similar naming. A selection's name is truncated based on the "_" character,
and an integer input determines the name selection criteria. For example, a piece of fractured geometry with name Building12_Wall7_Shard23 and an input of 2 would result in a selection of all geometry beginning with Building12_Wall7 (select -r "Building12_Wall7*").
Title Image Analysis
Version 4.9's title image may seem like just a large mess of debris bits, but it's actually an analysis in level of detail. In this test, buildings with different attributes and face-counts are analyzed at various distances from the camera.
The color-coded image above distinguishes the three types of buildings used.
The green buildings are ~2400 polys and only consist of outer wall geometry - no interior details have been generated and fractured geometry is left into relatively large chunks. These simple ruins add a decent amount of detail at a low face-count cost. The results are best when
all the geometry is thoroughly fractured and crumbled. For example, the buildings in the upper left look horrible, but the ones in the lower right look decent.
Blue mid-res buildings are ~32,000 polys. Floors are added to these models. They provide scale and inner detail which improve believability. These buildings look interesting when sections are ripped out, but not as believable when entire halves are exposed.
Supports are necessary if that much demolition is done.
Red hi-res buildings are ~73,000 polys. These models have walls, floors, and basic columns to fake internal and external supports. When dealing with this much geometry, it should be used to its fullest. For example,
the foremost building should have been ruined further for additional aesthetic interest and to provide more material to set-dress into the environment. The fact that it looks similar to its blue neighbor is a sign of wasted detail potential.
Putting aside level of detail, the 4.9 script can create a debris-filled, ruined city model, but metal details are lacking. Tools to add and manipulate building supports, street signs, and other non-concrete detail will add believability. Also
remnants of a highway system would complement the model's visual complexity.
To tackle the problem of faking dynamic destruction and adding believable debris, I've begun development of a new crumbling tool in an attempt to mimic simulated results. Although dynamic simulation can provide physical accuracy, the processing time
can be extremely expensive, especially if simulation needs to be performed across an entire city. Also considering that I ultimately wish to create a believable but not physically accurate post-apocalyptic city model, it's logical to try and code a solution which doesn't rely on
After fracturing such geometry as a building's wall, I needed a solution which could collapse the newly fractured shards with some degree of control. First, I required a way to manipulate the direction of the crumbling and collapsing of a selection.
After all, I may want to create the illusion that walls or floors exploded outwards or inwards. I resorted to using a specially named "Crumble Target" locator which works fairly well. By determining the difference in XYZ positions, the selection(s) can be translated towards the target
locator fairly easily. Unfortunately, this method alone causes selections to bunch up when approaching the locator so more rules need to be imposed.
To help prevent this unwanted effect, I added height and width falloff inputs. By implementing falloff, the fractured shards more believably mimic the movement from an explosive force. The examples to the left show the different effects that can be
achieved by adjusting the falloff values. Each frame represents a single mouse click and is performed virtually instantaneously if the selection is kept to a reasonable amount. An input for movement threshold can be adjusted to automatically deselect any object
which doesn't move above the threshold value. By using this in conjunction with falloff, an irregular hole can be left in a wall without manually deselecting objects. Also the user can adjust the amount of influence in each of the XYZ directions and the amount of random rotation.
If gravity is taken into account, selections will never drop below the Y value of the target locator.
At this point, the crumbling tool works decently well especially if the locator is placed perpendicular to the selection. However there's still room for improvement. For one, an option to use the locator as a direction instead of a target point would be useful.
This would allow the fractured shards to spread out in the locator's general direction instead of clumping together when reaching the target. It would also help create a better result when selecting multiple walls and positioning the target diagonally relative to the selection.
Geometry interpenetration is also an issue so a volume detection procedure would be useful.
Recently I've been pondering how to quickly demolishing all the buildings in a city in one swoop. This would involve detecting every object in the scene and appropriately
calling the correct procedure to manipulate it. Established naming conventions allow me to do this with some degree of control, but I've realized that this goal is actually quite foolish. Despite being able to say that the script
can generate a demolished city very quickly in so and so minutes, over-proceduralizing this demolition phase could easily waste time in a similar way as a simulation with incorrect values. Even though my fracturing procedures work
quickly on one building, the calculation time exponentially grows when increasing the number of operated objects and shard count. Testing has lead me to believe that the tools of this phase need to have more artist input
than I previously anticipated.
Version 4.7's main addition is web-pattern fracturing. Using a cylinder with noise applied to it, irregular-shaped concentric holes can be easily cut into geometry. This helps to create the illusion of an impact
when used with the shatter effect of the previous script. The user selects what is to be factured and clicks a button which creates a specially named locator at the center of the selection. Next the user can adjust the position of the locator which acts as
the center point/target of the web-pattern. After fiddling with some values such as max number of rings, the user selects the target geometry and clicks a button to fracture it.
Preview buttons have been added so that the user can see roughly how irregular the fracturing geometry is from the frequency and amplitude noise input values. There are buttons to view both the noise cylinders (circlular cracks) and the noise planes (jagged cracks).
Also a new procedure makes sure the fracturing geometry always starts perpendicular to the selection for a cleaner cut. The image to the left shows the effect of the procedure without randomizing rotation values afterwards.
Initially the development of this tool ran into some problems. The solution seemed simple enough: Use noise planes to cut the select geometry like before only instead of moving the plane to the center of the
largest, newly-created shard, keep the plane in place and rotate it. Once there are a few shards, a checking procedure/method is necessary to make sure the plane's rotation actually intersects with the piece(s) to be cut. One way to ensure this is to use the Combine() function to merge
the separate shards into one piece before the next boolean cut. After the fracturing process is done, just Separate() the geometry
into its individual shard pieces. The problem is that Maya merges vertices during boolean operations so the Separate() function will always yield just two shards. One option now is to delete all faces which do not face "outwards" relative to the building. Then
separate the faces into individual objects and extrude for thickness. While this solution will work, its calcuation requires knowledge of "the outside faces" - something doable, but not easily implemented.
Ultimately this problem's solution became too expensive to simply get lines that automatically radiate out from a center point - something the user can do relatively quickly with another tool.
Maya's unpredictability when using booleans has also made user feedback necessary during the fracturing process. When using booleans, there are three options: union, difference, and intersection.
Surprise, surprise, these options don't always give predictable results. The image to the left shows the flawed & correct versions. To solve this problem, I've added a boolean switch to the interface which defaults to union operations
(works 80% of the time). If this causes undesirable effects, the user can undo and switch the operation to difference or intersection; whatever gets the job done. Although this solution is simple, it still hinders workflow efficiency
and makes it a bit sloppy. Until I gain a better understand of Maya's boolean operations or they are improved in newer versions, this approach will have to do.
Many of the tools I have developed rely on a standarized naming convention. The fracturing tool currently takes the name of the original object and adds the suffix "_Shard" to any fractured pieces.
Unfortunately this poses a problem if the user fractures a wall and then wants to repeatedly fracture the new shards into smaller and smaller pieces (pCube1_shard51_shard21_shard15_...etc). To prevent this, I will have to
take advantage of the Tokenize() function to truncate and analyze naming. I hope to implement this in the script's next version. On the plus side, this procedure is something I've been wanting to tackle but never found it too
critical. Once I have naming detection working, I should be able to create a procedure that selects all objects with similar naming. This should prove very useful during the selection and demolition process.
Next up: Faking dynamic forces and tackling debris.....yikes....
My latest work has been focusing on procedurally converting a normal building structure into one in ruins. For testing, first I created a simple building structure
with different types of extrusions and angled walls. The quickest way to create walling that conforms to the topology is to simply extrude in local -Z. The downfalls of this approach are that all the walls,
floors, and ceilings have the same thickness, and some cracks unnaturally traverse the entire building. (Lower left example) Another approach involves detaching all the faces of the original, extruding them in local -Z, and
then separating the newly formed pieces of geometry. Naming conventions can be established from the normals of the original faces. This approach creates more building sections to work with meaning more control.
Unfortunate some geometry interpenetration occurs when two non-perpendicular walls meet and some unnaturally flat surfaces occur where walling meets. (Lower right example)
The user can use either or both of these techniques to create different effects. Click on the images for larger examples.
With walls, floors, and ceilings now created through extrusions; I wanted to control the demolition without resorting to simulation. Maya 2008 has a shatter function, but it lacks a lot of control. One major
shortcoming is that the function often creates tiny chips of geometry with an unreasonable face count. I tried creating a procedure where the shatter action is redone if pieces aren't above a minimum surface
area, but this procedure crashed Maya. From the testing I did in the version 4.5 script, I thought of subdividing the geometry and then procedurally handling the vertex manipulation to shape the
geometry into random demolished-looking shards. Unfortunately getting a believable result with this approach was difficult. Ultimately the solution that worked the best turned out to be
very simple - using booleans.
By using deformed planes in boolean union operations, I have complete control over shaping a crack with visual feedback. The deformed plane uses frequency and amplitude inputs to determine it's noise pattern.
When I proceduralize the process to create multiple fractures in a wall, the script recursively performs the procedure on the largest fractured shard by comparing surface areas. To make the cracks more visually prominent,
each fractured piece is randomly offset by a few inches. This approach will work on any type of building detail - window frames, door frames, columns, etc.
At this point, decent ruined buildings can be created from normal models fairly quickly ~1-2 minutes starting from a normal building model. However there is still much room for improvement in workflow
and more tools need to be created. 1) Establish presets or rules for the deformation values of the cutting planes. The frequency and amplitude values need to relate to the scale of what is being demolished.
Good values for a small residential wall will look like a straight line on a skyscraper. Also the resolution and noise of the plane determines the crack edge jagginess which relates to the type of wall material.
2) Random deletion of shards needs to be supplemented with some rules. It doesn't make sense to delete a large bottom shard if it supports the ones above it.
3) Different fracture patterns need to be created. Besides the random cracking pattern, a spiral crack pattern should be easy to implement with a similar boolean approach.
Curving roads!!! I've finally found a decent solution to deform the city blocks. The answer begins with a 3x2x3 lattice (white lines) applied to a subdivided block. Clusters are
attached to the corners of the lattice, and the clusters are parented to road locators. Intersection type is recorded using custom attributes on the locators.
Proxy buildings are now created through appropriate scaling and extruding of face-up polys. Now the buildings can take on the shapes of their blocks - a major problem I've been trying to
solve. This approach, however, will require me to develop a better way to detect shapes. Many procedures are reliant on bounding box and rotation information. These will have to be replaced with ones that
analyze edges and face normals.
The image to the left shows random translation of block corners within a small radius. Too large of a radius and the geometry pinches on itself. The image to the right shows a result after
a few rules are imposed. Obviously more work needs to be done for smoother directional changes and consistent road width under extreme curving. Also researching road patterns should help me improve the results.
To begin modeling a ruined or post-apocalyptic city, giving buildings a random rotation in XYZ is a good start although there's definitely a sweet spot in relation to the dimensions of a building
and the amount of rotation towards the horizonal. It seems that less rotation is more believable but more rotation (image to the left) leads to exaggeration and is more interesting.
For now, inter-penetrating geometry does occur, but isn't a huge problem with a few minutes of manual adjusting and light rotation values. I have thought of a method to calculate if buildings penetrate
each other, but it may be too computationally expensive. I will continue testing and thinking of other approaches.
City ruins or post-apocalyptic settings are usually visually associated with things like piles of debris or exposed support structures like girders. These details
are necessary for believability but don't really matter much overall. Since the debris and girders probably won't be visually scrutinized too much, a procedural solution should work well.
Introducing the junk pile tool! To quickly create piles of rubble, the user moves an object to a desired height. This will serve as the pinnacle of the pile. If the user wants to create a pile composed of several
models, he just needs to shift-click them afterwards - see demo video to the left. The user controls the slope of the pile, number of models in the pile, and if a proxy "filler" cube is placed at the center of the pile. More work will be done to reduce the amount of inter-geometry
penetrations, but the results are reached quickly in comparison to setting up a simulation. I will continue trying to figure out ways to reduce geometry penetrations and optimize polygon use and pile coverage.
I've added some more functionality to the girder tool back in version 1.0. Instead of using polygonal extrusions that may lead to manifold problems, the new option creates a girder through positioning, rotating, and scaling cubes.
This new option is more favorable for dynamics, shattering, or close-ups. The user can select an object and randomly distribute proxy girder geometry within a certain radius from the selection. To help with visual cues, the proxy girders are automatically
shaded red. Once the position and scaling of the proxy girders are good, the user can run a procedure to turn all the proxies to full res. A future update will add I-beams as an additional option.
After much testing and fine-tuning, several building modeling tools have been improved. One of the major updates is that a selected object's rotation is now considered in most procedures. Adding a new piece of geometry on top won't add it to the top of the bounding box;
it will be moved along the selection's local space. Also a new procedure creates cylinders within a selection to mimic the metal bar weaving in wall and floor support structures. Another procedure creates a wall with a doorway.
The video to the left shows how a few tools can be used to model a ruined building. The 7MB video is 3 minutes long condensed from 30 minutes.
The video to the left demonstrates a building detailing tool that helps with the positioning of windows, columns, and roof detail. The user supplies window and column geometry,
but more importantly, a very basic shape of the new building. The proxy model of the building is analyzed per polygon as the window and column geometry get duplicated, placed, and scaled automatically. The new geometry is selected after the procedure
to help with immediate scaling adjustments. Once a few windows and columns are modeled, this tool can turn low-poly, background models to foreground, hero models pretty quickly. The 3.5MB video is 1.5 minutes long condensed from 20 minutes.
It should be noted that detailing process above was designed with ZBrush in mind. Highly detailed models of windows
and columns can be modeled, and then their displacement maps and low-res standin geometry can be exported for use in Maya with this script. I have yet to test this, but it should work fine. I will post images when I have them.
For a bit more realism, new buildings may have random Y rotations. The user controls how often buildings have rotation and what the maximum rotate value is. The image to the left shows that random rotation definitely helps, but complete randomness won't work.
Buildings need to be rescaled to fit their original bounding boxes. That way they won't run into the sidewalks, streets, or neighboring structures. It may seem more believable if buildings at corners of city blocks are favored for rotation. I will have to find a way to record corner info, but
it seems possible that the rotation of a building may be a good factor in determining if it should be an n-sided-poly instead of a cube.
Similar to the random spires of the previous update, the script can now automatically create a city with buildings composed of randomized cubes and/or cylinders. The result gives the impression of buildings with several
tiered levels and extrusions. These buildings are created by using a procedure similar to the city generator only that it ignores block structure and randomizes the distribution of geometry within a small radius. Since it's based on the city generator
code, the buildings can be affected by falloff.
To the bottom left are several variations of buildings and city layouts with different falloff values. I believe the lower examples which use the Phi ratio look surprisingly believable considering the short setup time ~ 30 seconds on a low-end dual-core laptop.
The image below shows a city after being imported into ZBrush. I have created 4 different sections to show some style diversity that can be generated just by changing a few
checkboxes and sliders values. The city model is ~ 100,000 polys; very reasonable at this point in regards to render times and scene density before more detail is added through general modeling, shading, and set dressing.
The image to the left shows a section of the city subdivided and textured green. With just a few levels of smoothing subdivision, a section of the city can start to form the impressions of vegetation.
Below to the left shows the model after a few displacing brush strokes. The results is much more interesting with a bit of turbulence, but it has become clear than I need to raise the subdivisions in the city block geometry if I
intend to edit models this way. So far, this approach seems very promising in the aspect of modeling stylized cities or post-apocalyptic ruins.
By using ZBrush, I can also mask out
sections of the city to minimize scene geometry and render times on a per shot basis - lower right image for example.
Lastly, I've begun testing some non-photorealistic shading, particularly with toon and contour techniques. The image below shows a few styles that can be achieved through manipulating the diffuse, toon, and ambient occlusion passes.
I've also done a similar "toon" study of a creature character.
Recently, I have focused my attention towards scripting tools that will help me create buildings more quickly. My script's latest installment features a new randomized tower tool that stacks & scales cubes and cylinders to create varying types
of towers and spire buildings with a single click. The image to the left shows structures created by playing with a few input values. Notice how creating a few buildings consecutively can create a layered effect to build a more complex structure.
Naturally the user can quickly undo and regenerate a building until a satisfying result is reached.
I originally developed this tool to create background buildings, but after integrating it with my city generator tool, an entire city composed of these types of buildings created an interesting aesthetic style. Clicking on the top image will
display two cities composed of the randomized towers.
In my script's initial version 1.0, I created a building by condensing an entire city. In the next version, I will implement this concept in the same way I did with the
randomized tower tool to quickly construct a city with a different visual style.
In addition to creating the randomized tower construction tool, I've also begun development on another building tool that will read in the polygonal info of a simple model and add structures such as columns, windows, and doors. When complete,
I hope to have something that can help me quickly model buildings with European architecture. The image to the left shows the tool at an early stage. More work needs to be done in regards to automatic scaling and spacing, but the tool can add columns
and windows now. After selecting the column and window geometry, sliders control how many of each are duplicated in the X and Z directions.
For this update, I have begun using the golden ratio phi (1.618) in some calculations. Examples of the golden ratio can be found in art, nature, architecture, and science. It’s my hope
that using this ratio will create more believable and aesthetically pleasing results by preventing unusually thin buildings. A new slider controls what
percentage of buildings use phi in their dimensions. Also random blocks now have open areas for parks, lawns, etc.
Click here for more information on phi.
The image to the left shows how use of the phi slider changes the look of the city generated. It should be noted that the buildings are much shorter when phi is at 100% because the script is trying to
add several buildings per block without making them look like “pencils". Lowering the number of buildings per block & phi percentage to ~75% will create a few skyscrapers.
I have also changed the units of the script to feet. Standardization will make future features easier to code for and hopefully the script will be a little more intuitive to use.
Subsequently, when loaded, the script automatically changes the far clipping planes for each default camera to 1,000,000. Calculations for building height falloff have been simplified. Also common functions have
been separated into its own script for easier access and a more efficient workflow. Click here for a screen shot.
The "Organized City Generator" panel now has checkboxes that offer options to add details in roofing,
exterior building columns, and overhead street sign supports. While these options can quickly add detail to sections of a city,
they are meant to be used for areas that will be in the background of a shot. Also a city can now be generated on top of a curving NURBS surface.
This latest version focuses primarily on tools for detailing buildings. These new features rely on bounding box detection and include:
1) creation of X/Z # of columns around a selection 2) placement of new geometry on top of a selection upon creation 3) addition of two types of railings
with adjustable tiers, thickness, & height 4) fitting of X # of floors within a selection.
The video to the left demonstrates how I can use these simple
features to quickly model five buildings. Overall modeling time was less than half an hour without reference images. Below is an image of my construction tools
interface divided into sections.
When creating more sophisticated cityscapes, I've found that simpler is better for the first step, especially
if detailed building models have already been created. I focus on the spacing and size of buildings and the general layout of the city using only simple
cubes. After that a new building replacement function allows me to import a pre-existing model and replace selected buildings. Sizing is automatic based on
bounding boxes, and I have the option to replace each individually selected object with a copy of the imported geometry or all of the selected objects with a
single copy of the import.
The video above demonstrates this technique. Since the imported building is sized to fit within a selection, a single detailed building can
appear radically different if fitted to selections with varying proportions. The complexity of the city image at the top of the page can now be achieved in less
than a half hour minus the time spent on modeling each building type.
The script's latest iteration can create a city on top of a curving NURBS surface in two different ways. 1) The first type creates a terraced effect.
As city blocks are laid down, the script analyzes the height of the NURBS surface directly under the four top corners of the block. After that, the block is placed at the highest
position of those four values with the addition of the desired block thickness value. The downfall of this technique is that the highest point of the NURBS surface may be at the
center of the block which causes it to protrude in the center, but for the most part, this doesn't occur.
2) The city blocks adopt the normals of the surface under them. The buildings laid on top still stand
completely vertically. This second variation is a more accurate representation of how a city would be built on a hill.
Besides the city and building improvements, I've added a few other features. First I created some simple buttons that create basic primitives.
These buttons automatically generate cubes, cylinders, hexagons, and octagons that are flush with the XZ zero plane and have their pivot points moved to the
bottom of their bounding boxes. Although very simple in concept, several minutes can be saved when creating many building sections from scratch. As I began to
create a library of structures, this simple feature eliminated a very annoying, repetitive task.
Also I added an option to quickly create a lighting sphere for a quick, fake ambient occlusion effect. Its functionality is limited at the moment, but I will
incorporate options for automatic light linking and custom attribute controls later.
Lastly, a "Particles" tab was added for the baking of positional information and the creation of a MEL script that can create curves based on a particle's path.
Greater detail can be found on the Particle Baking Page.
Many improvements have been made to this version of my script, specifically in the coding of the city generator. Now I have the
option of creating a city that is organized into street blocks. Other improvements include an option to toggle the visibility of selected objects within
the current viewport, multiple button instances (like Undo) throughout the interface so less scrolling is necessary, and an option to deselect all the
shape nodes in the current selection.
The image to the left shows an example of the first step in generating an organized city structure. While my original script focused on
specifying the attributes on buildings, version 3 relies on the settings of city blocks. By specifying the radius of the city, maximums of a block's
dimension, street width, and percentage of whether or not a block connects to its neighbor; I can quickly create the ground work for either a city or
an urban environment. Click on the image to the left for more examples.
Click the image to the left for more city variations.
Besides the organized structure, this version incorporates details such as lightning rods, block walling, roofing tiers and borders, and sign bases that
stretch above and across streets. Now my girder functions can be used for further detailing. For now, I can probably automate the use of these functions with sliders,
but I would rather have control over where these kinds of details occur to minimize my scene geometry.
In version 2, I added a button that automatically creates a polygonal sphere composed of quad faces. This is particularly
useful when modeling with ZBrush/Maya since triangular faces causes mesh and displacement irregularities. Within the common functions panel, I added
a combine button to group objects that share the same material shaders (example: sections of the soldier's shoulderpads, gauntlets, leg armor, and shin guards).
The addition of a selection button allows me to select any object that contains the designated text anywhere in its name.
A pivot manipulation panel allows me to quickly center an object's pivot point to its center or the scene origin. Future options will include bounding box
limits. A clipping plane panel was added that changes the front, side, top, and perspective cameras accordingly.
The images below show how I use some of the new functions. I quickly selected all the hair pieces, grouped them so that the pivot
of the entire group was at the origin, duplicated with a negative X scale, and then ungrouped them for a clean hair model hierachy.
The latest version of the city generator allows for simple roof top structures and cylindrical and spherical buildings.
Although Maya offers shelves, hotkeys, and marking menus; I wanted to create an all purpose
window that holds collapsable panels for all my most commonly used functions. Most of the features
revolve around polygon modeling. As seen below, the common functions include polygonal extrusion, duplication, extraction,
and creation. For this first version, I focused on functionality, and I will make future versions more user friendly.
Three of the common functions (Select Edge Loop, Select Edge Ring, & Add Edge Loop) were obtained from
a Gnomon Modeling DVD. They were written by Mikkel Jans from Tippett Studios. These procedures are extremely handy when modeling all sorts of organic or hard surfaces and
especially radial-based geometry. I wrote a fourth function that expands on these procedures so that a row of faces can be selected with two mouse
clicks. It's often much faster to select a row and then deselect faces by dragging and holding "ctrl" when compared to just selecting faces individually.
By using a combination of these functions, I can quickly add detail to any polygonal object.
The beveling and chamfer features are pretty self-explanatory. I added sliders that adjust the manipulator's size
because it usually varies between computers and sometimes gets in the way of selecting objects or vertices. I often use lattice and bend deformers to help
shape objects and then use the "Delete History" button in the common functions panel. I also use clusters more often nowadays when dealing with
dynamics and parenting. When I approach animation, I always use some custom attributes as animation drivers.
After viewing the work done by Professor Ming Tang, I wanted to implement my own version of creating girder geometry. This will become particularly useful when
adding detail to my virtual cityscape. Also, when I implement Blastcode features into later versions of this script, the demolition of structures will look more
impressive if they contain interior girder geometry. My script creates two different types for variety, and the results can be seen below.
The final feature of version 1.0 is the creation of a randomized, generic city. I will be working on this particular feature much more extensively in the future. For now,
I can specify how the buildings shorten or heighten the further they are from the center of the city. Even though there's limited functionality at the moment, the time spent on development
has already saved me hours of modeling. Procedural texturing at this point may yield some interesting results. Below are some examples of cityscapes and to the left is an example of condensing
an entire "city" to create single buildings.