Creature and character artist Yuriy Dulich, breaks down his photoreal Somali ostrich. Check it out below!
This is a breakdown of one of my most recent works - the Somali Ostrich. I’ll be walking you through my typical workflow for projects, as well as effective ways to quickly create photorealistic models.
My goal was to create a photorealistic ostrich render in the shortest possible time. To do this, I started by pulling together reference images so that I could have all the visual information at my fingertips.
I learned a lot of interesting facts about the Somali Ostrich during this process. I looked at photos and video references, macro photos, documentaries, feather photos, anatomical atlases... I collected everything that could be useful. Here’s my general rule – nothing is ever superfluous.
Next, I did the project setup, creating a typical folder structure, and laying out the materials in the right places. I then input the project into a Google Sheet with theoretical calculations along with the timing of the various development stages. This allows me to get statistics in the future and improve my time management process. After that, my typical routine began.
As a rule, I always start with ZBrush from the sphere in dynamesh mode.In Maya, I created a blocking object using simple primitives, which limits the body volume. I followed that up by sculpting a rough volume of external muscles in ZBrush. I chose a T-pose for the ostrich, so that it would be easy to fold the wings and at the same time, have control over the primary feathers. I then made some more progress on my sculpting.
When the volume and proportions were just right, I did retopology in TopoGun and followed that with UV mapping.
I always use UDIM.
In the next step, the model (now with a working topology and UV maps) is returned into ZBrush. I created a re-project of the necessary parts of the body and added a lot of detail by hand. I didn't waste time on the high-detailed sculpted parts of the body which are hidden under the feathers anyway.
To save time, I purchased a foot skin scan here. I extracted the necessary parts of texture into "alpha textures" which I used in ZBrush. The rest of the details, like the large folds of skin, parts of the head and pores were brought in manually. For the beak and claws, I used the surface noise generator. After the final sculpting, I exported them from ZBrush as 32-bit vector displacement maps. I also exported the grayscale regular displacement (for different subdivision levels) and cavity maps for future texturing.
This was the most fun and painstaking part of the grooming workflow. I used Yeti for this stage.
Having previous experience with grooming feathers, I already knew what some of the technical nuances were such as the length of the feathers, the approximate density, and the structure of the feathers. I used the simplified method of grooming and scattering the feathers, as there was no need to control each feather individually. The fact that the feathers were disheveled actually made them easier to groom. This greatly improved the speed of grooming.
At this point, I drew the basic masks for grooming. I used the additive RGBA mask method (learn more here).
It was clear that the neck and head would be covered in curled fur with clumps, and there would be just a few feathers on the head,unlike the body, where everything would be dotted with feathers.
When creating strands, I always use my iterative method. I used a simplified groom for more detail and generated the Yeti fiber nodes that were then converted to the groom. I repeated this until I got the desired result (usually, I stop at 3 or 4 iterations). During this stage, I decided how many Yeti nodes I would split the model into and how many groom nodes I would create, which ultimately impacts the unloading of the cache. My ostrich ended up with only 8 groom nodes and 5 Yeti nodes.
I don’t like using polygonal planes with alpha. Instead, I prefer imitating feathers based on fibers. I like to think that this is the secret to my photoreal result.
To generate the feathers, I used the jcFeather plugin for Maya and the standard Yeti feather. I did this to create finer settings for the animation stage. By doing this, each hair in a feather can react to light and correctly defocus on macro renders, the way it would in nature.
At this point, I generated the desired set of feathers and converted them into curves, which I used in Yeti. After that, I selected the number of hairs and their thickness based on my research photos and a constant render of the base Yeti tree. I also used a 3-layer, multi-layer scattering on the body with different densities for certain areas.
Because of the written expressions, the necessary set of feathers were automatically selected depending on the length of the strand and their position on the body. The picture below shows different sets of feathers organized by color.
Each set shown consists of 6-8 feathers that are randomly sorted by expression. I developed a 2-axis model for changing attributes (such as scraggle, bend, etc.) along the length of the feathers and on each individual fiber within the feather by painting the attributes in the groom node.
Didn’t do anything special here. After I tweaked the model, I created an animation rig.
I used Advanced Skeleton in Maya for this. I’m not a high-quality rigger, so the rig in my work is mainly used for posing. At this stage, I separated the project into reference scenes: scenes with rig, scenes with groom and scenes with shaders. I transferred the scenes through Alembic and Yeti caches.
Texturing and Shading
The body texturing was done in Mari and was mostly limited to manual painting. I mixed displacement, cavity textures and various marble textures for the skin, beak, and claws with different noise procedural textures. I also drew technical textures and masks for SSS.
Fun fact: in Yeti, you can create texture coordinates for any object based on fibers with custom UVs and use them with any render engine later. I utilized this feature for my project here. You can check out the textures I drew for melanin below. I also used Arnold’s procedural noise.
I drew a total of 24 textures for 11 sets of feathers.
In my workflow, I did preliminary shading during grooming with and without a basic texture. But even then, I adjusted the look of the material and its main characteristics, because the result in the viewport is sometimes different from what we see on the render. I also used a standard Arnold aiStandardHair material with a melanin-centric model built in.
In other words, I drew monochrome textures that went to the melanin parameter and slightly adjusted the color in the base color parameter. For a realistic touch, I slightly changed the shade both in melanin and in the color of each individual hair by its ID in the feather itself. Also, with the help of the Maya ramp, I adjusted the shade of the hair from the root to the tip and added a central vein of each hair in the feather.
Each feather layer had its own ID, and each individual feather had its own ID as well. I then transferred all this information from Yeti and used it in a massive shading system.
Rendering and Post
I tend to render animals in a dark space because I want the focus to be on the model itself, so I reused the “studio” used for my Subarctic Great Horned Owl project. I only added a few details like dirt by the ostrich’s feet for realism. Finally, the project came to life! I created a light rig for each pose. The final render scene was assembled from reference scenes with a groom + shader, a mesh with a pose and lighting + studio.
I always try to achieve a good result on the render in order to do minimal post-processing work. I rendered the necessary RGB masks, position, sometimes normal and always Z depth passes.
Finally, I did my post-processing and color grading in Fusion.
Thanks for reading and I hope you enjoyed it and you learned something new.
Some statistics data:
Total number of feathers - 9196
Total number of fibers - 3427455
Total number of sets of feathers - 11
Total number of feather textures - 24
Polycount of ZBrush hi-res model- 43.18M
Rendertime 8k ~ 17h
Want to see more from Yuriy?