Tales-of-PKMN/game/player/shader/botw_toon.gdshader

77 lines
2.6 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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;
}