OpenGL: Objekte werfen keinen Schatten auf andere Objekte

Hi!

Ich habe ein OpenGL-Programm geschrieben, in dem Blöcke (wie in Minecraft) zusammengesetzt werden. Ich wollte, dass die Blöcke Schatten werfen, doch im Moment tun sie das nur auf sich selbst. Ich arbeite mit GLFW, GLEW und einer Intel HD Graphics 4000 (unterstützt OpenGL 4.0). Hier sind Teile meines Quellcodes (Hauptdatei), da sonst alles viel zu lang wäre:

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);




        




    winInfo.frames = 0;




    winInfo.lastKeyPress = glfwGetTime();




    




    viewPos.eyeX = -3.0f;




    viewPos.eyeY = 3.0f;




    viewPos.eyeZ = 5.0f;




    viewPos.upX = 0.0f;




    viewPos.upY = 1.0f;




    viewPos.upZ = 0.0f;




    viewPos.lookDegreeHorizontal = 270.0f;




    viewPos.lookDegreeVertical = 90.0f;




    




    matrices.biasMatrixDepth = glm::mat4(glm::vec4(0.5f, 0.0f, 0.0f, 0.0f),




                                         glm::vec4(0.0f, 0.5f, 0.0f, 0.0f),




                                         glm::vec4(0.0f, 0.0f, 0.5f, 0.0f),




                                         glm::vec4(0.5f, 0.5f, 0.5f, 1.0f));




    




    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.mvpMatrix = matrices.pMatrix \* matrices.vMatrix \* matrices.mMatrix;




        matrices.mvpMatrixBiasDepth = matrices.biasMatrixDepth \* matrices.mvpMatrixDepth;




        




        glUniformMatrix4fv(glGetUniformLocation(renderProg, "mvpMatrix"), 1, GL\_FALSE, &matrices.mvpMatrix[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.mMatrixDepth = glm::translate(glm::mat4(1.0f), position);




        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);




    




    matrices.vMatrixDepth = glm::lookAt(glm::vec3(8.0f, 12.4f, 13.5f), glm::vec3(7.8f, 11.5f, 12.6f), glm::vec3(0.0f, 1.0f, 0.0f));




    matrices.pMatrixDepth = glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f, -10.0f, 20.0f);




    //matrices.mvpMatrixDepth = matrices.pMatrixDepth \* matrices.vMatrixDepth \* matrices.mMatrixDepth;




    //glUniformMatrix4fv(glGetUniformLocation(renderProgDepth, "mvpMatrixDepth"), 1, GL\_FALSE, &matrices.mvpMatrixDepth[0][0]);




    




&nbsp;&nbsp; &nbsp;for(z=-5; z\<=5; z++)




&nbsp;&nbsp; &nbsp;{




&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;for(y=0; y\<=6; y++)




&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;{




&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;for(x=-5; x\<=5; x++)




&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;{




&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if(blockMap[z+5][y][x+5].id != -1)




&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;setBlock(blockMap[z+5][y][x+5].position, blockMap[z+5][y][x+5].id, 1);




&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}




&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}




&nbsp;&nbsp; &nbsp;}




&nbsp;&nbsp; &nbsp;




&nbsp;&nbsp; &nbsp;




&nbsp;&nbsp; &nbsp;




&nbsp;&nbsp; &nbsp;glBindFramebuffer(GL\_FRAMEBUFFER, 0);




&nbsp;&nbsp; &nbsp;glClearBufferfv(GL\_COLOR, 0, bgColor);




&nbsp;&nbsp; &nbsp;glClearBufferfv(GL\_DEPTH, 0, &depthOne);




&nbsp;&nbsp; &nbsp;glUseProgram(renderProg);




&nbsp;&nbsp; &nbsp;




&nbsp;&nbsp; &nbsp;glEnableVertexAttribArray(0);




&nbsp;&nbsp; &nbsp;glEnableVertexAttribArray(1);




&nbsp;&nbsp; &nbsp;glEnableVertexAttribArray(2);




&nbsp;&nbsp; &nbsp;




&nbsp;&nbsp; &nbsp;matrices.vMatrix = glm::lookAt(glm::vec3(viewPos.eyeX, viewPos.eyeY, viewPos.eyeZ),




&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; glm::vec3(viewPos.centerX, viewPos.centerY, viewPos.centerZ),




&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; glm::vec3(viewPos.upX, viewPos.upY, viewPos.upZ));




&nbsp;&nbsp; &nbsp;matrices.pMatrix = glm::stuck\_out\_tongue:erspective(45.0f, (GLfloat)winInfo.winWidth/(GLfloat)winInfo.winHeight, 0.1f, 1000.0f);




&nbsp;&nbsp; &nbsp;




&nbsp;&nbsp; &nbsp;for(z=-5; z\<=5; z++)




&nbsp;&nbsp; &nbsp;{




&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;for(y=0; y\<=6; y++)




&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;{




&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;for(x=-5; x\<=5; x++)




&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;{




&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if(blockMap[z+5][y][x+5].id != -1)




&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;setBlock(blockMap[z+5][y][x+5].position, blockMap[z+5][y][x+5].id, 0);




&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}




&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}




&nbsp;&nbsp; &nbsp;}




&nbsp;&nbsp; &nbsp;glfwSwapBuffers(window);




&nbsp;&nbsp; &nbsp;winInfo.frames++;




}

Hier sind meine GLSL-Quelldateien:

openglSuperTutorials12.vss:




#version 430 core




layout (location = 0) in vec3 vPosition;




layout (location = 1) in vec2 vTexCoord;




layout (location = 2) in vec3 vNormal;




out vec4 fShadowCoord;




out vec2 fTexCoord;




uniform mat4 mvpMatrix;




uniform mat4 mvpMatrixBiasDepth;




void main()




{




&nbsp;&nbsp; &nbsp;gl\_Position = mvpMatrix \* vec4(vPosition, 1.0);




&nbsp;&nbsp;&nbsp; fShadowCoord = mvpMatrixBiasDepth \* vec4(vPosition, 1.0);




&nbsp;&nbsp;&nbsp; fTexCoord = vTexCoord;




}




openglSuperTutorials12.fss:




#version 430 core




in vec4 fShadowCoord;




in vec2 fTexCoord;




layout (location = 0) out vec4 outColor;




uniform sampler2D texBlock;




uniform sampler2DShadow shadowMap;




void main()




{




&nbsp;&nbsp; &nbsp;vec4 materialColor = texture(texBlock, fTexCoord);




&nbsp;&nbsp; &nbsp;float visibility = shadow2DProj(shadowMap, fShadowCoord).r;




&nbsp;&nbsp; &nbsp;outColor = visibility \* materialColor;




}




openglSuperTutorials12\_depth.vss:




#version 430 core




layout (location = 0) in vec3 vPosition;




uniform mat4 mvpMatrixDepth;




void main()




{




&nbsp;&nbsp;&nbsp; gl\_Position = mvpMatrixDepth \* vec4(vPosition, 1.0);




}




openglSuperTutorials12\_depth.fss:




#version 430 core




layout (location = 0) out vec4 outColor;




void main()




{




&nbsp;&nbsp;&nbsp; outColor = vec4(1.0, 0.0, 0.0, 1.0);




}

Was muss ich jetzt noch verändern, damit die Objekte gegenseitig aufeinander Schatten werfen?
Über eine hilfreiche Antwort wäre ich sehr dankbar.

Gruß,
nano99

Dass es keinen Schatten gibt, liegt manchmal daran, dass kein Licht da ist, wo kein Licht, da kein Schatten. Hatte ich auch mal in Povray, war alles zwar sichtbar, aber ziemlich fade.

Also muss eine Lichtquelle definiert werden. Ich habe nichts dergleichen im Code erkennen können.

Gruß, Lutz

Hallo Lutz,

erstmal vielen Dank für deine Antwort, doch soweit ich weiß, braucht man in OpenGL für Schatten keine Lichtquelle. Denn Schatten werden folgendermaßen erstellt:

  1. Die einzelnen Tiefen der Szene werden vom Standpunkt des Lichtes gerendert, doch dieser ist dann nur irgendein Punkt, der kein sichtbares Licht aussenden muss.
  2. Beim richtigen Rendern der Szene werden die einzelnen Tiefen der Fragmente mit den Tiefen von der sogenannten „Shadow Map“ verglichen, denn vom Standpunkt des Lichtes erkennt man nirgendwo Schatten, also ist jedes Fragment, das vom Standpunkt des Lichts nicht sichtbar ist, im Schatten.

Falls dich das noch nicht überzeugt, ist hier ein Screenshot von der Szene mit Licht:
http://i.stack.imgur.com/E5v3Z.png

Gruß,
nano99