shader_type spatial; uniform bool is_target = false; uniform bool is_focus = false; uniform float target_position_y = 0; uniform float target_level_top_y = 0; uniform vec3 focus_min = vec3(0,0,0); uniform vec3 focus_max = vec3(0,0,0); uniform sampler2D tex_noise1 : source_color; uniform sampler2D tex_noise2 : source_color; uniform sampler2D tex_noise_sub : source_color; uniform sampler2D tex_material : source_color; uniform sampler2D tex_material_normal : source_color; uniform sampler2D tex_material_sub : source_color; uniform sampler2D tex_material_normal_sub : source_color; varying vec3 world_position; varying vec2 uv1; varying vec2 uv2; varying vec2 uv_sub; varying vec2 uv_material; void vertex() { world_position = (MODEL_MATRIX * vec4(VERTEX, 1.0)).xyz; vec2 local_uv = vec2(world_position.x,world_position.y + world_position.z); uv1 = local_uv / 32.0; uv2 = local_uv / 32.0; uv_sub = local_uv / 4.0; uv_material = local_uv / 8.0; } bool is_in_focus(vec3 f_min,vec3 f_max){ if(world_position.z>f_max.z){return false;} if(world_position.y>f_max.y){return false;} return true; } void fragment() { if (is_focus && !is_in_focus(focus_min,focus_max)){ discard; } vec3 c = COLOR.rgb; if(c.r+c.g+c.b<0.1){ ALBEDO = vec3(0.0); }else if(c.r+c.g+c.b>2.9){ discard; }else{ float brightness = 1.0; if(is_target){ float offset_y = abs(floor((world_position.y-target_position_y) / 0.02) * 0.02); offset_y = max(0.0,offset_y-0.64); float rate = clamp(1.0-offset_y/4.48,0.0,1.0); brightness = rate; }else{ brightness = 1.0; } vec3 world_normal = (INV_VIEW_MATRIX * vec4(NORMAL, 0.0)).xyz; bool is_light = c.r+c.g+c.b>2.8; if(!is_light && world_normal.y<0.1){ brightness = brightness*0.6; } //通用网格纹理 float noise_value1 = texture(tex_noise1,floor(uv1 /0.02) *0.02).r; float discrete_noise_value1 = floor(noise_value1 / 0.5) * 0.5; float noise_value2 = texture(tex_noise2,floor(uv2 /0.02) *0.02).r; float discrete_noise_value2 = floor(noise_value2 / 0.5) * 0.5; //材质纹理 float noise_value_material = texture(tex_material,floor(uv_material /0.0025) *0.0025).r; float discrete_noise_value_material = floor(noise_value_material / 0.1) * 0.1; c -= discrete_noise_value1 * 0.2; c += discrete_noise_value2 * 0.2; c += discrete_noise_value_material * 0.2; //顶部侵蚀效果 float offset_y = abs(world_position.y-target_level_top_y); float sub_rate = 1.0 - min(1.0,offset_y/0.2); float noise_value_material_sub = texture(tex_material_sub,floor(uv_material /0.0025) *0.0025).r; float discrete_noise_value_material_sub = floor(noise_value_material_sub / 0.1) * 0.1; float noise_value_sub = texture(tex_noise_sub,floor(uv_sub /0.02) *0.02).r; c.rgb = mix(c.rgb,vec3(0), noise_value_sub * sub_rate * sub_rate * 4.0); vec3 normal_map = texture(tex_material_normal, floor(uv_material /0.0025) *0.0025).rgb; normal_map.xy *= 0.2; NORMAL = normalize(TANGENT * normal_map.x + BINORMAL * normal_map.y + NORMAL * normal_map.z); //应用亮度 c = clamp(c,vec3(0.0),vec3(0.95)); c.rgb = mix(vec3(0.0), c, brightness); //颜色像素化 float div_rate = 0.02; c.r = floor(c.r /div_rate) *div_rate; c.g = floor(c.g /div_rate) *div_rate; c.b = floor(c.b /div_rate) *div_rate; ALBEDO = c.rgb; if(is_light){ EMISSION = c.rgb * 2.0; } } } void light() { vec3 c = ALBEDO.rgb; float rgb_sum = c.r+c.g+c.b; if (!(rgb_sum<0.1 || rgb_sum>2.9)){ DIFFUSE_LIGHT += clamp(dot(NORMAL, LIGHT), 0.0, 1.0) * ATTENUATION * LIGHT_COLOR; } }