Final Render
|
Reference
|
| While the reference spans many species of trees, I wanted to show how different fall colors can be. From over all colors to even color detail within each leaf the detail and differences is staggering. |
Creating .ribs and Bringing Them Back In
|
Generating rib archives is one of the many important things to create good working environments with large jobs. They can allow for a simple render file with very detailed reference files. In Maya, you need to go through multiple windows in order to add the riReadArchive command. Houdini gives us a much simpler time at this.
First though we must generate the ribs. This is easily done by going to /out and dropping down a Renderman Archive node. After we lay that down you will see you can have multiple objects to bake out to ribs with one Archive node. Keep in mind you can only use objects. In other words if you want seperated elements from a single geometry node you can't do the normal technique of dropping a null and doing OUT_PART1 or something of the sort. Instead we must have seperate geometry nodes for every object we want archived. Simply done with an Object merge pointing at your null OUT nodes(always a good technique anyhow).
Next we need to be able to bring them back in. For this we need to go to /shop, from there drop down a RSL Delayed Read Archive node. If you remember back the difference between Read Archive and Delayed Read Archive is simple: When it loads the geometry into memory. Think of it this way: when a camera shoots out an eye ray and hits an object it knows it can then start shading at that point correct? With delayed reading of our archive the renderer will wait until an eye ray has HIT the bounding box of the object in order to load it into memory. Efficient no? This also means if an eye ray never hits the bounding box it never gets loaded. Here mantra and renderman differ in their implementation of delayed read. Mantra does not need explicit bounds for its delayed read in order to function. It is better to, but it still works. Renderman needs explicit bounds. You can find this in the second tab of the node. Keep in mind if you have a very tight bound on the geometry it means you can wait until the last possible moment to load it into memory. If you bloat the bounds you can potentially bog down the renderer needlessly. Obviously in our scene this does not matter. I have noticed a bug(I believe). When I changed it to SOP Bounds and had it pointing at my geometry that I used to archive out the leaves, I was getting no geometry. I had to massage the explicit values in order to see the full geometry. Pictured above is what can happen with good and bad bounds. |
Getting the Shader on your Leaves
|
|
From here I chose to take my own approach to the project at hand. I wanted a specific workflow worked out where I had the leaves created in Houdini that could be more easily artisticaly controlled while still being a procedural system at it's core. Getting the shader to interact with attributes on the geometry, as in a simple create attribute node, can be tricky at first. As of right now we are only dealing attributes on a per primitive basis, which translates to a "uniform float" when it is promoted to a renderman attribute. The renderman attributes are uniform, constant, vertex and varying. Uniform can be though of as primitive attributes, constant can be thought of as detail attributes, vertex is self explanitory and I am unsure as of the time of this writing what varying is.
After creating our attributes and making the attributes renderman compatible it is time to go back over to the shader. Malcom detailed in class as to getting his procedural system to create user attributes that can be read into the shader. For the attributes we created however, you need to create a parameter within the shader that exactly matches the name of the attribute created on the geometry, case included.
For those looking at my shader you will notice the if statement. I did this because I like to account for as many cases as possible within any tool(or in this case shader) I create. I feel it is better in the long run to take into account these sorts of possibilities. The if statement simply checks for the user attribute created by Malcom's genleaves python script and overwrites anything possibly done in Houdini. Again, a personal choice on which to overwrite.
|
|
Helper Programs
|
|
Helper programs are any kind of code that at render time can do any number of things by means of print statements. In our case we are using it to generate potentially millions of pieces of leaves and pushing them around at render time. Why is this nice you may ask? Because if the generation of geometry happens at render time that means they exist only in memory. No disk space required for geometry. The python code linked above has a total of 13 lines with around 60 characters per line. Multiply that by around say 15,000 leaves you want for your scene and you get around 11,700,000 bytes of data for just your leaves. That is roughly 11MB of data for just 15,000 1 poly planes. Push that up higher and higher and you can get a good amount of disk space needed for just leaves. Add in the time it takes to read geometry from hard drives to RAM and you can easily watch your efficiency start to fail. For my final render above I have 45,500 planes representing the leaves. The rib file for those leaves, and of course minimum attribute information, is 16.7MB of data.
Setting up a helper program in Houdini is simple. First throw down a RSL Run Program node in your shop context and point it at your python(or any language) script. The second string parameter is for passing any and all values to the script itself for rendertime generation. Go back to your SOP context and create a proxy object with accurate bounds relative to your scene. Put on your choice of material shader, then in the geometry tab point it at the rirunprogram shader. Simple as that. Nearly identical methods to reading in rib archives. |
|
Closing notes and thoughts
|
For my final image I ended up adding a second parameter to my leaf geometry: bendMult. I made it random within a certain bound to give a slightly more interesting image. Overall it is negligable unless you look close enough at the leaves themselves. The setup I have, especially the L-System is simplistic and is more intended for being a background tree that would not be under scrutiny.
With this project came the first major hurdles of Renderman 2. Mostly with understanding how Houdini and Renderman interact and how to structure my networks to take advantage or work around Renderman's implementation. Overall I enjoyed this project, partly due to the fact I got an image I am reasonably pleased with. It was also nice having a good deal of knowledge I have gained with Houdini be parallel in some fashion to Renderman. |
|
|
|
|