diff --git a/shaders/forward.frag.glsl b/shaders/forward.frag.glsl index fcba7e1..06cd67c 100644 --- a/shaders/forward.frag.glsl +++ b/shaders/forward.frag.glsl @@ -44,14 +44,27 @@ in vec4 posInLightSpace; in vec2 varTexCoord; -#ifndef AMBIENT_LIGHT +// switch on light type +#if defined POINT_LIGHT + in vec3 lightDirInView; in vec3 halfVecInView; -#endif - -#ifdef POINT_LIGHT in vec3 lightDistInView; uniform float attenuation; + +#elif defined DIRECTIONNAL_LIGHT + +in vec3 lightDirInView; +in vec3 halfVecInView; + +#elif defined SPOT_LIGHT + +in vec3 lightDirInView; +in vec3 halfVecInView; +in vec3 lightDistInView; +uniform float attenuation; +uniform float cutoff; + #endif layout(location = 0)out vec4 outColor; diff --git a/shaders/shadow.frag.glsl b/shaders/shadow.frag.glsl index 4a5b750..f166d2b 100644 --- a/shaders/shadow.frag.glsl +++ b/shaders/shadow.frag.glsl @@ -7,9 +7,9 @@ out float fragmentdepth; void main() { - #ifdef ALPHA_MASK - if(texture(alphaMask, varTexCoord).r < 0.5) - discard; - #endif - fragmentdepth = gl_FragCoord.z; -} \ No newline at end of file + #ifdef ALPHA_MASK + if(texture(alphaMask, varTexCoord).r < 0.5) + discard; + #endif + fragmentdepth = gl_FragCoord.z; +} diff --git a/shaders/gbuffer.geom.glsl b/shaders/shadow.geom.glsl similarity index 62% rename from shaders/gbuffer.geom.glsl rename to shaders/shadow.geom.glsl index 103bf08..b20b04e 100644 --- a/shaders/gbuffer.geom.glsl +++ b/shaders/shadow.geom.glsl @@ -1,10 +1,12 @@ -#version 330 core +// inspired from +// http://learnopengl.com/#!Advanced-Lighting/Shadows/Point-Shadows layout(triangles) in; layout(triangle_strip, max_vertices = 18) out; -uniform mat4 view[6]; -uniform mat4 proj; +uniform mat4 MVP[6]; + +out vec4 FragPos; // debug parameter flat out int fcolor_idx; @@ -14,7 +16,8 @@ void main(void){ for (int i = 0; i < gl_in.length(); ++i){ gl_Layer = layerId; fcolor_idx = layerId; - gl_Position = proj * view[layerId] * gl_in[i].gl_Position; + FragPos = gl_in[i].gl_Position; + gl_Position = MVP[layerId] * FragPos; EmitVertex(); } EndPrimitive(); diff --git a/shaders/shadow.vert.glsl b/shaders/shadow.vert.glsl index ad6ae36..71e25d8 100644 --- a/shaders/shadow.vert.glsl +++ b/shaders/shadow.vert.glsl @@ -5,12 +5,19 @@ layout(location = 2) in vec2 inTexCoord; out vec2 varTexCoord; #endif +#ifndef POINT_LIGHT uniform mat4 MVP; +#endif void main() { #ifdef ALPHA_MASK varTexCoord = inTexCoord.xy; #endif - gl_Position = MVP * vec4(inPosition, 1.0); -} \ No newline at end of file + +#ifdef POINT_LIGHT + gl_Position = vec4(inPosition, 1.0); +#else + gl_Position = MVP * vec4(inPosition, 1.0); +#endif +} diff --git a/src/deferredmodule.cpp b/src/deferredmodule.cpp deleted file mode 100644 index e4ecef9..0000000 --- a/src/deferredmodule.cpp +++ /dev/null @@ -1,35 +0,0 @@ -#include "deferredmodule.h" - -#include "texture.h" - -GBuffer::GBuffer(int width, int height) : FrameBuffer() -{ - Texture* tex; - // - Normal buffer - tex = new Texture(GL_RGB, GL_RGB16F, width, height, GL_FLOAT); - tex->setFiltering(GL_NEAREST); - addTexture(tex, GL_COLOR_ATTACHMENT0); - - // - Color + Specular exponent buffer - tex = new Texture(GL_RGBA, GL_RGBA, width, height); - tex->setFiltering(GL_NEAREST); - addTexture(tex, GL_COLOR_ATTACHMENT1); - - // - Specular color + objectId buffer - tex = new Texture(GL_RGBA, GL_RGBA, width, height); - tex->setFiltering(GL_NEAREST); - addTexture(tex, GL_COLOR_ATTACHMENT2); - - // - depth buffer - tex = new Texture(GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, width, height, GL_FLOAT); - tex->setFiltering(GL_NEAREST); - addTexture(tex, GL_DEPTH_ATTACHMENT); - - initColorAttachments(); -} - -GBuffer::~GBuffer() -{ - for(Texture* t : m_textures) - delete(t); -} diff --git a/src/deferredmodule.h b/src/deferredmodule.h deleted file mode 100644 index 13ba1f7..0000000 --- a/src/deferredmodule.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef DEFERREDMODULE_H -#define DEFERREDMODULE_H - -#include "framebuffer.h" -#include "module.h" - -class Shader; -class PhongEntity; - -// TODO : everything - -class GBuffer : public FrameBuffer -{ -public: - GBuffer(int width, int height); - ~GBuffer(); -}; - -class DeferredModule : public Module -{ -public: - DeferredModule(); - - virtual void renderGL(Camera* myCamera, Scene* scene); -private: - -}; - -#endif // DEFERREDMODULE_H diff --git a/src/forwardmodule.cpp b/src/forwardmodule.cpp index baad211..9501440 100644 --- a/src/forwardmodule.cpp +++ b/src/forwardmodule.cpp @@ -5,6 +5,7 @@ #include "light.h" #include "phongmaterial.h" #include "texture.h" +#include "camera.h" #include void ForwardModule::renderGL(Camera* myCamera, Scene* scene) @@ -43,7 +44,7 @@ void ForwardModule::renderGL(Camera* myCamera, Scene* scene) shader->bindVec3(shader->getLocation("lightColor"), light->getColor()); if(light->isShadowCaster()) { - light->getShadowMap()->bind(PhongMaterial::NB_PHONG_SLOTS); // NB_PHONG_SLOTS has the value of the first available slot after the phong material texture slots + light->getShadowMapTexture()->bind(PhongMaterial::NB_PHONG_SLOTS); // NB_PHONG_SLOTS has the value of the first available slot after the phong material texture slots shader->bindInteger(shader->getLocation("shadowMap"), PhongMaterial::NB_PHONG_SLOTS); } break; @@ -54,7 +55,8 @@ void ForwardModule::renderGL(Camera* myCamera, Scene* scene) break; case Light::SPOT: shader->bindVec3(shader->getLocation("lightColor"), light->getColor()); - // TODO add cutoff and attenuation + shader->bindFloat(shader->getLocation("attenuation"), light->getAttenuation()); + shader->bindFloat(shader->getLocation("cutoff"), light->getCutoffAngle()); break; } unsigned int id = 2; @@ -70,10 +72,7 @@ void ForwardModule::renderGL(Camera* myCamera, Scene* scene) glm::mat4 mvp = myCamera->getProjectionMatrix() * modelViewMatrix; glm::mat4 normalMatrix = glm::transpose(glm::inverse(modelViewMatrix)); if(light != NULL && light->isShadowCaster()) - { - glm::mat4 lightMVP = Light::biasMatrix * light->getProjectionMatrix() * light->getViewMatrix() * node->modelMatrix; - shader->bindMat4(shader->getLocation("lightMVP"), lightMVP); - } + light->bindShadowMap(Shader *shader); shader->bindMat4(shader->getLocation("viewMatrix"), myCamera->getViewMatrix()); shader->bindMat4(shader->getLocation("modelViewMatrix"), modelViewMatrix); shader->bindMat3(shader->getLocation("normalMatrix"), glm::mat3(normalMatrix)); diff --git a/src/light.cpp b/src/light.cpp index aa006b1..012bca2 100644 --- a/src/light.cpp +++ b/src/light.cpp @@ -84,7 +84,7 @@ void Light::initShadowMap(int resolution, glm::vec3 dim) case DIRECTIONNAL: // 3 orthogonal matrices (cascaded shadowmaps) // 3 square textures - m_viewMatrix = glm::lookAt(m_position, m_position-m_direction, glm::vec3(0, 1, 0)); + m_viewMatrix.push_back(glm::lookAt(m_position, m_position-m_direction, glm::vec3(0, 1, 0))); m_projectionMatrix = glm::ortho(-dim.x/2, dim.x/2, -dim.y/2, dim.y/2, -dim.z/2, dim.z/2); tex = new Texture(GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, resolution, resolution, GL_FLOAT, GL_TEXTURE_2D); break; @@ -96,11 +96,24 @@ void Light::initShadowMap(int resolution, glm::vec3 dim) m_viewMatrix = glm::lookAt(m_position, m_position-glm::vec3(0, 0, 1), glm::vec3(0, 1, 0)); m_projectionMatrix = glm::perspective(90.f, 1.f, 0.1f, 100.f); tex = new Texture(GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, resolution, resolution, GL_FLOAT, GL_TEXTURE_CUBE_MAP); + + m_viewMatrices.push_back(shadowProj * + glm::lookAt(m_position, m_position + glm::vec3(1.0,0.0,0.0), glm::vec3(0.0,-1.0,0.0)); + m_viewMatrices.push_back(shadowProj * + glm::lookAt(m_position, m_position + glm::vec3(-1.0,0.0,0.0), glm::vec3(0.0,-1.0,0.0)); + m_viewMatrices.push_back(shadowProj * + glm::lookAt(m_position, m_position + glm::vec3(0.0,1.0,0.0), glm::vec3(0.0,0.0,1.0)); + m_viewMatrices.push_back(shadowProj * + glm::lookAt(m_position, m_position + glm::vec3(0.0,-1.0,0.0), glm::vec3(0.0,0.0,-1.0)); + m_viewMatrices.push_back(shadowProj * + glm::lookAt(m_position, m_position + glm::vec3(0.0,0.0,1.0), glm::vec3(0.0,-1.0,0.0)); + m_viewMatrices.push_back(shadowProj * + glm::lookAt(m_position, m_position + glm::vec3(0.0,0.0,-1.0), glm::vec3(0.0,-1.0,0.0)); break; case SPOT: // 1 projection matrix // 1 square texture - m_viewMatrix = glm::lookAt(m_position, m_position+m_direction, glm::vec3(0, 1, 0)); + m_viewMatrix.push_back(glm::lookAt(m_position, m_position+m_direction, glm::vec3(0, 1, 0))); m_projectionMatrix = glm::perspective(m_cutOffAngle, 1.f, 0.1f, 100.f); tex = new Texture(GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, resolution, resolution, GL_FLOAT, GL_TEXTURE_2D); break; @@ -142,7 +155,7 @@ void Light::generateShadowMap(Scene* scene) glClear(GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); - //glCullFace(GL_FRONT); + // glCullFace(GL_FRONT); for(SceneIterator* geometryIt = scene->getGeometry(); geometryIt->isValid(); geometryIt->next()) { @@ -157,10 +170,16 @@ void Light::generateShadowMap(Scene* scene) node->mesh->draw(m_shaders[hasAlpha], false, hasAlpha, false); } } - //glCullFace(GL_BACK); + // glCullFace(GL_BACK); } -Texture* Light::getShadowMap() +void Light::bindShadowMap(Shader *shader) +{ + glm::mat4 lightMVP = Light::biasMatrix * m_projectionMatrix * light->getViewMatrix() * node->modelMatrix; + shader->bindMat4(shader->getLocation("lightMVP"), lightMVP); +} + +Texture* Light::getShadowMapTexture() { return m_shadowMap->getTexture(0); } diff --git a/src/light.h b/src/light.h index 507210b..dc5ec2f 100644 --- a/src/light.h +++ b/src/light.h @@ -4,14 +4,14 @@ #include #include #include -#include "camera.h" +#include class FrameBuffer; class Shader; class Scene; class Texture; -class Light : public Camera +class Light { public: enum LightType { @@ -32,33 +32,77 @@ public: static const char* flagStr[]; static const glm::mat4 biasMatrix; + virtual LightType getType() = 0; + + glm::vec3 getColor() { return m_color; } + + virtual bool isShadowCaster() { return false; } + + virtual void bindAttributes(Shader *shader) = 0; + + virtual unsigned int getFlags() = 0; + +protected: + glm::vec3 m_color; +}; + +class AmbientLight : public Light +{ +public: + AmbientLight(glm::vec3 lightColor = glm::vec3(0.1f)) : m_color(lightColor) {} + virtual LightType getType() { return AMBIENT; } + virtual void bindAttributes(Shader *shader) + { shader->bindVec3(shader->getLocation("lightColor"), m_color); } + virtual unsigned int getFlags() { return 1 << AMBIENT_FLAG; } +}; + +class ShadowableLight : public Light +{ +public: + // enables shadowmapping on this light + virtual void initShadowMap(int resolution, glm::vec3 dim = glm::vec3(1)) = 0; + + // disables shadowmapping on this light + virtual void destroyShadowMap() = 0; + + // returns true is shadowmapping is enabled on this light + virtual bool isShadowCaster() { return m_shadowCaster; } + + // updates the shadowmap if shadowmapping is enabled + virtual void updateShadowMap(Scene* scene) = 0; + +protected: + bool m_shadowCaster; +}; + +class Light +{ +public: + Light(); void initAmbientLight(glm::vec3 lightColor = glm::vec3(0.1f)); void initDirectionnalLight(glm::vec3 dir = glm::vec3(0, -1, 0), glm::vec3 lightColor = glm::vec3(1)); void initPointLight(glm::vec3 pos = glm::vec3(0), glm::vec3 lightColor = glm::vec3(1), float att = 1); void initSpotLight(glm::vec3 pos = glm::vec3(0), glm::vec3 dir = glm::vec3(1, 0, 0), float spotAngle = 360, glm::vec3 lightColor = glm::vec3(1), float att = 1); - LightType getType() {return m_type;} - glm::vec3 getDir() {return m_direction;} - glm::vec3 getPos() {return m_position;} - glm::vec3 getColor() {return m_color;} - float getAttenuation() {return m_attenuation;} + + glm::vec3 getDir() { return m_direction; } + glm::vec3 getPos() { return m_position; } + glm::vec3 getColor() { return m_color; } + float getAttenuation() { return m_attenuation; } + float getCutoffAngle() { return m_cutOffAngle; } bool isShadowCaster() {return m_shadowCaster;} void initShadowMap(int resolution, glm::vec3 dim = glm::vec3(1)); void generateShadowMap(Scene* scene); - Texture* getShadowMap(); + void bindShadowMap(Shader *shader); + Texture* getShadowMapTexture(); - void setAttenuation(float a) {m_attenuation = a;} + void setAttenuation(float a) { m_attenuation = a; } + void setCutoffAngle(float c) { m_cutOffAngle = c; } void setPosition(glm::vec3 new_pos); void setColor(glm::vec3 new_color) {m_color = new_color;} - // camera inheritance - glm::mat4 getProjectionMatrix() {return m_projectionMatrix;} - glm::mat4 getViewMatrix() {return m_viewMatrix;} - // does nothing, just required for inheriting Camera - void resize(int width, int height) {} - /** * @brief getFlags returns the flags that defines the specificities of the light */ @@ -78,7 +122,7 @@ private: int m_shadowMapResolution; FrameBuffer* m_shadowMap; Shader* m_shaders[2]; - glm::mat4 m_viewMatrix; + std::vector m_viewMatrices; glm::mat4 m_projectionMatrix; }; diff --git a/src/phongmaterial.cpp b/src/phongmaterial.cpp index ca6daab..873d8e5 100644 --- a/src/phongmaterial.cpp +++ b/src/phongmaterial.cpp @@ -8,7 +8,7 @@ void PhongMaterial::bindAttributes(Shader* myShader) { - // TODO store the attributes location (in the shader class maybe) + // TODO store the attributes location myShader->bindFloat(myShader->getLocation("materialNs"), shininess); if(normal_map != NULL)