Выборка данных из текстуры карты теней с использованием автоматического сравнения с помощью функции texture2D - PullRequest
0 голосов
/ 28 июля 2011

В моем шейдере есть sampler2DShadow, и я хочу использовать его для реализации теневого отображения.Моя теневая текстура имеет хорошие инициализаторы, для GL_TEXTURE_COMPARE_MODE установлено значение GL_COMPARE_R_TO_TEXTURE, а для GL_TEXTURE_COMPARE_FUNC установлено значение GL_LEQUAL (это означает, что сравнение должно вернуть 1, если значение r моих координат меньше или равно значению глубины, выбранному в текстуре).Эта текстура привязана к GL_DEPTH_ATTACHMENT объекта FBO, отображаемого в светлых космических координатах.

Какие координаты я должен дать функции texture2D в своем конечном фрагментном шейдере?В настоящее время у меня есть

сглаживания в vec4 light_vert_pos

, установленного в моем фрагментном шейдере, который определяется в вершинном шейдере функцией

light_vert_pos = light_projection_camera_matrix * modelview * in_Vertex;

Я бы предположил, что мог бы умножить свое освещение на значение

texture2D (shadowmap, (light_vert_pos.xyz) /light_vert_pos.w)

но это, похоже, не работает.Так как light_vert_pos находится только в постпроективных координатах (матрица, используемая для его создания - это матрица, которую я использую для создания буфера глубины в FBO), я должен вручную фиксировать переменные 3 x / y / z в [0,1]?

1 Ответ

2 голосов
/ 29 июля 2011

Вы не говорите, как вы создали свои значения глубины. Поэтому я предполагаю, что вы сгенерировали значения глубины, отрисовывая треугольники с помощью обычной проекции. То есть вы преобразуете геометрию в пространство камеры, преобразуете ее в пространство проекции и позволяете конвейеру растеризации обрабатывать вещи оттуда как обычно.

Чтобы сделать отображение теней, ваши текстурные координаты должны совпадать с тем, что делал растеризатор.

Вывод вершинного шейдера - это клип-пространство. Оттуда вы получите разрыв перспективы, сопровождаемый преобразованием области просмотра. Последний использует значения из glViewport и glDepthRange для вычисления XYZ пространства окна. Окно-пространство Z - это значение глубины, записанное в буфер глубины.

Обратите внимание, что это все во время прохода глубины: генерация значений глубины для карты теней.

Однако вы можете воспользоваться некоторыми сочетаниями клавиш. Если для вашего диапазона glViewport был установлен тот же размер, что и для текстуры (что обычно и делается), то вы можете игнорировать преобразование области просмотра. Вам все равно понадобится glDepthRange, который вы использовали в проходе глубины.

В своем фрагментном шейдере вы можете выполнить деление перспективы, которое помещает координаты в нормализованное пространство координат устройства (NDC). Это пространство [-1, 1] во всех направлениях. Ваши координаты текстуры [0, 1], поэтому вам нужно разделить X и Y на два и добавить к ним 0,5:

vec3 ndc_space_values = light_vert_pos.xyz / light_vert_pos.w
vec3 texCoords;
texCoords.xy = ndc_space_values.xy * 0.5 + 0.5;

Чтобы вычислить значение Z, вам нужно знать значения ближнего и дальнего расстояний, которые вы используете для glDepthRange.

texCoords.z = ((f-n) * 0.5) * ndc_space_values.z + ((n+f) * 0.5);

Где n и f - значения ближнего и дальнего радиуса glDepthRange. Конечно, вы можете предварительно вычислить некоторые из них и передать их как униформу. Или, если вы используете диапазон по умолчанию вблизи = 0 и далеко = 1, вы получите

texCoords.z = ndc_space_values.z * 0.5 + 0.5;

Что выглядит как-то знакомо.

За исключением:

Поскольку вы определили свои входные данные с in вместо varying, вы должны использовать GLSL 1.30 или выше. Так почему вы используете texture2D (это старая функция), а не texture?

...