Вам нужно измерить длину светового дельта-вектора и использовать ее для ослабления.
Сразу после линии lightDir
вы можете поместить что-то вроде этого, но вам придется настроить FALLOFF
, чтобы получить нужное расстояние. FALLOFF
должно быть больше 0. В качестве отправной точки значение 0,1 даст вам радиус света около 4 единиц. Меньшие значения увеличивают радиус. Вы даже можете определить его как параметр каждого источника света (сделайте их vec4
s).
float distance = length(deltaPos);
float attenuation = 1.0 / (1.0 + FALLOFF * distance * distance);
float lambert = attenuation * clamp(dot(normal, lightDir), 0.0, 1.0);
Эта формула затухания имеет колоколообразную кривую. Если вы хотите, чтобы кривая имела заостренный кончик, что, возможно, более реалистично c (хотя, вероятно, бессмысленно для 2D-освещения), вы можете добавить второй параметр (которому вы можете изначально присвоить значение 0,1, а затем увеличивать его):
float attenuation = 1.0 / (1.0 + SHARPNESS * distance + FALLOFF * distance * distance);
Кто-то по этому вопросу опубликовал эту полезную диаграмму , с которой вы можете поиграть, чтобы визуально увидеть, как параметры меняют кривую.
Также , не умножайте на целое число. Это приведет к сбою компиляции шейдера на некоторых устройствах:
vec3 lightDir = normalize(deltaPos * 1); // The integer 1 is unsupported.