Merge pull request #68 from devZoGok/imp-67-lighting

Imp 67 lighting
This commit is contained in:
devZoGok
2024-09-26 17:30:33 +00:00
committed by GitHub
5 changed files with 89 additions and 21 deletions
+17 -4
View File
@@ -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<Node*> descendants;
rootNode->getDescendants(descendants);
descendants.push_back(rootNode);
vector<Light*> lights;
vector<Material*> 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<Node*> 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<Material*> 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();
@@ -185,6 +194,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 +204,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) + "].useAngle");
break;
case DIRECTIONAL:
shader->setMat4(proj * view, "lights[" + to_string(thisId) + "].lightMat");
+14 -2
View File
@@ -17,10 +17,13 @@ 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();
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;
@@ -31,7 +34,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 +53,12 @@ namespace vb01{
void updateShader(std::vector<Material*>, 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;
};
}
+14 -2
View File
@@ -58,10 +58,10 @@ namespace vb01{
if(!render) break;
}
if(render){
for(Light *l : lights)
l->update();
l->update(render);
if(render){
for(Mesh *m : meshes)
m->update();
@@ -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];
+1
View File
@@ -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);
+41 -11
View File
@@ -15,10 +15,11 @@ layout (location = 1) out vec4 BrightColor;
//0-POINT,1-DIRECTIONAL,2-SPOT
struct Light{
int type;
bool useAngle, additive, render;
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,17 +97,38 @@ void main(){
vec3 diffuseCol = vec3(0), specularCol = vec3(0);
if(checkLights){
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 = 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, 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;
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].type == 1)
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){
lightDir = -normalize(lights[i].direction);
factor = max(dot(lightDir, normalize(normal)), 0.) * attenuation;
}
else if(lights[i].type == 2){
lightDir = normalize(lights[i].pos - fragPos);
float innerAngle = lights[i].innerAngle;
@@ -118,10 +140,18 @@ void main(){
if(angle > lights[i].outerAngle)
continue;
}
factor = max(dot(lightDir, normal), 0.);
diffuseCol += lights[i].color * (factor * attenuation * coef);
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;
@@ -130,8 +160,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));
}
}