Ideas
Crowd Simulation
This is a project contracted outside of school. It is for a feature film. I will be expected to produce 2 shots with crowd simulation due April/May.
Crowd Simulation is new to me so I would have to plan for learning and researching this.
At this time I don’t have a lot of information about the project itself. I have a digital meeting scheduled Wednesday 7th of February where I will get the information I need in order to make a decision about whether to join the project or not.
Water Simulation
- Tsunami
This will involve advanced water simulation as well as destruction simulation.
- Drink/Fluids
This project I believe is a smaller project which could be combined with other projects.
Particle Simulation
- Crystal to Orb
Ref:
Potential Footage:
Further developing tsunami idea
Time Management plan
Color Palette
Moodboard
Storyboard
After discussing briefly the project with an industry professional she advised me to adjust the shots. Therefore, I created a second storyboard with the shots she recommended.
Concept Art
Scope
References
- The particular scene starts at timestamp 2:00.
- The scenes I like are at timestamp 0:33-0:39 & 0:43-0:49.
The scenes I like are at timestamp 5:04-5:07 & 0:43-0:49.
Resources
- Gnomon Workshop
- Rebelway
- VFX Grace
Early Testing
- Ocean Wave Node
Weekly Presentation – Week 2
Mockup Models
PP Week 3
Previz
For the previz I did a mockup of the environment. I added my proxy models as well as made an elevated ground floor. I then used OSM in Houdini to get the city buildings. Then I played around with scaling as well as angles for the shots.
Version 1
Version 2
Recieved some feedback on my previz and did a few changes to the scale of things, added a man as scale referance and also changed the camera angles and movements sightly. I also adjusted the speed and scale of the wave and ocean.
PP Week 4
Munch Museum
Process:
To create the windows I started by creating one window using extrude on a grid. Then I used copy and transform to set the width and height. I linked the copy transform to the size of the window so the width and height could be adjusted procedurally. I made the front, sides and back separate since they weren’t identical. The sides I did windows on only half of them. The back is just a solid grid. I then used transform to assemble the walls together. I linked these to each other as well so if I go back and adjust the height and width on a wall, then it will still stick together.
For the base it was the same process as the top walls. With this I just added a roof as well that I just used extrude to make the indent.
The roof was a grid, then extruded that to give it width, and created edges to seperate the surface that I wanted to extrude downwards. That surface is going to be a window.
Then I merged the building together.
I used Lattice to create the bend at the top of the building.
I created a group for the windows so I can add seperate materials on them. This is just a mockup of the materials, and I will have to go back and adjust as I proceed to UV mapping and texturing.
I then just manually deleted the stuff on the inside from the top.
I then created floors out of grids and copy transformed them. The bottom floors I needed to extrude some bits to fit the shape of it.
Turntable of model
Oslo Opera House
Process:
First step was to create the base shape for the geometry. Then I moved on to create the hill on the side as well as handrails for it.
Then I added a row of windows on the side, and handrails for the other side. I also extruded it a bit on the back and adjusted the width.
I then moved onto the main body of the building. Starting with the base shape, and adding handrails on the side.
Then I created the windows on the side by first drawing up the lines. Then using facet to seperate the primitives and then extruding them.
I then adjusted the angle of the backside and added a box with boolean. Used extrude to add details to the shape.
Then I created the backside shapes with boolean, extrude and drawing edges manually.
I then moved on to the details on this side. I created the big section with windows as well as some small narrow ones.
Then I moved on to the details on the left side. Hand rails and windows, using the same technique as I did for the other details.
The huge node graph for creating the base geometry for the opera house.
For the glass house I used most of the same techniques as I did with the base of the building. Creating windows and a handrail at the top.
The pipe is simple with only some extruded handrails at the top.
The bridge was also simple with just a basic grid with handrails.
The final base model of the opera house.
Created some groups for the different materials.
Then assigned materials to the groups, these are just visualizing. The plan is to do final textures in substance painter, if I run low on time to do the UV mapping I might see if I can get away with doing it in Houdini.
Final Model without interior.
Creating the interior I just made the rough outline of what is looks like. I started with creating a helix for the front spiral section. Then extruded that out to give it thickness. I then made a box and a tube and combined that with boolean, and then combined with the spiral. I just gave it some test material for viewing.
I then created columns to go in front of the spiral interior.
Finished model with the interior added to it.
Turntable of model
Setting up the environment
OSM
I created an OSM of the section of Oslo where I’ll be setting the scene in. I used the OSM import to import the map, then filter to remove the streets and other data I didn’t need. The OSM buildings help control the height and created buildings that had little data as well. Then I only used match size while I was working to fit it with the other buildings I had. I then also transformed it to fit the scene in terms of angles. Then I grouped the Opera House and the Munch Museum so they could be deleted later.
I then removed the Opera House and Munch Museum, then cliped out areas that isn’t going to be visible in the shots.
Street
To create the pavement I just started with boxes and then extruded them out to cover where the buildings are, then I merged them together.
I then created a group of where I want the street to be, and then I extruded that area so that I get sidewalks and roads.
Hill
I started with a grid. Then selected an area and grouped it, and soft transformed that upwards slightly.
I then did the same technique at the top to create more of a hill, and then I added some noise and a color.
This is not the finished hill, I will either make it nicer in Houdini or replace it for a 2D image in compositing.
Adding Street Details
Sourced:
Street Light – Artist: Streetlights & ETC Link: Sketchfab – The best 3D viewer on the web
Crane – Artist: Chamod1999 Link: Sketchfab – The best 3D viewer on the web
Flowerbed – Artist: stevencmutter Link: Sketchfab – The best 3D viewer on the web
Traffic Light – Artist: miwaVV Link: Sketchfab – The best 3D viewer on the web
City Props (Bus Stop, Bench, Drain, Manhole, Post Barrier, Trash Can) – Artist: TampaJoey Link: Sketchfab – The best 3D viewer on the web
City Props Vol. 2 (…) – Artist: TampaJoey Link: TampaJoey – Sketchfab
Curb – Megascans
When I added the details I found the models online. I added them and moved them to where I wanted them, and for some of the models I used copy and transform to instance the model.
The environment
Sourced buildings from sketchfab:
Shot replacing OSM buildings:
- This was supposed to be shot 03. However, there were changes made and this became the main shot.
Setting up the buildings as collision objects
There were issues with converting this building into a VDB because some of the geometry only had one side, and then it became empty when it was converted. I fixed this by extruding the building only for the collision, and used the original without extruding for the rendering.
To set up the buildings as collision objects I converted them to VDB and cached it. I used transform to place and scale the buildings according to the scene.
Creating the ocean wave mesh
In this Houdini network, I start by generating a grid with the grid node to serve as the base geometry for the ocean. I then created the wave details using the ocean spectrum node. I used two different ones, one for the smaller waves and one for the bigger ones. Next, I combine these spectra with the merge node. To add more detail, I subdivide the grid using the subdivide node. After that, I evaluate the combined ocean spectra on the subdivided grid with the ocean preview node, generating the ocean surface. Finally, I save the resulting ocean surface geometry to a file using the save spectra node.
I created the wave shape by first adjusting point positions within a compiled block. The Attribute Wrangle node modifies the y-coordinates of points based on their z-coordinates. This is done using two ramps and a multiplier. The first ramp (‘area’) displaces points vertically, and the second ramp (‘area2’) scales this displacement. This process reshapes the geometry efficiently within the compiled block.
In this attribute wrangle I used the expression to make the wave go smaller at the end with a ramp.
I used a VOP node to create more noise at the top of the wave. I did this by creating noise on the position, converted it to a float and plugged the y value into the multiply. I then multiplied that with a ramp, the relbbox gives the position of a point within its bounding box as a value between 0 and 1. It helps to normalize coordinates for procedural effects. I converted it to a float and used the z position for the ramp. I then added all this to the position.
I then moved the wave down slightly below zero.
I then deleted everything below 0.05 in the y axis and used clean to remove any attributes and groups I didn’t need to optimize it and cached it.
Development version of the wave mesh:
Main Splashes
Source
Firstly I started by creating the the geometry source the splashes will emit from. The first step is importing the ocean mesh we created previously with an object merge. Then I used an expression that takes the cusp attribute that was created through the ocean spectrum and putting that into a slider. This controls the amount of points based on the cusp attribute that will be added to the del (delete) group we created. Then the group promote converts it from a point group to a primitive group.
In the ocean mesh node I created bounding boxes that are linked to the movement of the mesh.
I then imported the bounding box we created, divided it to give it more primitives. Then noised it up.
I used the bounding box to create a new del group and then promoted it from points to primitives.
The Group Transfer node copies the first del group to the other, keeping selected elements grouped after changes. The group combine combines the group based on intersection. This gives the top edge of the first group some more noise rather than be a straight line.
Then I deleted the parts that were not in the group.
I then took another bounding box I created to delete a section I did not need to emit from. This is for optimization purposes, I’m trying to avoid simulating more particles than needed.
I created an animated box based on what the camera sees. I used this expression that I found online to do so.
I used the trail node to create multiple increments of the area to capture all the movement. Then I stopped the animation so it is standstill but because we did the trail node it ensured that the box is accurate even when the camera moves. Then I converted it to a volume.
I then used the camera bounding box and made a group based on that.
I then used another bounding box to delete some more areas that I didn’t need. I then used the blast nodes to delete both the geometry outside the camera bounding box, and inside the second one I made. Then I used an add node to delete any points that wasn’t connected to the geometry to clean up the geometry.
I then used a bounding box to group this area of the ocean mesh. Â
Then I deleted all the geometry that was not part of the group. Then I extruded the mesh to make it have thickness.
Next step was to convert this to a volume and used the reshape to control erode the mesh slightly. When you convert something to a VDB it tends to expand a little from it’s original size.
That was the process of creating the source geometry for the splashes. I did however end up adjusting this due to adjusting the camera angle but the process was entirely the same, the adjustments were just made to the bounding boxes.
I used an attribute VOP which you can see above to create animated noise to the geometry. I plugged the position into a turbulent noise, then an absolute node to make any negative value 0 or positive. Then used fit to fit it to a range that looked nice. The ramp creates a ramp channel on the VOP node that controls the noise. I took the normals and converted from vectors to floats. Then applied values to each of those float channels (x,y,z). Then converted that to a vector again, and multiplied it with the noise. Then added that to the position, as well as outputting the multiply to the velocity attribute.
In the attribute wrangle I added an expression that removed the noise from the position, but kept the velocity values. I then used pointvelocity to add noise to the velocity.
Then used clean to remove any attributes and groups that we don’t need for optimization and cached it.
POP Source
The setup for the particle simulation is simple. Just a POP net and then a clean node and caching.
Inside the POP network I first used a POP replicate to make clumps of points, then the SOP solver which is explained below. Then a POP force to add noise and more velocity. Lastly added the buildings as collision object and a ground plane.
In the SOP solver I imported the inside volume of the ocean mesh we created earlier, and grouped all points that fall inside that region and delete those. This is also for optimization so we don’t get all the particles from the inside that we don’t need.
Below are different versions of the particle simulation as I worked on them:
FLIP
The FLIP setup is fairly simple. I connected the POP into a DOP network. Then used an import DOP to be able to work on the simulation. I used the group expression to delete the unnecessary points and clean, attribcast and fluid compress to optimize the simulation and make it less heavy. Then I caches it. I use particle fluid surface to visualize what the simulation looks like.
The SOP solver is explained below. POP drag applies resistance to particle movement, slowing them down. POP force gives it noise and I used it to adjust the velocity as well. The static objects are the collisions, which are the buildings, the ocean mesh and the street, as well as a ground plane.
The SOP solver is basically the same one I used in the particle simulation, deleting particles that have a velocity of less than 6, which are basically the particles that are standstill.
Testing with fluid surface as surface polygons:
Different versions of the flip as I developed it:
Compress FLIP
This was the first version of the fluid simulation, but there way to many points and it was too heavy for me to work with.
This is the second iteration, I lowered the amount of particles in the POP source which helped, but it was still too big.
In the final version I adjusted the particle separation and amount of particles being emitted in the fluid simulation and that helped and made it workable.
This is an example of how long it took to cache when it was very heavy, this was about 21 hours to cache 164 frames.
Whitewater
I started by using the unpacking to unpack the fluid from the fluid compress node back into particles. I then created a bounding box to delete an area I didn’t need. Then I converted the fluids into a volume, and used the reshape to set the a size small enough to keep the major details but not to small that it was too heavy. Then I cached this. I also extracted the surface from the VDB.
I then created the whitewater source, then used the VDB clip to remove some of the particles at the back and then cached the source.
Then I simulated the whitewater with a DOP network. Same process as the fluid with cleaning up and optimizing and then caching.
The pop drag adds resistance and the pop force adds noise. It’s pretty much the same as the fluid with different settings and a different solver.
It’s the same process in the SOP solver with different values.
For simulating the mist the process is the same as previously.
The process inside the DOP network is pretty much the same as well just different values.
In this attribute wrangle I’m using expressions to create channels to create a group. The goals is to get the points that are on the edge or at the top, and not inside the simulation.
This wrangle has the same purpose of separating the top layer of particles from the simulation. This is done with a ramp that uses the xyzdis function, the function calculates the distance from a point in 3D space to the closest point on a geometry or VDB surface. This groups all the points closest to the mesh.
I delete all the points that are not the top most layer of the simulation. This source will enable me to simulate more mist based on only the outer layer.
I then simulate this just like I have with the other mist layer.
When the simulations are done I merged them and converted them into a volume. I adjusted voxel size as small as I could with the computer power I had.
I converted the whitewater the same way as the mist, but added a wrangle that gives the particles a set particle scale based on depth. So further out is smaller, and further in is bigger. I also deleted the parts I didn’t need to optimize as much as possible.
This was the whole node graph for creating the splashes.
Development versions of the whitewater and mist:
Josh Review
These are the versions I showed an industry professional Josh to give feedback. We talked mostly about camera angels. He recommended putting the camera on the ground as if it was a person filming. He talked about trying to imagine how they would shoot the shot in real life. Would there be a rig, helicopter, handheld etc. He told us that often CG cameras tend to look weird because we don’t think about those things.
v1
v2
Destruction
I started by importing the buildings and separating out the ones that were going to be destroyed.
I started by soloing out the windows. I used the connectivity node to generate a piece attribute for the fracturing. The for each loop applies the process within on each piece that is plugged in. This would be each window. I scatter points which is where the breaks are going to be, the amount of points is the amount of breaking.
I then did this to each section of the building.
I then assembled this together and gave each of them a separate value.
I merge sections that are connected such as the windows and the walls. Then scatter points which helps control how strong the constraint is. Then create the constraint with the connectadjecentpieces node. In the wrangle I give it a constraint name and type.
For the constraints for the entire building I first do a simple constraint without scattering points, and then scatter the points.
I then do this process for all constraints.
To create the ground I make a bounding box based on the building and group all the sides except the bottom and delete those.
I set the ground to have a value of 0 in the active attribute so that its not affected by the simulation.
I then set constraints for the ground as well, I clip the building so we only get constraints connected to the bottom.
To create the collision object which is going to drive the destruction, I create a box, give it noise in the mountain node and set it to 0 active attribute, and 1 with animate. So it does not get destroyed but it will be animated in the simulation. I then keyframe the movement to resemble waves movement.
I then simulate the destruction and set this to points instead of geometry so it runs faster. Therefore, I need the transform pieces that makes it geometry again and its connected to the packed version of the entire building.
In the DOP solver I import all the constraints and adjust the values to a result I like.
I then retimed it to match with when the wave crashes.
Rendering
I had a lot of issues with rendering this. I tried using my own computer first, but I only have 32gb RAM so it just crashed because of insufficient memory. I then tried to render at University but had issues due to the machines being rebooted after I started the render so everything I had set up and downloaded locally on the machine was deleted, as well as the rendered stopped. I set it to render before I left town for a couple of days, this caused the render to be delayed by several days. However, when I got back, I downloaded the project onto 12 computers and split up the sequence between them. It was heavy so it took very long to render. 30 frames took around 30-45 hours.
The lights I used for the scene were a sun to get nice details on the ocean mesh, as well as an HDRI.
I set up different cameras for the different renders. We had to render prints for our other module so I set up the camera with the settings for that separately from the camera for the video sequence.
I imported the buildings from sketchfab as GLTF scenes and retrieved them from a null in the project to be used.
This was the whole setup of everything together in the object network.
I also rendered with cryptomatte so I could have more control in composting.
Compositing
The pictures are before and after changes were done. I used the cryptomatte layers to control different adjustments. I defocused the front buildings by using a roto mask. I then tried to blend the edge of the ocean a little as I found it to be slightly to harsh. I then created a color grade on the buildings that is keyframed at the end. They are graded to a color matching the water to make it look more like the scene is engulfed in the water at the end. I also applied a little bit of edgeblur to the mist and whitewater to make it a little bit less blocky.
For the sky I color graded it and added noise to integrate with the environment.
Then I graded the scene to make it darker and colder, I wanted to enhance the scary ambiance.
I then created a vignette with a roto mask.
I also created camera shake to give it more of a handheld effect and keyframed it to be more violent when it hits the buildings, as well as the end when the water engulfed the camera. This added motion blur automatically as well.
I used a grey fade similar to the water color first to help with the appearance of the water submerging the camera, and a black fade in and out for the sequence.
The nodegraph for the whole compositing setup.
Powerpoints
- The rest of the powerpoints throughout the semester
There are several weeks missing because something happened with the files and I lost the files.
Week 9:
Week 13:
Changes made throughout the process
During the process, I adjusted the camera angle several times to find the best view. Eventually, I decided to shoot from ground level to avoid adding extra things like street lights or ocean details, which saved time. Originally, I planned for 3-4 shots, but to meet my deadline, I narrowed it down to just one. This way, I could focus on making that one shot as perfect as possible, following advice from my teachers. In addition, I also made the desicion to not use the buildings I modelled to save time. Modelling was not my main focus in this assignment, and spending time on modelling, UV mapping and texturing would take away from the time I had on the FX.
Reflection
Reflecting on the process, I recognize that I could have managed my time more effectively. Spending excessive time on modeling for multiple shots wasn’t the most efficient approach. In hindsight, omitting the modeling part entirely would have allowed me to concentrate solely on perfecting the FX, which is the hero object and the focus of my study. By reallocating my time, I could have dedicated more attention to refining the chosen shot and ensuring that the FX element was executed to its fullest potential. This experience underscores the importance of prioritizing tasks and optimizing time management for more successful outcomes in future projects.
Final Product
Final shot
Final shot with breakdowns