├── ToonShaderExample1.gif ├── Godot_shader_example2.PNG ├── LICENSE ├── toonProva.shader ├── toon_with_texture.shader └── README.md /ToonShaderExample1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakedsnake888/GodotToonShader/HEAD/ToonShaderExample1.gif -------------------------------------------------------------------------------- /Godot_shader_example2.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nakedsnake888/GodotToonShader/HEAD/Godot_shader_example2.PNG -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Simone 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /toonProva.shader: -------------------------------------------------------------------------------- 1 | shader_type spatial; 2 | 3 | uniform sampler2D text : hint_albedo; 4 | uniform sampler2D normal_map : hint_albedo; 5 | uniform vec4 color : hint_color; 6 | uniform bool useTexture = true; 7 | uniform bool useNormalMap = false; 8 | uniform float amount_of_light : hint_range(0.0,1.0); 9 | uniform float amount_of_shadow : hint_range(0.0,1.0); 10 | uniform float cut_point : hint_range(0.0, 1.0); 11 | uniform float normalMapDepth; 12 | 13 | void fragment() 14 | { 15 | if(useTexture) 16 | { 17 | vec3 a1 = texture(text, UV).rgb; 18 | ALBEDO = a1*color.rgb; 19 | } else 20 | { 21 | ALBEDO = color.rgb; 22 | } 23 | if(useNormalMap == true) 24 | { 25 | vec3 normalmap = texture(normal_map, UV).xyz * vec3(2.0,2.0,2.0) - vec3(1.0,1.0,1.0); 26 | vec3 normal = normalize(TANGENT * normalmap.y + BINORMAL * normalmap.x + NORMAL * normalmap.z); 27 | NORMAL = normal; 28 | } else 29 | { 30 | NORMALMAP_DEPTH = 0.0; 31 | } 32 | } 33 | float calc_NdotL(vec3 light, vec3 normal) 34 | { 35 | float NdotL = dot(normalize(light), normal); 36 | return NdotL; 37 | } 38 | float calc_toonStripes(float NdotL) 39 | { 40 | if(NdotL > cut_point) 41 | { 42 | return amount_of_light; 43 | } else 44 | { 45 | return amount_of_shadow; 46 | } 47 | } 48 | void light() 49 | { 50 | float NdotL = calc_NdotL(LIGHT, NORMAL); 51 | float intensity = calc_toonStripes(NdotL); 52 | if(useNormalMap == true) 53 | { 54 | DIFFUSE_LIGHT = ALBEDO*intensity*ATTENUATION; 55 | } else 56 | { 57 | DIFFUSE_LIGHT = ALBEDO*intensity*ATTENUATION; 58 | } 59 | 60 | } -------------------------------------------------------------------------------- /toon_with_texture.shader: -------------------------------------------------------------------------------- 1 | shader_type spatial; 2 | //Texture for light color 3 | uniform sampler2D light_text : hint_albedo; 4 | 5 | //Texture for shadow color (REMEMBER that shadow areas are light_texture multiplied with shadow_texture, basically) 6 | uniform sampler2D shadow_text : hint_albedo; 7 | //this value decides how much "lit" (or "unlit") is the mesh based on NdotL value 8 | uniform float cut_point : hint_range(0.0, 1.0); 9 | //this value set the influence of vertx_color (DEFAULT/IF NOT USED 1) 10 | uniform float adjust_threshold : hint_range (0.0, 1.0); 11 | //this value determine the force of the shadow texture 12 | uniform float shadow_force : hint_range(0.0, 1.0); 13 | //this varying retrieve uv for usage in light pass! 14 | varying vec2 uv; 15 | //this is used for retrieving threshold values from Vector color (REMEMBER that i used channel R(Red) for this) 16 | varying vec4 color; 17 | 18 | //vertex pass -> retriev uv from mesh's UV main channel (channel 0 I think) & will retrieve vertex color for thresholding lighting 19 | void vertex() 20 | { 21 | uv = UV; 22 | color = COLOR; 23 | } 24 | 25 | void fragment() 26 | { 27 | ALBEDO = texture(light_text, uv).rgb; 28 | } 29 | 30 | //This function is used to calculate NdotL 31 | float calc_NdotL(vec3 normal, vec3 light) 32 | { 33 | float NdotL = dot(light, normal); 34 | return NdotL; 35 | } 36 | 37 | //This function is used for calculate shading 38 | bool calc_shading(float sm) 39 | { 40 | if(sm > cut_point) 41 | { 42 | return true; 43 | } else 44 | { 45 | return false; 46 | } 47 | } 48 | 49 | //light pass -> we get LIGHT vector and normalize it, calculate the NdotL, calculate shading and appy LIGHT 50 | //REMEMBER that we aren't really using LIGHT_COLOUR, so it won't affect the mesh colour! 51 | void light() 52 | { 53 | vec3 light = normalize(LIGHT); 54 | vec3 shadow = texture(shadow_text, uv).rgb; 55 | float NdotL = calc_NdotL(NORMAL, light); 56 | vec3 col = color.rgb; 57 | col.g = 1.0; 58 | col.b = 1.0; 59 | float sm = smoothstep(0.0, 1.0, NdotL*(col.r*adjust_threshold)); 60 | bool shade = calc_shading(sm); 61 | if(shade == true) 62 | { 63 | DIFFUSE_LIGHT = ALBEDO; 64 | } else 65 | { 66 | DIFFUSE_LIGHT = ALBEDO*shadow*shadow_force; 67 | } 68 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GodotToonShader 2 | An implementation of a custom toon shader made with Godot shading language. 3 | 4 | ## Godot Simple Toon Shader 5 | 6 | GodotToonShader is my first spatial shader made with Godot Engine. At the current stage it is very simple, but it works. Some customization will come. I hope to help someone out there who was struggling to create shader like me. 7 | 8 | Version 1.0: 9 | 10 | Finally it is online! Currently I'm testing the shader so it's still in an early stage, but it is working good. Normal maps are working good! I don' know (at the moment) if they are pefect but for the moment they are ok. 11 | 12 | How to use it: 13 | 14 | 1) Create a new ShaderMaterial; 15 | 2) Load my toonProva.shader into the shader box; 16 | 3) (TEMPORARY) since it seems that Godot Shading Language has a problem with assigning default values to uniforms (but it should be fixed for release 3.1) you have to Adjust the parameters. 17 | The default values are: 18 | Color -> White (All 1.0) 19 | Use Texture -> On (Still you need to load a texture in order to see textures, so if you just want to use a color turn it off) 20 | Use Normal Map -> Off (To use a normal map, just sey it to "on" and load a normalMap. Remember to import it in the correct way, or they won't work good) 21 | Amount Of Light -> 0.8 (this value indicate to the shader how much "lit" is the surface) 22 | Amount of Shadow -> 0.2 (this value indicate how much "unlit" is the surface) 23 | Cut Point -> 0.5 (It is used to fix the position shadow on the surface) 24 | 25 | And that's it! Feel free to use it anyway you want, i will probably add comments to the code today so you can tune yourself the code if you need it. 26 | 27 | ## Godot Guilty Gear Style Shader (Version 1.0) 28 | 29 |
30 |
31 |
44 |
45 |