thumbnail.png
When I figured out how to do this I was OVERJOYED because I was under the impression that the only way to get the eyebrows over hair effect for a 3D model was using a shader like Poiyomi in unity, but that would require me to trap the model in a somewhat restrictive format like VSFAvatar. But turns out, MToon is a lot more versatile than expected!
I used this unity tutorial as a base, but did it in Blender with the added benefit of keeping the outlines!
Tutorial
This tutorial requires you to have some knowledge about using blender, and a vrm model to work with! We will be using Kana Fuyuko's Test-Chan. This works only on VRM 0.x models, I haven't tried this on 1.0 models.
Importing your model into blender
Start by downloading and installing the blender VRM addon, this will add the .vrm option in the blender import window. Import your .vrm model into blender
1865068c-add3-4d59-ac7d-b7fb2878fc24-imagen.png
Preparing the materials
Start by identifying the eyebrow material, usually freshly exported VRM model have a longer identifier like "N00_000_00_FaceBrow_00_FACE"
97ae6a37-be3c-4091-ba55-8ffb8656cc9e-imagen.png
In this material, you will set the settings in the VRM Material panel under the material selection box like in this screenshot:
3420b115-f3d9-4d78-a59c-efe29c708ebd-imagen.png
Alpha mode must be set to transparent so it can interact with other transparent materials, ZWrite Mode must be disabled or it will not work, and same with Double Sided.
Now identify the material(s) associated to the strands you want the eyebrows to be seen through, you can do this by selecting the hair faces in edit mode and see what materials light up. In this case, there's only one hair material called "Hair".
You will now create a new material, give it a good name like "Hair Stencil", assign it to these strands, and check the "Enable VRM MToon Material" box to convert it into an MToon Material, and try to copy all the settings from the Hair material manually so it looks the same, save for the Alpha mode, ZWrite mode and Double Sided settings.
176537fd-6bf1-408a-a47f-02b6f1136362-imagen.png
I don't just duplicate the Hair material because I've encountered an outline related bug when you duplicate VRM materials, and I'm not sure if it's fixed yet.
Hair stencil and Render Queue
Now that the front strands and the eyebrows are set to transparent, the renderer will determine which one goes first using a render queue, with materials with a lower render queue value being rendered first, and materials with a higher render queue value are rendered on top of them, so we want the eyebrows to have a higher render queue value than the front hair.
The RenderQueue Offset slider you saw in the previous screenshot IS NOT the one we will be modifying, as it is meant for MToon 1.0 as far as I know. Scroll down, and check the "Show MToon 0.0 Options" checkbox, revealing the Render Queue slider:
3161074c-95d0-48f9-9917-0e7f7a9eeec4-imagen.png
This slider goes from 2951 to 3000, so we will leave the Hair Stencil material at 2955 and the eyebrow material at 2960.
Keeping the outline
If you were to export the model now, this would happen:
a06fc3b0-3c4f-4517-811c-295969e384e3-imagen.png
This is because MToon outlines don't follow the material settings, so they just render as opaque strands with inverted normals. We will fixing by converting the outlines into an actual 3D object and putting and MToon shader on it!
First, separate the front strands, and create a duplicate of them, naming it something like "Front Outline". Now if you go to the modifier tab with that mesh selected, you will see some geometry nodes modifiers. We will convert these into geometry!
3231a653-62ba-4812-ac11-691fa2d6db23-imagen.png
Go to the Geometry Nodes workspace, select the modifier for the hair stencil, create a copy of the outline node tree, and change the name to something descriptive like "Outline Factory".
5f17e81b-80e7-4695-bdcd-56d2bac9374b-imagen.png
74d1d123-f43e-4889-a935-594045657071-imagen.png
c8c3a523-2478-4841-84a1-3819468b0207-imagen.png
Now in the node tree, move the output close to the Separate Components node, and connect its mesh output to Geometry input of the Group Output node
88a51bc1-6e98-48c1-b503-62106d064863-imagen.png
706c1fa9-8513-4db6-a22f-a52342db9878-imagen.png
This hijacks the outline creation pipeline before it converts the previously created outline geometry into an instance. I am not very knowledgeable in geometry nodes, but afaik converting geometry into an instance makes the created geometry lose all vertex weights and not be able to become actual geometry if the geometry node modifier is applied, so we skip that step.
Now we apply the modifier, and we are left with a mesh of outlines!
4d1df2c6-6006-4898-bb50-238e37134e97-imagen.png
Now we will disable the outlines for the Hair Stencil material, select the Hair Outline mesh and create a material for it. Convert it to MToon, set the settings like in the screenshot, and assign it to the the whole mesh:
b4e03266-f27b-4d83-bf46-a3a940a03e2f-imagen.png
You can copy and paste the color from the outline settings in the rest of the hair. Now we will set the Render Queue value for this material to 2954 so the hair and eyebrows render on top of it.
d0485892-27c3-451a-b10d-8642e8b24ec1-imagen.png
If you export the model now, you will see the effect work with outlines
e051946e-0a0e-4420-a1b7-10eb1d5ce406-imagen.png
You can see some issues with the lashes, so you have to change the render queue values of those materials so they render before the outline (Have a value below 1954). After doing that, this is the result
ae528fbb-dc4b-4453-8c37-4556e74c6232-imagen.png
The cost of happiness
This looks great! It has a couple of downsides though. You may have noticed that all the outlines that usually render on the front of the hair are gone (because the outlines render after the hair), and this is more or less inevitable.
Another inevitable issue occurs when you turn to the side too much:
Peek 2024-06-22 18-04.gif
This happens because the order at which faces are rendered cannot change dynamically, so when there two overlapping faces with their normals facing you, the engine may render the one that's further back instead of the one in front of it, causing this weird effect. It can be mitigated by texturing with that in mind, changing the hair shape or some other fancy thing but afaik you can never get totally rid of it, not even with other kinds of shaders.
Here's a good explanation of this issue on the minute 3:30:
Conclusion
And that's how you get outlines and eyebrow transparency on a VRM model without unity or need to use other shaders. You can also do this for eyelashes, irises or anything you can think of, but it gets increasingly more cumbersome as you juggle more materials.
I really hope this was useful and don't hesitate to ask questions, after all, this is a forum!
If you want to check out the result or take a look at the .blend I did, you can download the files here.