Amazing. Thank you for doing this. I have wanted to see if it were possible to do a Toon Shader for a long time, but it's something that I have been pushing away from me because I felt that Shaders were not something that I would be able to do at the level I am at, but it seems to be quite simple after all..
@@andresbocchigliere3227 it surely is because it's an unlit shader. I didn't try this one out yet but if you create a lit one it will most likely receive shadows (let's now hope that it doesn't receive it with the normal shading :') but with this code to cast shadows it must be working ig, I'll try this out when I can)
Fantastic video. Every other tutorial I've seen for this type of effect always try incorporating superfluous features which require C# coding and things like that, really appreciate the simplicity of just using CG.
I am blown away by the quality and simplicity of this. I'm new to Unity and 3D rendering in general and this is immensly helpful! I'll share as much as possible :D
How Wind Waker’s cel shading works, is that it shades the object with values from 0-255 (0 being black, and 255 being white), then looks in a texture at the coordinate of the pixel’s color value to find the final color. The texture is about 47.5% black on the left, 47.5% white on the right, and a smooth gradient from black to white in the middle 5% (rough approximation from memory on the percentage). Wind Waker’s cel shading is very interesting, it’s so simple, yet looks so good. Great video btw, cel shading is very interesting, and cool.
After testing the shader a bit in unity i found out that the model is not receiving any shadows from outside sources. For example a building casting a shadow on the ground has no effect on the character that this toon shader has been applied to. Although the shader is visually very good, this sitution makes it some what less useful for practical use. I dont know how to fix this but if anyone can chime in to improve this, it will be appreciated and beneficial for everyone.I am not mentioning that the model does not cast any shadows as someone in the commets below has already provided a fix for that.
It was a little too fast for me, but I'll watch it again until I get it! I've been working with Unity for 9 years now but I've been too lazy to learn shaders. Thank you so much for your video and please keep doing more!
Wow this is an excellent tutorial, concrete and simple, yet deep. Thank you for sharing your knowledge. Any chances you give us a little hint on how to add a "transparent" funcion?
Wow, this tutorial is amazing. I love all the customizable options that you added as well! And this only in an 8min video, awesome :D Any chance you could add an outline as well to this? (I know nothing about shaders :p)
I have an issue with the shader, I’m not sure what it is, but it’s either that sometime it will randomly show what the camera sees as a texture, or it becomes super reflective. Why does this happen?
Hello eleonora could I ask if there is a way to add transparency to this shader at all?? If so may I request to see it, it would be a great help. Thank you
Hi. can you check the cartoon and the comic reshade of the reshade software, both of them are good but also they bring some visuals problems to the game (you should check that, maybe you can fix those things)
Is there anyway i can change the colors of the highlights and shadows? have them set to a specific color. im trying to make a 3d sonic 1 that looks like pixel art and i have the 3d loop im testing this on. the lighting thanks to this tutorial is really good except the colors of the shadows and highlights is slightly off if there was only a way to change that.
There is a bug in the code in the video in the Toon function. The floor method will return an integer that can be larger than 1. As the result from the Toon function should be between 0 and 1 the code will give you black and white and nothing in between. The way to solve it, is by multiplying by the _Detail variable again before returning: return floor(NdotL / _Detail) * _Detail;
Maybe, but for me the provided code didnt work. They way to make it work was to add the addition i mentioned above. In the node graph they block is called posterize, which does exactly the same thing
@@Markkaz88 maybe you didn't declare the property for the strength multiplier correctly. That would explain why the extra multiplication of _Detail made yours look better. Whatever at least it works :) for me the above code works correctly
It works perfectly for objects with textures, but how do I do it for objects without textures (Just a single base colour)? If I try to do it normally, it works but the object becomes quite light/white
Hi, I was just having a small problem, every time I move my back, the shades get dark as if under a shadow but when I get close, they light up as if the light is hitting that object directly
How do you make the object with this shader cast shadow? I added the shader to my gameobjects and suddenly they don't cast shadow anymore. Can you please help me?
really amazing!! what is the difference with using nodes? i'm starting to try to do this on my models but i want the best performance possible for mobile games :)
Nice tutorial! But how do i let it cast shadows on itself? And is there any way to let the ambient color of the world affect the shaded object? It doesn't seem to do that right now
Hey! I followed this without shader coding experience and the result looks great, thank you! :3 I was wondering if I can somehow access the written toon shader within a curved world shader made in Shader Graph? I am going for a toon shaded round planet and I am not sure if I would be able to translate the written toon shader into the shader graph at my current skill level qwq
Amazing. Thank you for doing this. I have wanted to see if it were possible to do a Toon Shader for a long time, but it's something that I have been pushing away from me because I felt that Shaders were not something that I would be able to do at the level I am at, but it seems to be quite simple after all..
Thank you, that is so kind of you! I'm glad it was useful!
For anyone who does just wants to copy paste the shader code, here it is:
Shader "Unlit/ToonShader"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_Brightness("Brightness", Range(0,1)) = 0.3
_Strength("Strength", Range(0,1)) = 0.5
_Color("Color", COLOR) = (1,1,1,1)
_Detail("Detail", Range(0,1)) = 0.3
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float3 normal : NORMAL;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
half3 worldNormal: NORMAL;
};
sampler2D _MainTex;
float4 _MainTex_ST;
float _Brightness;
float _Strength;
float4 _Color;
float _Detail;
float Toon(float3 normal, float3 lightDir) {
float NdotL = max(0.0,dot(normalize(normal), normalize(lightDir)));
return floor(NdotL / _Detail);
}
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
o.worldNormal = UnityObjectToWorldNormal(v.normal);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
// sample the texture
fixed4 col = tex2D(_MainTex, i.uv);
col *= Toon(i.worldNormal, _WorldSpaceLightPos0.xyz) * _Strength * _Color + _Brightness;
return col;
}
ENDCG
}
}
}
Bibbidi Bobbidi, your code is my property kiddo
@@lolcat69 **OUR** CODE
@@Luckysury333 DANI DEV
do you even wear a cap bro
my hero, bro.
The Original Toon shader doesn't cast shadows so I modified the code so that It now cast shadows
Shader "Unlit/ToonShader"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_Brightness("Brightness", Range(0,1)) = 0.3
_Strength("Strength", Range(0,1)) = 0.5
_Color("Color", COLOR) = (1,1,1,1)
_Detail("Detail", Range(0,1)) = 0.3
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
//Pass for Toon shader
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float3 normal : NORMAL;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
half3 worldNormal: NORMAL;
};
sampler2D _MainTex;
float4 _MainTex_ST;
float _Brightness;
float _Strength;
float4 _Color;
float _Detail;
float Toon(float3 normal, float3 lightDir) {
float NdotL = max(0.0,dot(normalize(normal), normalize(lightDir)));
return floor(NdotL / _Detail);
}
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
o.worldNormal = UnityObjectToWorldNormal(v.normal);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
// sample the texture
fixed4 col = tex2D(_MainTex, i.uv);
col *= Toon(i.worldNormal, _WorldSpaceLightPos0.xyz) * _Strength * _Color + _Brightness;
return col;
}
ENDCG
}
//Pass for Casting Shadows
Pass
{
Name "CastShadow"
Tags { "LightMode" = "ShadowCaster" }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_shadowcaster
#include "UnityCG.cginc"
struct v2f
{
V2F_SHADOW_CASTER;
};
v2f vert( appdata_base v )
{
v2f o;
TRANSFER_SHADOW_CASTER(o)
return o;
}
float4 frag( v2f i ) : COLOR
{
SHADOW_CASTER_FRAGMENT(i)
}
ENDCG
}
}
}
Thank you! :)
Awesome 👏🏼
THANK YOUUUUUUUUU
Nice! How about if i want to receive Shadows too ? with that code is casting but not recieving... pls Help!!! Thanks in Advance
@@andresbocchigliere3227 it surely is because it's an unlit shader. I didn't try this one out yet but if you create a lit one it will most likely receive shadows (let's now hope that it doesn't receive it with the normal shading :') but with this code to cast shadows it must be working ig, I'll try this out when I can)
Fantastic video. Every other tutorial I've seen for this type of effect always try incorporating superfluous features which require C# coding and things like that, really appreciate the simplicity of just using CG.
I am blown away by the quality and simplicity of this. I'm new to Unity and 3D rendering in general and this is immensly helpful! I'll share as much as possible :D
I have watched so many videos related to this. But no one explained the dot product and the floor to group part. Now it just clicked. Thank you.
Imagine being so good at explaining that you're underrated
That's you. You need more subs.
Thanks for the video.
Very helpful video! Made shaders feel 5% less scary to me tysm
Girl!!! i'm brazilian guy, i undestand all, and I LOVE the tutorial! Congratz!
Nice, I might end up using this for my videogame project in class
you are a stunning teacher the way you simplifed the proccess to that extent, yet kept the same effect is brilliant!
I like how you say consider subscribing instead of like how everyone else just tells you to subscribe
How Wind Waker’s cel shading works, is that it shades the object with values from 0-255 (0 being black, and 255 being white), then looks in a texture at the coordinate of the pixel’s color value to find the final color. The texture is about 47.5% black on the left, 47.5% white on the right, and a smooth gradient from black to white in the middle 5% (rough approximation from memory on the percentage).
Wind Waker’s cel shading is very interesting, it’s so simple, yet looks so good.
Great video btw, cel shading is very interesting, and cool.
With all due respect, i love you! Thank you. I´m starting with shader scripts, and this video make me understand the concepts of this
you channel deserves so much more followers ! I had both me and my boyfriend following you!!!
Thank you for your kind words!! xxx
This video is exactly what I was looking for!! Thank you so much for the help!
Hey! Love this tutorial! Really nice and informative ^^ Maybe you could make some tutorials regarding basic shader programming? Would be awesome!
I would love to make more of these for sure!
Works like a charm. Thanks for providing this.
After testing the shader a bit in unity i found out that the model is not receiving any shadows from outside sources. For example a building casting a shadow on the ground has no effect on the character that this toon shader has been applied to. Although the shader is visually very good, this sitution makes it some what less useful for practical use. I dont know how to fix this but if anyone can chime in to improve this, it will be appreciated and beneficial for everyone.I am not mentioning that the model does not cast any shadows as someone in the commets below has already provided a fix for that.
你的教程真的太经典了,网络上非常稀少。希望老师更多教程
Thanks a lot for this tutorial. Nice explanations and finally someone who is not using shader graph! That was really helpful!
It was a little too fast for me, but I'll watch it again until I get it! I've been working with Unity for 9 years now but I've been too lazy to learn shaders. Thank you so much for your video and please keep doing more!
Thank you for the kind words! Please feel free to drop me a message on discord if you have any questions!
Wow this is an excellent tutorial, concrete and simple, yet deep. Thank you for sharing your knowledge. Any chances you give us a little hint on how to add a "transparent" funcion?
Best video ever! Thank you so much!
Wow, this tutorial is amazing. I love all the customizable options that you added as well!
And this only in an 8min video, awesome :D
Any chance you could add an outline as well to this? (I know nothing about shaders :p)
This was spot on!!! Thank you!!!
is this the best shader tutorial ever, or what?? great job!! im just wondering if this will look as good for other objects as well, like a person?
Great video. Very easy to follow and understand
This video was amazing. Thank you so much!!!
This is beyond science
Just saw this tutorial on gamedev.net, and instantly subscribed.
Awesome video! My fears of working with shaders have been squashed.
Hi I came from the Facebook, I love the result,Nice work 🤗🤗
what a good and solid content you have!
Lvl up!
+1 Atk
+2 Def
+1 Sub
I have an issue with the shader, I’m not sure what it is, but it’s either that sometime it will randomly show what the camera sees as a texture, or it becomes super reflective. Why does this happen?
here is a question, how would I go about including a normal map with this cell shader?
This was super interesting ! Thanks !
Oh my god, you are my Lady Luck!!!
thanks ! its very helpful and inspired turtial !
Very good and simple! excelent job! please, more tutorials like this!!!!
This was actual helpful! Thanks a lot
I cant thank you enough for making this tutorial
This is fantastic. Thank you
How hard would it be to add casted shadows to this?
Pretty cool! Thanks for the knowledge without dumb talking/making things complex :D
@eleonora Is there perhaps a chance of you creating a pixel shader turorial? Totally asking for a friend :)
this is aewsome
Old video but still helpful.
Good evening, very good tutorial.
But how would I make Point Light influence and create shadow, thank you very much
This was a really good tutorial!
Tight, Ty
Hello eleonora could I ask if there is a way to add transparency to this shader at all?? If so may I request to see it, it would be a great help. Thank you
Hi. can you check the cartoon and the comic reshade of the reshade software, both of them are good but also they bring some visuals problems to the game (you should check that, maybe you can fix those things)
Simple and useful!
thank you very much!
Is there anyway i can change the colors of the highlights and shadows? have them set to a specific color. im trying to make a 3d sonic 1 that looks like pixel art and i have the 3d loop im testing this on. the lighting thanks to this tutorial is really good except the colors of the shadows and highlights is slightly off if there was only a way to change that.
Simple and informative video, ty ^^
Thank you for the kind words!
Amazing video , Does it work for URP ?
she said bread of the wild
How to add shadows so that it can receive and cast shadows ??
Which illustration/Drawing software were you using at 2:10 ?
There is a bug in the code in the video in the Toon function. The floor method will return an integer that can be larger than 1. As the result from the Toon function should be between 0 and 1 the code will give you black and white and nothing in between. The way to solve it, is by multiplying by the _Detail variable again before returning:
return floor(NdotL / _Detail) * _Detail;
The return value gets multiplied by strength and it is supposed to be able to go above 1.... This is not a Bug
Maybe, but for me the provided code didnt work. They way to make it work was to add the addition i mentioned above. In the node graph they block is called posterize, which does exactly the same thing
Not sure how to edit a comment, but auto complete change the into they.
@@Markkaz88 maybe you didn't declare the property for the strength multiplier correctly. That would explain why the extra multiplication of _Detail made yours look better. Whatever at least it works :) for me the above code works correctly
It works perfectly for objects with textures, but how do I do it for objects without textures (Just a single base colour)? If I try to do it normally, it works but the object becomes quite light/white
Hi, I was just having a small problem, every time I move my back, the shades get dark as if under a shadow but when I get close, they light up as if the light is hitting that object directly
Great tutorial.
Mas e a sombra do chão? Perde?
Hi! and thanks for this awesome tutorial, great splaning btw i wanted to ask ¿what program do you use to write script?
How do you make the object with this shader cast shadow? I added the shader to my gameobjects and suddenly they don't cast shadow anymore. Can you please help me?
Me staring at the TV wondering why my homecooked meal looks nothing like the picture.
I'm really interested in this game "Bread of the Wild" that you mentioned. Sounds fun
Alec Anderson haha
It's looking so good 😭😭 that I watched it and I know only blender😭😭
I see a glaring problem with this.
the normal can't give you occlusion shadows [casted or casting] so this can't really be a functional shader
How come other lights dont effect how the toon light glows?
hey im here after wasting hours making cel shaders in blender which cant be exported to unity _) ill try your thing before i give up thx
really amazing!! what is the difference with using nodes? i'm starting to try to do this on my models but i want the best performance possible for mobile games :)
Please make it with shader graph
Hey, good night.
I am a beginner in unity and would like to know how I make this shader to cast shadows and add metallic properties, is it possible?
It's a great video you made. Good content, good presentation, everything needed is good. I have to keep an eye on your videos. Keep it up. ^_^
I can not get the step after use the floor function,Is there any points
Cool !!! Thank you:)
Excelent, thanl you so much!
any suggestions on how you might add the ability to change the shadow colours?
does this support shadows
?
thank you!
I want to add transparency to this shader, how can I do it?
Hey, thanks for the video.... but pointlight and spotlight is dissapeared ... it can only on directional light
Amazing, does anyone know how to also add an outline?
Nice tutorial! But how do i let it cast shadows on itself? And is there any way to let the ambient color of the world affect the shaded object? It doesn't seem to do that right now
oh, it doesnt seem like it interacts with the world at all,, is there a way to make it do that? or would i have to use a surface shader for that?
cool.. can we do the same shader for unity terrain ?
Great shader effect, Do you know if this may work on URP? have you ever tested on?
I tested it in URP, it worked. Make sure to still use non-URP shaders for this though.
Plz can you do a toon shader for environment plz plz plz plz plz
Thx
How to add fade in effect to this shader ?
Can u add outline?
Can this project working in the HDRP?
Is there a way to smooth the shade edge?
you are amazing ❤❤❤❤❤❤❤❤❤❤
Nice
Hi! Thank you for this. I really like the result. Is there a way I can get shadows from it? my character is like floating in the grass? xD
Und where are my shadows?
Unlit materials don't produce shadows because they are unlit
I modified the code and now It produce shadows.
Shader "Unlit/ToonShader"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_Brightness("Brightness", Range(0,1)) = 0.3
_Strength("Strength", Range(0,1)) = 0.5
_Color("Color", COLOR) = (1,1,1,1)
_Detail("Detail", Range(0,1)) = 0.3
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
//Pass for Toon shader
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float3 normal : NORMAL;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
half3 worldNormal: NORMAL;
};
sampler2D _MainTex;
float4 _MainTex_ST;
float _Brightness;
float _Strength;
float4 _Color;
float _Detail;
float Toon(float3 normal, float3 lightDir) {
float NdotL = max(0.0,dot(normalize(normal), normalize(lightDir)));
return floor(NdotL / _Detail);
}
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
o.worldNormal = UnityObjectToWorldNormal(v.normal);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
// sample the texture
fixed4 col = tex2D(_MainTex, i.uv);
col *= Toon(i.worldNormal, _WorldSpaceLightPos0.xyz) * _Strength * _Color + _Brightness;
return col;
}
ENDCG
}
//Pass for Casting Shadows
Pass
{
Name "CastShadow"
Tags { "LightMode" = "ShadowCaster" }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_shadowcaster
#include "UnityCG.cginc"
struct v2f
{
V2F_SHADOW_CASTER;
};
v2f vert( appdata_base v )
{
v2f o;
TRANSFER_SHADOW_CASTER(o)
return o;
}
float4 frag( v2f i ) : COLOR
{
SHADOW_CASTER_FRAGMENT(i)
}
ENDCG
}
}
}
Any way to make it able to cast shadows?
Hey! I followed this without shader coding experience and the result looks great, thank you! :3 I was wondering if I can somehow access the written toon shader within a curved world shader made in Shader Graph?
I am going for a toon shaded round planet and I am not sure if I would be able to translate the written toon shader into the shader graph at my current skill level qwq