77 lines
2.6 KiB
Plaintext
77 lines
2.6 KiB
Plaintext
// BoTW Toon Shader by NekotoArts
|
||
// Migré vers Godot 4.7
|
||
shader_type spatial;
|
||
render_mode diffuse_toon, specular_toon;
|
||
|
||
uniform vec4 tint : source_color = vec4(1.0);
|
||
uniform sampler2D albedo_texture : source_color;
|
||
uniform float metallic : hint_range(0.0, 1.0) = 0.0;
|
||
uniform sampler2D normal_map : source_color;
|
||
uniform float shadow_size = 0.045;
|
||
uniform float shadow_blend = 0.001;
|
||
uniform float shadow_extra_intensity = 0.0;
|
||
uniform vec4 shadow_color : source_color = vec4(0.0, 0.0, 0.0, 1.0);
|
||
uniform vec4 light_tint : source_color = vec4(1.0);
|
||
uniform float rimlight_size = 0.921;
|
||
uniform float rimlight_blend = 0.01;
|
||
uniform vec4 rimlight_color : source_color = vec4(1.0);
|
||
uniform bool use_normalmap = true;
|
||
uniform bool animated = true;
|
||
uniform float time_scale = 0.02;
|
||
uniform vec3 normal_bias = vec3(0.0);
|
||
uniform vec3 light_bias = vec3(0.0);
|
||
uniform bool use_view = true;
|
||
uniform vec4 view_bias : source_color = vec4(1.0, 0.0, 1.0, 1.0);
|
||
uniform float view_multiplier : hint_range(-1.0, 1.0) = -1.0;
|
||
|
||
float fresnel(float amount, vec3 normal, vec3 view)
|
||
{
|
||
return pow((1.0 - clamp(dot(normalize(normal), normalize(view)), 0.0, 1.0)), amount);
|
||
}
|
||
|
||
void vertex() {
|
||
// VERTEX 和 NORMAL 是 Godot 4 的顶点内置变量
|
||
// TANGENT 在 Godot 4 中仍需从 TANGENT 读取,但已不再推荐存储
|
||
// 如需传递法线,直接用 NORMAL 即可,Godot 会自动处理
|
||
}
|
||
|
||
void fragment() {
|
||
ALBEDO = texture(albedo_texture, UV).rgb * tint.rgb;
|
||
METALLIC = metallic;
|
||
}
|
||
|
||
void light() {
|
||
vec3 normal;
|
||
if (use_normalmap) {
|
||
vec3 normal_from_texture;
|
||
if (animated) {
|
||
normal_from_texture = texture(normal_map, UV + TIME * time_scale).rgb;
|
||
} else {
|
||
normal_from_texture = texture(normal_map, UV).rgb;
|
||
}
|
||
// Godot 4 中法线贴图的解码通常用 texture().rgb * 2.0 - 1.0
|
||
// 但原代码直接做减法,这里保持原逻辑但修正分量使用
|
||
normal = NORMAL - (normal_from_texture * 2.0 - 1.0);
|
||
} else {
|
||
normal = NORMAL;
|
||
}
|
||
|
||
if (use_view) {
|
||
normal -= VIEW * view_bias.rgb * view_multiplier;
|
||
}
|
||
|
||
float NdotL = dot(normal + normal_bias, LIGHT + light_bias);
|
||
|
||
float rounded = smoothstep(shadow_size, shadow_blend + shadow_size, NdotL);
|
||
float one_minus = 1.0 - rounded;
|
||
vec3 mult1 = LIGHT_COLOR * rounded * light_tint.rgb * ATTENUATION;
|
||
vec3 mult2 = (one_minus * 1.4 * shadow_color.rgb) - shadow_extra_intensity;
|
||
vec3 add1 = mult1 + mult2;
|
||
|
||
float add3 = rimlight_blend + rimlight_size;
|
||
float basic_fresnel = fresnel(1.0, NORMAL, VIEW);
|
||
float smoothed = smoothstep(rimlight_size, add3, basic_fresnel);
|
||
|
||
vec3 add2 = add1 + smoothed * rimlight_color.rgb;
|
||
DIFFUSE_LIGHT += ALBEDO * add2;
|
||
} |