GLSL sampler2DShadow и shadow2D разъяснения

быстрый фон, где я нахожусь (чтобы убедиться, что мы на одной странице, и здравомыслие проверить, если я не хватает / предполагая что-то глупое):

  • цель: я хочу сделать мою сцену с тенями, используя отложенное освещение и shadowmaps.
  • борьба: поиск четкой и последовательной документации о том, как использовать shadow2D и sampler2DShadow.

вот что я сейчас делаю:

в шейдере фрагментов моего окончательного рендеринга pass (тот, который фактически вычисляет окончательные значения фрага), у меня есть матрицы MVP с точки зрения прохода с точки зрения света, текстура глубины из этого прохода (он же "теневая карта") и текстуры положения/нормального/цвета из моего буфера геометрии.

из того, что я понимаю, мне нужно найти, что UV теневой карты соответствует положению текущего фрагмента. Я делаю это следующим образом:

//Bring position value at fragment (in world space) to screen space from lights POV
vec4 UVinShadowMap = (lightProjMat * lightViewMat * vec4(texture(pos_tex, UV).xyz,1.0)).xy; 
//Convert screen space to 'texture space' (from -1to1 to 0to1)
UVinShadowMap = (UVinShadowMap+1)/2;

Теперь, когда у меня есть этот УФ, я могу получить полученную "глубину" от pov света с

float depFromLightPOV = texture2D(shadowMap, UVinShadowMap).r;

и сравните это с расстоянием между положением на текущем фрагменте и светом:

float actualDistance = distance(texture2D(pos_tex, UV).xyz, lightPos);

проблема исходит из того, что "глубина" хранится в значениях 0-1, а фактическое расстояние-в мировых координатах. Я пытался сделать это преобразование вручную, но не смог заставить его работать. И при поиске в Интернете, похоже, что я должен делать это с sampler2DShadow...


так вот мой вопрос(ы):

какие изменения мне нужно внести, чтобы вместо этого использовать shadow2D? Что вообще делает shadow2D? Это просто более или менее автоматическое преобразование текстуры из глубины в мир? Могу я использовать такую же текстуру глубины? Или мне нужно отобразить текстуру глубины по-другому? Что я передаю shadow2D? Положение фрагмента в мировом пространстве, которое я хочу проверить? Или тот же УФ, что и раньше?

Если на все эти вопросы можно найти ответы в простой документации Пейдж, я был бы рад, если бы кто-нибудь мог это опубликовать. Но я клянусь, я искал часами и не могу найти ничего, что просто говорит, что, черт возьми, происходит с shadow2D!

спасибо!

1 ответов


прежде всего, какую версию GLSL вы используете?

начиная с GLSL 1.30, нет специальной функции поиска текстуры (имя в любом случае) для использования с sampler2DShadow. GLSL 1.30 + использует кучу перегрузок texture (...) которые выбираются на основе типа sampler пройдены и размеры координат.

во-вторых, если вы используете sampler2DShadow вам нужно сделать две вещи по-другому:

  1. сравнение текстур должно быть включено или вы получите неопределенные результаты

    • GL_TEXTURE_COMPARE_MODE = GL_COMPARE_REF_TO_TEXTURE​

  2. координаты, которые вы передаете texture (...) являются 3D вместо 2D. Новая 3-я координата-это значение глубины, которое вы собираетесь сравнить.

наконец, вы должны понять, что texture (...) возвращает при использовании sampler2DShadow:

если это сравнение проходит, texture (...) вернутся 1.0, если его не будет возвращение 0.0. Если вы используете GL_LINEAR текстурный фильтр на текстуре глубины, затем texture (...) выполнит 4 сравнения глубины, используя 4 ближайших значения глубины в текстуре глубины и вернет значение где-нибудь между 1.0 и 0.0 чтобы дать представление о количестве образцов, которые прошли/не удалось.

это правильный способ сделать аппаратное сглаживание теневых карт. Если вы пытались использовать обычный sampler2D С GL_LINEAR и реализовать глубинный тест самостоятельно вы получите одну усредненную глубину назад и логический результат pass / fail вместо поведения, описанного выше для sampler2DShadow.


что касается получения значения глубины для тестирования с позиции мирового пространства, вы были на правильном пути (хотя вы забыли разделение перспективы).

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

  1. умножьте мир-космос положение по вашей (световой) проекции и матрицам просмотра
  2. разделить полученную координату на ее W компонент
  3. масштабировать и смещать результат (который будет в диапазоне [-1,1]) в диапазон [0,1]

на последнем шаге предполагается, что вы используете диапазон глубины по умолчанию... если вы не позвонили glDepthRange (...) тогда это будет работать.

конечный результат шага 3 является и a глубина значение (R) и текстурные координаты (ST) для поиска в глубину карте. Это позволяет передать это значение напрямую to texture (...). Напомним, что первые 2 компонента координат текстуры такие же, как всегда, и что 3-е значение глубины для проверки.