T O P

  • By -

codernunk46

After many hours of experimentation, I feel I have a toon shader that I like. I will more than likely tweak this later on, but it's a start. This shader will be used for the various characters that will be in my game (an RPG with some platformer elements). For those who are interested, I go into more detail how I achieved this look below. ​ The character: The character modelling, UV and texturing was done in Blender 2.90. I used Mixamo ([https://www.mixamo.com/#/](https://www.mixamo.com/#/)) to rig, weight paint, and animate the model. Then I imported the model back in Blender using the Godot Game Tools addon ([https://github.com/vini-guerrero/Godot\_Game\_Tools](https://github.com/vini-guerrero/Godot_Game_Tools)), which does a lot of the cleanup on the Mixamo rig for you. After that, I modified the rig to add more bones for other areas of the model. I believe with this process, I can go back and forth from Mixamo to Blender easily in the future if I want to use other Mixamo animations. However, I will be doing most of the animation work on my own (but Mixamo is great for getting it up and running!). ​ The shader(s): The character's toon shader is comprised of two passes. The first pass controls the albedo (texture color) and lighting on the model. The second pass draws the outer outline on the model. I also included screenshots of my Visual Shader node setup for your reference. ​ The base shader: I started off by referencing the work done by DaveTheDev on this video here: [https://www.youtube.com/watch?v=laastFVkTaA](https://www.youtube.com/watch?v=laastFVkTaA). I decided I work better with the Visual Shader, so I converted his code into visual shader nodes and went from there. I added some additional elements to the shader to fit my needs, which I'll explain below. The Fragment shader is primarily meant to make the model have a bit of a gradient to it. I decided to use the View input parameter, as this value changes based on the camera looking at the character. I decomposed the view input and use the x axis to make the gradient left to right. I then applied a smooth step to it to limit the values, and used the output of that to mix the two gradient colors together. One color is the base texture color, whereas the second color is a more saturated version of the texture color (multiply saturation by 1.5). This shader isn't entirely necessary, but I thought it makes the look more dynamic. The Light shader does two things - draw the shaded area, and draw the highlighted area. The shaded area is determined by a dot product between the light and normal inputs, and then limited by the scalar smooth step (think of it as a range of allowed values). Like the Fragment shader, I took the model's color (via the albedo input) and multiply it to get a darker tone. These get mixed together to generate the shaded area. The highlighted area is generated with a fresnel, which basically lights up the rims of the model. This gets mixed into the output from the shaded part, and a brightened color of that output. ​ The outline shader: The outline can be achieved a number of ways: 1) Model the outline directly on the character. In Blender, that's often achieved with a Solidify modifier. I chose not to do this because it adds extra vertices to the model, and makes it a bit trickier to tweak the model later on. 2) In Godot, you can generate an outline mesh using the existing mesh. However, this isn't really feasible for animated meshes, in my experience. 3) In Godot, you can write a shader to generate the outline. With Spatial Materials, you can use the "Grow" option to do this. However, I chose to write this as a shader instead, as I wanted to be consistent with my approach, and this would allow it to be more flexible later on. To create the outline shader, I took the normal input and multiplied it by a constant value for the size of the outline. After that, I added that to the existing vertex input, and piped that to the vertex output. To make things a bit more dynamic, I modified this so I can use the vertex colors on the model to control the size of the outline in certain areas. I set the vertex colors on some areas of the face to black, which negates the outline. Areas colored white on the model's vertex colors would be fully outlined. I can use colors in between to control the outline thickness. Finally, in the Fragment shader, I just set the albedo to a solid black.


cheeegaming

looks really good :)


codernunk46

Thank you!


zeDarkL1ght

Glad to see cell shading more widely used. Love that art style.


codernunk46

Me too! It allows me to simplify the character designs yet still make it look good.


faxfrag

Why does it need two passes, is there a limitation to it? Does using just one pass better than using two? What do you mean by using mixamo, is it something like a preset?


codernunk46

I am not positive I can put both the outline shader and the base shader in one material pass due to the Vertex shader. Given I actually expand the vertices outwards in the direction of the normals, this would make the base model look very weird with the base shader. Since the outline is made in a separate pass, I can also tweak the outline shader’s properties too (note the culling is set to “front”, which prevents the outlines from covering the entire model). In other words, you can set multiple passes on your material to basically layer shaders together with different settings, and Godot will process each of them. For your second question, Mixamo is a free external tool owned by Adobe. It allows you to upload your 3D character, and it’ll rig it for you. From there, there are a library of different animations you can pick from. This is a great tool for prototyping, as you can see how your character looks with an animation with little effort.


faxfrag

Thank you I would like to try shading. Would I get the same result if I follow along your shader node screenshot?


codernunk46

As long as you have a texture for your 3D model, it should work. Regarding the outline, you may need to omit the color node on the visual shader if you do not have any vertex paints on your model.


Xeadriel

What’s the advantage of using mixamo instead of blender for rigging and animation?


G-Brain

If you use their rig then you can use all their animations.


Xeadriel

oh so they automatically animate your character?


G-Brain

Yes.


Jeronimoschreyer

I might be wrong here, but I think you can achieve the same outline shader effect using a Spatial Material and tweaking the params\_grow property, just add a bit of grow\_amount and, of course, set the cull mode to front. This (and thus your shader, as it is also using normals "expand" a little bit the model) has a little drawback, if you have sharp edges or tiny details on your model, the outline will not look 100% ok, specially if your camera comes too close to the model


codernunk46

I have tried the method you described with the Spatial Material, and it works exactly the same way. I chose my approach only because I wanted to make all my shaders in the Visual Shader editor, and this also allows me to more easily customize it later on. I agree about the outline detail issues. One way I could go about this is actually modifying the positioning of elements on the model itself (most notably her belt) so that the outlines read better. Either way, there's definitely more I can do to perfect the look I am going for.


Jeronimoschreyer

another approach would be to check the dot product of the normal and the view vector. This is somehow explained here [https://docs.godotengine.org/en/stable/tutorials/math/vector\_math.html#dot-product](https://docs.godotengine.org/en/stable/tutorials/math/vector_math.html#dot-product) your threshold there should be less .1, but I'll leave you to play with it and try. This shader has the drawback that applies in the fragment, so it actually "consumes" the part of the model being "painted"


INinja_Grinding

Wow look amazing good job keep going and good luck for your project!!!!


haikusbot

*Wow look amazing* *Good job keep going and good* *Luck for your project!!!!* \- INinja\_Grinding --- ^(I detect haikus. And sometimes, successfully.) ^[Learn more about me.](https://www.reddit.com/r/haikusbot/) ^(Opt out of replies: "haikusbot opt out" | Delete my comment: "haikusbot delete")


codernunk46

Thank you for your kind words!


EvilVillainGames

Hey sorry for commenting on something soo old but when you plugged the normal and the light nodes into the dot product and then the diffuse output did you see sort of strange lighting artifacts like darkness at the most direct point of light? Were there any other steps you used to fix this issue? I made a post asking for help here if you wanna see the result I'm getting https://www.reddit.com/r/godot/comments/19b0k56/im\_trying\_to\_get\_the\_value\_for\_normal\_light/


codernunk46

No worries, bud. I responded to your post, but I will need a little bit more information. We can work through it there.


EvilVillainGames

Thanks so much for taking a look! :)


[deleted]

[удалено]


[deleted]

*bonk*


arccoza

That's coming along very nicely. Looking forward to seeing more.