Blobby/src/Environment/LightingShaderMaterial.tres

98 lines
3.1 KiB
Plaintext

[gd_resource type="ShaderMaterial" load_steps=2 format=2]
[sub_resource type="Shader" id=1]
code = "shader_type canvas_item;
render_mode unshaded;
uniform sampler2D noise_img;
uniform mat4 global_transform;
uniform mat4 viewport_transform;
uniform sampler2D light_data;
uniform int n_lights = 0;
uniform vec4 default_light_color : hint_color;
uniform float light_level : hint_range(0.0, 1.0) = 0.0;
uniform float offset_modifier : hint_range(0.0, 8.0) = 1.0;
uniform int n_light_bands : hint_range(1, 13) = 7;
uniform bool will_smooth_shade = false;
uniform float band_decay_rate : hint_range(0.0, 1.0, 0.05) = 0.5;
uniform float light_strength_modifier : hint_range(0.0, 1.0) = 1.0;
varying vec2 world_position;
void vertex() {
world_position = (viewport_transform * (global_transform * vec4(VERTEX, 0.0, 1.0))).xy;
}
void fragment() {
vec4 col = texture(TEXTURE, UV);
if (col.a <= 0.0){
COLOR = col;
}
else{
// floor() the world_position so that it matches the native resolution
vec2 frag_position = floor(world_position);
float m_value = 0.0; // 0.0 == dark, 1.0 == light
vec4 light_color = default_light_color;
// Iterate through every light source.
for(int i = 0; i < n_lights; i++) {
// Get the data for this light source as passed in via texture
vec4 texel = texelFetch(light_data, ivec2(i, 0), 0);
vec2 texel_pos = (viewport_transform * (global_transform * vec4(texel.xy, 0.0, 1.0))).xy;
vec2 texel_pos2 = texel.xy;
// How far the light source extends
float radius = texel.a;
// How bright the light source is
float strength = texel.b;
// Distance from this pixel to the light source then normalize
float dist = distance(texel_pos, frag_position);
dist = min(dist / radius, 1.0);
// offset so that light source doesn't fade immediately
dist = max((dist * offset_modifier) - (offset_modifier - 1.0), 0.0);
float value = 0.0;
if(will_smooth_shade) {
value = (1.0 - dist) * strength * light_strength_modifier + value;
}
else {
// decay offset so that max value == 1.0
float offset = pow(band_decay_rate, float(n_light_bands));
for(int p = 0; p < n_light_bands; p++) {
// Get max radius for this light band
float radius_check = 1.0 - pow(band_decay_rate, float(p + 1)) + offset;
// if pixel is less than the band's radius, then it's in the pth band
if(dist < radius_check) {
// Set it's value to the position of the band before this one
value = (pow(band_decay_rate, float(p)) - offset)
* strength * light_strength_modifier;
// Nearest band was found, so break the loop
break;
}
}
}
value = clamp(value, 0.0, 1.0);
if(value > m_value) {
m_value = value;
light_color = texelFetch(light_data, ivec2(i, 1), 0);
}
}
COLOR = col + m_value * light_color;
}
}"
[resource]
shader = SubResource( 1 )
shader_param/global_transform = null
shader_param/viewport_transform = null
shader_param/n_lights = 0
shader_param/default_light_color = null
shader_param/light_level = 0.0
shader_param/offset_modifier = 1.0
shader_param/n_light_bands = 7
shader_param/will_smooth_shade = false
shader_param/band_decay_rate = 0.5
shader_param/light_strength_modifier = 1.0