shader_type spatial; render_mode blend_mix, depth_draw_opaque, cull_back, diffuse_burley, specular_schlick_ggx; #include "res://addons/rokojori_action_library/Runtime/Shading/Library/Math.gdshaderinc" #include "res://addons/rokojori_action_library/Runtime/Shading/Library/Transform.gdshaderinc" #include "res://addons/rokojori_action_library/Runtime/Shading/Library/Wind.gdshaderinc" #include "res://addons/rokojori_action_library/Runtime/Shading/Library/Line3.gdshaderinc" uniform vec4 albedo : source_color; uniform sampler2D texture_albedo : source_color, filter_linear_mipmap, repeat_enable; uniform float albedoToBacklight:hint_range( 0.0, 1.0 ) = 0.2; uniform float albedoToEmission:hint_range( 0.0, 1.0 ) = 0.2; uniform float roughness : hint_range(0.0, 1.0); uniform sampler2D texture_metallic : hint_default_white, filter_linear_mipmap, repeat_enable; uniform vec4 metallic_texture_channel; uniform sampler2D texture_roughness : hint_roughness_r, filter_linear_mipmap, repeat_enable; uniform float specular : hint_range(0.0, 1.0, 0.01); uniform float metallic : hint_range(0.0, 1.0, 0.01); uniform sampler2D texture_ambient_occlusion : hint_default_white, filter_linear_mipmap, repeat_enable; uniform vec4 ao_texture_channel; uniform float ao_light_affect : hint_range(0.0, 1.0, 0.01); uniform vec3 uv1_scale; uniform vec3 uv1_offset; // [ PLAYER DEFROM ] group_uniforms playerDeform; global uniform vec3 playerPosition; global uniform vec3 smoothedPlayerPosition; uniform float playerDeformRange = 2.0; uniform float playerDeformAmount = 0.5; uniform float playerDeformPower:hint_range( 0.25, 4 ) = 1; uniform float playerDeformYStart = 0.2; uniform float playerDeformYMax = 1; // [ WIND ] group_uniforms wind; // Texture for close wind: grass/foliage global uniform sampler2D rj_GlobalWindNoiseTextureClose; // Texture for far wind: trees global uniform sampler2D rj_GlobalWindNoiseTextureFar; // Windposition close global uniform vec2 rj_GlobalWindPositionClose; // Windposition far global uniform vec2 rj_GlobalWindPositionFar; // Wind direction for both global uniform vec2 rj_GlobalWindDirection; // Wind speed for both global uniform float rj_GlobalWindSpeed; // Weights for x: close and y: far uniform vec2 windWeights = vec2( 0.5, 0.5 ); // Scales the world-vertex based variance uniform float windSeedSize = 1.0; // Max xz bending uniform float windMaxStrength = 0.2; // Max yaw rotation uniform float windMaxRotation = 0.1; // Linear/Inv-Quadratic mapping for the strength uniform float windStrengthCurve:hint_range( 0.0, 1.0 ); // Influence start in local Y uniform float windStart = 0.1; // Influence max in local Y uniform float windEnd = 2.0; // Influence mapping over local Y uniform float windWeightCurve:hint_range( 0.0,1.0 ) = 0.5; // Ducking in y for amount, strong wind => vertices lower uniform float windHeightCompensation; // Normal incluence uniform float windNormalBending; // AO influence uniform float windOcclusionAmount; varying float vertexWindAO; // void vertex() { UV = UV * uv1_scale.xy + uv1_offset.xy; // PLAYER DEFORM vec3 playerPositionLocal = worldToLocal( playerPosition, MODEL_MATRIX ); vec3 smoothedPlayerPositionLocal = worldToLocal( smoothedPlayerPosition, MODEL_MATRIX ); playerPositionLocal.y = 0.0; smoothedPlayerPositionLocal.y = 0.0; vec3 flatVertex = VERTEX; flatVertex.y = 0.0; Line3 line; line.start = playerPositionLocal; line.end = smoothedPlayerPositionLocal; float distance = Line3_getDistance( line, flatVertex ); vec3 dir = vec3( 1.0, 0, 0 ); if ( distance != 0.0 ) { dir = playerPositionLocal - VERTEX; dir.y = 0.0; // vec3 closestPoint = Line3_closestPointToPoint( line, flatVertex ); // dir = closestPoint - flatVertex; } dir = normalize( dir ); // vec3 localPlayerPosition = worldToLocal( playerPosition, MODEL_MATRIX ) - VERTEX; // localPlayerPosition.y = 0.0; // float distance = length( localPlayerPosition ); // if ( distance == 0.0 ) // { // localPlayerPosition = vec3( 0.0001, 0, 0 ); // } // vec3 dir = normalize( localPlayerPosition ); float amount = mapClamped( distance, 0.0, playerDeformRange, playerDeformAmount, 0 ); amount = clamp01( pow( amount, playerDeformPower ) ); float yAmount = mapClamped( VERTEX.y, playerDeformYStart, playerDeformYMax, 0.0, 1.0 ); // vec3 worldDir = localToWorldDirection( dir, MODEL_MATRIX ); // worldDir = normalize( worldDir ); // vec3 worldVertex = localToWorld( VERTEX, MODEL_MATRIX ); // worldVertex += worldDir * - amount * yAmount; // VERTEX = worldToLocal( worldVertex, MODEL_MATRIX ); VERTEX += dir * - amount * yAmount; // WIND float windAO = 0.0; applyGlobalWind( MODEL_MATRIX, VERTEX, NORMAL, windAO, windOcclusionAmount, rj_GlobalWindNoiseTextureClose, rj_GlobalWindNoiseTextureFar, rj_GlobalWindPositionClose, rj_GlobalWindPositionFar, rj_GlobalWindDirection, rj_GlobalWindSpeed, windWeights, windSeedSize, windMaxStrength, windMaxRotation, windStrengthCurve, windStart, windEnd, windWeightCurve, windHeightCompensation, windNormalBending ); vertexWindAO = windAO; } void fragment() { vec2 base_uv = UV; vec4 albedo_tex = texture(texture_albedo, base_uv); ALBEDO = albedo.rgb * albedo_tex.rgb; float metallic_tex = dot(texture(texture_metallic, base_uv), metallic_texture_channel); METALLIC = metallic_tex * metallic; SPECULAR = specular; vec4 roughness_texture_channel = vec4(1.0, 0.0, 0.0, 0.0); float roughness_tex = dot(texture(texture_roughness, base_uv), roughness_texture_channel); ROUGHNESS = roughness_tex * roughness; // Ambient Occlusion: Enabled AO = dot(texture(texture_ambient_occlusion, base_uv), ao_texture_channel) * vertexWindAO; AO_LIGHT_AFFECT = ao_light_affect; BACKLIGHT = ALBEDO * albedoToBacklight; EMISSION = ALBEDO * albedoToEmission; }