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
вам нужно сделать две вещи по-другому:
-
сравнение текстур должно быть включено или вы получите неопределенные результаты
-
GL_TEXTURE_COMPARE_MODE
=GL_COMPARE_REF_TO_TEXTURE
-
координаты, которые вы передаете
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
.
что касается получения значения глубины для тестирования с позиции мирового пространства, вы были на правильном пути (хотя вы забыли разделение перспективы).
есть три вещи, которые вы должны сделать, чтобы создать глубину от мира-места установки:
- умножьте мир-космос положение по вашей (световой) проекции и матрицам просмотра
- разделить полученную координату на ее
W
компонент - масштабировать и смещать результат (который будет в диапазоне [-1,1]) в диапазон [0,1]
на последнем шаге предполагается, что вы используете диапазон глубины по умолчанию... если вы не позвонили glDepthRange (...)
тогда это будет работать.
конечный результат шага 3 является и a глубина значение (R
) и текстурные координаты (ST
) для поиска в глубину карте. Это позволяет передать это значение напрямую to texture (...)
. Напомним, что первые 2 компонента координат текстуры такие же, как всегда, и что 3-е значение глубины для проверки.