From 93e479662f24be28e77ba00d944a620b38c57248 Mon Sep 17 00:00:00 2001 From: devZoGok Date: Sun, 8 Sep 2024 20:32:34 +0300 Subject: [PATCH 1/4] lighting fixes --- texture.frag | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/texture.frag b/texture.frag index ae5330c..38a3aa4 100755 --- a/texture.frag +++ b/texture.frag @@ -98,11 +98,14 @@ void main(){ if(checkLights){ for(int i = 0; i < numLights; i++){ vec3 lightDir = vec3(0), viewDir = normalize(camPos - fragPos); - float attenuation = 1.0; - float a = lights[i].a, b = lights[i].b, c = lights[i].c, dist = length(fragPos - lights[i].pos), factor, coef = 1; + float attenuation = 1.0, coef = 1; if(lights[i].type == 0){ lightDir = normalize(lights[i].pos - fragPos); + + float a = lights[i].a, b = lights[i].b, c = lights[i].c; + float dist = length(fragPos - lights[i].pos); + attenuation = 1.0 / (a * dist * dist + b * dist + c); } else if(lights[i].type == 1) @@ -120,8 +123,8 @@ void main(){ continue; } - factor = max(dot(lightDir, normal), 0.); - diffuseCol += lights[i].color * (factor * attenuation * coef); + float factor = (lights[i].type < 3 ? (max(dot(lightDir, normalize(normal)), 0.) * attenuation * coef) : 1); + diffuseCol += lights[i].color * factor; if(specularMapEnabled){ float specularSample = texture(textures[2].pastTexture, texCoords).r; @@ -130,8 +133,8 @@ void main(){ specularCol += specularStrength * spec * specularSample * lights[i].color; } - float shadow = getShadow(i); - diffuseCol *= (1.0 - shadow); + if(castShadow) + diffuseCol *= (1.0 - getShadow(i)); } } From 059136a6887587ba7d2d0be8a70c70b6541dfe3b Mon Sep 17 00:00:00 2001 From: devZoGok Date: Sun, 8 Sep 2024 20:33:13 +0300 Subject: [PATCH 2/4] removing lights by pointer --- node.cpp | 12 ++++++++++++ node.h | 1 + 2 files changed, 13 insertions(+) diff --git a/node.cpp b/node.cpp index 3560121..ce478d9 100755 --- a/node.cpp +++ b/node.cpp @@ -253,6 +253,18 @@ namespace vb01{ } + void Node::removeLight(Light *light){ + for(int i = 0; i < lights.size(); i++) + if(lights[i] == light){ + lights.erase(lights.begin() + i); + + Root::getSingleton()->shiftNumLights(false); + updateShaders(); + + break; + } + } + void Node::removeLight(int id){ Root::getSingleton()->shiftNumLights(false); Light *light = lights[id]; diff --git a/node.h b/node.h index bce352c..46aec28 100755 --- a/node.h +++ b/node.h @@ -31,6 +31,7 @@ namespace vb01{ void attachChild(Node*); void dettachChild(Node*); void addLight(Light*); + void removeLight(Light*); void removeLight(int); void addText(Text*); virtual void lookAt(Vector3, Vector3); From 1103e527a8a7e622318208d6f436d734d6eb4863 Mon Sep 17 00:00:00 2001 From: devZoGok Date: Wed, 11 Sep 2024 20:23:25 +0300 Subject: [PATCH 3/4] added angle usage, attenuation, additive lighting properties --- light.cpp | 4 ++++ light.h | 12 +++++++++++- texture.frag | 49 +++++++++++++++++++++++++++++++++++++------------ 3 files changed, 52 insertions(+), 13 deletions(-) diff --git a/light.cpp b/light.cpp index 4984e62..db080fe 100755 --- a/light.cpp +++ b/light.cpp @@ -185,6 +185,7 @@ namespace vb01{ shader->setVec3(color, "lights[" + to_string(thisId) + "].color"); shader->setFloat(nearPlane, "lights[" + to_string(thisId) + "].near"); shader->setFloat(farPlane, "lights[" + to_string(thisId) + "].far"); + shader->setBool(additiveLighting, "lights[" + to_string(thisId) + "].additive"); int depthMapId = 10; shader->setInt(depthMapId, "lights[" + to_string(thisId) + "].depthMap"); @@ -194,9 +195,12 @@ namespace vb01{ switch(type){ case POINT: shader->setVec3(position, "lights[" + to_string(thisId) + "].pos"); + shader->setInt((int)attenuation, "lights[" + to_string(thisId) + "].attenuation"); + shader->setFloat(radius, "lights[" + to_string(thisId) + "].radius"); shader->setFloat(attenuationValues.x, "lights[" + to_string(thisId) + "].a"); shader->setFloat(attenuationValues.y, "lights[" + to_string(thisId) + "].b"); shader->setFloat(attenuationValues.z, "lights[" + to_string(thisId) + "].c"); + shader->setBool(useAngle, "lights[" + to_string(thisId) + "].additive"); break; case DIRECTIONAL: shader->setMat4(proj * view, "lights[" + to_string(thisId) + "].lightMat"); diff --git a/light.h b/light.h index 1732d94..93d47b5 100755 --- a/light.h +++ b/light.h @@ -17,6 +17,7 @@ namespace vb01{ class Light : public Animatable, public Attachable{ public: enum Type{POINT, DIRECTIONAL, SPOT, AMBIENT}; + enum Attenuation{QUADRATIC, LINEAR, NONE}; Light(Type, std::string = ""); ~Light(); @@ -31,7 +32,14 @@ namespace vb01{ inline void setOuterAngle(float outerAngle){this->outerAngle = outerAngle;} inline void setShadowNearPlane(float nearPlane){this->nearPlane = nearPlane;} inline void setShadowFarPlane(float farPlane){this->farPlane = farPlane;} + inline void setAttenuation(Attenuation at){this->attenuation = at;} + inline void setRadius(float r){this->radius = r;} + inline void setAdditiveLighting(bool al){this->additiveLighting = al;} + inline void setUseAngle(bool ua){this->useAngle = ua;} + inline Attenuation getAttenuation(){return attenuation;} inline Vector3 getAttenuationValues(){return attenuationValues;} + inline bool isAdditiveLighting(){return additiveLighting;} + inline float getRadius(){return radius;} inline float getInnerAngle(){return innerAngle;} inline float getOuterAngle(){return outerAngle;} inline float getShadowNearPlane(){return nearPlane;} @@ -43,10 +51,12 @@ namespace vb01{ void updateShader(std::vector, int, glm::mat4&, glm::mat4&); Type type; + bool additiveLighting = true, useAngle = true; + Attenuation attenuation = Attenuation::QUADRATIC; Shader *depthMapShader; Texture *depthMap = nullptr; Vector3 color = Vector3::VEC_IJK, attenuationValues = Vector3(1.8, .7, 1); - float innerAngle = .707, outerAngle = .714, nearPlane = .1, farPlane = 100; + float innerAngle = .707, outerAngle = .714, nearPlane = .1, farPlane = 100, radius = 0; unsigned int depthmapFBO, depthMapSize = 1024; }; } diff --git a/texture.frag b/texture.frag index 38a3aa4..b8023e1 100755 --- a/texture.frag +++ b/texture.frag @@ -15,10 +15,11 @@ layout (location = 1) out vec4 BrightColor; //0-POINT,1-DIRECTIONAL,2-SPOT struct Light{ - int type; + bool useAngle, additive; + int type, attenuation; vec3 pos, color, direction; float innerAngle, outerAngle; - float a, b, c, near, far; + float a, b, c, near, far, radius; sampler2D depthMap; samplerCube depthMapCube; mat4 lightMat; @@ -33,7 +34,7 @@ struct Texture{ uniform Texture textures[4]; uniform samplerCube environmentMap; uniform Light lights[numLights]; -uniform bool lightingEnabled, texturingEnabled, normalMapEnabled, specularMapEnabled, castShadow, environmentMapEnabled; +uniform bool lightingEnabled, constLightingEnabled, texturingEnabled, normalMapEnabled, specularMapEnabled, castShadow, environmentMapEnabled; uniform vec4 diffuseColor, specularColor; uniform float shinyness, specularStrength; uniform vec3 camPos; @@ -96,20 +97,36 @@ void main(){ vec3 diffuseCol = vec3(0), specularCol = vec3(0); if(checkLights){ + bool addedLighting = false; + for(int i = 0; i < numLights; i++){ vec3 lightDir = vec3(0), viewDir = normalize(camPos - fragPos); - float attenuation = 1.0, coef = 1; + float attenuation = 0, coef = 1; + float factor = 0; + bool canAdd = false; if(lights[i].type == 0){ lightDir = normalize(lights[i].pos - fragPos); + float dist = length(lights[i].pos - fragPos), radius = lights[i].radius; - float a = lights[i].a, b = lights[i].b, c = lights[i].c; - float dist = length(fragPos - lights[i].pos); - - attenuation = 1.0 / (a * dist * dist + b * dist + c); + if(lights[i].attenuation == 0){ + float a = lights[i].a, b = lights[i].b, c = lights[i].c; + attenuation = 1.0 / (a * dist * dist + b * dist + c); + factor = (lights[i].useAngle ? max(dot(lightDir, normalize(normal)), 0.) : 1) * attenuation; + } + else if(lights[i].attenuation == 1 && dist < radius && radius > 0){ + canAdd = !lights[i].additive; + factor = 1.0 - dist / lights[i].radius; + } + else if(lights[i].attenuation == 2 && dist < radius && radius > 0){ + canAdd = !lights[i].additive; + factor = 1; + } } - else if(lights[i].type == 1) + else if(lights[i].type == 1){ lightDir = -normalize(lights[i].direction); + factor = max(dot(lightDir, normalize(normal)), 0.) * attenuation * coef; + } else if(lights[i].type == 2){ lightDir = normalize(lights[i].pos - fragPos); float innerAngle = lights[i].innerAngle; @@ -121,10 +138,18 @@ void main(){ if(angle > lights[i].outerAngle) continue; - } - float factor = (lights[i].type < 3 ? (max(dot(lightDir, normalize(normal)), 0.) * attenuation * coef) : 1); - diffuseCol += lights[i].color * factor; + factor = max(dot(lightDir, normalize(normal)), 0.) * attenuation * coef; + } + else factor = 1; + + + if(lights[i].additive) + diffuseCol += lights[i].color * factor; + else if(!lights[i].additive && constLightingEnabled && !addedLighting && canAdd){ + addedLighting = true; + diffuseCol += lights[i].color * factor; + } if(specularMapEnabled){ float specularSample = texture(textures[2].pastTexture, texCoords).r; From 0b99083bab7c4ec6dc706ac4b0df0f4d1b8d60b9 Mon Sep 17 00:00:00 2001 From: devZoGok Date: Fri, 13 Sep 2024 19:46:57 +0300 Subject: [PATCH 4/4] refactored light updating to account for lights in hidden nodes --- light.cpp | 19 ++++++++++++++----- light.h | 4 +++- node.cpp | 6 +++--- texture.frag | 8 +++++--- 4 files changed, 25 insertions(+), 12 deletions(-) diff --git a/light.cpp b/light.cpp index db080fe..0f423e2 100755 --- a/light.cpp +++ b/light.cpp @@ -75,32 +75,39 @@ namespace vb01{ glBindFramebuffer(GL_FRAMEBUFFER, *(Root::getSingleton()->getFBO())); } - void Light::update(){ + void Light::update(bool render){ Root *root = Root::getSingleton(); Node *rootNode = root->getRootNode(); vector descendants; rootNode->getDescendants(descendants); descendants.push_back(rootNode); + vector lights; vector materials; for(Node *d : descendants){ for(Light *l : d->getLights()) lights.push_back(l); - for(Mesh *m : d->getMeshes()) - materials.push_back(m->getMaterial()); + for(Mesh *mesh : d->getMeshes()) + materials.push_back(mesh->getMaterial()); } int thisId = -1; + for(int i = 0; i < lights.size(); i++) if(lights[i] == this) thisId = i; + for(Material *mat : materials){ + Shader *shader = mat->getShader(); + shader->use(); + shader->setBool(render, "lights[" + to_string(thisId) + "].render"); + } + mat4 proj = mat4(1.), view = mat4(1.); renderShadow(descendants, proj, view); updateShader(materials, thisId, proj, view); - } void Light::renderShadow(std::vector descendants, mat4 &proj, mat4 &view){ @@ -176,8 +183,10 @@ namespace vb01{ glViewport(0, 0, root->getWidth(), root->getHeight()); } + //TODO replace depth map id literals void Light::updateShader(vector materials, int thisId, mat4 &proj, mat4 &view){ Vector3 position = node->localToGlobalPosition(Vector3::VEC_ZERO), direction = node->getGlobalAxis(2); + for(Material *m : materials){ Shader *shader = m->getShader(); shader->use(); @@ -200,7 +209,7 @@ namespace vb01{ shader->setFloat(attenuationValues.x, "lights[" + to_string(thisId) + "].a"); shader->setFloat(attenuationValues.y, "lights[" + to_string(thisId) + "].b"); shader->setFloat(attenuationValues.z, "lights[" + to_string(thisId) + "].c"); - shader->setBool(useAngle, "lights[" + to_string(thisId) + "].additive"); + shader->setBool(useAngle, "lights[" + to_string(thisId) + "].useAngle"); break; case DIRECTIONAL: shader->setMat4(proj * view, "lights[" + to_string(thisId) + "].lightMat"); diff --git a/light.h b/light.h index 93d47b5..9fe4424 100755 --- a/light.h +++ b/light.h @@ -21,7 +21,9 @@ namespace vb01{ Light(Type, std::string = ""); ~Light(); - void update(); + void update(bool); + inline Vector3 getColor(){return color;} + inline Type getLightType(){return type;} inline void setColor(Vector3 color){this->color = color;} inline void setAttenuationValues(float a, float b, float c){ attenuationValues.x = a; diff --git a/node.cpp b/node.cpp index ce478d9..f49aaaf 100755 --- a/node.cpp +++ b/node.cpp @@ -58,10 +58,10 @@ namespace vb01{ if(!render) break; } - if(render){ - for(Light *l : lights) - l->update(); + for(Light *l : lights) + l->update(render); + if(render){ for(Mesh *m : meshes) m->update(); diff --git a/texture.frag b/texture.frag index b8023e1..75de987 100755 --- a/texture.frag +++ b/texture.frag @@ -15,7 +15,7 @@ layout (location = 1) out vec4 BrightColor; //0-POINT,1-DIRECTIONAL,2-SPOT struct Light{ - bool useAngle, additive; + bool useAngle, additive, render; int type, attenuation; vec3 pos, color, direction; float innerAngle, outerAngle; @@ -100,8 +100,10 @@ void main(){ bool addedLighting = false; for(int i = 0; i < numLights; i++){ + if(!lights[i].render) continue; + vec3 lightDir = vec3(0), viewDir = normalize(camPos - fragPos); - float attenuation = 0, coef = 1; + float attenuation = 1, coef = 1; float factor = 0; bool canAdd = false; @@ -125,7 +127,7 @@ void main(){ } else if(lights[i].type == 1){ lightDir = -normalize(lights[i].direction); - factor = max(dot(lightDir, normalize(normal)), 0.) * attenuation * coef; + factor = max(dot(lightDir, normalize(normal)), 0.) * attenuation; } else if(lights[i].type == 2){ lightDir = normalize(lights[i].pos - fragPos);