For this assignment we were tasked with using MEL mesh query operations to populate leaves onto a tree. Additionally, we utilized the RenderMan preShape injection point to generate the leaves at rendertime and became familiar with the RenderMan UI workflow.
I love the liveoak trees throughout Savannah, so I focused most of my efforts on recreating their look. I used a tree generation tool to create a bare leafless tree that resembled an oak tree.
Creating a RenderMan UI requires a MEL script and a .RMAN TCL file. More information about the creation process can be found in the "Extensions" section of the RMS 3.0 documentation and at Fundza.
A third script (or global function) is required for the actual preShape rendertime MEL execution.
There are a number of ways to approach the problem of creating realistic bunches of leaves. One approach is to create a bounding volume of some kind (a sphere, perhaps) and perform mesh query operations to place leaves onto the vertices of the sphere. This can be randomized, but generally is still going to look like leaves pasted to a sphere, unless a lot of time is spent masaging the bounding volume. This method does have the advantage of being fairly art-directable.
I chose to generate leaves directly onto the branches of the tree base mesh, with some controls to only create those leaves if the branch was a certain distance away from the parent tree shape.
First, all the vertices are queried and stored in an array. The array is traversed and the distances are compared to the base mesh using nearestPointOnMesh. If vertices are above a user input threshold, they are kept and considered for leaf creation.
The remaining vertices are traversed and generate leaves at random positions based on various randomized parameters. When a leaf is created, I skip the next few vertices to try to prevent obvious grid-like clumping. The number of vertices skipped is determined by the Density parameter.
Leaves are brought in using RiReadArchive and have a shader with externalized parameters for color, allowing the user color parameter to be transferred up to the shader.
Density is controlled by skipping larger numbers of vertices between each leaf creation. Very high values (0.9+) skip very few vertices and can look unnatural depending on the tesselation of the geometry.
Parameters are available for both a random value and random color multiplier per leaf. The color mode should be used very sparingly, as random amounts of the selected color are added to the base color. Large values create an otherworldly 'rainbow' effect like I have exaggerated in the image below.
The distance check discussed above is quite slow, so I added a checkbox to disable this. With the option off, some branches may create a leaf very close to the main branch, and then have a long thin branch sticking out. Generally this would not happen and leaves are created near the end of the smaller branches (Distance check enabled).
The scale can also be randomized, along with the rotation of the leaves. Random rotations take place after aligning the leaf to the creation vertex normal.
To increase density without increasing the tesselation of the branch itself, up to 4 leaves can be created at each vertex.
The leaf and stem rib archive can be specified separately, allowing for a variety of effects depending on the tree type.
Computing the leaf positions on every render frame is quite expensive for a high density of leaves., so the ability to reuse leaf positions was added with MEL's file reading and writing capability. When active, reading in the stored leaf information is quite fast.