Basic TOON SHADER In UNITY Using Shader Graph - Unity Lazy Tutorial
ฝัง
- เผยแพร่เมื่อ 15 มิ.ย. 2024
- Hi, I'm stealing the "Lazy Tutorial" naming from the great Ian Hubert. This is not a proper tutorial, more of a rundown of how I achieved this effect.
#indiegame #gamedev #unity
Please consider supporting me by following me over at / whateep
Custom Function node HLSL code:
#if SHADERGRAPH_PREVIEW
Direction = half3(0.5, 0.5, 0);
Color = 1;
#else
Light light = GetMainLight();
Direction = light.direction;
Color = light.color;
game endif
if you get an error, try this (thanks to John Pitaniello in the comments):
#if defined(SHADERGRAPH_PREVIEW)
Direction = half3(0.5, 0.5, 0);
Color = 1;
#else
Light light = GetMainLight();
Direction = light.direction;
Color = light.color;
#endif
Twitter: / punkpebble_
Discord Server: / discord
Itch.io store page: punkpebblestudio.itch.io/
If you liked this video, you might also like these from other creators:
I Made Among Us, but it's 3D, by Dani: • I Made Among Us, but i...
Game Dev: The Week Before Launch (Devlog) by Jonas Tyroller: • Game Dev: The Week Bef...
HOW TO DRAW PIXEL ART GAME CHARACTERS IN PS - TUTORIAL by Blackthornprod: • HOW TO DRAW PIXEL ART ...
5 Steps to Start Making Games by Thomas Brush: • 5 Steps To Start Makin...
Video Timestamps:
0:00 Intro
0:22 The Idea
0:53 The Shader
2:17 Outro
Video Tags:
#indiegame #gamedev #unity #indiegames #gamedevelopment #programming #3dgame #3dmodeling #lowpoly #blender #photoshop #unrealengine #godot #devlog #indiedev - วิทยาศาสตร์และเทคโนโลยี
Just incase you get any errors in the custom function, be sure to put #if defined(SHADERGRAPH_PREVIEW) instead of
#if SHADERGRAPH_PREVIEW.
I might have copied the wrong code in the description. Thanks, I’ll update that
I used your Code but it still shows errors
it says Shader error in 'Master': "MainLight_float": output parameter 'Direction' not completely initialized at line (and then several lines like 1349 and 289) (on d3d11)
Please help me :,(
@@cubus5451 I was having the same issue - I think the GetMainLight() function doesn't exist in older versions. I used the following code (using _WorldSpaceLightPos0), which seems to work:
#if defined(SHADERGRAPH_PREVIEW)
Direction = half3(0.5, 0.5, 0);
Color = 1;
#else
Direction = _WorldSpaceLightPos0;
Color = 1;
#endif
btw, "Color" is useless, but since I couldn't use GetMainLight(), it was useless anyways :)
@@davidjoelstevenson thanks I‘m going to test this
Such a necessary video material, but an absolutely incomprehensible lesson for beginners.
Noob
You keep showing every part in segments and not really showing how everything connects together. It's hard for me to follow personally
Very helpful explanation! Can't wait to see the post processing on it!
love stuff at this level, fast and an overview of whats important to make a change to whats existing
Nicely done my friend! Very concise and well executed tutorial for a look I've been wanting to achieve for a very long time :D
Hey, thanks dude!
Hi I would love to just keep getting more content of this, this is something I've been looking for, for a minute keep up the great work
Love your videos man! Continue with what you're doing.
I really needed to understand this. Thank you!!!
Can someone help, i cant figure out where to put output of lerp, when i put it in base color just pink texture appears and material becomes just flat color
First, you should make outline as separate shader and material of renderer. Second, you should setup shader graph property, in it's inspector, set render only back side (I don't exactly know what name of property, but you'll find it)
Adore you! This is exactly what I need! You are super cool as always! By the way, cool beard)
Thank you! I appreciate this comment hahaha
just wondering where the Lerp node is meant to connect to, its going off screen. any help would be appreciated.
The Lerp Out(1) should be connected to the Fragment Base Color(3)
Hey im very new to unity and doing anything in shaders, but i'm trying to understand how this works. Like, I have an object with a mesh renderer and multiple materials (with textures and multiple colors, not just a base color). I wanna give that object this type of look. Could I just go to the existing materials and switch them to this shader ? From what I tried, I cant seem to do it like that... or at least I can't seem to make the shader inherit/use the material's already existing color and texture. Do I need to make a new material and shader for every individual material of the object ?? Im very lost. Sorry if it isn't explained well enough :/
Hi Aser! You did a good job explaining your doubts, don’t worry. I’m super busy with work atm. I’ll try to come back and respond to you in a few hours.
If I forget please feel free to reply to this comment again so I get an extra ping
can you show how the final shader looks?
For some reason I had to write:
#if SHADERGRAPH_PREVIEW
Direction = half3(0.5, 0.5, 0);
Color = 1;
#else
Light light = GetMainLight();
Direction = light.direction;
Color = light.color;
#endif
instead of:
#if SHADERGRAPH_PREVIEW
Direction = half3(0.5, 0.5, 0);
Color = 1;
#else
Light light = GetMainLight();
Direction = light.direction;
Color = light.color;
game endif
Which it said in description, why?
Love the vid btw!
I have no idea 😅 I’m glad you got it working
Thanks for the fix!
What is lerp 4 i am unable to find it
Excellent tutorial! Is the fresnel the part of the shader that adds the edge outlines though? If so, they're not appearing for me.
They are in this case, yes, but it has a limitation: it can only appear on the *inside* of the geometry, which means up close you're going to get some funky light behavior
I've found that when I sample the shading ramp the resulting sample is blurry. How do I make sure the colors stay distinct?
Change the import settings of your image to use point filtering. You’re probably now using bilinear. Since you’re already there also make sure to set the repeat mode to clamp
Fantastico grazieee
Thanks for this .👍 but I didn't get how to create this ?? what to use and how?? Ate these in urp sprite lite shader graph ??
This is for 3D, not for 2D. You have to create an Unlit Shader Graph and create the nodes there. The code is put into a Custom Function node. Make sure to define the input and output variables above the code block and specify it exactly how it is written in the parameter names of the code block (spelling and case sensitive, as well as the same order).
Create a material using this shader graph, and apply it to the objects you want to have the toon effect applied.
How do i get the black outline?
Set up color field of shader
How do I make this toon shading work with normal map?
I guess you could sample the normal map and do the same dot product with the light direction, then clamo the results to [0,1] and multiply them
for some reason the normal vector goes all blurry instead of being in 4 quarters like yours is, any ideas why?
You mean the dot product? The 4 bands are due to the shading ramp. You want to make sure the image’s import settings have the filter mode set to point
Hi, I’m a beginner of unity. Could you tell me What type of node is Fresnel Power and Fresnel Threshold?I couldn’t find appropriate node.
Hi! Those are float shader properties that I defined! You can define them and expose them in the inspector and in the shader editor you can drag them into the graph and plug them in the fresnel node
well made video, I really enjoyed it!
Could you maybe explain how to make the shadows in some color too?
I’ll look into it
@@whateep I looked into HDRP and their is no easy way to get acces to shadow, confirmed even by a Unity guy at the forum 3 weeks ago. URP has some "getShadowOrSomething" function though that can be added per custom function node
I would like to use shadows that have some cross hatch, one guy did it by having a pass just for shadows, saved it into a texture and used it then in the next pass to calc custom toon shadows.
Pretty complicated though ;/
I'm getting this error: 'MainLight_float': output parameter 'Direction' not completely initialized
And yes, I've tried the Josh Pitaniello solution, and still gets the error.
how do you solve it?
I was having the same issue - I think the GetMainLight() function doesn't exist in older versions. I used the following code (using _WorldSpaceLightPos0), which seems to work:
#if defined(SHADERGRAPH_PREVIEW)
Direction = half3(0.5, 0.5, 0);
Color = 1;
#else
Direction = _WorldSpaceLightPos0;
Color = 1;
#endif
btw, "Color" is useless, but since I couldn't use GetMainLight(), it was useless anyways :)
any idea on how to make this work with textures instead of just solid colours?
Yes. Add a texture sampler node and multiply the result by the color of the gradient. If you want to retain the texture colors just use grayscale colora for the gradient :)
Great tutorial! Could you tell me the name of the music in the background? Thanks!
Hi! Sorry I just see it. I have no idea, but it’s most likely from the youtube audio library
The outro is too good
I followed this pretty much to the t (except i used the light direction node instead of the custom function) but for some reason my output was always just the middle of the color ramp all around, with no shadows or highlights. Has anyone else had this problem?
There was no light direction node when I made this so I’m not so sure. First thing that comes to mind is check the import settings of the ramp - maybe it is blurred?
yeah, I made sure to use point sampling. Did you use a specific pixel size for the ramp? maybe mine is too large@@whateep
Nevermind, I got it working by mixing this tutorial and another one :)
@@DK-1474 oh great, what was it? Sorry I didn’t reply I got super stuck between work and uni this week
@@whateep ah no problem! I'm not sure actually- I used a different node to reference the texture, so maybe that was it? I ended up using a mix of the light direction node and the custom function too lol
I've tried as much as hard as i follow your guide but i am way too new to the shader environment, can you make an in depth tutorial like step by step or just share the project for me to follow up your guide?, gave a sub because your pixel guide is whack
Actually, I find the first example quite charming, like a pixel 2D shader 0:
(Obviously, I like every kind of toon shader
Oh absolutely, I love that look, too!
could adding this shader to multiple objects in my game cause performance issues?
I don’t think it’s much different from the standard shader
The only way you would get a performance hit from having this shader on multiple objects is if you created a different material for each object. Always try to use the same material where possible in Unity so that the automatic "batching" renders the objects in the same draw call. A tip I recommend if you are doing simple colors is to create a color grid and use that to color your objects via the texture input. If they all share the same material and texture, then you can set your object colors by changing the object's model's UV coordinates. This method works really well for simple models that don't need detail in the textures, but it does require that you either create your own models and setup the color grid in advance, map your UVs in your modeling software and then have the process in full consideration during your workflow.
You could take it a step further and write your own Unity Editor scripts that allow you to configure colors per object and have it modify the models as well as the texture automatically so you can make changes in the editor with less effort, but in my opinion this is a lot more work in the long run and would only be a worthwhile task if you wanted to do the dirty work behind the scenes so that a less experienced asset designer can make a bunch of changes very quickly on their end.
In the dark color and lit color what did you use?
It’s been quite a long time, I do not remember which one did I use. But I do have multiple examples shown on screen so you can get inspired by those and try out your own
@@whateep I'm trying to convert your shader graph example to a similar system in s&box's engine hah, last thing I'd like to ask is where did you actually plug the Lerp and then the sample texture 2d in the end? Because the first one you plugge
I Wonder, if i aply this shader does it save me fps or does it cost some?
How did you get 1 pixel perfect outline?
I did it by sampling the depth texture around multiple times around the pixel I think. I’ll see if I can find that code
@@whateep Did you find that code? :)
Thx
What does the color ramp texture looks like ?
There are some examples shown on screen right as I talk about it in the video
Oh yeah thank you 👍
I was looking for them at the point in the video where you add it to the shadergraph.
👍👍👍
How did you achieve the outlines?
Post process effect sampling the depth map around each pixel
ENGAGEMENT BOOSTER!! x1
Well. I as well as some here had a mistake with Direction. It turns out that I just wrote accidentally into the output "Directions" with S... I feel ashamed.
There’s no need to feel ashamed! You should be proud of yourself for spotting the mistake! Practice makes perfect, remember that :)
@@whateep Huh, thank you!
Hey just wondering can u make a mobile 3rd person controller with joystick and btw ur 10x more handsome with this haircut
My shader cannot take shadows. Help?
This is an unlit shader, so that’s expected. You need to sample the shadowmap, but I’m not sure how to do that in shadergraph
@@whateep I got something to work with the shadows, had to rewrite the Main Light function alittle to include a "ShadowAtten" and "DistanceAtten", and added another dot product wich is taking the first dot, products result and the shadowatten as a and b, then just plugging it in to the add like normal.
MainLight code:
#ifdef SHADERGRAPH_PREVIEW
Direction = normalize(float3(1,1,-0.4));
Color = float4(1,1,1,1);
DistanceAtten = 1;
ShadowAtten = 1;
#else
Light mainLight = GetMainLight();
Direction = mainLight.direction;
Color = mainLight.color;
DistanceAtten = mainLight.distanceAttenuation;
float4 shadowCoord = TransformWorldToShadowCoord(WorldPos);
// or if you want shadow cascades :
// half cascadeIndex = ComputeCascadeIndex(WorldPos);
// float4 shadowCoord = mul(_MainLightWorldToShadow[cascadeIndex], float4(WorldPos, 1.0));
ShadowSamplingData shadowSamplingData = GetMainLightShadowSamplingData();
float shadowStrength = GetMainLightShadowStrength();
ShadowAtten = SampleShadowmap(shadowCoord, TEXTURE2D_ARGS(_MainLightShadowmapTexture, sampler_MainLightShadowmapTexture), shadowSamplingData, shadowStrength, false);
#endif
when making the custom function, it gives an error "Unterminated conditional expression on line 207" D:
same here
Change 'game endif' to '#endif' in the code
@@kavinvardhan1621 Thank you, this fixed this error
@@kavinvardhan1621 Life saver ♥
@@kavinvardhan1621 thank you! ♥
undeclared identifier "direction", please help
Had the same, to fix that make sure you created and setup Universal renderer pipeline (URP), and created your shader graph from the URP option, not the unity bult-in
@@EricDallo13 Did it but still the same error on my side
Hello
Hello to you!
LMAO, you forgot to show the full shader graph at the end
đâsdasdasd