From 7ca0d3d0035ae25e20c6e40287f1dbd5a5509574 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anselme=20FRAN=C3=87OIS?= Date: Sun, 24 Jul 2016 14:53:31 +0200 Subject: [PATCH] 2D elements are correctly blended and rendered according to depth --- shaders/gui.frag.glsl | 4 +++- shaders/gui.vert.glsl | 3 +-- shaders/lighting.frag.glsl | 8 +++++--- shaders/shadow.frag.glsl | 24 ++++++++++++------------ shaders/shadow.geom.glsl | 9 +++------ src/deferredpipeline.cpp | 8 +++++++- src/light.cpp | 38 +++++++++++++++++++++++--------------- src/light.h | 11 ++++++----- src/mesh.h | 2 +- src/phongmaterial.cpp | 1 + src/phongmaterial.h | 4 +++- 11 files changed, 65 insertions(+), 47 deletions(-) diff --git a/shaders/gui.frag.glsl b/shaders/gui.frag.glsl index 8d6683a..6421896 100644 --- a/shaders/gui.frag.glsl +++ b/shaders/gui.frag.glsl @@ -12,6 +12,8 @@ uniform vec3 materialKd; #ifdef ALPHA_MASK uniform sampler2D alphaMask; +#else +uniform float opacity; #endif // OUTPUT COLOR @@ -31,7 +33,7 @@ void main(void) #ifdef ALPHA_MASK float alpha = texture(alphaMask, texCoord).r; #else - float alpha = 1.0; + float alpha = opacity; #endif outColor = vec4(color, alpha); diff --git a/shaders/gui.vert.glsl b/shaders/gui.vert.glsl index d0edea0..0abe214 100644 --- a/shaders/gui.vert.glsl +++ b/shaders/gui.vert.glsl @@ -8,11 +8,10 @@ out vec2 texCoord; uniform mat4 transformMatrix; uniform mat4 orthoMatrix; -uniform float depth; void main(void) { #ifdef TEXTURABLE texCoord = inTexCoord; #endif - gl_Position = orthoMatrix * transformMatrix * vec4(inPosition, depth, 1.0); + gl_Position = orthoMatrix * transformMatrix * vec4(inPosition, 0.0, 1.0); } diff --git a/shaders/lighting.frag.glsl b/shaders/lighting.frag.glsl index 667314a..3879b77 100644 --- a/shaders/lighting.frag.glsl +++ b/shaders/lighting.frag.glsl @@ -17,7 +17,7 @@ uniform vec3 lightColor; #ifdef SHADOWMAP #ifdef POINT_LIGHT -uniform samplerCubeShadow shadowMap; +uniform samplerCube shadowMap; uniform mat3 inverseViewMatrix; #else uniform sampler2DShadow shadowMap; @@ -118,8 +118,10 @@ void main(void) { #ifdef POINT_LIGHT vec3 dirLight = pointLight - fragPos.xyz; vec4 pointShadowParam = vec4(inverseViewMatrix * dirLight, length(dirLight)); - att = texture(shadowMap, pointShadowParam); - //outColor = vec4(vec3(texture(shadowMap, vec4(inverseViewMatrix * dirLight, length(dirLight))).r), 1); + //att = texture(shadowMap, pointShadowParam); + //outColor = vec4(vec3(texture(shadowMap, vec4(inverseViewMatrix * dirLight, length(dirLight)/range))), 1); + //outColor = vec4(vec3(texture(shadowMap, vec3(inverseViewMatrix * dirLight)).r), 1); + //outColor = vec4(vec3(length(dirLight)/range), 1); //return; att = clamp(att, 0, 1); dirLight = normalize(dirLight); diff --git a/shaders/shadow.frag.glsl b/shaders/shadow.frag.glsl index 7b9aab7..c0352e9 100644 --- a/shaders/shadow.frag.glsl +++ b/shaders/shadow.frag.glsl @@ -3,25 +3,25 @@ uniform sampler2D alphaMask; in vec2 varTexCoord; #endif -out float fragmentdepth; - #ifdef POINT_LIGHT -in vec4 FragPos; +in vec4 fragPos; +flat in int fcolor_idx; -uniform vec3 pointLight; uniform float far_plane; #endif void main() { - #ifdef ALPHA_MASK +#ifdef ALPHA_MASK if(texture(alphaMask, varTexCoord).r < 0.5) discard; - #endif - - #ifdef POINT_LIGHT - fragmentdepth = length(FragPos.xyz - pointLight)/far_plane; - #else - fragmentdepth = gl_FragCoord.z; - #endif +#endif + /* +#ifdef POINT_LIGHT + //gl_FragDepth = float(fcolor_idx)/6; + gl_FragDepth = length(fragPos.xyz)/far_plane; +#else + gl_FragDepth = gl_FragCoord.z; +#endif*/ + gl_FragDepth = 0.5; } diff --git a/shaders/shadow.geom.glsl b/shaders/shadow.geom.glsl index 6a66dc0..12dd9be 100644 --- a/shaders/shadow.geom.glsl +++ b/shaders/shadow.geom.glsl @@ -7,10 +7,9 @@ layout(triangles) in; layout(triangle_strip, max_vertices = 18) out; -uniform mat4 projectionMatrix; -uniform mat4 viewMatrices[6]; +uniform mat4 layerTransform[6]; -out vec4 FragPos; +out vec4 fragPos; // debug parameter flat out int fcolor_idx; @@ -18,12 +17,11 @@ flat out int fcolor_idx; void main(void){ 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; + gl_Position = layerTransform[layerId] * gl_in[i].gl_Position; EmitVertex(); } EndPrimitive(); @@ -42,4 +40,3 @@ uniform mat4 backShadowMVP; #endif - diff --git a/src/deferredpipeline.cpp b/src/deferredpipeline.cpp index aac035d..4466c49 100644 --- a/src/deferredpipeline.cpp +++ b/src/deferredpipeline.cpp @@ -9,6 +9,7 @@ #include "phongmaterial.h" #include "camera.h" #include +#include RESOURCE_PACK(shaders) @@ -95,6 +96,10 @@ DeferredPipeline::DeferredPipeline() : m_postEffectsShader = new Shader(vertSource, fragSource); } +bool depthCompare(const GeometryNode* firstElem, const GeometryNode* secondElem) { + return firstElem->mesh->getDepth() < secondElem->mesh->getDepth(); +} + void DeferredPipeline::renderGL(Scene *scene) { if(m_renderTarget == NULL) @@ -118,7 +123,7 @@ void DeferredPipeline::renderGL(Scene *scene) unsigned int type = node->mesh->getFlags(); if(type & (1 << Mesh::MESH_2D)) { - mesh2D.push_back(node); + mesh2D.push_back(node); // TODO : not every frame continue; } Shader *shader = m_mesh3DShaders[node->mesh->getFlags()]; @@ -191,6 +196,7 @@ void DeferredPipeline::renderGL(Scene *scene) glClear(GL_DEPTH_BUFFER_BIT); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + std::sort(mesh2D.begin(), mesh2D.end(), depthCompare); for(GeometryNode* node : mesh2D) { Shader *shader = m_mesh2DShaders[node->mesh->getFlags()]; diff --git a/src/light.cpp b/src/light.cpp index 2572f30..12314b5 100644 --- a/src/light.cpp +++ b/src/light.cpp @@ -27,16 +27,6 @@ const glm::mat4 Light::biasMatrix( 0.0, 0.0, 0.5, 0.0, 0.5, 0.5, 0.5, 1.0); -const glm::mat4 PointLight::m_viewMatrices[6] = -{ - glm::lookAt(glm::vec3(0), glm::vec3(1, 0, 0 ), glm::vec3(0,-1, 0 )), - glm::lookAt(glm::vec3(0), glm::vec3(-1,0, 0 ), glm::vec3(0,-1, 0 )), - glm::lookAt(glm::vec3(0), glm::vec3(0, 1, 0 ), glm::vec3(0, 0, 1 )), - glm::lookAt(glm::vec3(0), glm::vec3(0, -1,0 ), glm::vec3(0, 0, -1)), - glm::lookAt(glm::vec3(0), glm::vec3(0, 0, 1 ), glm::vec3(0,-1, 0 )), - glm::lookAt(glm::vec3(0), glm::vec3(0, 0, -1), glm::vec3(0,-1, 0 )) -}; - void AmbientLight::bindAttributes(Shader *shader, Camera *camera) { shader->bindVec3(shader->getLocation("lightColor"), m_color); @@ -271,7 +261,8 @@ unsigned int PointLight::getFlags() void PointLight::initShadowMap(int resolution) { m_shadowMapResolution = resolution; - + setPos(m_position); + // shader compilation if(m_shaderRefCounter == 0) { @@ -299,8 +290,27 @@ 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::updateTransform() +{ + if(m_shadowCaster) + { + m_shadowTransforms.clear(); + glm::mat4 shadowProj = glm::perspective(45.0f, 1.f, 0.01f, m_range); + m_shadowTransforms.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_shadowTransforms.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_shadowTransforms.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_shadowTransforms.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_shadowTransforms.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_shadowTransforms.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))); + } } void PointLight::destroyShadowMap() @@ -339,9 +349,7 @@ void PointLight::updateShadowMap(Scene* scene) m_shaders[shaderId]->bind(); m_shaders[shaderId]->bindMat4(m_shaders[shaderId]->getLocation("modelMatrix"), node->modelMatrix); - 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]->bindMat4Array(m_shaders[shaderId]->getLocation("layerTransform"), m_shadowTransforms.data(), m_shadowTransforms.size()); m_shaders[shaderId]->bindFloat(m_shaders[shaderId]->getLocation("far_plane"), m_range); node->mesh->draw(m_shaders[shaderId], false, shaderId, false); } diff --git a/src/light.h b/src/light.h index 321d219..31ae946 100644 --- a/src/light.h +++ b/src/light.h @@ -97,9 +97,9 @@ public: glm::vec3 getPos() { return m_position; } float getAttenuation() { return m_range; } - void setPos(glm::vec3 pos) { m_position = pos; /* TODO : update projection matrix */ } - void setAttenuation(float attenuation) { m_range = attenuation; } - + void setPos(glm::vec3 pos) { m_position = pos; updateTransform(); } + void setRange(float range) { m_range = range; updateTransform(); } + virtual LightType getType() { return POINT; } virtual void bindAttributes(Shader *shader, Camera *camera); virtual unsigned int getFlags(); @@ -109,14 +109,15 @@ public: void updateShadowMap(Scene* scene); private: + void updateTransform(); + glm::vec3 m_position; float m_range; bool m_shadowCaster; int m_shadowMapResolution; FrameBuffer* m_shadowMap; - static const glm::mat4 m_viewMatrices[6]; - glm::mat4 m_projectionMatrix; + std::vector m_shadowTransforms; static int m_shaderRefCounter; static Shader* m_shaders[2]; diff --git a/src/mesh.h b/src/mesh.h index aafda2a..2242cae 100644 --- a/src/mesh.h +++ b/src/mesh.h @@ -152,7 +152,7 @@ public: * @brief setDepth allows to set the depth of a 2D mesh, the depth must be between -1 and 1, -1 being the closest to the camera */ void setDepth(float d) { depth = d; } - float getDepth() { return depth; } + float getDepth() { return depth; } const /*************************************************************/ /* 3D MESH PROPERTIES */ diff --git a/src/phongmaterial.cpp b/src/phongmaterial.cpp index e34aebc..4ef2b7e 100644 --- a/src/phongmaterial.cpp +++ b/src/phongmaterial.cpp @@ -10,6 +10,7 @@ void PhongMaterial::bindAttributes(Shader* myShader) { // TODO store the attributes location myShader->bindFloat(myShader->getLocation("materialNs"), shininess); + myShader->bindFloat(myShader->getLocation("opacity"), m_opacity); if(textures[NORMALS_SLOT] != NULL) { diff --git a/src/phongmaterial.h b/src/phongmaterial.h index a6b92d2..3dbd7e5 100644 --- a/src/phongmaterial.h +++ b/src/phongmaterial.h @@ -23,6 +23,7 @@ struct PhongMaterial : public Material glm::vec3 diffuse; glm::vec3 specular; float shininess; + float m_opacity; Texture* textures[NB_PHONG_SLOTS]; std::string textureNames[NB_PHONG_SLOTS]; @@ -30,7 +31,8 @@ struct PhongMaterial : public Material emission(0), diffuse(0.5f), specular(0.5f), - shininess(10) + shininess(10), + m_opacity(1.f) { for(int i=0; i