From c5c8158653ff6bdd8238f9bb72af29de1ff5a17c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anselme=20FRAN=C3=87OIS?= Date: Sat, 23 Jul 2016 13:59:34 +0200 Subject: [PATCH] point light shadows are implemented, but not working yet --- shaders/lighting.frag.glsl | 33 +++++++++++++++++++-------------- shaders/shadow.geom.glsl | 15 ++++++++------- src/camera.h | 12 +++++++----- src/light.cpp | 13 +++++++++---- src/light.h | 6 +++--- src/trackballcamera.cpp | 2 +- 6 files changed, 47 insertions(+), 34 deletions(-) diff --git a/shaders/lighting.frag.glsl b/shaders/lighting.frag.glsl index 2f15600..5b8e47d 100644 --- a/shaders/lighting.frag.glsl +++ b/shaders/lighting.frag.glsl @@ -16,13 +16,18 @@ uniform sampler2DRect depthBuffer; uniform vec3 lightColor; #ifdef SHADOWMAP +#ifdef POINT_LIGHT +uniform samplerCubeShadow shadowMap; +uniform mat3 inverseViewMatrix; +#else uniform sampler2DShadow shadowMap; uniform mat4 viewToLightMatrix; #endif +#endif #if defined POINT_LIGHT uniform vec3 pointLight; -uniform float attenuation; +uniform float range; #elif defined DIRECTIONNAL_LIGHT uniform vec3 dirLight; #elif defined SPOT_LIGHT @@ -57,7 +62,7 @@ vec3 CookTorranceSpecularHighlight(in vec3 ks, in float ns, in vec3 normal, in v float VN = dot(viewDir, normal); float VH = dot(viewDir, halfVec); float LN = dot(lightDir, normal); - + HN = max(HN, 0); VN = max(VN, 0); LN = max(LN, 0); @@ -67,7 +72,7 @@ vec3 CookTorranceSpecularHighlight(in vec3 ks, in float ns, in vec3 normal, in v float denom = mix(1, roughness, HN*HN); float D = roughness/(3.1416*denom*denom); //D = pow(HN, ns); - + // Fresnel term with Schlick's approximation vec3 F = mix(ks, vec3(1), pow(1 - VH, 5)); @@ -75,7 +80,7 @@ vec3 CookTorranceSpecularHighlight(in vec3 ks, in float ns, in vec3 normal, in v // Geometric attenuation float G = min(1, min(2*HN*VN/VH, 2*HN*LN/VH)); - + return D * F * G; } @@ -84,11 +89,6 @@ vec3 testLighting(in vec3 kd, in vec3 ks, in float ns, in vec3 color, in vec3 no return color*diffuseComponent*(kd+ks*CookTorranceSpecularHighlight(ks, ns, normal, lightDir, halfVec, viewDir)); } -float computeShadow(sampler2D shadowmap, vec3 shadow){ - float lightFragDepth = texture(shadowmap, shadow.xy).r; - return lightFragDepth < shadow.z ? 0 : 1; -} - // MAIN PROGRAM void main(void) { @@ -101,11 +101,15 @@ void main(void) { float shininess = specularTexel.w*255; vec4 fragPos = texelFetch(positionBuffer, texCoord); float depth = texelFetch(depthBuffer, texCoord).r; - + #ifdef SHADOWMAP + #ifdef POINT_LIGHT + float shadow = 1; + #else vec4 fragInLightSpace = viewToLightMatrix * fragPos; fragInLightSpace.z = fragInLightSpace.z - 0.002; float shadow = texture(shadowMap, fragInLightSpace.xyz/fragInLightSpace.w); + #endif #else float shadow = 1; #endif @@ -113,10 +117,11 @@ void main(void) { float att = 1; #ifdef POINT_LIGHT vec3 dirLight = pointLight - fragPos.xyz; - float dist = length(dirLight); - if(dist > attenuation) - att = 0; - att = 1 - dist/attenuation; + vec4 pointShadowParam = vec4(inverseViewMatrix * dirLight, length(dirLight)); + att = texture(shadowMap, pointShadowParam); + //outColor = vec4(vec3(texture(shadowMap, vec4(inverseViewMatrix * dirLight, length(dirLight))).r), 1); + //return; + att = clamp(att, 0, 1); dirLight = normalize(dirLight); #endif diff --git a/shaders/shadow.geom.glsl b/shaders/shadow.geom.glsl index 8313a46..6a66dc0 100644 --- a/shaders/shadow.geom.glsl +++ b/shaders/shadow.geom.glsl @@ -16,13 +16,14 @@ out vec4 FragPos; flat out int fcolor_idx; void main(void){ - for (int layerId = 0; layerId < 6; ++layerId){ - mat4 MVP = projectionMatrix * viewMatrices[layerId]; - for (int i = 0; i < gl_in.length(); ++i){ - gl_Layer = layerId; - fcolor_idx = layerId; - FragPos = gl_in[i].gl_Position; - gl_Position = MVP * FragPos; + for (int layerId = 0; layerId < 6; ++layerId) + { + mat4 MVP = projectionMatrix * viewMatrices[layerId]; + gl_Layer = layerId; + fcolor_idx = layerId; + for (int i = 0; i < 3; ++i) + { + gl_Position = MVP * gl_in[i].gl_Position; EmitVertex(); } EndPrimitive(); diff --git a/src/camera.h b/src/camera.h index ccd2ffb..5d75970 100644 --- a/src/camera.h +++ b/src/camera.h @@ -22,13 +22,14 @@ class BasicCamera : public Camera float m_fov; float m_near; float m_far; - float m_ratio; + float m_width; + float m_height; - void computeProj() { m_projection = glm::perspective(m_fov, m_ratio, m_near, m_far); } + void computeProj() { m_projection = glm::perspectiveFov(m_fov, m_width, m_height, m_near, m_far); } public: BasicCamera(float myFov = 70.f, float myNear = 0.1f, float myFar = 100.f) : - m_fov(myFov), m_near(myNear), m_far(myFar), m_ratio(1.f) + m_fov(myFov), m_near(myNear), m_far(myFar), m_width(800.f), m_height(600.f) { computeProj(); setView(glm::vec3(0), glm::vec3(0, 0, 1)); @@ -36,11 +37,12 @@ class BasicCamera : public Camera virtual glm::mat4 getProjectionMatrix() { return m_projection; } virtual glm::mat4 getViewMatrix() { return m_view; } - virtual void resize(int width, int height) + virtual void resize(int width, int height) { if(width > 0 && height > 0) { - m_ratio = float(width)/float(height); + m_width = width; + m_height = height; computeProj(); } } diff --git a/src/light.cpp b/src/light.cpp index 0c46fcb..2572f30 100644 --- a/src/light.cpp +++ b/src/light.cpp @@ -236,9 +236,9 @@ void DirectionnalLight::updateShadowMap(Scene* scene) int PointLight::m_shaderRefCounter = 0; Shader* PointLight::m_shaders[2] = {NULL}; -PointLight::PointLight(glm::vec3 pos, float attenuation, glm::vec3 lightColor) : +PointLight::PointLight(glm::vec3 pos, float range, glm::vec3 lightColor) : m_position(pos), - m_attenuation(attenuation), + m_range(range), m_shadowCaster(false) { @@ -251,11 +251,12 @@ void PointLight::bindAttributes(Shader *shader, Camera *camera) glm::vec4 posInView = camera->getViewMatrix() * glm::vec4(m_position.x, m_position.y, m_position.z, 1.f); shader->bindVec3(shader->getLocation("lightColor"), m_color); shader->bindVec3(shader->getLocation("pointLight"), glm::vec3(posInView)); - shader->bindFloat(shader->getLocation("attenuation"), m_attenuation); + shader->bindFloat(shader->getLocation("range"), m_range); if(m_shadowCaster) { m_shadowMap->getTexture(0)->bind(7); // TODO use something else than 7 shader->bindInteger(shader->getLocation("shadowMap"), 7); + shader->bindMat3(shader->getLocation("inverseViewMatrix"), glm::inverse(glm::mat3(camera->getViewMatrix()))); } } @@ -298,6 +299,8 @@ void PointLight::initShadowMap(int resolution) m_shadowMap = new FrameBuffer(); m_shadowMap->addTexture(tex, GL_DEPTH_ATTACHMENT); m_shadowMap->initColorAttachments(); + + m_projectionMatrix = glm::perspective(90.f, 1.f, 0.01f, m_range); } void PointLight::destroyShadowMap() @@ -320,8 +323,8 @@ void PointLight::destroyShadowMap() void PointLight::updateShadowMap(Scene* scene) { glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - glViewport(0, 0, m_shadowMapResolution, m_shadowMapResolution); m_shadowMap->bindFBO(); + glViewport(0, 0, m_shadowMapResolution, m_shadowMapResolution); glClearDepth(1.0); glClear(GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); @@ -339,9 +342,11 @@ void PointLight::updateShadowMap(Scene* scene) m_shaders[shaderId]->bindMat4(m_shaders[shaderId]->getLocation("projectionMatrix"), m_projectionMatrix); m_shaders[shaderId]->bindMat4Array(m_shaders[shaderId]->getLocation("viewMatrices"), m_viewMatrices, 6); m_shaders[shaderId]->bindVec3(m_shaders[shaderId]->getLocation("pointLight"), m_position); + m_shaders[shaderId]->bindFloat(m_shaders[shaderId]->getLocation("far_plane"), m_range); node->mesh->draw(m_shaders[shaderId], false, shaderId, false); } } + FrameBuffer::screen->bindFBO(); } // OLD IMPLEMENTATION diff --git a/src/light.h b/src/light.h index bf6fc6e..321d219 100644 --- a/src/light.h +++ b/src/light.h @@ -95,10 +95,10 @@ public: PointLight(glm::vec3 pos = glm::vec3(0), float attenuation = 1, glm::vec3 lightColor = glm::vec3(1)); glm::vec3 getPos() { return m_position; } - float getAttenuation() { return m_attenuation; } + float getAttenuation() { return m_range; } void setPos(glm::vec3 pos) { m_position = pos; /* TODO : update projection matrix */ } - void setAttenuation(float attenuation) { m_attenuation = attenuation; } + void setAttenuation(float attenuation) { m_range = attenuation; } virtual LightType getType() { return POINT; } virtual void bindAttributes(Shader *shader, Camera *camera); @@ -110,7 +110,7 @@ public: private: glm::vec3 m_position; - float m_attenuation; + float m_range; bool m_shadowCaster; int m_shadowMapResolution; diff --git a/src/trackballcamera.cpp b/src/trackballcamera.cpp index af75d4d..f37c189 100644 --- a/src/trackballcamera.cpp +++ b/src/trackballcamera.cpp @@ -30,7 +30,7 @@ void TrackBallCamera::moveCamera(float dx, float dy) glm::mat4 MVP = m_projection * m_view; glm::mat4 inverseMVP = glm::inverse(MVP); screenPos = MVP * screenPos; - glm::vec4 pos(dx, -dy, (m_dist/m_far)*2 - 1, 1); + glm::vec4 pos(dx/m_width, -dy/m_height, (m_dist/m_far)*2 - 1, 1); pos *= screenPos.w; glm::vec4 diff = (inverseMVP * glm::vec4(0, 0, pos.z, pos.w)) - (inverseMVP * pos); moveCamera(glm::vec3(diff));