shader_type spatial; render_mode blend_mix, depth_draw_opaque, diffuse_lambert, specular_schlick_ggx, skip_vertex_transform; varying vec3 var_model_normal; varying vec3 var_vertex_position; group_uniforms Floor1; uniform sampler2D floor_1_albedo : source_color, hint_default_black, filter_linear_mipmap; uniform sampler2D floor_1_normal : hint_normal, filter_linear_mipmap; uniform float floor_1_roughness = 0.7; uniform float floor_1_tiling = 500.0; uniform float floor_1_specular = 0.5; uniform float floor_1_metallic = 0.5; group_uniforms Floor2; uniform sampler2D floor_2_albedo : source_color, hint_default_black, filter_linear_mipmap; uniform sampler2D floor_2_normal : hint_normal, filter_linear_mipmap; uniform float floor_2_roughness = 0.7; uniform float floor_2_tiling = 500.0; uniform float floor_2_specular = 0.5; uniform float floor_2_metallic = 0.5; group_uniforms Floor3; uniform sampler2D floor_3_albedo : source_color, hint_default_black, filter_linear_mipmap; uniform sampler2D floor_3_normal : hint_normal, filter_linear_mipmap; uniform float floor_3_roughness = 0.7; uniform float floor_3_tiling = 500.0; uniform float floor_3_specular = 0.5; uniform float floor_3_metallic = 0.5; group_uniforms Regions; uniform sampler2D floor_region_map : hint_default_black, filter_linear_mipmap; uniform float region_blending : hint_range(0, 10) = 1.0; group_uniforms Slope.Textures; uniform sampler2D slope_albedo : source_color, hint_default_white; uniform sampler2D slope_normal : hint_normal, filter_linear_mipmap; uniform float slope_tiling = 100.0; uniform float slope_roughness = 0.7; uniform float slope_specular = 0.5; uniform float slope_metallic = 0.5; group_uniforms; group_uniforms Slope; uniform float slope_threshold = 0.9; uniform float slope_blend_distance = 0.05; void vertex() { var_model_normal = NORMAL; var_vertex_position = (vec4(VERTEX, 1.0) * MODEL_MATRIX).xyz; VERTEX = (MODELVIEW_MATRIX * vec4(VERTEX, 1.0)).xyz; NORMAL = normalize(MODELVIEW_MATRIX * vec4(NORMAL, 0.0)).xyz; TANGENT = normalize(MODELVIEW_MATRIX * vec4(TANGENT, 0.0)).xyz; BINORMAL = normalize(MODELVIEW_MATRIX * vec4(BINORMAL, 0.0)).xyz; } vec3 lerp(vec3 a, vec3 b, float t) { return (1.0 - t) * a + b * t; } float lerpf(float a, float b, float t) { return (1.0 - t) * a + b * t; } vec2 lerp2(vec2 a, vec2 b, float t) { return (1.0 - t) * a + b * t; } // adapted from https://github.com/Experience-Monks/glsl-fast-gaussian-blur/blob/master/9.glsl vec4 sample_texture_blurred(sampler2D tex, vec2 uv) { if(region_blending == 0.0) // short-circuit for zero case return texture(tex, uv); vec4 color = vec4(0.0); vec2 resolution = vec2(textureSize(tex, 0)); vec2 offset_1 = vec2(1.3846153846) * region_blending; vec2 offset_2 = vec2(3.2307692308) * region_blending; // add weighted samples. Magic numbers are pre-computed gaussian function results color += texture(tex, uv) * 0.2270270270; color += texture(tex, uv + (offset_1 / resolution)) * 0.3162162162; color += texture(tex, uv - (offset_1 / resolution)) * 0.3162162162; color += texture(tex, uv + (offset_2 / resolution)) * 0.0702702703; color += texture(tex, uv - (offset_2 / resolution)) * 0.0702702703; return color; } void fragment() { float slope_blend = clamp(slope_threshold + ((acos(abs(var_model_normal.y)) / (PI * 0.5) - slope_threshold) * 1.0/slope_blend_distance), 0.0, 1.0); vec4 region_masks = sample_texture_blurred(floor_region_map, UV); vec2 sqr_normal = normalize(var_model_normal.xz * var_model_normal.xz); float biplanar_index = round(abs(sqr_normal.x)); vec2 slope_uv = lerp2(var_vertex_position.xy, var_vertex_position.yz, biplanar_index); ALBEDO = texture(floor_1_albedo, UV * floor_1_tiling).xyz; ALBEDO = lerp(ALBEDO, texture(floor_2_albedo, UV * floor_2_tiling).xyz, region_masks.x); ALBEDO = lerp(ALBEDO, texture(floor_3_albedo, UV * floor_3_tiling).xyz, region_masks.y); ALBEDO = lerp(ALBEDO, texture(slope_albedo, slope_uv * slope_tiling).xyz, slope_blend); //ALBEDO = region_masks.xyz; NORMAL_MAP = texture(floor_1_normal, UV * floor_1_tiling).xyz; NORMAL_MAP = lerp(NORMAL_MAP, texture(floor_2_normal, UV * floor_2_tiling).xyz, region_masks.x); NORMAL_MAP = lerp(NORMAL_MAP, texture(floor_3_normal, UV * floor_3_tiling).xyz, region_masks.y); NORMAL_MAP = lerp(NORMAL_MAP, texture(slope_normal, slope_uv * slope_tiling).xyz, slope_blend); SPECULAR = floor_1_specular; SPECULAR = lerpf(SPECULAR, floor_2_specular, region_masks.x); SPECULAR = lerpf(SPECULAR, floor_3_specular, region_masks.y); SPECULAR = lerpf(SPECULAR, slope_specular, slope_blend); ROUGHNESS = floor_1_roughness; ROUGHNESS = lerpf(ROUGHNESS, floor_2_roughness, region_masks.x); ROUGHNESS = lerpf(ROUGHNESS, floor_3_roughness, region_masks.y); ROUGHNESS = lerpf(ROUGHNESS, slope_roughness, slope_blend); METALLIC = floor_1_metallic; METALLIC = lerpf(METALLIC, floor_2_metallic, region_masks.x); METALLIC = lerpf(METALLIC, floor_3_metallic, region_masks.y); METALLIC = lerpf(METALLIC, slope_metallic, slope_blend); }