Почему происходит неплавное снижение интенсивности ослабленного света?

Я пытаюсь реализовать ослабление света в шейдере Фонга. Пиксельный / фрагментарный шейдер выполняет следующие вычисления (для каждого источника света):

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.


person user1803551    schedule 21.01.2019    source источник


Ответы (1)


Вы столкнулись с цветными полосами. Уменьшая интенсивность света, вы в основном растягиваете градиент все больше и больше. Поскольку каждый цвет отображается тремя 8-битными цветовыми каналами, точность вывода ограничена. В какой-то момент вы можете увидеть отдельные шаги между двумя цветами, когда область одного цвета становится слишком широкой, потому что ваш глаз распознает границу между двумя плоскими областями цветов, даже если они находятся так близко, как (0, 64, 64) к (0, 63, 63).

Поскольку обычный монитор поддерживает только 24-битные цвета, единственное жизнеспособное решение afaik - применить дизеринг . Это разбивает плоские цветные области, добавляя узор шума, поэтому глаз не может так легко уловить границы. Я уверен, что поиск в Google показывает несколько интересных ссылок, как реализовать какой-то дизеринг (например, this).

person Gnietschow    schedule 21.01.2019