You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
TouhouGD/render/shader/level_grid_block.gdshader

114 lines
3.7 KiB
Plaintext

9 months ago
shader_type spatial;
uniform bool is_target = false;
9 months ago
uniform bool is_focus = false;
uniform float target_position_y = 0;
uniform float target_level_top_y = 0;
9 months ago
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;
9 months ago
varying vec3 world_position;
varying vec2 uv1;
varying vec2 uv2;
varying vec2 uv_sub;
varying vec2 uv_material;
9 months ago
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;
9 months ago
}
9 months ago
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;
}
9 months ago
void fragment() {
9 months ago
if (is_focus && !is_in_focus(focus_min,focus_max)){
discard;
}
8 months ago
9 months ago
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){
9 months ago
discard;
9 months ago
}else{
float brightness = 1.0;
if(is_target){
float offset_y = abs(floor((world_position.y-target_position_y) / 0.02) * 0.02);
9 months ago
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;
}
8 months ago
//通用网格纹理
9 months ago
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;
8 months ago
//材质纹理
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);
8 months ago
//应用亮度
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;
9 months ago
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;
}
}