Procedural skin using TexturingXYZ maps in Mari - part 2
V - Albedo creation - Secondary colors
The creation of the primary colors is the one that is often taking more time. The secondary colors are usually easier and quicker to set up. They’re here to add the information of secondary volumes thanks to the curvature and to create some breakup.
Here’s my workflow:
darkCurvature (same workflow as the one we did with the AO in the primary colors):
- Select your primaryColors_GRP, add an MRG node. Connect this same group to an HSV, then connect this HSV to the Over of the MRG. Rename it darkCurvature_MRG.
- Tweak the HSV to become slightly darker, slightly red and more saturated.
- On the darkCurvature_MRG, connect a Geo-channel node to the mask input. Then, add a Brightness Lookup (BLU) between the Geo-channel and the mask input.
- In the settings of the Geo-channel, select your ISO_curvature.
- From now, you should be able to see the darker values happening on the external volumes of your model. We want to do the opposite. In order to do that, simply select the curve of your BLU, right-click, invert it. Then you can play a bit more with the contrast to make it happens only in the selected areas.
brightCurvature (same workflow as the one we did with the AO in the primary colors):
- Select your darkCurvature_MRG, add another MRG node after it. Connect this same group to an HSV, then connect this HSV to the Over of the new MRG. Rename it brightCurvature_MRG.
- Tweak the HSV to become slightly brighter, a bit more yellow and less saturated.
- On the brightCurvature_MRG, connect a Geo-channel node to the mask input. Then, add a Brightness Lookup (BLU) between the Geo-channel and the mask input.
- In the settings of the Geo-channel, select your ISO_curvature.
- This time, the effect should be working already. You’ll simply need to tweak the curve of your BLU to make it happen only where you need it to.
- Remember to rename all of your nodes!
Various cloud breakups:
We want to add even more break up to make the diffuse map to look more natural. An easy and efficient way to do it is with procedural clouds. When you’re doing this, you want to keep breakdown things in a hierarchical way. Start by working on the primary break up, then the secondary… and so on. Here’s my workflow:
- Primary dark cloud:
- Connect the previous branch to an MRG node. Add an HSV between the former node and the Over entry.
- Make your HSV slightly darker and more saturated. You can play with the Hue and make it red.
- Connect a cloud to the Mask of your MRG. Make the values of this cloud to be low frequency, with a mid-size and low roughness.
- Primary bright cloud:
- Connect the previous branch to an MRG node. Add an HSV between the former node and the Over entry.
- Make your HSV slightly brighter and less saturated. You can play with the Hue as well and make it yellow.
- Connect a cloud to the Mask of your MRG. Make the values of this cloud to be low frequency, with a mid-size and low roughness.
- Secondary dark cloud:
- Connect the previous branch to an MRG node. Add an HSV between the former node and the Over entry.
- Make your HSV slightly darker and more saturated. You can play with the Hue and make it red.
- Connect a cloud to the Mask of your MRG. This time, make the values of this cloud to be higher frequency, with a small-size and higher roughness.
- Secondary bright cloud:
- Connect the previous branch to an MRG node. Add an HSV between the former node and the Over entry.
- Make your HSV slightly brighter and less saturated. You can play with the Hue as well and make it yellow.
- Connect a cloud to the Mask of your MRG. This time, make the values of this cloud to be higher frequency, with a small-size and higher roughness.
That’s it. Once you understand the repetitive and hierarchical logic behind this workflow, things become easy to set up. You can even add more complexity to your procedural noises. Things like cellular patterns can help you to push you albedo even further and to look more natural. It’s up to you to customize it.
When you’re done… remember to group, clean connections and promote values. Rename your group secondaryCOlors_GRP.
VI - Albedo creation - Tertiary colors
We are entering into the last stage of the albedo creation. This one is quite easy to achieve, and add tons of info. That’s where our mariDisplacement that is using TexturingXYZ maps come into play.
Workflow explanation:
- You’ll need to use your mDisp to mask out the interior of the pores
- Connect your secondaryColors_GRP as a Base in a new MRG.
- Connect your secondaryColors_GRP to a HSV. Then connect this HSV on the Over of your MRG.
- Make your new HSV slightly dark. Rename it into disp_interiorPores_HSV.
- Add a Brightness Lookup after your mDisp channel, and connect it to the Mask of your MRG.
- Invert the curve of your Brightness Lookup, and contrast it to make the inside of the skin pores white, and the outside black. Keep in mind to retain some range of your map.
- Redo the same process to highlight the exterior of the pores.
- This time, you’ll need to make your HSV a bit brighter.
- Your brightness Lookup will need to be reversed to its default settings and contrasted to hide the inside of the pores.
Done! Group, clean and promote. Rename this group tertiaryColors_GRP. You now have your albedo channel ready.
VII - specW and specR
A skin material should have 2 levels of specularity. A first one, pretty generic and controlled with simple values. A second one, presenting a wet Spec showing only at glancing angles. We only want to control the second one.
In order to play with two levels of Specularity, Arnold Surface offers a standard Spec slot and SpecR. The second level can be controlled with the Coat and CoatR slots.
The Specular Weight and Spec
- Create a simple Color node to control the value of SpecW. Put this CLR node in Scalar.
- Replicate the value that you had in your Shader in the CLR node. The values I’m using are presented at the beginning of this tutorial.
- Plug this node into the SpcW input of your Shader.
- Do the same process for the SpcR.
VIII - clearCoatWeight and clearCoatRoughness
This is where things can become a bit more interesting in-term of Spec control maps. We will now play with the CoatWeight and CoatRoughness of our shader. The AO, Curvature, and mDisplacement will be used, as they clearly indicate the information of the surface.
Here’s my workflow:
CoatWeight:
- Instance the Ambient Occlusion as a base for clearCoatWeight. Use a Grade or Brightness Lookup to control the main weight.
- Merge the graded AO with the curvature on top. Do not forget to put your MRG in overlay and disable color management. Use another BLU to control the curvature info.
- In order to control the weight of the clear coat in different areas, we will call our ISO masks (lips, eyelids, etc…)
- Connect your former nodes branch to both inputs of an MRG. Add a Brightness node between the former branch and the Over.
- Play with the value of your Brightness. Rename it by the area it’s controlling. Then, connect your ISO to the Mask input of your MRG node.
- Redo the same process for every area you want to control.
- Merge your mDisp on top in overlay mode. Kill color management from MRG node.
- Use a Brightness Lookup to control the contrast of your mDisp. You want to make sure the inside of the pores is almost black.
- Add clamp at the end of the node tree.
- Group and promote values.
CoatRoughness:
- Instance the Ambient Occlusion as a base for clearCoatWeight. Use a Grade or Brightness Lookup to control the main weight. Values should be around 0.2 to 0.4. It doesn’t need too much contrast to start with.
- Merge the curvature on top. Do not forget to put your MRG in overlay and disable color management. Use another BLU to control the curvature info.
- In order to control the weight of the clear coat in different areas, we will call our ISO masks (lips, eyelids, etc…)
- Use the same workflow like the one we used for the CoatWeight to control the quality of the spec. Lips should be wetter and have a darker value. The nose can be more oily… etc.
- Merge your mDisp on top in overlay mode. Kill color management from MRG node.
- Use a Brightness Lookup to control the contrast of your mDisp. You want to make sure the inside of the pores is almost black.
- Stay subtle in the contrast of your clearCoatRoughness channel. Bump already controls the quality of the spec.
- Add clamp at end of the node tree.
- Group and promote values.
IX - Create your skin material using your nodegraph.
We are now approaching the end and final pass of this tutorial. This one is about how to create a Material out of our main nodegraph. This will allow us to replicate all of our texturing process on other assets. This workflow is a HUGE time saver. Since Mari 4.5, we can drag and drop Materials on objects and allow for a smart controlling workflow. The only thing we will need to manually repaint is the mDisp and our black and white masks. However, if you’re smart enough with your Base mesh management, you could potentially re-use your former masks by using the same UVs and generate a lot of different characters out of one.
In order to convert into a Material, you simply need to be careful and willing to clean up a lot of the connections. Take your time and think about the hierarchy of your nodes tree.
Here’s my workflow:
Creation of the Geo-channels:
- Add bakePoint node in front of every painted Layer with the following settings:
- Depth 16 bits for black and white masks. 16 bits for BUMP.
- Colorspace depending on your OCIO. Can be ACEScg or Linear.
- Check Scalar Data. Uncheck it for your albedoCleaning _LR.
- Name the Geo-channel that will be created after bake with an appropriate name. Usually, I am using the same name as the one that comes from the Layer (ISO_lips for the ISO_lips_LR, ... etc)
- Once everything has been set up, you can bake all of your BKP.
- Replace every direct input connection by a GEO-Channel node. Select the appropriate channel on your list. This is a simple but time-consuming step. Make sure to do it properly, otherwise, our Material will not be able to reference the Masks.
- The treatment of the ISO_colorID_LR is a little bit different. Instead of using baked GEO-Channels, I recommend you to connect them to input. This will allow them to stay live, without the need to bake them every time they need an update.
Creation of the Material:
- Create a Material that matches your Shader. In our case, we are using an Arnold Standard Surface.
- One by one, copy and paste your main groups into this Material. Start with the texturingXYZ_unpacker_GRP. Connect it to the Bump and make sure it’s showing properly in the Viewport.
- Keep going with the tileable, primary, secondary, and tertiary colors Groups. Connect it to the Diff Output node of your Material.
Redo the same process for your other channels.
- Sort all of your Material network using Backdrops.
- The pasted groups can now be treated as subgroups. You will now need to expose only the main values to make them available in the Material’s properties. No need to expose everything. If you wish to have more control, you can simply head back inside of your material.
- Remember to sort things and rename them using the Knob Editor in Mari.
- Once done, select your skin_MTL. Under Node, click on Export as Material.
- Done!
This Material pass marks the end of our procedural skin Material. We now have a template that can be replicated on all of our upcoming assets. The masks based workflow is also a fantastic way to quickly update our model without the risk of losing textures. Would you need to update your sculpt? you’ll be able to do it. Would you need to change the UV? Thanks to this workflow you’ll not lose your former channels info.
We all know that VFX needs to force us to be quick and efficient in order to update our texturing. Working with a client is an organic and evolutive process. We are often asked to slightly tilt one of the tones of our albedo. The legacy workflow was hard and time-consuming. We often had to do it by hand, using projection and tedious manual grading. With this procedural approach, you can now simply select the color, change its value and update its ISO_mask to control its repartition.
This is also an accurate and physical approach to texturing. We are using surface information as a guide to controlling different info. Thanks to the Ambient Occlusion, Curvature, and texturingXYZ Displacement, the color will be tinted the right way and the specular will look accurate without too much trouble.
Doing humans and animals used to be a tedious process. However, texturingXYZ has opened new doors to make the creative process more fun and easily enjoyable. Even though this tutorial is pretty in-depth, it could never cover the variety of different Workflows that Jeremy and his team have open to us. Remember to always read the connection between sculpting and surfacing.
Be creative, dig the technique so you can enjoy and focus on the creative aspect.
I hope that you enjoyed the content of this course. See you at the next one!
Part 1 - Part 2
Once again, we would like to thank Gaël for his helpful contribution. If you're also interested to be featured here on a topic that might interest the community, feel free to contact us! |