Я пытаюсь реализовать ослабление света в шейдере Фонга. Пиксельный / фрагментарный шейдер выполняет следующие вычисления (для каждого источника света):
float3 refl = reflect(e, n);
float dist = length(L.xyz);
float3 l = normalize(L.xyz);
float attn = 1.0 / (1.0 + 1.0 / 30 * dist + 1.0 / 700 * dist * dist);
d += saturate(dot(n,l)) * gLightColor[i].xyz * attn.xxx;
s += pow(saturate(dot(-refl, l)), power) * gLightColor[i].xyz;
где:
- e - нормализованный вектор глаза
- n - нормаль к поверхности
- L - (ненормализованный) вектор света.
- d - диффузный цвет
- s - цвет зеркального отражения
Для простоты я игнорирую влияние затухания на цвет отражения и использую некоторые встроенные коэффициенты затухания. Как правило, я получаю правильное поведение:
Когда я увеличиваю расстояние между источником света и объектом, уменьшение интенсивности становится не плавным:
Я получаю кольца вместо градиента. Это вопрос точности с плавающей запятой? Как добиться плавного изменения интенсивности на всех дистанциях?
Использование D3D 9 и HLSL шейдерной модели 3.