This tutorial is totally out of the box, very well done. Unfortunately, there isn't much material out there comparable to this. I believe I can say that most of us are somewhat capable of applying four textures, more or less, but playing with shaders as you do in this tutorial is a whole different story. One cannot expect anything, but if you feel like creating more tutorials like this one, explaining not only how to do something but also why it’s done a certain way, the appreciation won't take long to follow... Cheers.
Thank you so much for the kind words 😮😊! Those kind of comments really make me want to do more! More tutorial are definitely coming although as I am currently working on an unreal engine game they will much likely be on unreal. I do intend to come back to Godot eventually but you will probably have to wait a year for those kind of tutorials 😢
@@pinkivic1010 "There's absolutely no problem at all! It's only right that everyone does what they feel like doing... In the meantime, you've been a great help with a project I'm working on, and I want to give it a look similar to 1970s Japanese cartoons!"
Hi thank you ☺️! Unfortunately I am currently working on an unreal engine project and subsequently the next tutorial to come will be on unreal. I will probably come back on Godot next year though 😉
For Godot 4.3 the void vertex has to be changed to this: void vertex() { POSITION = vec4(VERTEX.xy, 1.0, 1.0); } Dunno why I didn't see the error popup until a day later, but I was baffled why it wasn't working initially
What do you mean by that? The shader modifies the geometry of your model directly. If you are trying to modify your texture too, you could also move around the UV coordinates of each vertex in the animated object shader
If you want to add a texture to your mesh you can add a sampler2d to your object shader, Pass your texture and in the vertex function sample from that sampler2d using your object uv’s
@@pinkivic1010 I applied the shader material as a surface override and added some transparency hoping that it would show the base surface through the transparent areas, but godot doesn't work like that and instead generated a white texture and turned the entire model transparent instead. Interesting, ok I'll have a go at that, thank you very much!
Great tutorial, very clear explanation-well done! I was wondering how you could add edge detection for two objects positioned right next to each other but made of using two different materials. For example, if you have a blue square and a red square (of the same size) placed side by side, how could you add an edge detection line between them so they appear as two separate boxes?
You could use the roughness of object to add extra lines. Basically you would give different roughness values to object that you wish to have lines between them. Then in the post process shader you could get the roughness pass and find edges on that image too. You could even add custom lines by using roughness textures on your object
@@pinkivic1010 That's an interesting solution! Apologies, I'm quite new to GDScript and was wondering how that might look? Edit: I've put together something that sort of works, but it definitely needs some fine-tuning. void fragment() { // SCREEN TEXTURE vec3 original = get_original(SCREEN_UV);
Okay, you want to look at this documentation docs.godotengine.org/en/stable/tutorials/shaders/screen-reading_shaders.html#doc-screen-reading-shaders Under normal- roughness It tells you how you can get the roughness data of your scene. Then you can do the same math as we did with the depth texture.(you might have to multiply it a bit for better results) You can then add this outline to the other.
So i have a few questions. 1 I'm trying to make a "comic book style" shader and id like to apply it to the entire game. how would I do what you have done with the character but on everything? 2 How would I make it so the hash shading only updates when the vertex displacement updates? 3 I assume this works with colors underneath? 4 Do you have a discord server for better questions and responses?
No discord yet but that’s a good idea 1: The simplest way to apply the hatching effect to everything would be in the post process shader, you can Calculate the world coordinates (you can find that in the Godot documentation) and then multiply it by an arbitrary vector and use it as your UV texture also multiply it by the normal so that it wraps around the object, you might also use other techniques to break out the repetition. Now there is still the problem of knowing the amount of light on each pixel, Godot currently does not give us access to the unshaded view (which would enable us to calculate the light amount) so the simplest way is to pass the light as a V3 uniform in your post process shader However doing this in the post process shader as it’s limitation, objects that moves trough spaces will have their texture move with them(which is not a problem if you can make sure all your moving elements are perfectly static in between frame) A GitHub request was made on the Godot repo to add it. 2: as said before if your moving objects are perfectly still in between frames, the hatching will not move (all elements that can affect your movable objects should use the rounded time technique) 3: yes as shown in the tutorial, you can add some V3 uniforms to your objects shader(for color)or a sampler2D (texture)
This is a good tutorial but do you mind lower the volume of the music next time or not have ant music please? Not having music makes watching in x2 speed possible also it's a not too loud to hear you easily. it is nice music
Wonderful work! Do you have any script to generate the Stop Motion effect with 3D models but also work with transitions, or what would you recommend? Thanks
I'm referring to Blend, the transitions between animations: For example, going from Run to Idle in a smooth way. animation.play(Name,Blend,Speed) I implemented your code, I made many adjustments but I managed to keep the blend parameters. What would you recommend? Thanks
Aaaa I see, I have no idea on how you might do it 🤷 you will have to go trough Godot documentation to find out, The best way to do it would probably be by first calculating your animation with blend and all the other fancy stuff you might want and then somehow only sample from every so often. Maybe you could have two skeletal mesh the first would behave normally, no choppiness , with smoothing and all the cool animation stuff you might want. This first mesh would be hidden in game(you don’t render it but it’s still there) The second mesh would copy the first mesh skeletal pose every so often. I don’t know if such a thing is possible (copying a pose from one mesh to another)in Godot but it’s worth looking into (or implementing yourself too!), it would be a pretty clean solution as you would be free to animate the first mesh however you want.
Yes kind of but it is a hacky solution. Ideally we would need Godot to give us the unshaded view (so that we can compare it to the default one and see how much light is hitting each pixel) A Pull request was made so this might be possible some time in the future. The Hacky solution is to override the light shader to put a specific color on the part of your object that is receiving light and then reading that colour in our post process shader and transforming it into our hatching. This however will make you lose some colors but you can find more hacky solution to kind of work around it If you are interested you could try to contact me directly on my instagram @pinkivic.3.d so I can share the code with you.
Thanks for the tutorial! I can't seem to see my vfx (gpu particles) trough the shader. Is their a change to the shader itself or the gpu particles I can make to be able to see them?
Right now I don’t think Godot post processes have access to transparent object. You might want to read trough the documentation for shader( I put a link in the description to it) and you might find a workaround. Until Godot updates their post process I think the easiest solution would be to simply not use transparency and make your particle mesh use the desired shape (it’s obviously not an optimal solution but it could work well based on the style of your game…)
my left ear felt that
Sorry I did not realise I messed up the sound as I was editing on my speaker 💀
You got a patreon? Pleaee dont quit, the last guy to make high quality shader tutorials quit after a couple months.
could you please share their channel
please don't stop making shaders, I wouldn't mind a patreon either
Thanks! I’m working on an unreal project right now but I will definitely come back for some more godot
Man, this is amazing material. Was a bit afraid of the math at first but everything is crystal clear. Congrats !!
Awesome, thank you! ☺️
This tutorial is totally out of the box, very well done. Unfortunately, there isn't much material out there comparable to this. I believe I can say that most of us are somewhat capable of applying four textures, more or less, but playing with shaders as you do in this tutorial is a whole different story. One cannot expect anything, but if you feel like creating more tutorials like this one, explaining not only how to do something but also why it’s done a certain way, the appreciation won't take long to follow... Cheers.
Thank you so much for the kind words 😮😊!
Those kind of comments really make me want to do more!
More tutorial are definitely coming although as I am currently working on an unreal engine game they will much likely be on unreal.
I do intend to come back to Godot eventually but you will probably have to wait a year for those kind of tutorials 😢
@@pinkivic1010 "There's absolutely no problem at all! It's only right that everyone does what they feel like doing... In the meantime, you've been a great help with a project I'm working on, and I want to give it a look similar to 1970s Japanese cartoons!"
I’m glad it helped! Be sure to let me know when you start posting about it 😉
Thanks for the tutorial. It's probably the best shader video for godot
Glad it helped 🥰
please more godot tutorials , you have no idea how much it means for the godot people
Hi thank you ☺️! Unfortunately I am currently working on an unreal engine project and subsequently the next tutorial to come will be on unreal.
I will probably come back on Godot next year though 😉
For Godot 4.3 the void vertex has to be changed to this:
void vertex() {
POSITION = vec4(VERTEX.xy, 1.0, 1.0);
}
Dunno why I didn't see the error popup until a day later, but I was baffled why it wasn't working initially
Thanks for sharing that 😌!
New to Godot, 4 years on Unity, your lecture is amazing.
really cool and simply presented thanks
Thank you 🙏, I’m still new at the whole making TH-cam video so it can only get better from here to 😉
OMG you are a genius! You are a LIFESAVER!! Thank you for making this video and sharing this shader with us.
Glad it helped ☺️
this is amazing, keep up the good work.
Thanks 😊!
Very interesting ! Keep up the good work :)
Thanks, will do!
This is really cool! I had a play around with it to see if I could get it to deform a mesh with UVs but it only works on a solid colour it seems.
What do you mean by that?
The shader modifies the geometry of your model directly.
If you are trying to modify your texture too, you could also move around the UV coordinates of each vertex in the animated object shader
If you want to add a texture to your mesh you can add a sampler2d to your object shader,
Pass your texture and in the vertex function sample from that sampler2d using your object uv’s
@@pinkivic1010 I applied the shader material as a surface override and added some transparency hoping that it would show the base surface through the transparent areas, but godot doesn't work like that and instead generated a white texture and turned the entire model transparent instead. Interesting, ok I'll have a go at that, thank you very much!
Looks really nice! I like the hand drawn look of the shaded areas.
Thank you!
Awesome work brother, like everyone else says keep up the good work! Would love to see more videos from you. Thanks for the tutorial!
So cool! Gonna try it right away
Fantastic work!
Great tutorial, thanks for sharing!
This is awesome, you explained everything very well. Could you try making a tutorial on toon shading (cel shading)?
th-cam.com/video/io2y8RgF39A/w-d-xo.htmlsi=BYArcxndyWX4m146 this one on cell shading on Godot is really good
@@pinkivic1010 thanks mate
looks so good
Thank you ☺️!
Such an entertaining and educational video. Loved it. I'd like to point out that your voice is only on the left side of the spatial sound.
Yep editing mistake sorry 😔
This was awesome, thanks for sharing!
Thanks ☺️
Looks beautiful, thanks
Very nice video !! thanks for your work
Great tutorial, very clear explanation-well done!
I was wondering how you could add edge detection for two objects positioned right next to each other but made of using two different materials. For example, if you have a blue square and a red square (of the same size) placed side by side, how could you add an edge detection line between them so they appear as two separate boxes?
You could use the roughness of object to add extra lines.
Basically you would give different roughness values to object that you wish to have lines between them.
Then in the post process shader you could get the roughness pass and find edges on that image too.
You could even add custom lines by using roughness textures on your object
@@pinkivic1010 That's an interesting solution! Apologies, I'm quite new to GDScript and was wondering how that might look?
Edit: I've put together something that sort of works, but it definitely needs some fine-tuning.
void fragment() {
// SCREEN TEXTURE
vec3 original = get_original(SCREEN_UV);
// NORMAL
vec3 normal = get_normal(SCREEN_UV);
// DEPTH
float depth = get_depth(SCREEN_UV, INV_PROJECTION_MATRIX);
// GET SURROUNDING TEXEL
vec2 texel_size = line_thickness / VIEWPORT_SIZE.xy;
vec2 uvs[4]; // array containing the uvs of the surrounding pixel
uvs[0] = vec2(SCREEN_UV.x, SCREEN_UV.y + texel_size.y );
uvs[1] = vec2(SCREEN_UV.x, SCREEN_UV.y - texel_size.y );
uvs[2] = vec2(SCREEN_UV.x + texel_size.x, SCREEN_UV.y);
uvs[3] = vec2(SCREEN_UV.x - texel_size.x, SCREEN_UV.y);
// EDGE DETECTION
float depth_diff = 0.0;
float normal_sum = 0.0;
float color_diff_sum = 0.0;
for (int i = 0; i < 4; i++) {
// Depth difference
float d = get_depth(uvs[i], INV_PROJECTION_MATRIX);
depth_diff += depth - d;
// Normal difference
vec3 n = get_normal(uvs[i]);
vec3 normal_diff = normal - n;
vec3 normal_edge_bias = vec3(1.0, 1.0, 1.0);
float normal_bias_diff = dot(normal_diff, normal_edge_bias);
float normal_indicator = smoothstep(-0.01, 0.01, normal_bias_diff);
normal_sum += dot(normal_diff, normal_diff) * normal_indicator;
// Color difference for edge detection
vec3 color_neighbor = get_original(uvs[i]);
vec3 color_diff = abs(original - color_neighbor);
color_diff_sum += dot(color_diff, vec3(0.3, 0.59, 0.11)); // Using luminance factors for perceptual difference
}
// Thresholds
float depth_edge = step(depth_treshold, depth_diff);
float color_edge = step(0.1, color_diff_sum); // Adjust the threshold as needed for color edges
// Combine all edge detection methods
float outline = depth_edge + normal_sum + color_edge;
ALBEDO = mix(original, outline_color, outline);
}
Okay, you want to look at this documentation
docs.godotengine.org/en/stable/tutorials/shaders/screen-reading_shaders.html#doc-screen-reading-shaders
Under normal- roughness
It tells you how you can get the roughness data of your scene.
Then you can do the same math as we did with the depth texture.(you might have to multiply it a bit for better results)
You can then add this outline to the other.
Cool, saw this on Reddit
bro this is insane wtf genius
Great job on this!
So i have a few questions.
1 I'm trying to make a "comic book style" shader and id like to apply it to the entire game. how would I do what you have done with the character but on everything?
2 How would I make it so the hash shading only updates when the vertex displacement updates?
3 I assume this works with colors underneath?
4 Do you have a discord server for better questions and responses?
No discord yet but that’s a good idea
1:
The simplest way to apply the hatching effect to everything would be in the post process shader, you can Calculate the world coordinates (you can find that in the Godot documentation) and then multiply it by an arbitrary vector and use it as your UV texture also multiply it by the normal so that it wraps around the object, you might also use other techniques to break out the repetition.
Now there is still the problem of knowing the amount of light on each pixel, Godot currently does not give us access to the unshaded view (which would enable us to calculate the light amount) so the simplest way is to pass the light as a V3 uniform in your post process shader
However doing this in the post process shader as it’s limitation, objects that moves trough spaces will have their texture move with them(which is not a problem if you can make sure all your moving elements are perfectly static in between frame)
A GitHub request was made on the Godot repo to add it.
2: as said before if your moving objects are perfectly still in between frames, the hatching will not move (all elements that can affect your movable objects should use the rounded time technique)
3: yes as shown in the tutorial, you can add some V3 uniforms to your objects shader(for color)or a sampler2D (texture)
If you have further questions or if you want to share your results, contact me on my LinkedIn Victor Steimberg
Very nice, keep going!
This is a good tutorial but do you mind lower the volume of the music next time or not have ant music please? Not having music makes watching in x2 speed possible also it's a not too loud to hear you easily. it is nice music
Wonderful work!
Do you have any script to generate the Stop Motion effect with 3D models but also work with transitions, or what would you recommend?
Thanks
Hello I’m not sure what you mean by transitions 🤔
I'm referring to Blend, the transitions between animations:
For example, going from Run to Idle in a smooth way.
animation.play(Name,Blend,Speed)
I implemented your code, I made many adjustments but I managed to keep the blend parameters.
What would you recommend?
Thanks
Aaaa I see, I have no idea on how you might do it 🤷 you will have to go trough Godot documentation to find out,
The best way to do it would probably be by first calculating your animation with blend and all the other fancy stuff you might want and then somehow only sample from every so often.
Maybe you could have two skeletal mesh the first would behave normally, no choppiness , with smoothing and all the cool animation stuff you might want.
This first mesh would be hidden in game(you don’t render it but it’s still there)
The second mesh would copy the first mesh skeletal pose every so often.
I don’t know if such a thing is possible (copying a pose from one mesh to another)in Godot but it’s worth looking into (or implementing yourself too!), it would be a pretty clean solution as you would be free to animate the first mesh however you want.
You can add me on discord if you want to discuss it further I’d love to see how you do it
My discord name is “Pinkivic”
This is an awesome tutorial! Is there any way to get this shader to consider the lighting like the light shader does rather than a static vec3?
Yes kind of but it is a hacky solution.
Ideally we would need Godot to give us the unshaded view (so that we can compare it to the default one and see how much light is hitting each pixel)
A Pull request was made so this might be possible some time in the future.
The Hacky solution is to override the light shader to put a specific color on the part of your object that is receiving light and then reading that colour in our post process shader and transforming it into our hatching.
This however will make you lose some colors but you can find more hacky solution to kind of work around it
If you are interested you could try to contact me directly on my instagram @pinkivic.3.d so I can share the code with you.
please do not put the main voice on left side. it is quite uncomfortable. But overall thanks for your tutorial, this is so helpful!
Yeah sorry about that, I did not notice as I edited this video on my speakers…
How do u make the colour be the same colour as the material of the mesh?
You can pass the color as an uniform in your animated object shader.
instead of using white you can then use your color.
@@pinkivic1010 thx
Imma subscribe
Thank u ☺️
Thanks for the tutorial! I can't seem to see my vfx (gpu particles) trough the shader. Is their a change to the shader itself or the gpu particles I can make to be able to see them?
Right now I don’t think Godot post processes have access to transparent object.
You might want to read trough the documentation for shader( I put a link in the description to it) and you might find a workaround.
Until Godot updates their post process I think the easiest solution would be to simply not use transparency and make your particle mesh use the desired shape (it’s obviously not an optimal solution but it could work well based on the style of your game…)
@@pinkivic1010 it does seems to be the issue, thanks alot for responding
No problem good luck to you
I wonder how it woud look if the character movement where also updated with the same limited framerate
StereoToMono browser extension, thank me later