Я пытаюсь реализовать точечные источники света в OpenGL с GLSL. Я отправляю все необходимые данные в шейдеры. Для простоты здесь я использую только рассеянный свет.
Мой пример показывает огромный треугольник, который я хочу осветить одним источником света. Источник света показан в виде маленького синего треугольника.
Для рассеянного света мне нужно знать угол между светом и поверхностью. Поэтому я вычисляю нормали и направление света. Точечный продукт даст мне число от -1 до 1, тогда как все от 0 до 1 будет подсвечено.
Однако здесь я застрял, потому что в моем примере этот угол вычислен неправильно. Поскольку шейдеры трудно отлаживать, я использовал несколько выходных данных в качестве цвета моей поверхности. Я использовал нормаль в качестве цвета для треугольника, и где бы ни был свет, поверхность всегда была зеленой. То есть нормали указывают вверх по оси y, и поэтому они вычисляются правильно. То есть направление света должно быть неправильным. Однако я не могу найти причину, почему это неправильно. Положение источника света и положение вершины передаются в мировом пространстве вершинному шейдеру, который затем преобразует их в пространство глаза, вычисляет направление света и передает его фрагментному шейдеру:
вершинный шейдер:
vec4 pos = modelview_matrix * <input vertex>;
vec4 lightPos = modelview_matrix * <light position>;
vec3 lightDir = normalize(lightPos.xyz - pos.xyz);
фрагментный шейдер:
float NdotL = max(dot(normalize(<correct normal>), normalize(lightDir)), 0.0);
gl_FragColor = vec4(1.0, NdotL, 0.0, 1.0);
Я добавил несколько картинок этого примера, которые определенно показывают, что интерполяция действительно странная. Я знаю, хочу знать, является ли код, который я вставил, правильным или вам нужно знать больше кода. Кроме того, это интерполяционное поведение нормально или это ошибка в моем коде?
http://img41.imageshack.us/img41/3566/interpolation.png
http://img189.imageshack.us/img189/3566/interpolation.png
Особенно первое изображение показывает, что центральное пятно света находится НЕ непосредственно под светом, но немного смещено к центру треугольника.
Если я передаю «pos» фрагментному шейдеру (то есть он интерполируется), а затем вычисляет «lightDir» в фрагментном шейдере, все работает нормально.