clip
Last time we learned how to do toon shading!
Claire in her full toony glory – btw this is a variant of the toon shader we did last time that has the rim strongest on one side. I challenge you to figure that out for yourself. Or, if you’re a $5 patron, you can just download it straight up here.
And yet, something is amiss – her eyes and mouth are just kinda dull. That’s because they’re still using the standard shader! Let’s put them on the toon shader too! Make a new material called ClaireFeatures and drag Girl01_FacialAnimMap into the Albedo texture slot. Put the shader XibToon on it. If you don’t already have XibToon, you can download it here. (It is also attached to this post.)
Now let’s drag the material ClaireFeatures into the material slots on Girl_Brows_Geo, Girl_Eyes_Geo, and Girl_Mouth_Geo in the hierarchy.
Oh no! It’s like she’s got clown makeup on. This happened because the eyes, brows, and mouth, are on a texture in which the background is transparent and our shader is not designed to handle transparency.
Well first, let’s examine our texture import settings to make sure we’re importing it with its alpha transparency handled correctly. Hm, “Alpha Is Transparency” isn’t checked, Let’s try that.
aaaaAAAAAAAAAA! Nope, that’s not the solution! We need to make a shader that only shows the 3d object if the pixel currently being colored isn’t transparent.
Go to XibToon in the project files and duplicate it. Name the duplicate XibToon Cutout. Open XibToon Cutout in Visual Studio and change the name at the top to XibToon Cutout.
Let’s also add this property
_Cutout("Cutout", Range(0,1)) = 0.5
Back in Unity, change the shader used by the ClaireFeatures material to XibToon Cutout. You can see the new cutout slider we just added at the bottom of the material properties there.
Back in our code, update the Tags near the top to this:
Tags { "RenderType" = "TransparentCutout" "Queue" = "Transparent" }
Render Type, as you imagine, is the type of object being rendered. Queue tells Unity what order to draw the object in. In Forward rendering (which we’re using) objects get drawn back to front, going forward (get it?) so transparent objects should be drawn last so that the stuff behind them that we should see has already been drawn. So we’re telling Unity to draw the things with this shader after the other stuff.
Above your surface function, be sure to declare our _Cutout variable with half _Cutout;
The transparency info has been in the texture all along, we just weren’t using it. tex2D gets us a variable that holds 4 numbers at once, red, green, blue, and alpha (transparency) so let’s get this info from our texture and put it into our Albedo and Alpha values.
If you were to save and head back to Unity now though, you’d find that nothing’s changed. We need to do one more thing. Under those three lines (or anywhere in your surface function after them) put this:
clip(tex.a - _Cutout);
This clip function takes a number. If the number given to it is less than zero, then the pixel being shaded won’t even be drawn at all. So we are saying, if the alpha value of the texture at the pixel we’re coloring is less than the number we put into _Cutout, make that pixel invisible.
We should now have this.
Save and head back to Unity.
Yay!
btw if you get something like this
make sure the Render Queue in the material properties is set to Transparent
Hooray! Now everything is in balance and all is right with the world!
Now that you have your cutout shader, try sliding the cutout value around to see the effect that has.
This is at 0.05
This is at 1
Cutouts are a really handy trick for a lot of things. They get used a lot for making plants ‘cause then you don’t have to model a whole branch with leaves, you just stick a cutout shader on a plane! In fact they’re pretty much perfect for things that have complicated shapes but are mostly flat. If you’re feeling creative, try making some transparent textures on your own and putting them into cutout materials on planes.
Have any questions, comments, or corrections? Let me know on Twitter or Discord! And if I helped you out, please consider becoming a patron!
This tutorial is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. The code shared with this tutorial is licensed under a Creative Commons Attribution 4.0 International License.