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