Я работаю над трассировкой лучей, используя C++ и OpenGL (glDrawPixels), и пока все идет хорошо. Тем не менее, мое затенение кажется немного неправильным. Я хочу, чтобы мои сферы выглядели более гладкими, без резких линий между уровнями интенсивности. На данный момент я просто пытаюсь реализовать ламбертовское затенение, то есть Intensity = Id * pd * (N dot L). Я знаю, как мне нужно рассчитать (N dot L) путем нормализации вектора нормали и вектора света, но как насчет Id и pd (диффузная интенсивность и коэффициент пропорциональности)? Я просто использую постоянное значение 2,5 для достижения следующего:
(Вот изображение того, как выглядит мое затенение)
Очевидно, что 2.5 совершенно произволен, и я использую его только потому, что другие мои попытки даже не напоминали правильное затенение. Уравнение выше, кажется, предполагает, что я должен умножить цвет на интенсивность. Это мой метод:
Color simpleIlluminate(Vector3D normal, Vector3D light, Color color) {
float intensity = dotProduct(normal, light)*2.5f;
color = Color((unsigned int)intensity*color.r, (unsigned int)intensity*color.g, (unsigned int)intensity*color.b);
return color;
}
Предположим, что вектор нормали и вектор света верны. Color — это просто созданная мной цветовая структура, которая имеет целое число без знака для каждого из значений RGB. Параметр Color color — это цвет сферы, которую я хочу затенить, например. красный = цвет (255,0,0). Чтобы изменить интенсивность цвета, я просто умножаю каждое значение на вычисленную интенсивность, но при запуске это выглядит неправильно.
Может ли кто-нибудь объяснить, чего мне не хватает, и показать мне, как должна выглядеть правильная функция с учетом векторов и цвета сферы? Я искал везде, но я не могу найти хорошее решение. Возможно, я также неправильно выполняю преобразование float в unsigned int, но я не уверен. Любая помощь приветствуется.