代码之家  ›  专栏  ›  技术社区  ›  Kugel

OpenGL中的延迟着色?

  •  3
  • Kugel  · 技术社区  · 12 年前

    我的延迟着色实现遇到了一个奇怪的问题。 我通过MRT将所需的信息渲染到FBO中,当前是世界空间中的漫反射、位置和法线,如下所示:

    enter image description here

    这是通过对所有树纹理进行以下设置来完成的:

    diffuse = std::shared_ptr<bb::Texture>(new bb::Texture(GL_TEXTURE_2D)); // generates texture ID
    diffuse->bind();
    diffuse->texture2D(0, GL_RGB, width, height, 0, GL_RGB, GL_FLOAT, 0); // glTexture2D
    diffuse->parameterf(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    diffuse->parameterf(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    diffuse->parameterf(GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    diffuse->parameterf(GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    diffuse->unbind();
    texture2D(GL_COLOR_ATTACHMENT0+1, diffuse->getID(), 0);
    

    然后在我的绘图阶段使用这些:

    dsShader->bind();
    dsShader->enableVertexAttribArrays();
    
    ds->diffuse->bind(GL_TEXTURE0); // "ds" is an FBO containing the textures
    ds->position->bind(GL_TEXTURE0+1);
    ds->normal->bind(GL_TEXTURE0+2);
    
    dsShader->sendUniform("diffuse", 0);
    dsShader->sendUniform("position", 1);
    dsShader->sendUniform("normal", 2);
    
    dsShader->sendUniform("camera", camera3D->position.x, camera3D->position.y, camera3D->position.z);
    
    dsOut->indexBuffer->bind();
    dsOut->vertex2Buffer->bind();
    dsOut->vertex2Buffer->vertexAttribPointer(dsShader->getAttribLocation("vertex0"), 2, GL_FLOAT, false, 0, 0);
    
    glDrawElements(GL_TRIANGLES, dsOut->indexBuffer->size(), GL_UNSIGNED_INT, 0);
    
    ds->diffuse->unbind();
    ds->position->unbind();
    ds->normal->unbind();
    
    dsShader->disableVertexAttribArrays();
    dsShader->unbind();
    

    使用以下着色器(仅是必要的部分,光源是硬编码的):

    struct DirLight{
        vec3 direction;
        vec4 diffuse, specular;
    };
    
    uniform sampler2D diffuse;
    uniform sampler2D position;
    uniform sampler2D normal;
    
    uniform vec3 camera;
    
    DirLight light0 = DirLight(vec3(1, 1, 0), vec4(0.3), vec4(0.1));
    
    in vec2 vertex;
    
    void main(){
        vec4 color = texture(diffuse, vertex)*0.5;
        vec3 p = vec3(texture(position, vertex));
        vec3 n = normalize(vec3(texture(normal, vertex)));
    
        float ndotl = max(dot(n, normalize(light0.direction)), 0.0); // simple phong
    
        if(ndotl > 0.0){
            color += ndotl*light0.diffuse;
        }
    
        gl_FragColor = color;
    }
    

    如果我将光源方向设置为负值,那么wierd部分是:

    DirLight light0 = DirLight(vec3(-1, 0, 0), vec4(0.3), vec4(0.1));
    

    最终结果不会着色。它看起来适合正值(或多或少)。 以下是输出的图片:

    enter image description here

    红色区域标记的法线也可能有问题。

    1 回复  |  直到 12 年前
        1
  •  2
  •   Kugel    12 年前

    好的,Andon M.Coleman的解决方案奏效了,我将内部格式切换为GL_RGB8_SNORM。 感谢您的帮助:)