Light rendering problem

While learning OpenGL I encountered a problem with light rendering. It looks like the first thing my program is doing is rendering one box, calculating light and then copying it. As a result, it looks like the light is coming from many directions (I’m using a directional light).
Screen:
[ATTACH=CONFIG]1841[/ATTACH]


#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <assert.h>
#include "ShaderLoader.h"
#include "Camera.h"
#include "Callbacks.h"

#define STB_IMAGE_IMPLEMENTATION
#include "ImageLoader.h"

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

#define WIND_X 800
#define WIND_Y 600

//Window
GLfloat Wind_width = WIND_X;
GLfloat Wind_height = WIND_Y;

//Camera----------------------
Camera camera( glm::vec3( 1.0f, 1.0f, 5.0f ) );
float lastX = WIND_X / 2;
float lastY = WIND_Y / 2;
bool firstMause = true;

//Timing---------------------------------------------
float deltaTime = 0.0f;
float lastFrame = 0.0f;

int main()
{
    //GLFW----------------------------------------------------------------------------------------------
    if( glfwInit() )
         assert( "Cant init GLFW" );
    
    glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, 3 );
    glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, 3 );
    glfwWindowHint( GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE );
    
    GLFWwindow * window = glfwCreateWindow( WIND_X, WIND_Y, "Level Editor 0.23", nullptr, nullptr );
    if( window == nullptr )
    {
        assert( "cant create a GLFW window" );
        glfwTerminate();
        return - 1;
    }
    
    glfwMakeContextCurrent( window );
    glfwSetFramebufferSizeCallback( window, framebuffer_size_callback );
    glfwSetCursorPosCallback( window, mouse_callback );
    glfwSetScrollCallback( window, scroll_callback );
    
    glfwSetInputMode( window, GLFW_CURSOR, GLFW_CURSOR_DISABLED );
    //---------------------------------------------------------------------------------------------------
    
    //DEPTH TEXT-----------------------------------------------------------------------------------------
    glEnable( GL_DEPTH_TEST );
    //---------------------------------------------------------------------------------------------------
    
    //GLEW-----------------------------------------------------------------------------------------------
    glewExperimental = GL_TRUE;
    
    if( glewInit() != GLEW_OK )
    {
        assert( "Cant init GLEW" );
        glfwTerminate();
        return - 1;
    }
    
    glViewport( 0, 0, WIND_X, WIND_Y );
    //---------------------------------------------------------------------------------------------------
    
    //Shader loaderd
    Shader lightingShader( "Shaders/T3_VertexShader.glsl", "Shaders/T3_FragmentShader.glsl" );
    
    //Cube---------------------------------------------------
    GLfloat vertices[] = {
        // positions          // normals           // texture coords
        - 0.5f, - 0.5f, - 0.5f, 0.0f, 0.0f, - 1.0f, 0.0f, 0.0f,
        0.5f, - 0.5f, - 0.5f, 0.0f, 0.0f, - 1.0f, 1.0f, 0.0f,
        0.5f, 0.5f, - 0.5f, 0.0f, 0.0f, - 1.0f, 1.0f, 1.0f,
        0.5f, 0.5f, - 0.5f, 0.0f, 0.0f, - 1.0f, 1.0f, 1.0f,
        - 0.5f, 0.5f, - 0.5f, 0.0f, 0.0f, - 1.0f, 0.0f, 1.0f,
        - 0.5f, - 0.5f, - 0.5f, 0.0f, 0.0f, - 1.0f, 0.0f, 0.0f,
        
        - 0.5f, - 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
        0.5f, - 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f,
        0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
        0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
        - 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f,
        - 0.5f, - 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
        
        - 0.5f, 0.5f, 0.5f, - 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
        - 0.5f, 0.5f, - 0.5f, - 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
        - 0.5f, - 0.5f, - 0.5f, - 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
        - 0.5f, - 0.5f, - 0.5f, - 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
        - 0.5f, - 0.5f, 0.5f, - 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
        - 0.5f, 0.5f, 0.5f, - 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
        
        0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
        0.5f, 0.5f, - 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
        0.5f, - 0.5f, - 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
        0.5f, - 0.5f, - 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
        0.5f, - 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
        0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
        
        - 0.5f, - 0.5f, - 0.5f, 0.0f, - 1.0f, 0.0f, 0.0f, 1.0f,
        0.5f, - 0.5f, - 0.5f, 0.0f, - 1.0f, 0.0f, 1.0f, 1.0f,
        0.5f, - 0.5f, 0.5f, 0.0f, - 1.0f, 0.0f, 1.0f, 0.0f,
        0.5f, - 0.5f, 0.5f, 0.0f, - 1.0f, 0.0f, 1.0f, 0.0f,
        - 0.5f, - 0.5f, 0.5f, 0.0f, - 1.0f, 0.0f, 0.0f, 0.0f,
        - 0.5f, - 0.5f, - 0.5f, 0.0f, - 1.0f, 0.0f, 0.0f, 1.0f,
        
        - 0.5f, 0.5f, - 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
        0.5f, 0.5f, - 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
        0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
        0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
        - 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
        - 0.5f, 0.5f, - 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f
    };
    
    glm::vec3 cubePositions[] = {
        glm::vec3( 0.0f, 0.0f, 0.0f ),
        glm::vec3( 2.0f, 5.0f, - 15.0f ),
        glm::vec3( - 1.5f, - 2.2f, - 2.5f ),
        glm::vec3( - 3.8f, - 2.0f, - 12.3f ),
        glm::vec3( 2.4f, - 0.4f, - 3.5f ),
        glm::vec3( - 1.7f, 3.0f, - 7.5f ),
        glm::vec3( 1.3f, - 2.0f, - 2.5f ),
        glm::vec3( 1.5f, 2.0f, - 2.5f ),
        glm::vec3( 1.5f, 0.2f, - 1.5f ),
        glm::vec3( - 1.3f, 1.0f, - 1.5f )
    };
    
    //-------------------------------------------------------
    
    GLuint VBO, cubeVAO;
    glGenVertexArrays( 1, & cubeVAO );
    glGenBuffers( 1, & VBO );
    
    glBindBuffer( GL_ARRAY_BUFFER, VBO );
    glBufferData( GL_ARRAY_BUFFER, sizeof( vertices ), & vertices, GL_STATIC_DRAW );
    
    glBindVertexArray( cubeVAO );
    glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof( GLfloat ),( GLvoid * ) 0 );
    glEnableVertexAttribArray( 0 );
    glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof( GLfloat ),( GLvoid * )( 3 * sizeof( float ) ) );
    glEnableVertexAttribArray( 1 );
    glVertexAttribPointer( 2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof( GLfloat ),( GLvoid * )( 6 * sizeof( float ) ) );
    glEnableVertexAttribArray( 2 );
    glBindVertexArray( 0 );
    
    glBindBuffer( GL_ARRAY_BUFFER, 0 );
    
    //Texture
    GLuint diffuseMap = loadTexture( "Textures/container2.png" );
    GLuint specularMap = loadTexture( "Textures/container2_specular.png" );
    
    lightingShader.use();
    lightingShader.setInt( "material.diffuse", 0 );
    lightingShader.setInt( "material.specular", 1 );
    
    while( !glfwWindowShouldClose( window ) )
    {
        //Delta time-----------------------------
        float currentFrame = glfwGetTime();
        deltaTime = currentFrame - lastFrame;
        lastFrame = currentFrame;
        
        //Events---------------------------------
        glfwPollEvents();
        processInput( window );
        
        //clear---------------------------------
        glClearColor( 0.1f, 0.1f, 0.1f, 1.0f );
        glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
        
        //Run shader----------------------------
        lightingShader.use();
        lightingShader.setVec3( "light.direction", glm::vec3( - 0.2f, - 1.0f, - 0.3f ) );
        lightingShader.setVec3( "viewPos", camera.Position );
        
        lightingShader.setVec3( "light.ambient", glm::vec3( 0.2f, 0.2f, 0.2f ) );
        lightingShader.setVec3( "light.diffuse", glm::vec3( 0.5f, 0.5f, 0.5f ) ); //darken the light a bit to fit the scene
        lightingShader.setVec3( "light.specular", glm::vec3( 1.0f, 1.0f, 1.0f ) );
        
        lightingShader.setVec3( "material.specular", glm::vec3( 0.5f, 0.5f, 0.5f ) );
        lightingShader.setFloat( "material.shininess", 32.0f );
        
        //Do math------------------------------
        glm::mat4 projection = glm::perspective( glm::radians( camera.Zoom ), Wind_width / Wind_height, 0.1f, 100.0f );
        glm::mat4 view = camera.GetViewMatrix();
        lightingShader.setMat4( "projection", projection );
        lightingShader.setMat4( "view", view );
        
        
        glm::mat4 model( 1.0f );
        lightingShader.setMat4( "model", model );
        
        //Texture------------------------------
        glActiveTexture( GL_TEXTURE0 );
        glBindTexture( GL_TEXTURE_2D, diffuseMap );
        
        glActiveTexture( GL_TEXTURE1 );
        glBindTexture( GL_TEXTURE_2D, specularMap );
        
        //Draw---------------------------------
        glBindVertexArray( cubeVAO );
        
        for( int i = 0; i < 10; i++ )
        {
            glm::mat4 model( 1.0f );
            model = glm::translate( model, cubePositions[ i ] );
            float angle = 20.0f * i;
            model = glm::rotate( model, glm::radians( angle ), glm::vec3( 1.0f, 0.3f, 0.5f ) );
            lightingShader.setMat4( "model", model );
            
            glDrawArrays( GL_TRIANGLES, 0, 36 );
        }
        
        glBindVertexArray( 0 );
        
        //Swap---------------------------------
        glfwSwapBuffers( window );
        
    }
    
    glDeleteVertexArrays( 1, & cubeVAO );
    glDeleteBuffers( 1, & VBO );
    
    glfwTerminate();
    
    return 0;
}

Vertex Shader:


#version 330 core

layout (location = 0) in vec3 aPosition;
layout (location = 1) in vec3 aNormal;
layout (location = 2) in vec2 aTexCoords;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

out vec3 FragPos;
out vec3 Normal;
out vec2 TexCoords;

void main()
{
gl_Position = projection * view * model * vec4(aPosition, 1.0f);
FragPos = vec3(model * vec4(aPosition, 1.0f));
Normal = aNormal;
TexCoords = aTexCoords;
}

Fragment Shader:


#version 330 core

struct Material{
sampler2D diffuse;
sampler2D specular;
sampler2D emmission;

float shininess;
};

uniform Material material;

struct Light{
vec3 direction;

vec3 ambient;
vec3 diffuse;
vec3 specular;
};

uniform Light light;
uniform vec3 viewPos;

out vec4 FragColor;

in vec3 FragPos;
in vec3 Normal;
in vec2 TexCoords;

void main()
{
//Ambient
vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords));

//diffuse
vec3 norm = normalize(Normal);
vec3 lightDir = normalize(-light.direction);
float diff = max(dot(norm, lightDir), 0.0f);
vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords));

//specular
vec3 viewDir = normalize(viewPos - FragPos);
vec3 reflectDir = reflect(-lightDir, norm);
float spec = pow(max(dot(viewDir, reflectDir), 0.0f), material.shininess);
vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords));

vec3 result = ambient + diffuse + specular;

FragColor = vec4(result, 1.0f);
}

You aren’t transforming the normal, so the lighting for each face is calculated based upon its initial (untransformed) orientation.

Ok found it. I change(in vertex shader).


//Normal = aNormal;
Normal = mat3( transpose( inverse( model ) ) ) * aNormal;

Thanks for help.

[QUOTE=WuwusOne;1292412]Ok found it. I change(in vertex shader).


//Normal = aNormal;
Normal = mat3( transpose( inverse( model ) ) ) * aNormal;

[/QUOTE]
Note that a matrix inversion is fairly expensive. If this calculation is required, it should be performed in the application, with the result stored in a separate uniform variable. If the model matrix consists solely of rotations and translations, it isn’t required; conversion to a mat3 discards any translation, and for a rotation matrix the inverse is simply the transpose.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.