Я пытаюсь выполнить рендеринг орто-значений глубины моих сцен в порядке текстур, чтобы использовать текстуру в последующем цикле рендеринга, чтобы определить, какие фрагменты находятся в тени.В основном Shadow Map.
Однако текстура, которую я рендерил, в итоге оказывается однородно пустой.Учитывая, что я действительно могу проверить это только в шейдере, я ограничен тем, какой вывод я могу генерировать.Однако кажется, что все мои значения z в текстуре равны 0.
Вот код, который генерирует текстуру (ширина и высота - 1024, а pixelFormat - GL_DEPTH_COMPONENT
):
this.id = glGenTextures();
glBindTexture(GL_TEXTURE_2D, id);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, width, height, 0, pixelFormat, GL_FLOAT, (ByteBuffer) null);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
return id;
Здесь я создаю FrameBuffer и прикрепляю текстуру:
// Create a FBO to render the depth
this.depthMapFBO = glGenFramebuffers();
// Create the depth map texture
this.depthMap = new Texture(SHADOW_MAP_WIDTH, SHADOW_MAP_HEIGHT, GL_DEPTH_COMPONENT);
// Attach the the depth map texture to the FBO
glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, this.depthMap.getId(), 0);
// Set only depth
glDrawBuffer(GL_NONE);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
throw new Exception("Could not create FrameBuffer" +glCheckFramebufferStatus(GL_FRAMEBUFFER));
}
// Unbind
glBindFramebuffer(GL_FRAMEBUFFER, 0);
Перед тем, как рендерить мою сцену, я вызываю эту функцию для рендеринга глубины текстуры:
if(shaderMap.containsKey("shadow")){
shaderprogram = shaderMap.get("shadow");
}
shaderprogram.bind();
Sun sun = resourceManager.getSun();
Matrix4f LightViewMatrix = transformation.getLightViewMatrix(sun);
Matrix4f modelLightViewMatrix = transformation.getModelViewMatrix(object, LightViewMatrix);
shaderprogram.setUniform("modelLightViewMatrix",modelLightViewMatrix);
glBindFramebuffer(GL_FRAMEBUFFER,this.shadowmap.getDepthMapFBO());
glViewport(0, 0, 1024, 1024);
glClear(GL_DEPTH_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
this.shadowmap.getDepthMapTexture().bind();
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
glBindVertexArray(object.getMesh().getVaoId());
glEnableVertexAttribArray(0);//Vertex positions
glEnableVertexAttribArray(1);//Color Positions
glEnableVertexAttribArray(2);//Normals
glDrawElements(GL_TRIANGLES, object.getMesh().getVertexcount(),GL_UNSIGNED_INT ,0);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
glBindVertexArray(0);
glBindTexture(GL_TEXTURE_2D,0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
shaderprogram.unbind();
Я могу опубликоватьМатрицы для OrthogonalViewMatrix и LightViewMatrix, если необходимо, но я проверил их и визуализировал с ними свою сцену, и это дает желаемый эффект от того, что Камера летит над Землей и смотрит в центр карты.В основном, как бы вы себе представляли сцену, если бы камера была солнцем.Поэтому я не думаю, что с ними что-то не так.
Это мой второй рендер с нормальными проекциями.В основном обычная камера:
shaderprogram.createUniform("shadowMap");
glActiveTexture(GL_TEXTURE4);
this.shadowmap.getDepthMapTexture().bind();
shaderprogram.setUniform("shadowMap", 4);
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
glBindVertexArray(object.getMesh().getVaoId());
glEnableVertexAttribArray(0);//Vertex positions
glEnableVertexAttribArray(1);//Color Positions
glEnableVertexAttribArray(2);//Normals
glDrawElements(GL_TRIANGLES, object.getMesh().getVertexcount(),GL_UNSIGNED_INT ,0);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
glBindVertexArray(0);
glBindTexture(GL_TEXTURE_2D,0);
shaderprogram.unbind();
Некоторые части не учтены, но я думаю, что это наиболее важные части кода, где может быть ошибка.
Вот вершина и фрагментный шейдер, которыйиспользуется в первом цикле рендеринга карты теней:
#version 330
layout (location=0) in vec3 position;
layout (location=1) in vec2 texCoord;
layout (location=2) in vec3 vertexNormal;
uniform mat4 modelLightViewMatrix;
uniform mat4 orthoProjectionMatrix;
void main()
{
gl_Position = orthoProjectionMatrix * modelLightViewMatrix * vec4(position, 1.0f);
}
Я знаю, что я не использую texCoords и vertexNormal.Вот фрагментный шейдер:
#version 330
void main()
{
gl_FragDepth = gl_FragCoord.z;
}
Следует просто сохранить значение глубины фрагментов.И вот часть шейдера фрагмента обычных сцен:
float shadowfactor = 0;
vec3 projCoords = mlightviewVertexPos.xyz;
projCoords = projCoords * 0.5 + 0.5;
if (projCoords.z < texture(shadowMap,projCoords.xy).r){
// Current fragment is not in shade
shadowfactor = 1;
}else{
shadowfactor = 0.5;
}
color = color * (vec4(1,1,1,1)* shadowfactor);
fragColor = color;
Я ввожу orthoMatrix и LightViewMatrix, чтобы определить, где фрагмент будет в POV Солнца, и проверим значение Z в этой части текстуры.
Проблема в том, что теневой фактор кажется однородно черной текстурой.Я попытался присвоить текстуру (shadowMap, projCoords.xy) .r непосредственно фрагменту, чтобы увидеть, есть ли где-нибудь различия, но это все тот же черный цвет, например.0.
Я также пытался использовать текстуру ShadowMap непосредственно на местности, чтобы увидеть, есть ли там что-нибудь, но я также получаю только черную текстуру.
Я знаю, что это очень длинный вопрос, но я пытался отладить его последние 2 дня и не могу найти ошибку.Я предполагаю, что я либо не связываю текстуру правильно, либо в цикле рендеринга используется неправильный FrameBuffer.
Надеюсь, кто-то захочет помочь и сможет найти ошибку.
Спасибо, что заранее договорились, Алекс