Rookie Awards 2024 - Open for Entries!
Journey to Tech Art
Share  

Journey to Tech Art

Nathan Vandevoort
by NathanVandevoort on 28 May 2023 for Rookie Awards 2023

This submission tells the story of my journey through school so far. The pieces are in the order they were created. Each newer piece uses more elements of proceduralism than the one before.

75 1331 24
Round of applause for our sponsors

Tin Tin Maker 

Concept by: JP Targete.

About:

The Tin Tin Maker is a concept by the amazing JP Targete for the game Machinarium. I completed this piece for my Intro to Maya class at Gnomon, the assignment was to replicate 2D concept art into 3D. This was my first project I completed in Maya and Substance Painter and my knowledge has grown a whole lot since this piece. 

Software: Maya, Vray, Substance Painter, Blender, photoshop

The Queens Rose

Original Concept

About:

The Queens Rose is the name of the airship I modeled and textured in my hard surface 1 and texturing and shading 2 classes at Gnomon. This was a pretty massive undertaking to finish in two and a half months and came with a whole bunch of technical and artistic challenges. I've attached a breakdown for the biggest learning opportunity on this project.

Software: Substance Painter, Marvelous Designer, Substance Designer, Maya, Photoshop, Blender, Nuke, Vray, Redshift

Breakdown 01: 

Rope Nets

I thought the idea of a sky ship carrying its cargo precariously underneath the boat was a cool one. And what boat is complete without netting?

To create this net I used substance designer to create a tileable texture. to make it actually have depth and not just be a flat card I use displacement on two identical planes with the same material assigned to them, one with its normals flipped. The advantage of this method is I can keep my net geometry extremely simple and for the nets holding the cargo I can use a cloth simulation from marvelous designer which allows the net to hold and cup the cargo realistically.

Techniques like this are probably used in production often, I'm just proud of coming to it without being explicitly lead there. I also think its just so cool!

Lake Cascade

Original Concept

About:

Lake Cascade is my most technically complex piece I've made to date. This project was made in my Houdini 1 class at Gnomon and is my first project in Houdini. There was quite a large learning curve as well as many technical challenges. I'm proud to say every asset except the tent, backpack, and hiking poles are made and surfaced entirely procedurally in Houdini. Below Is a detailed breakdown for how I created all aspects of this project. Enjoy!

Software: Houdini, Redshift, Marvelous Designer, Maya, Blender, Substance Painter, Nuke

Terrain and Water

The terrain is all normal Houdini Heightfield stuff. Just various noises with a few erosion simulations. The little craters in the foreground are dirt skirts I created using the proximity of the terrain points to the surface of the rocks I have scattered around.

The water is just normal ocean spectrum stuff with the wind up a little bit for the animation, I scattered a lot of wave instancing points to try to achieve the scale I was going for.

Trees

My Trees are made entirely procedurally and took a few attempts to get right. The trees are 20 branch variations instanced onto a whole bunch of tree trunks scattered all over the place. The branches are generated through three iterations of for-loops which randomly split the branch into smaller and smaller subbranches and scatter pine needles all over it when done. (I later found out this is just an L system and there are native Houdini tools to do similar effects). I build all of this custom instead of using the LABS tree tools because I was trying to take advantage of nested instances to drastically reduce my memory footprint, unfortunate it turns out redshift (What I rendered in) does not support nested instances hence why I instance the tree branches and not the entire trees. Doing it this way also allows me to control number of branches per tree.  

The different colors correspond to different values I use when shading the trees. Red is just a random value per tree so I can offset the hue and saturation on a tree by tree basis. Blue is for my "deadness Mask" which controls how yellow, rough, and sparse the trees are (this last one is not controlled in shading but by how many branches I instance to each trunk). 

The "deadness mask" and other scattering masks are all created logically from the heightfield, for example: trees will be more dead where water will not flow and even more dead in places that would receive less sunlight. I did all of this logic procedurally for example by projecting an attribute along a vector to simulate sunlight. 

Rocks

I have Three different rock variations: Large smooth rocks, Medium jagged rocks, Small smooth pebbles. These variations were all created on my custom rock generator just using various noises and voronoi fracturing for the more geometric rocks. 
The Rocks also scatter following some basic logic. Steeper places are more likely to have a rock field, pebbles will surround larger rocks, etc. I didn't scatter rocks under the water as any visual gains were extremely miniscule. 

Grass

Grass was much more difficult to make than I thought it would be. It turns out it isnt so simple as scattering a bunch of points and instancing stalks with random rotation to them. 

The solution I came up with was to use a "clump by nearest point" approach. Basically I scatter a whole bunch of points and then scatter a smaller number of points on top of that I have each point query which "clump point" they are closest to and then take a distance from it. Then using all of the other "clump homies" normalize that distance and use it to lerp between an upward vector and an outward vector. Throw in a little bit of noise and I think the effect is pretty convincing! I realize this is just voronoi noise with extra steps but its cool to kind of directly see why voronoi noise is so important. I've attached some of my vex snippets I wrote for this below.

As for scattering, the grass has all the same logic as the trees plus it wont scatter within a certain distance of rocks. It will also point slightly away from the rocks as to not have them clip into them while animating. 

Bushes

I have 5 bush variations generated from my custom bush generator. It works very similar to my tree branch generator though as I made it later I was able to build it much more quickly and it computes much quicker. The real key for the efficiency upgrade was using instance attributes instead of for each loops to modify each component. 

I'm proud of my bush generator, I made a UI for it using the Houdini parameter interface and put time into making it easy to use. My generator is technically capable to instance any "three layer deep" foliage though I've only tried it with the bush pieces I've made procedurally. When you enable animation it will also show you a simplified view to speed up viewport playback which I think is pretty nifty. 

Random Rotation was harder to implement then I thought it would be. I wanted my bushes to rotate around the normal vector inherited from the terrain, this sparked 5 weeks of linear algebra learning and the attached vex snippet is the fruit of that labor. I rotate around the normal by creating a rotation matrix with a random rotation encoded in it and then converting that rotation matrix to a quaternion which I then plug into the orient attribute which is expecting a vector 4. I use this technique all throughout my project for randomizing rotation of things.

Animation

This project wasn't originally going to have any motion in it at all, one of my roommates (shoutout Gabe) said it would be really cool if things moved and I couldn't disagree. Because I was implementing animation after the assets were made (or at least their generators) I needed to work around some of the work I already had done.

Grass: Animating the grass was pretty strait forward. In my scene I have a global attribute on a null for wind direction. Basically to animate the grass I run a curl noise through it and the stronger the noise the the normal points in the direction of the wind. 

Water: I already talked about this but I basically just turned up the wind in the solver and that's it.

Trees: This was a bit of a challenge because the branches don't actually adhere to the trunks. So I needed to deform the branches and trunks together as a unit. I did this by averaging each "row" of the trunk mesh (its just a sweep) to get kind of a line that represents my tree. I then deform this line and do all my transformations relative to that. As for the mechanics of the wind it just functions the same way as the grass.

Bushes: This is where I "cheated" the most. I wanted my bush generator to be usable outside of this project so in the controller for it I built in animation controls. Basically each branch component moves in a sinusoidal pattern with some noise thrown in lerping between its normal rest position and the wind direction. I also have controls for how much the leaves should move.

Tent/Assets: The tent and the backpack were modeled in marvelous designer (it was just like pitching a real tent!) so to animate it I just added a wind force and then exported an alembic.

What's Next:

I still have a year and a half left in school and I'm determined to be able to truly call myself a tech artist. However, I'm proud of what I've made so far but I'm far from learning everything I want to yet. I plan on moving forward with more challenging pieces to hone both my technical and artistic skill. 

Thank you so much for reading,

Nathan Vandevoort

ArtStation: https://www.artstation.com/nathan-vandevoort

Instagram: nathan.vandevoort


Comments (24)