heroes-of-nerevelon/assets/shaders/sprite_light.glsl

67 lines
2.3 KiB
GLSL
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#define MAX_LIGHTS 8
struct Light {
vec2 position;
vec3 color;
};
extern Light lights[MAX_LIGHTS];
extern int num_lights;
extern vec2 sprite_pos; // Мировая позиция спрайта (в метрах)
extern vec3 ambient; // Эмбиентное освещение
extern vec3 sky; // Цвет неба
// Функция для имитации easing.easeInSine
float easeInSine(float x) {
return 1.0 - cos((x * 3.14159) / 2.0);
}
vec4 effect(vec4 vcolor, Image tex, vec2 texture_coords, vec2 screen_coords)
{
vec3 baseLight = ambient + (vec3(1.0) - ambient) * sky;
float luma = dot(baseLight, vec3(0.2126, 0.7152, 0.0722)); // https://en.wikipedia.org/wiki/Relative_luminance
vec3 characterBaseLight = mix(baseLight, vec3(luma), 0.3); // 30% обесцвечивания, а то глаза выгорают
vec4 texColor = Texel(tex, texture_coords);
if (texColor.a == 0.0) {
return vec4(0.0);
}
vec3 pointLight = vec3(0.0);
for (int i = 0; i < num_lights; i++) {
vec2 lightPos = lights[i].position;
vec2 lightVec = lightPos - sprite_pos;
float dist = length(lightVec);
float attenuation = 0.0;
// Логика из shadowcaster.lua:
// if lightPos.y > position.y then
// 1 - 0.3 * lightVec:length()
// elseif position.y - lightPos.y < 3 then
// (1 - easing.easeInSine((position.y - lightPos.y))) - 0.3 * lightVec:length()
if (lightPos.y > sprite_pos.y) {
attenuation = 1.0 - 0.3 * dist;
} else {
float yDiff = sprite_pos.y - lightPos.y;
if (yDiff < 3.0) {
attenuation = (1.0 - easeInSine(yDiff)) - 0.3 * dist;
}
}
attenuation = max(attenuation, 0.0);
pointLight += lights[i].color * attenuation;
}
pointLight = clamp(pointLight, 0.0, 1.0);
vec3 a = clamp(ambient, 0.0, 1.0);
// Канальный множитель: от ambient до 1 в зависимости от точечного света
// Это гарантирует, что спрайт не будет черным в отсутствие источников света
vec3 lightMultiplier = a + (vec3(1.0) - a) * pointLight;
return vec4(texColor.rgb * (characterBaseLight + pointLight), texColor.a);
}