Partage
  • Partager sur Facebook
  • Partager sur Twitter

OpenGL Problème Ombres

Anonyme
    12 juin 2021 à 13:56:20

    Bonjour, bonsoir ! J'ai suivi le cours de https://learnopengl.com/Advanced-Lighting/Shadows/Shadow-Mapping pour apprendre à rendre mon jeu plus réaliste avec des ombres ^^. Mon problème, c'est que toute ma carte est noire, comme s'il y avait une ombre qui recouvrait toute la map :euh:.

    Voici mon code :

    Renderer.h

    #ifndef RENDERER_H
    #define RENDERER_H
    
    #define GLM_FORCE_INLINE
    
    #include "Entity.h"
    #include "Shader.h"
    #include "Skybox.h"
    #include "Camera.h"
    #include "Light.h"
    #include "Shadow.h"
    
    #include <unordered_map>
    
    class Renderer
    {
    private:
        std::unordered_map<const TexturedModel*, std::vector<const Entity*>> entities;
        glm::mat4 projection;
        Shader simpleDepthShader, shader;
        Skybox skybox;
        Shadow shadow;
        float skyboxRotation = 0;
        inline void renderScene(Shader &shader);
        inline void prepareModel(const TexturedModel &texturedModel);
    
    public:
        Renderer(Loader &loader, const glm::mat4 &projection);
        void addEntity(const Entity *entity);
        void prepare();
        void render(const Camera &camera, const Light &light);
    };
    
    #endif // RENDERER_H
    

    Renderer.cpp

    #include "Renderer.h"
    #include "Maths.h"
    #include "Window.h"
    
    #define GLM_FORCE_INLINE
    #include <glm/trigonometric.hpp>
    
    #include <GL/glew.h>
    #include <glm/gtc/matrix_transform.hpp>
    
    Renderer::Renderer(Loader &loader, const glm::mat4 &projection) :
        projection(projection), simpleDepthShader("entity3"), shader("entity"), skybox(loader, projection), shadow()
    {
        shader.bind();
        shader.loadMat("projection", projection);
        shader.unbind();
    }
    
    void Renderer::addEntity(const Entity *entity)
    {
        auto texturedModel = &entity->texturedModel;
    
        if (entities.count(texturedModel))
            entities[texturedModel].push_back(entity);
        else
        {
            std::vector<const Entity*> newBatch;
            newBatch.push_back(entity);
            entities[texturedModel] = newBatch;
        }
    }
    
    void Renderer::prepare()
    {
    }
    
    inline void Renderer::renderScene(Shader &shader)
    {
        for (auto &texturedModel : entities)
        {
            prepareModel(*texturedModel.first);
            for (auto &entity : texturedModel.second)
            {
                shader.loadMat("transformation", Maths::createTransformationMatrix(entity->translation, entity->rotation, entity->scale));
                glDrawElements(GL_TRIANGLES, texturedModel.first->model.count, GL_UNSIGNED_INT, nullptr);
            }
    
            glBindVertexArray(0);
        }
    }
    
    inline void Renderer::prepareModel(const TexturedModel &texturedModel)
    {
        const auto &model = texturedModel.model;
        const auto &texture = texturedModel.texture;
    
        glBindVertexArray(model.vao);
    
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, texture.texture);
        glActiveTexture(GL_TEXTURE1);
        glBindTexture(GL_TEXTURE_2D, shadow.texture);
    
        shader.loadFloat("shineDamper", texture.shineDamper);
        shader.loadFloat("reflectivity", texture.reflectivity);
        shader.loadFloat("repeatCount", texture.repeatCount);
    }
    
    void Renderer::render(const Camera &camera, const Light &light)
    {
        const auto &lightProjection = glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f, 1.0f, 7.5f);
        const auto &lightView = glm::lookAt(light.position, {0, 0, 0}, {0, 1, 0});
        const auto &lightSpaceMatrix = lightProjection * lightView;
    
        simpleDepthShader.bind();
        simpleDepthShader.loadMat("lightSpaceMatrix", lightSpaceMatrix);
    
        glViewport(0, 0, 1024, 1024);
        glBindFramebuffer(GL_FRAMEBUFFER, shadow.fbo);
        glClear(GL_DEPTH_BUFFER_BIT);
        renderScene(simpleDepthShader);
    
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
    
        glViewport(0, 0, Window::width, Window::height);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
        shader.bind();
        shader.loadVec("lightPosition", light.position);
        shader.loadVec("lightColor", light.color);
        shader.loadMat("lightSpaceMatrix", lightSpaceMatrix);
    
        const auto &view = Maths::createViewMatrix(camera.position, camera.rotation);
        shader.loadMat("view", view);
        renderScene(shader);
    
        shader.unbind();
    
        skyboxRotation += glm::radians(0.1f);
        const auto &skyboxView = Maths::createViewMatrix( {}, {camera.rotation.x, camera.rotation.y + skyboxRotation});
        skybox.render(skyboxView);
    
        entities.clear();
    }
    

    entity.vert (vertex shader des entités)

    #version 400 core
    
    layout (location = 0) in vec3 position;
    layout (location = 1) in vec2 in_textureCoord;
    layout (location = 2) in vec3 normal;
    
    out vec2 textureCoord;
    out vec3 surfaceNormal, toLightVector, toCameraVector;
    out vec4 fragPosLightSpace;
    
    uniform mat4 projection, view, transformation, lightSpaceMatrix;
    uniform vec3 lightPosition;
    uniform float repeatCount;
    
    void main()
    {
        vec4 worldPosition = transformation * vec4(position, 1.0);
        gl_Position =  projection * view * worldPosition;
        textureCoord = in_textureCoord * repeatCount;
    
        surfaceNormal = (transformation * vec4(normal, 0.0)).xyz;
        toLightVector = lightPosition - worldPosition.xyz;
        toCameraVector = (inverse(view) * vec4(0.0, 0.0, 0.0, 1.0)).xyz - worldPosition.xyz;
        fragPosLightSpace = lightSpaceMatrix * worldPosition;
    }
    

    entity.frag (fragment shader des entités)

    #version 400 core
    
    in vec2 textureCoord;
    in vec3 surfaceNormal, toLightVector, toCameraVector;
    in vec4 fragPosLightSpace;
    
    uniform sampler2D sampler, shadowMap;
    uniform vec3 lightColor;
    uniform float shineDamper, reflectivity;
    
    float calcShadow()
    {
        vec3 position = fragPosLightSpace.xyz * 0.5 + 0.5;
        float depth = texture(shadowMap, position.xy).r;
    
        return depth < position.z ? 0.0 : 1.0;
    }
    
    void main()
    {
    	vec3 unitNormal = normalize(surfaceNormal);
    	vec3 unitLightVector = normalize(toLightVector);
    
    	float brightness = max(dot(unitNormal, unitLightVector), 0.2);
    	vec3 diffuse = lightColor * brightness;
    
    	vec3 unitCameraToCamera = normalize(toCameraVector);
    	vec3 lightDirection = -unitLightVector;
    	vec3 reflectedLightDirection = reflect(lightDirection, unitNormal);
    
    	float specularFactor = max(dot(reflectedLightDirection, unitCameraToCamera), 0.0);
    	float dampedFactor = pow(specularFactor, shineDamper);
    	vec3 finalSpecular = lightColor * reflectivity * dampedFactor;
    
    	gl_FragColor = (texture(sampler, textureCoord) * vec4(diffuse, 1.0) + vec4(finalSpecular, 1.0)) * calcShadow();
    }
    


    shadow.vert

    #version 400 core
    
    layout (location = 0) in vec3 position;
    
    uniform mat4 transformation, lightSpaceMatrix;
    
    void main()
    {
    	gl_Position = transformation * lightSpaceMatrix * vec4(position, 1.0);
    }
    


    shadow.frag

    #version 400 core
    
    void main()
    {
    }
    

    Après quelques tests, j'a remarqué que dans entity.frag, la valeur de calcShadow() est toujours de 0.


    Merci d'avance :D !

    -
    Edité par Anonyme 12 juin 2021 à 13:57:43

    • Partager sur Facebook
    • Partager sur Twitter
      15 juin 2021 à 16:26:45

      Salut !

      As-tu tenté d'utiliser RenderDoc, pour voir ce qu'il se passe ?

      • Partager sur Facebook
      • Partager sur Twitter

      Si vous ne trouvez plus rien, cherchez autre chose.

      Anonyme
        16 juin 2021 à 15:13:37

        RenderDoc ? Je ne connais pas. Qu'est-ce que c'est ?
        • Partager sur Facebook
        • Partager sur Twitter
          16 juin 2021 à 18:22:18

          Une application pour le débogage d'appli graphique (supporte OpenGL, Direct3D et Vulkan)
          • Partager sur Facebook
          • Partager sur Twitter

          Si vous ne trouvez plus rien, cherchez autre chose.

          OpenGL Problème Ombres

          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
          × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
          • Editeur
          • Markdown