add cel shader

This commit is contained in:
Teatov 2025-02-27 02:08:29 +10:00
parent 02e18694d5
commit 352004a393
16 changed files with 565 additions and 7 deletions

View File

@ -1,6 +1,16 @@
[gd_resource type="StandardMaterial3D" load_steps=2 format=3 uid="uid://bq6dojq8d7rk0"]
[gd_resource type="ShaderMaterial" load_steps=3 format=3 uid="uid://b685alw05nef"]
[ext_resource type="Texture2D" uid="uid://fj76wlr61buq" path="res://assets/textures/characters/batrix_bat_diffuse.png" id="1_p4uo6"]
[ext_resource type="Shader" path="res://shaders/cel_shader/cel_shader_base.gdshader" id="1_vv82l"]
[resource]
albedo_texture = ExtResource("1_p4uo6")
render_priority = 0
shader = ExtResource("1_vv82l")
shader_parameter/specular_smoothness = 0.05
shader_parameter/fresnel_smoothness = 0.05
shader_parameter/color = Color(1, 1, 1, 1)
shader_parameter/specular = Color(0.75, 0.75, 0.75, 0.552941)
shader_parameter/fresnel = Color(0.8, 0.8, 0.8, 0.615686)
shader_parameter/base_texture = ExtResource("1_p4uo6")
shader_parameter/uv_scale = Vector2(1, 1)
shader_parameter/uv_offset = Vector2(0, 0)

View File

@ -1,7 +1,16 @@
[gd_resource type="StandardMaterial3D" load_steps=2 format=3 uid="uid://dvr5ptylromau"]
[gd_resource type="ShaderMaterial" load_steps=3 format=3 uid="uid://ouhs42rmw6h6"]
[ext_resource type="Shader" path="res://shaders/cel_shader/cel_shader_no_culling.gdshader" id="1_3ide7"]
[ext_resource type="Texture2D" uid="uid://cv5cnlgxx3rud" path="res://assets/textures/characters/batrix_diffuse.png" id="1_8x1pe"]
[resource]
cull_mode = 2
albedo_texture = ExtResource("1_8x1pe")
render_priority = 0
shader = ExtResource("1_3ide7")
shader_parameter/specular_smoothness = 0.05
shader_parameter/fresnel_smoothness = 0.05
shader_parameter/color = Color(1, 1, 1, 1)
shader_parameter/specular = Color(0, 0, 0, 0)
shader_parameter/fresnel = Color(0.4, 0.4, 0.4, 0.690196)
shader_parameter/base_texture = ExtResource("1_8x1pe")
shader_parameter/uv_scale = Vector2(1, 1)
shader_parameter/uv_offset = Vector2(0, 0)

View File

@ -118,7 +118,7 @@ bones/6/rotation = Quaternion(-0.0323581, 2.46001e-07, 8.00608e-09, 0.999476)
bones/7/rotation = Quaternion(0.123965, -2.40098e-07, -2.92456e-09, 0.992287)
bones/7/scale = Vector3(1, 1, 1)
bones/8/rotation = Quaternion(-0.0917916, -2.67583e-15, 2.18848e-08, 0.995778)
bones/9/position = Vector3(-0.074, 0.011816, 0.0814253)
bones/9/position = Vector3(-0.0725585, 0.011605, 0.0832403)
bones/9/rotation = Quaternion(1.15202e-07, 0.707107, 0.707107, -5.33851e-08)
bones/9/scale = Vector3(1, 1, 1)
bones/21/rotation = Quaternion(0.19747, 0.678974, 0.678974, -0.19747)
@ -132,7 +132,7 @@ bones/45/scale = Vector3(1, 1, 1)
bones/46/rotation = Quaternion(-0.0181733, 2.38379e-07, 1.14098e-08, 0.999835)
bones/47/rotation = Quaternion(-1.20807e-07, 0.993087, -0.117383, 7.85287e-07)
bones/49/rotation = Quaternion(-0.034235, -3.57418e-07, 8.86969e-08, 0.999414)
bones/50/rotation = Quaternion(0.276203, -0.650931, -0.650931, -0.276203)
bones/50/rotation = Quaternion(-0.142502, -0.692599, -0.692599, 0.142502)
bones/51/rotation = Quaternion(0.403888, -2.98082e-07, -3.85178e-07, 0.914808)
bones/51/scale = Vector3(1, 1, 1)
bones/52/rotation = Quaternion(-0.512846, 3.82068e-07, 4.27952e-07, 0.858481)
@ -249,6 +249,12 @@ bones/175/scale = Vector3(1, 1, 1.00001)
bones/176/rotation = Quaternion(0.0296713, 1.1925e-07, -7.47368e-09, 0.99956)
bones/180/rotation = Quaternion(-0.730424, 1.08982e-07, 2.31437e-07, 0.682994)
[node name="Mesh" parent="Model/Armature/Skeleton3D" index="0"]
cast_shadow = 0
[node name="MeshBat" parent="Model/Armature/Skeleton3D" index="1"]
cast_shadow = 0
[node name="AnimationPlayer" parent="Model" index="1"]
autoplay = "RESET"

View File

@ -0,0 +1,53 @@
// https://github.com/eldskald/godot4-cel-shader
shader_type spatial;
#define USE_ALPHA_CUTOFF 1
render_mode cull_disabled;
#include "includes/base_cel_shader.gdshaderinc"
group_uniforms BaseProperties;
#if USE_ALPHA_CUTOFF
uniform float alpha_cutoff : hint_range(0.0, 1.0) = 0.5;
#endif
uniform vec4 color : source_color = vec4(0.7, 0.12, 0.86, 1.0);
uniform sampler2D base_texture : source_color;
uniform vec4 specular : source_color = vec4(0.3, 0.3, 0.3, 0.5);
uniform sampler2D specular_texture : hint_default_white;
uniform vec4 fresnel : source_color = vec4(0.2, 0.2, 0.2, 0.3);
uniform sampler2D fresnel_texture : hint_default_white;
group_uniforms;
varying vec3 SPECULAR_COLOR;
varying float SPECULAR_STRENGTH;
varying vec3 FRESNEL_COLOR;
varying float FRESNEL_STRENGTH;
group_uniforms Tiling;
uniform vec2 uv_scale = vec2(1, 1);
uniform vec2 uv_offset = vec2(0, 0);
group_uniforms;
void vertex() { UV = UV * uv_scale.xy + uv_offset.xy; }
void fragment() {
ALBEDO = color.rgb * texture(base_texture, UV).rgb;
#if USE_ALPHA_CUTOFF
ALPHA = color.a * texture(base_texture, UV).a;
ALPHA_SCISSOR_THRESHOLD = alpha_cutoff;
#endif
SPECULAR_COLOR = specular.rgb * texture(specular_texture, UV).rgb;
SPECULAR_STRENGTH = specular.a * texture(specular_texture, UV).a;
FRESNEL_COLOR = fresnel.rgb * texture(fresnel_texture, UV).rgb;
FRESNEL_STRENGTH = fresnel.a * texture(fresnel_texture, UV).a;
}
void light() {
DIFFUSE_LIGHT +=
diffuse_light(ALBEDO, LIGHT_COLOR, LIGHT, NORMAL, ATTENUATION);
SPECULAR_LIGHT += fresnel_light(LIGHT_COLOR, FRESNEL_COLOR, FRESNEL_STRENGTH,
NORMAL, VIEW, LIGHT, ATTENUATION);
}

View File

@ -0,0 +1,154 @@
// https://github.com/eldskald/godot4-cel-shader
shader_type spatial;
#define USE_ALPHA 0
#define USE_ALPHA_CUTOFF 0
#define USE_EMISSION 0
#define USE_REFLECTIONS 0
#define USE_NORMAL_MAP 0
#define USE_OCCLUSION 0
#define USE_ANISOTROPY 0
#define USE_BACKLIGHT 0
#define USE_REFRACTION 0
#if USE_ALPHA
render_mode depth_draw_always;
#endif
#include "includes/base_cel_shader.gdshaderinc"
#if USE_EMISSION
#include "includes/emission.gdshaderinc"
#endif
#if USE_REFLECTIONS
#include "includes/reflections.gdshaderinc"
#endif
#if USE_NORMAL_MAP
#include "includes/normal_map.gdshaderinc"
#endif
#if USE_OCCLUSION
#include "includes/occlusion.gdshaderinc"
#endif
#if USE_ANISOTROPY
#include "includes/anisotropy.gdshaderinc"
#endif
#if USE_BACKLIGHT
#include "includes/backlight.gdshaderinc"
#endif
#if USE_REFRACTION
#include "includes/refraction.gdshaderinc"
#elif !USE_REFRACTION && USE_ALPHA
#include "includes/transparency.gdshaderinc"
#endif
group_uniforms BaseProperties;
#if USE_ALPHA_CUTOFF
uniform float alpha_cutoff : hint_range(0.0, 1.0) = 0.5;
#endif
uniform vec4 color : source_color = vec4(0.7, 0.12, 0.86, 1.0);
uniform sampler2D base_texture : source_color;
uniform vec4 specular : source_color = vec4(0.3, 0.3, 0.3, 0.5);
uniform sampler2D specular_texture : hint_default_white;
uniform vec4 fresnel : source_color = vec4(0.2, 0.2, 0.2, 0.3);
uniform sampler2D fresnel_texture : hint_default_white;
group_uniforms;
varying vec3 SPECULAR_COLOR;
varying float SPECULAR_STRENGTH;
varying vec3 FRESNEL_COLOR;
varying float FRESNEL_STRENGTH;
group_uniforms Tiling;
uniform vec2 uv_scale = vec2(1, 1);
uniform vec2 uv_offset = vec2(0, 0);
group_uniforms;
void vertex() { UV = UV * uv_scale.xy + uv_offset.xy; }
void fragment() {
ALBEDO = color.rgb * texture(base_texture, UV).rgb;
#if USE_ALPHA
float alpha = color.a * texture(base_texture, UV).a;
ALBEDO *= alpha;
ALPHA = alpha;
#elif USE_ALPHA_CUTOFF
ALPHA = color.a * texture(base_texture, UV).a;
ALPHA_SCISSOR_THRESHOLD = alpha_cutoff;
#endif
#if USE_REFRACTION && USE_ALPHA
EMISSION += refraction_fragment(alpha, NORMAL, SCREEN_UV, FRAGCOORD.z);
#elif !USE_REFRACTION && USE_ALPHA
EMISSION += transparency_fragment(alpha, SCREEN_UV);
#endif
SPECULAR_COLOR = specular.rgb * texture(specular_texture, UV).rgb;
SPECULAR_STRENGTH = specular.a * texture(specular_texture, UV).a;
FRESNEL_COLOR = fresnel.rgb * texture(fresnel_texture, UV).rgb;
FRESNEL_STRENGTH = fresnel.a * texture(fresnel_texture, UV).a;
#if USE_EMISSION
EMISSION += emission_fragment(UV);
#endif
#if USE_REFLECTIONS
Surface surf = reflections_fragment(UV);
METALLIC = surf.metallic;
ROUGHNESS = surf.roughness;
#endif
#if USE_NORMAL_MAP
NormalData normal = normal_map_fragment(UV, NORMAL, TANGENT, BINORMAL);
NORMAL = normal.vector;
NORMAL_MAP = normal.map;
NORMAL_MAP_DEPTH = normal.depth;
#endif
#if USE_OCCLUSION
OcclusionData occlusion = occlusion_fragment(UV);
AO = occlusion.ao;
AO_LIGHT_AFFECT = occlusion.ao_light_affect;
#endif
#if USE_ANISOTROPY
AnisotropyData aniso = anisotropy_fragment(UV);
ANISOTROPY_DIR = aniso.direction;
ANISOTROPY_RATIO = aniso.ratio;
#endif
#if USE_BACKLIGHT
BACKLIGHT = backlight_fragment(UV);
#endif
}
void light() {
#if USE_BACKLIGHT
DIFFUSE_LIGHT += backlight_diffuse(ALBEDO, LIGHT_COLOR, LIGHT, NORMAL,
ATTENUATION, BACKLIGHT);
#else
DIFFUSE_LIGHT +=
diffuse_light(ALBEDO, LIGHT_COLOR, LIGHT, NORMAL, ATTENUATION);
#endif
#if USE_ANISOTROPY
SPECULAR_LIGHT += anisotropy_specular(
LIGHT_COLOR, SPECULAR_COLOR, SPECULAR_STRENGTH, NORMAL, VIEW, LIGHT,
ATTENUATION, UV, ANISOTROPY_DIR, ANISOTROPY_RATIO);
#else
SPECULAR_LIGHT +=
specular_light(LIGHT_COLOR, SPECULAR_COLOR, SPECULAR_STRENGTH, NORMAL,
VIEW, LIGHT, ATTENUATION);
#endif
SPECULAR_LIGHT += fresnel_light(LIGHT_COLOR, FRESNEL_COLOR, FRESNEL_STRENGTH,
NORMAL, VIEW, LIGHT, ATTENUATION
//);
) *
2.0;
}

View File

@ -0,0 +1,47 @@
// https://github.com/eldskald/godot4-cel-shader
shader_type spatial;
render_mode cull_disabled;
#include "includes/base_cel_shader.gdshaderinc"
group_uniforms BaseProperties;
uniform vec4 color : source_color = vec4(0.7, 0.12, 0.86, 1.0);
uniform sampler2D base_texture : source_color;
uniform vec4 specular : source_color = vec4(0.3, 0.3, 0.3, 0.5);
uniform sampler2D specular_texture : hint_default_white;
uniform vec4 fresnel : source_color = vec4(0.2, 0.2, 0.2, 0.3);
uniform sampler2D fresnel_texture : hint_default_white;
group_uniforms;
varying vec3 SPECULAR_COLOR;
varying float SPECULAR_STRENGTH;
varying vec3 FRESNEL_COLOR;
varying float FRESNEL_STRENGTH;
group_uniforms Tiling;
uniform vec2 uv_scale = vec2(1, 1);
uniform vec2 uv_offset = vec2(0, 0);
group_uniforms;
void vertex() { UV = UV * uv_scale.xy + uv_offset.xy; }
void fragment() {
ALBEDO = color.rgb * texture(base_texture, UV).rgb;
SPECULAR_COLOR = specular.rgb * texture(specular_texture, UV).rgb;
SPECULAR_STRENGTH = specular.a * texture(specular_texture, UV).a;
FRESNEL_COLOR = fresnel.rgb * texture(fresnel_texture, UV).rgb;
FRESNEL_STRENGTH = fresnel.a * texture(fresnel_texture, UV).a;
}
void light() {
DIFFUSE_LIGHT +=
diffuse_light(ALBEDO, LIGHT_COLOR, LIGHT, NORMAL, ATTENUATION);
SPECULAR_LIGHT += fresnel_light(LIGHT_COLOR, FRESNEL_COLOR, FRESNEL_STRENGTH,
NORMAL, VIEW, LIGHT, ATTENUATION
//);
) *
2.0;
}

View File

@ -0,0 +1,55 @@
#include "base_cel_shader.gdshaderinc"
group_uniforms Anisotropy;
uniform float anisotropy_ratio: hint_range(-1,1) = 0.0;
uniform vec3 anisotropy_direction = vec3(0.0, -1.0, 0.0);
uniform float aniso_map_dir_ratio: hint_range(0,1) = 0.0;
uniform sampler2D anisotropy_flowmap: hint_anisotropy;
uniform float specular_smoothness = 0.05;
group_uniforms;
varying vec3 ANISOTROPY_DIR;
varying float ANISOTROPY_RATIO;
struct AnisotropyData {
vec3 direction;
float ratio;
};
AnisotropyData anisotropy_fragment(vec2 uv) {
return AnisotropyData(
mix(
normalize(anisotropy_direction),
texture(anisotropy_flowmap, uv).rgb * 2.0 - 1.0,
aniso_map_dir_ratio
),
anisotropy_ratio * texture(anisotropy_flowmap, uv).a
);
}
vec3 anisotropy_specular(
vec3 light_color,
vec3 specular_color,
float specular_strength,
vec3 normal,
vec3 view,
vec3 light,
float attenuation,
vec2 uv,
vec3 aniso_dir,
float aniso_ratio
) {
vec3 half = normalize(view + light);
float aniso = max(0, sin(dot(normalize(normal + aniso_dir), half) * PI));
float spec = mix(dot(normal, half), aniso, aniso_ratio);
float spec_gloss = pow(2.0, 8.0 * (1.0 - specular_strength));
float spec_intensity = smoothstep(
0.05,
0.05 + specular_smoothness,
pow(spec, spec_gloss * spec_gloss)
);
return light_color
* specular_color
* spec_intensity
* is_lit(light, normal, attenuation);
}

View File

@ -0,0 +1,23 @@
#include "base_cel_shader.gdshaderinc"
group_uniforms Backlight;
uniform vec3 backlight : source_color;
uniform sampler2D backlight_texture : hint_default_white;
group_uniforms;
vec3 backlight_fragment(vec2 uv) {
return backlight * texture(backlight_texture, uv).rgb;
}
vec3 backlight_diffuse(
vec3 albedo,
vec3 light_color,
vec3 light,
vec3 normal,
float attenuation,
vec3 backlight_color
) {
float value = diffuse_sample(light, normal);
return albedo * light_color * attenuation
* (value + backlight_color * (1.0 - value));
}

View File

@ -0,0 +1,69 @@
// global uniform sampler2D diffuse_curve: repeat_disable;
// global uniform float specular_smoothness;
// global uniform float fresnel_smoothness;
uniform float specular_smoothness = 0.05;
uniform float fresnel_smoothness = 0.05;
float diffuse_sample(vec3 light, vec3 normal) {
// float remapped = (dot(light, normal) - (-1.0))/(1.0 - (-1.0));
// return texture(diffuse_curve, vec2(remapped, 1.0)).r;
return (dot(light, normal) - (-1.0))/(1.0 - (-1.0));
}
float is_lit(vec3 light, vec3 normal, float attenuation) {
return attenuation * diffuse_sample(light, normal);
}
vec3 diffuse_light(
vec3 albedo,
vec3 light_color,
vec3 light,
vec3 normal,
float attenuation
) {
// return albedo * light_color * is_lit(light, normal, attenuation);
return light_color * is_lit(light, normal, attenuation);
}
vec3 specular_light(
vec3 light_color,
vec3 specular_color,
float specular_strength,
vec3 normal,
vec3 view,
vec3 light,
float attenuation
) {
vec3 half = normalize(view + light);
float gloss = pow(2.0, 8.0 * (1.0 - specular_strength));
float intensity = pow(dot(normal, half), gloss * gloss);
return light_color
* specular_color
* is_lit(light, normal, attenuation)
* smoothstep(
0.05,
0.05 + specular_smoothness,
intensity
);
}
vec3 fresnel_light(
vec3 light_color,
vec3 fresnel_color,
float fresnel_strength,
vec3 normal,
vec3 view,
vec3 light,
float attenuation
) {
float fresnel_dot = 1.0 - dot(normal, view);
float fresnel_threshold = pow((1.0 - fresnel_strength), dot(light, normal));
return light_color
* fresnel_color
* is_lit(light, normal, attenuation)
* smoothstep(
fresnel_threshold - fresnel_smoothness / 2.0,
fresnel_threshold + fresnel_smoothness / 2.0,
fresnel_dot
);
}

View File

@ -0,0 +1,9 @@
group_uniforms Emission;
uniform vec4 emission : source_color = vec4(0.0, 0.0, 0.0, 1.0);
uniform float emission_energy = 1.0;
uniform sampler2D emission_texture : hint_default_black;
group_uniforms;
vec3 emission_fragment(vec2 uv) {
return (emission.rgb + texture(emission_texture, uv).rgb) * emission_energy;
}

View File

@ -0,0 +1,28 @@
group_uniforms NormalMap;
uniform float normal_scale : hint_range(-16,16) = 1.0;
uniform sampler2D normal_map : hint_normal;
group_uniforms;
struct NormalData {
vec3 vector;
vec3 map;
float depth;
};
NormalData normal_map_fragment(
vec2 uv,
vec3 normal,
vec3 tangent,
vec3 binormal,
) {
vec3 map = texture(normal_map, uv).rgb;
vec3 vector = map;
vector.xy = vector.xy * 2.0 - 1.0;
vector.z = sqrt(max(0.0, 1.0 - dot(vector.xy, vector.xy)));
vec3 ref_normal = normalize(mix(
normal,
tangent * vector.x + binormal * vector.y + normal * vector.z,
normal_scale
));
return NormalData(vector, map, normal_scale);
}

View File

@ -0,0 +1,16 @@
group_uniforms Occlusion;
uniform float ao_light_affect: hint_range(0,1) = 0.0;
uniform sampler2D ao_map : hint_default_white;
group_uniforms;
struct OcclusionData {
float ao;
float ao_light_affect;
};
OcclusionData occlusion_fragment(vec2 uv) {
return OcclusionData(
texture(ao_map, uv).r,
ao_light_affect
);
}

View File

@ -0,0 +1,17 @@
group_uniforms Reflections;
uniform float metallic : hint_range(0,1) = 0.0;
uniform float roughness : hint_range(0,1) = 1.0;
uniform sampler2D texture_surface : hint_default_white;
group_uniforms;
struct Surface {
float metallic;
float roughness;
};
Surface reflections_fragment(vec2 uv) {
return Surface(
metallic * texture(texture_surface, uv).r,
roughness * texture(texture_surface, uv).g
);
}

View File

@ -0,0 +1,36 @@
group_uniforms Refraction;
uniform float refraction : hint_range(-16, 16) = 0.05;
uniform float blurriness : hint_range(0.0, 1.0) = 0.0;
group_uniforms;
uniform sampler2D screen_texture :
hint_screen_texture,
repeat_disable,
filter_linear_mipmap;
uniform sampler2D depth_texture :
hint_depth_texture,
repeat_disable,
filter_linear_mipmap;
vec3 refraction_fragment(
float alpha,
vec3 normal,
vec2 screen_uv,
float depth
) {
float amount = 1.0 - alpha;
vec2 offset = screen_uv - normal.xy * refraction;
float image_depth = texture(depth_texture, offset).r;
return image_depth < depth
? textureLod(
screen_texture,
screen_uv,
blurriness * 8.0
).rgb * amount
: textureLod(
screen_texture,
offset,
blurriness * 8.0
).rgb * amount;
}

View File

@ -0,0 +1,8 @@
uniform sampler2D screen_texture :
hint_screen_texture,
repeat_disable,
filter_linear_mipmap;
vec3 transparency_fragment(float alpha, vec2 screen_uv) {
return (1.0 - alpha) * texture(screen_texture, screen_uv).rgb;
}

View File

@ -0,0 +1,18 @@
shader_type spatial;
render_mode cull_front, unshaded, depth_draw_never;
uniform vec4 outline_color : source_color;
uniform float outline_width = 4;
void vertex() {
vec4 clip_position =
PROJECTION_MATRIX * (MODELVIEW_MATRIX * vec4(VERTEX, 1.0));
vec3 clip_normal =
mat3(PROJECTION_MATRIX) * (mat3(MODELVIEW_MATRIX) * NORMAL);
clip_position.xy += normalize(clip_normal.xy) / VIEWPORT_SIZE *
clip_position.w * outline_width;
POSITION = clip_position;
}
void fragment() { ALBEDO = outline_color.rgb; }