Рендеринг OpenGL в текстуру дает пустую текстуру - PullRequest
0 голосов
/ 20 мая 2018

Я пытаюсь выполнить рендеринг орто-значений глубины моих сцен в порядке текстур, чтобы использовать текстуру в последующем цикле рендеринга, чтобы определить, какие фрагменты находятся в тени.В основном 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.

Надеюсь, кто-то захочет помочь и сможет найти ошибку.

Спасибо, что заранее договорились, Алекс

...