OpenGL GLSL интерполяция - PullRequest
1 голос
/ 14 июня 2009

Я пытаюсь реализовать точечные источники света в 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» в фрагментном шейдере, все работает нормально.

1 Ответ

3 голосов
/ 14 июня 2009

Я думаю, что нормализация вашего lightDir в вершинном шейдере влияет на результат, который вы получаете при интерполяции векторов, потому что он берет длину из уравнения и, таким образом, влияет на "скорость" интерполяции.

Если вы хотите (визуальное) объяснение, попробуйте нарисовать его в 2D на бумаге. Сначала нарисуйте линию (ваш треугольник) и точку (источник света). Добавьте две линии (lightDir) для обоих концов линии к источнику света, а затем сожмите (нормализуйте) эти линии lightDir, чтобы они имели одинаковую длину и встретились у источника света. Если вы соедините оба конца нормализованных линий lightDir, вы получите непараллельную линию (если источник света находится не совсем в середине вашей первой линии). Теперь, если вы нарисуете линию, которая проходит точно через середину одной из линий, вы увидите, что она не проходит через середину другой линии, но ударит ее немного влево или вправо.

...