winter-tales/VFX/Highlights-Shader.gdshader

73 lines
2.2 KiB
Plaintext
Raw Permalink Normal View History

2026-01-20 13:59:55 +00:00
shader_type spatial;
render_mode blend_mix, depth_draw_opaque, cull_back, diffuse_burley, specular_schlick_ggx, unshaded;
stencil_mode write, compare_less_or_equal, 1;
uniform vec4 albedo : source_color;
uniform sampler2D texture_albedo : source_color, filter_linear_mipmap, repeat_enable;
uniform bool useNormalMap = false;
uniform bool flipNormalMapZ = true;
uniform sampler2D texture_normal : filter_linear_mipmap, repeat_enable;
uniform float uvScale;
uniform float uvOffset;
uniform float uvSpeed;
uniform vec2 highlightDirection1;
uniform float highlightSharpness1: hint_range(0.0, 1.0) = 0.9;
uniform float highlightSize1: hint_range(0.0, 1.0) = 0.1;
uniform vec2 highlightDirection2;
uniform float highlightSharpness2: hint_range(0.0, 1.0) = 0.9;
uniform float highlightSize2: hint_range(0.0, 1.0) = 0.1;
varying float albedoU;
void vertex()
{
albedoU = VERTEX.y * uvScale + uvOffset + uvSpeed * TIME;
}
vec3 computeNormal( vec3 t, vec3 b, vec3 n, vec2 _UV )
{
vec3 sampledNormal = texture( texture_normal, _UV ).xyz * 2.0 - 1.0;
if ( flipNormalMapZ )
{
sampledNormal.z *= -1.0;
}
return normalize( mat3( t, b, n ) * sampledNormal );
}
float computeHighlight( vec3 lightDirection, vec3 _NORMAL, float size, float sharpness )
{
float invSize = 1.0 - pow( size, 3 );
float invSharpness = 1.0 - pow( sharpness, 0.1 );
float lowerEdge = invSize - invSharpness;
float upperEdge = invSize + invSharpness;
return smoothstep( lowerEdge, upperEdge, dot( _NORMAL, normalize( lightDirection ) ) );
}
void fragment()
{
vec2 base_uv = UV;
vec4 albedo_tex = texture(texture_albedo, vec2( albedoU, 0.0 ));
ALBEDO = albedo.rgb * albedo_tex.rgb;
vec3 combinedNormal = NORMAL;
if ( useNormalMap )
{
combinedNormal = computeNormal( TANGENT, BINORMAL, NORMAL, UV );
}
float highlight1 = computeHighlight( vec3( highlightDirection1, 1.0 ), combinedNormal, highlightSize1, highlightSharpness1 );
float highlight2 = computeHighlight( vec3( highlightDirection2, 1.0 ), combinedNormal, highlightSize2, highlightSharpness2 );
float highlightsCombined = max( highlight1, highlight2 );
ALBEDO = mix( ALBEDO, vec3( 1.0 ), highlightsCombined );
}