物体不会在其他物体上投射阴影

时间:2014-04-30 16:27:23

标签: c opengl shadows

我在Orwell Dev-C ++ 5.4.0上使用GLEW和GLFW制作了一个OpenGL程序,它显示了块。我添加了环境光,漫反射光和镜面光以及现在的阴影。我使用了深度纹理。但是现在,这些块不会在其他块上投射阴影,而只会在自己身上投射阴影!

这是我的源代码的重要部分:

void createShadows()
{
    int error;

    glGenFramebuffers(1, &buffers.depthFbo);
    glBindFramebuffer(GL_FRAMEBUFFER, buffers.depthFbo);

    glGenTextures(1, &buffers.depthTbo);
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, buffers.depthTbo);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, winInfo.winWidth, winInfo.winHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, buffers.depthTbo, 0);
    glDrawBuffer(GL_NONE);

    error = glCheckFramebufferStatus(GL_FRAMEBUFFER);
    if(error != GL_FRAMEBUFFER_COMPLETE)
        printError("FramebufferError.txt", "Framebuffer", error);

    glBindFramebuffer(GL_FRAMEBUFFER, 0);
}

void init()
{
    renderProg = compileShaders("openglSuperTutorials12.vss", "openglSuperTutorials12.fss", 0);
    renderProgDepth = compileShaders("openglSuperTutorials12_depth.vss", "openglSuperTutorials12_depth.fss", 0);

    glGenVertexArrays(1, &buffers.vao);
    glBindVertexArray(buffers.vao);

    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);

    glEnable(GL_CULL_FACE);
    glCullFace(GL_BACK);

    matrices.mMatrixDepth                    = glm::mat4(1.0f);
    matrices.pMatrixDepth                    = glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f, -10.0f, 20.0f);
    matrices.biasMatrixDepth                 = glm::mat4(0.5f, 0.0f, 0.0f, 0.0f,
                                                         0.0f, 0.5f, 0.0f, 0.0f,
                                                         0.0f, 0.0f, 0.5f, 0.0f,
                                                         0.5f, 0.5f, 0.5f, 1.0f);

    //Initialize light and material properties and give them to the "renderProg" (truncated)

    glfwGetWindowSize(window, &winInfo.winWidth, &winInfo.winHeight);
    glfwSetCursorPos(window, winInfo.winWidth/2.0, winInfo.winHeight/2.0);

    createTexture();
    createVertices();
    createBlocks();
    createShadows();
}

void setBlock(glm::vec3 position, int id, int depth)
{
    if(depth != 1)
    {
        matrices.mMatrix = glm::translate(glm::mat4(1.0f), position);
        matrices.mvpMatrixBiasDepth = matrices.biasMatrixDepth * matrices.mvpMatrixDepth;

        glUniformMatrix4fv(glGetUniformLocation(renderProg, "mMatrix"), 1, GL_FALSE, &matrices.mMatrix[0][0]);
        glUniformMatrix4fv(glGetUniformLocation(renderProg, "mvpMatrixBiasDepth"), 1, GL_FALSE, &matrices.mvpMatrixBiasDepth[0][0]);

        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, buffers.tbo);
        glUniform1i(glGetUniformLocation(renderProg, "texBlock"), 0);

        glActiveTexture(GL_TEXTURE1);
        glBindTexture(GL_TEXTURE_2D, buffers.depthTbo);
        glUniform1i(glGetUniformLocation(renderProg, "shadowMap"), 1);

        glGenBuffers(1, &buffers.tcbo);
        glBindBuffer(GL_ARRAY_BUFFER, buffers.tcbo);
        glBufferData(GL_ARRAY_BUFFER, sizeof(blocks[id]), blocks[id], GL_DYNAMIC_DRAW);
        glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, NULL);
        glEnableVertexAttribArray(1);
    }
    else
    {
        matrices.mvpMatrixDepth = matrices.pMatrixDepth * matrices.vMatrixDepth * matrices.mMatrixDepth;
        glUniformMatrix4fv(glGetUniformLocation(renderProgDepth, "mvpMatrixDepth"), 1, GL_FALSE, &matrices.mvpMatrixDepth[0][0]);
    }

    glDrawArrays(GL_TRIANGLES, 0, 36);

    if(depth != 1)
    {
        glDisableVertexAttribArray(1);
        glDeleteBuffers(1, &buffers.tcbo);
    }
}

void display()
{
    int x, y, z;

    GLfloat bgColor[] = { 0.0f, 0.73f, 1.0f, 1.0f };
    GLfloat depthOne = 1.0f;

    glBindFramebuffer(GL_FRAMEBUFFER, buffers.depthFbo);
    glClearBufferfv(GL_DEPTH, 0, &depthOne);
    glUseProgram(renderProgDepth);

    glEnableVertexAttribArray(0);
    glDisableVertexAttribArray(1);
    glDisableVertexAttribArray(2);

    if(viewPos.lightSticky == 1)
    {
        lightProperties.lightPosition  = glm::vec3(viewPos.eyeX, viewPos.eyeY, viewPos.eyeZ);
        lightProperties.lightDirection = glm::vec3(viewPos.centerX, viewPos.centerY, viewPos.centerZ);
    }

    matrices.vMatrixDepth = glm::lookAt(
                    lightProperties.lightPosition,
                    lightProperties.lightDirection,
                    glm::vec3(viewPos.upX, viewPos.upY, viewPos.upZ));

    for(z=-5; z<=5; z++)
    {
        for(y=0; y<=6; y++)
        {
            for(x=-5; x<=5; x++)
            {
                if(blockMap[z+5][y][x+5].id != -1)
                    setBlock(blockMap[z+5][y][x+5].position, blockMap[z+5][y][x+5].id, 1);
            }
        }
    }



    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    glClearBufferfv(GL_COLOR, 0, bgColor);
    glClearBufferfv(GL_DEPTH, 0, &depthOne);
    glUseProgram(renderProg);

    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);
    glEnableVertexAttribArray(2);

    lightProperties.cameraPosition = glm::vec3(viewPos.eyeX, viewPos.eyeY, viewPos.eyeZ);

    matrices.vMatrix = glm::lookAt(glm::vec3(viewPos.eyeX, viewPos.eyeY, viewPos.eyeZ),
                                   glm::vec3(viewPos.centerX, viewPos.centerY, viewPos.centerZ),
                                   glm::vec3(viewPos.upX, viewPos.upY, viewPos.upZ));
    matrices.pMatrix = glm::perspective(45.0f, (GLfloat)winInfo.winWidth/(GLfloat)winInfo.winHeight, 0.1f, 1000.0f);

    glUniformMatrix4fv(glGetUniformLocation(renderProg, "vMatrix"),                1, GL_FALSE, &matrices.vMatrix[0][0]);
    glUniformMatrix4fv(glGetUniformLocation(renderProg, "pMatrix"),                1, GL_FALSE, &matrices.pMatrix[0][0]);

    //Update light uniforms (truncated)

    for(z=-5; z<=5; z++)
    {
        for(y=0; y<=6; y++)
        {
            for(x=-5; x<=5; x++)
            {
                if(blockMap[z+5][y][x+5].id != -1)
                    setBlock(blockMap[z+5][y][x+5].position, blockMap[z+5][y][x+5].id, 0);
            }
        }
    }

    glfwSwapBuffers(window);
    winInfo.frames++;
}

Vertex-Shader“openglSuperTutorials12.vss”:

#version 430 core

layout (location = 0) in vec3 vPosition;
layout (location = 1) in vec2 vTexCoord;
layout (location = 2) in vec3 vNormal;

out vec3 fPosition;
out vec4 fShadowCoord;
out vec2 fTexCoord;
out vec3 fNormal;

uniform mat4 mMatrix;
uniform mat4 vMatrix;
uniform mat4 pMatrix;
uniform mat4 mvpMatrixBiasDepth;

void main()
{
    gl_Position = pMatrix * vMatrix * mMatrix * vec4(vPosition, 1.0);
    fPosition = vPosition;
    fShadowCoord = mvpMatrixBiasDepth * vec4(vPosition, 1.0);
    fTexCoord = vTexCoord;
    fNormal = normalize(transpose(inverse(mat3(mMatrix))) * vNormal);
}

Fragment-Shader“openglSuperTutorials12.fss”:

#version 430 core

in vec3 fPosition;
in vec4 fShadowCoord;
in vec2 fTexCoord;
in vec3 fNormal;

out vec4 outColor;

uniform sampler2D texBlock;
uniform sampler2D shadowMap;
uniform mat4 mMatrix;

uniform int   ambientLightEnabled;
uniform int   diffuseLightEnabled;
uniform int   specularLightEnabled;
uniform int   shadowsEnabled;
uniform vec3  ambientLightColor;
uniform vec3  diffuseLightColor;
uniform vec3  specularLightColor;
uniform vec3  lightPosition;
uniform vec3  cameraPosition;
uniform float lightAttenuation;
uniform vec3  spotlightConeDirection;
uniform float spotlightCosCutoff;
uniform float spotlightExponent;

uniform vec3  ambientMaterialColor;
uniform vec3  diffuseMaterialColor;
uniform vec3  specularMaterialColor;
uniform float shininess;
uniform float strength;

void main()
{
    vec3  shadowValue = vec3(textureProj(shadowMap, fShadowCoord));
    vec3  surfacePos = vec3(mMatrix * vec4(fPosition, 1.0));
    vec3  surfaceToLight = normalize(lightPosition - surfacePos);
    vec3  surfaceToCamera = normalize(cameraPosition - surfacePos);

    vec3  ambientColor = ambientMaterialColor * ambientLightColor;

    float diffuseIntensity = max(0.0, dot(fNormal, surfaceToLight));
    vec3  diffuseColor = diffuseIntensity * diffuseLightColor * diffuseMaterialColor;

    float specularIntensity;
    if(diffuseIntensity == 0.0)
        specularIntensity = 0.0;
    else
        specularIntensity = pow(max(0.0, dot(fNormal, normalize(surfaceToLight + surfaceToCamera))), shininess) * strength;
    vec3  specularColor = specularIntensity * specularLightColor * specularMaterialColor;

    float distanceToLight = length(surfacePos - lightPosition);
    float attenuation = 1.0 / (
                    lightAttenuation +
                    lightAttenuation * distanceToLight + 
                    lightAttenuation * distanceToLight * distanceToLight);

    vec3  lightColorCombined = vec3(0.0);
    if(ambientLightEnabled == 1)
    {
        lightColorCombined += ambientColor;
    }
    if(diffuseLightEnabled == 1)
    {
        if(shadowsEnabled == 1)
            diffuseColor *= shadowValue;
        lightColorCombined += diffuseColor;
    }
    if(specularLightEnabled == 1)
    {
        if(shadowsEnabled == 1)
            specularColor *= shadowValue;
        lightColorCombined += attenuation * specularColor;
    }

    outColor = texture(texBlock, fTexCoord) * vec4(lightColorCombined, 1.0);   
}

其他着色器(“openglSuperTutorials12_depth.vss”和“openglSuperTutorials12_depth.fss”)只是带有“mvpMatrixDepth”的简单直通着色器。

A screenshot of the scene

我需要更改什么才能让灯光投射到其他物体上?

0 个答案:

没有答案