Карта теней пуста с помощью GL_LESS, но не с помощью GL_GREATER или GL_ALWAYS?

#c #opengl #glsl #glm-math #shadow-mapping

#c #opengl #glsl #glm-математика #отображение теней

Вопрос:

Я уже несколько дней работаю над отображением теней в моем пользовательском движке OpenGL. После прочтения нескольких руководств я постарался как можно точнее придерживаться базового метода: создайте фреймбуфер shadowmap с GL_TEXTURE_2D для самой shadowmap, визуализируйте с точки зрения освещения, используя фреймбуфер и базовый шейдер, затем визуализируйте в обычном режиме с помощью моего основного шейдера.

Однако я столкнулся с чем-то странным: когда я выполняю рендеринг, используя функцию глубины по умолчанию или устанавливая для нее значение GL_LESS вручную, карта теней, кажется, заполнена исключительно 0s. (Я тестировал, сравнивая значения shadowmmap с 0 в моем шейдере, поэтому я считаю, что на самом деле они равны 0, а не просто очень маленьким числам.)

Когда я устанавливаю для функции глубины значение GL_GREATER или GL_ALWAYS, shadowmap содержит значения, отличные от 0, хотя я не могу сказать, являются ли эти значения, отличные от 0, теми, которых я пытаюсь достичь.

Для справки, вот часть кода, который я использую:

Для настройки моих матриц, связанных с освещением:

 glm::vec3 lightPos(100, 200, 0);
glm::mat4 lightProjection, lightView;
glm::mat4 lightSpaceMatrix;
float near_plane = 0.1f, far_plane = 1000.0f;
lightProjection = glm::ortho(-1000.0f, 1000.0f, -1000.0f, 1000.0f, near_plane, far_plane);
lightView = glm::lookAt(lightPos, glm::vec3(0.0f, 32.0f, 0.0f), glm::vec3(0, 1, 0));
lightSpaceMatrix = lightProjection * lightView;
shader.setMat4("lightSpaceMatrix", lightSpaceMatrix);
  

Код для тестирования shadowmap — объекты, которые я визуализирую, отображаются красным цветом с функцией глубины GL_GREATER, но красного цвета с GL_LESS нет:

 vec3 projCoords = FragPosLightSpace.xyz / FragPosLightSpace.w;
// transform to [0,1] range
projCoords = projCoords * 0.5   0.5;
...
float closestDepth = texture(shadowMap, projCoords.xy).r; 
if (closestDepth > 0) {
    FragColor = vec4(1, 0, 0, 1);
}
  

Комментарии:

1. вы очистили свою depth_texture после привязки к вашему fbo. glClearDepth(1.0); glClear(GL_DEPTH_BUFFER_BIT); очень важно установить для него значение 1.0, а не 0.0

2. это решило мою проблему — я очищал свою depth_texture до привязки к fbo, а не после.

Ответ №1:

Я предполагаю, что вы забыли очистить свой буфер глубины.

Вам нужно заполнить ее максимальной глубиной в начале каждого вашего фрейма

 glClearDepth(1.0); 
glClear(GL_DEPTH_BUFFER_BIT);
  

очень важно установить для него значение 1.0 вместо 0.0, иначе ничего не будет нарисовано