В попытке улучшить каскадные карты теней я рассмотрел использование GL_DEPTH_CLAMP и перемещение ближней и дальней плоскостей только вокруг фактического усеченного ракурса вместо глобальной ограничительной рамки. Но использование GL_DEPTH_CLAMP, кажется, не имеет никакого эффекта, и ближняя плоскость обрезает геометрию.
Я использую реверс z согласно Reversed-Z в OpenGL :
Версия tl / dr:
Изменить управление клипом на 0/1
glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE);
Использовать буфер глубины с плавающей запятой.
Очистить буфер глубины до 0
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glClearDepth(0.0f);
glClear(GL_DEPTH_BUFFER_BIT);
Изменить тест глубины на терку
glDepthFunc(GL_GREATER);
Измените матрицу проекции, чтобы она соответствовала
Обратный z работает очень хорошо, но, очевидно, он портится с GL_DEPTH_CLAMP. Если я выключу реверс z, GL_DEPTH_CLAMP будет работать, как задумано; но многие другие биты в коде запутались. (Он просто больше не переключается.)
Если вы посмотрите документацию GL_DEPTH_CLAMP , в ней говорится следующее:
Если включено, уравнение плоскости -wc ≤ zc ≤ wc игнорируется при ограничении объема обзора (фактически, отсечение в ближней или дальней плоскости отсутствует).
Я предполагаю, что реализация GL_DEPTH_CLAMP просто не совместима с обратным z. Но я чувствую, что что-то упустил. Любая идея о том, как заставить GL_DEPTH_CLAMP работать с реверсом z?
См. Следующее изображение буферов глубины:
Как вы можете видеть в первом каскаде, ближняя плоскость обрезает геометрию, она должна быть полностью белой.