2016-09-04 2 views
1

В настоящее время я пытаюсь реализовать отложенное затенение в OpenGL 3.2 и есть проблема, которую я просто не могу решить, несмотря ни на что.Отложенная затеняющая реализация OpenGL

Я реализовал его в два этапа (прохождение геометрии и пропуска освещения), как и следовало ожидать. После компиляции и запуска его экран показывает сцену, которую я подготовил, почти так, как хотелось бы, чтобы она выглядела. Цвета объектов верны, и они также расположены там, где и как я хотел, чтобы они были.

Дело в том, что расчеты света, похоже, не влияют на цвет, что так всегда. Через много часов я узнал, что текстуры для позиций и нормалей, похоже, содержат тот же контент, что и цветная текстура.

Если один изменяет последнюю строку в пиксельный шейдер освещения от fragColor = lightIntensity * color; к fragColor = lightIntensity * norm; или fragColor = lightIntensity * pos; это не имеет абсолютно никакого влияния на то, как визуализируется на экране.

Я пробовал многое выяснить, что происходит не так, но, честно говоря, понятия не имею, что это может быть.
Было бы здорово, если бы кто-нибудь мог мне помочь.

Мой метод визуализации выглядит следующим образом:

void render() 
{ 

    //geometry pass 
    gBuffer->bindForWriting(); 
    geometryShader->use(true); 
    calculateGBuffer(); 


    //lighting pass 
    gBuffer->bindForReading(lightShader->programID()); 
    lightShader->use(true); 
    drawOnScreen(); 

} 

Инициализация gBuffer объекта, как это:

void GBuffer::initializeFBO(int viewWidth, int viewHeight) 
{ 

    //initialize fbo and corresponding textures; 
    glGenFramebuffers(1, &fbo_ID); 
    glBindFramebuffer(GL_FRAMEBUFFER, fbo_ID); 

    glGenTextures(1, &colorTexture_ID); 
    glBindTexture(GL_TEXTURE_2D, colorTexture_ID); 
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, viewWidth, viewHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture_ID, 0); 

    glGenTextures(1, &posTexture_ID); 
    glBindTexture(GL_TEXTURE_2D, posTexture_ID); 
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, viewWidth, viewHeight, 0, GL_RGB, GL_FLOAT, NULL); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, posTexture_ID, 0); 

    glGenTextures(1, &normTexture_ID); 
    glBindTexture(GL_TEXTURE_2D, normTexture_ID); 
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, viewWidth, viewHeight, 0, GL_RGB, GL_FLOAT, NULL); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, normTexture_ID, 0); 

    GLuint attachments[3] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 }; 
    glDrawBuffers(3, attachments); 

    glGenRenderbuffers(1, &depthBuffer_ID); 
    glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer_ID); 
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, viewWidth, viewHeight); 
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuffer_ID); 



    //Check Status 
    if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) 
     qDebug() << "error while initializing framebuffer" << glCheckFramebufferStatus(GL_FRAMEBUFFER); 
    else{ 
     qDebug() << "framebuffer successfully created"; 
     initialized = true; 
    } 

    glBindFramebuffer(GL_FRAMEBUFFER, 0); 

} 

Методы bindForReading и bindForWriting:

void GBuffer::bindForWriting() 
{ 
    glBindFramebuffer(GL_FRAMEBUFFER, fbo_ID); 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
} 

void GBuffer::bindForReading(GLuint programID) 
{ 
    glBindFramebuffer(GL_FRAMEBUFFER, 0); 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    glActiveTexture(GL_TEXTURE0); 
    glBindTexture(GL_TEXTURE_2D, colorTexture_ID); 
    GLuint samplerTexture_ID = glGetUniformLocation(programID, "colorTexture"); 
    glUniform1i(samplerTexture_ID, 0); 

    glActiveTexture(GL_TEXTURE1); 
    glBindTexture(GL_TEXTURE_2D, posTexture_ID); 
    samplerTexture_ID = glGetUniformLocation(programID, "positionTexture"); 
    glUniform1i(samplerTexture_ID, 1); 

    glActiveTexture(GL_TEXTURE2); 
    glBindTexture(GL_TEXTURE_2D, normTexture_ID); 
    samplerTexture_ID = glGetUniformLocation(programID, "normTexture"); 
    glUniform1i(samplerTexture_ID, 2); 

} 

И в последние 4 шейдера:

Геометрия Vertex Shader:

#version 150 
#extension GL_ARB_separate_shader_objects : enable 
uniform mat4 MVPMatrix; 
uniform mat4 modelMatrix; 

in vec4 in_position; 
in vec4 in_color; 
in vec2 in_texcoord; 
in vec3 in_norm; 

out vec4 color_varying; 
out vec3 frag_position; 
out vec3 norm_vec; 
out vec2 texcoord_varying; 

void main() 
{ 
    gl_Position = MVPMatrix * in_position; 
    vec4 worldPosition = (modelMatrix * in_position); 
    frag_position = worldPosition.xyz; 
    norm_vec = in_norm; 

    color_varying = in_color; 
    texcoord_varying = in_texcoord; 
} 

Геометрия Фрагмент Shader:

#version 150 
#extension GL_ARB_explicit_attrib_location : enable 

in vec4 color_varying; 
in vec3 frag_position; 
in vec3 norm_vec; 
in vec2 texcoord_varying; 

layout (location = 0) out vec4 fragColor; 
layout (location = 1) out vec3 fragPosition; 
layout (location = 2) out vec3 frag_norm_vec; 

uniform sampler2D myTexture; 

void main() 
{ 
    vec4 texel = texture(myTexture, texcoord_varying); 
    fragColor = texel * color_varying; 
    fragPosition = frag_position; 
    frag_norm_vec = normalize(norm_vec); 
} 

Освещение VertexShader:

#version 150 
#extension GL_ARB_explicit_attrib_location : enable 
layout (location = 0) in vec2 in_position; 

out vec2 texCoord; 

void main() 
{ 
    gl_Position = vec4(in_position, 0, 1.0f); 

    texCoord = in_position; 
    if(texCoord.x == -1.0f) 
     texCoord.x = 0.0f; 
    if(texCoord.y == -1.0f) 
     texCoord.y = 0.0f; 
} 

освещения Фрагмент Shader (без освещения вычисления, чтобы сделать его короче)

#version 150 
#extension GL_ARB_separate_shader_objects : enable 

out vec4 fragColor; 
in vec2 texCoord; 


uniform sampler2D colorTexture; 
uniform sampler2D positionTexture; 
uniform sampler2D normTexture; 

void main() 
{ 
    //extract fragment data from fbo 
    vec3 pos = texture(positionTexture, texCoord).rgb; 
    vec3 norm = texture(normTexture, texCoord).rgb; 
    vec4 color = texture(colorTexture, texCoord); 


    fragColor = lightIntensity * color; 
} 

Sry для кодового спама, но я не могу сузить ошибку.

+1

«* Geometry Vertex Shader: *« Будьте осторожны, как вы выбрасываете такие термины, как «геометрия» рядом с «шейдером». Потому что у нас есть этап шейдера для этого, и мое первое чтение этого имени заставило меня подумать, что это то, что вы использовали. –

+1

"* OpenGL 3.1 *" Тогда почему ваши шейдеры используют '#version 150'? Это из GL 3.2. Это не ваша проблема, но вы должны четко понимать, какую версию OpenGL вы используете. –

+0

О, конечно, я развиваюсь под версией 3.2, я отредактировал это. – hey0

ответ

1

Проблема, скорее всего, в вашем заказе операций здесь:

gBuffer->bindForReading(lightShader->programID()); 
lightShader->use(true); 

где в bindForReading(), у вас есть вызовы, как это:

samplerTexture_ID = glGetUniformLocation(programID, "positionTexture"); 
glUniform1i(samplerTexture_ID, 1); 

The glUniform*() набор вызовы единых значений на Активность в настоящее время программа.Поскольку вы делаете lightShader активным после, вы делаете эти вызовы, равномерные значения будут установлены на ранее активной программе, которая, вероятно, даже не имеет этих униформ.

Просто изменяя порядок этих вызовов уже может это исправить:

lightShader->use(true); 
gBuffer->bindForReading(lightShader->programID()); 

Кроме того, вы используете GL_RGB16F как формат двух ваших буферов. Реализация OpenGL, которую вы используете, может поддержать это, но это не формат, который требуется для обработки цвета в спецификации. Если вы хотите, чтобы ваш код работал на разных платформах, вы должны использовать GL_RGBA16F, который гарантированно будет отображать цвета.

Смежные вопросы