From 9604e68aa4b83534bdabdd1f1f7fa1b840bda502 Mon Sep 17 00:00:00 2001
From: Linloir <3145078758@qq.com>
Date: Sat, 17 Dec 2022 22:27:22 +0800
Subject: [PATCH] [CORE][ADD] Illuminer Implementation
---
FinalProject/FinalProject.vcxproj | 1 +
FinalProject/FinalProject.vcxproj.filters | 3 +
FinalProject/illuminer.cpp | 136 ++++++++++++++++++++++
FinalProject/illuminer.h | 29 +++--
4 files changed, 160 insertions(+), 9 deletions(-)
create mode 100644 FinalProject/illuminer.cpp
diff --git a/FinalProject/FinalProject.vcxproj b/FinalProject/FinalProject.vcxproj
index 2722289..ede62bd 100644
--- a/FinalProject/FinalProject.vcxproj
+++ b/FinalProject/FinalProject.vcxproj
@@ -108,6 +108,7 @@
+
diff --git a/FinalProject/FinalProject.vcxproj.filters b/FinalProject/FinalProject.vcxproj.filters
index 8190b67..a4b9fad 100644
--- a/FinalProject/FinalProject.vcxproj.filters
+++ b/FinalProject/FinalProject.vcxproj.filters
@@ -168,6 +168,9 @@
Source Files\OpenGL Abstractions
+
+ Source Files\OpenGL Abstractions
+
diff --git a/FinalProject/illuminer.cpp b/FinalProject/illuminer.cpp
new file mode 100644
index 0000000..828c9f0
--- /dev/null
+++ b/FinalProject/illuminer.cpp
@@ -0,0 +1,136 @@
+#include "illuminer.h"
+#include "logger.h"
+
+Illuminer::Illuminer(glm::vec3 color) :
+ _lightColor(color)
+{}
+
+Illuminer::~Illuminer() {}
+
+DirLight::DirLight(glm::vec3 direction, glm::vec3 color) :
+ Illuminer(color), _direction(direction)
+{}
+
+DirLight::~DirLight() {}
+
+void DirLight::updateShader(ShaderProgram shader) const {
+ // Recall DirLight structure in fragment shader
+ // -------------
+ // struct DirLight {
+ // vec3 direction;
+ // vec3 ambient;
+ // vec3 diffuse;
+ // vec3 specular;
+ // };
+
+ shader.setUniform("DirLight.direction", -_direction);
+ shader.setUniform("DirLight.ambient", ambientLightColor());
+ shader.setUniform("DirLight.diffuse", diffuseLightColor());
+ shader.setUniform("DirLight.specular", specularLightColor());
+}
+
+ScopedLight::ScopedLight(glm::vec3 position, glm::vec3 direction, glm::vec3 color) :
+ Illuminer(color), _position(position), _direction(direction)
+{
+ updateLinear();
+ updateQuadratic();
+}
+
+ScopedLight::ScopedLight(int distance, glm::vec3 position, glm::vec3 direction, glm::vec3 color) :
+ Illuminer(color), _position(position), _direction(direction), _idealDistance(distance)
+{
+ updateLinear();
+ updateQuadratic();
+}
+
+ScopedLight::~ScopedLight() {}
+
+inline void ScopedLight::updateLinear() {
+ // Double is used here to prevent precision loss
+ double linear = -0.0001 + 4.7688 / (double)_idealDistance;
+ _attLinear = (float)linear;
+}
+
+inline void ScopedLight::updateQuadratic() {
+ // Double is used here to prevent precision loss
+ double quadratic = 82.4448 * glm::pow((double)_idealDistance, -2.0192);
+ _attQuadratic = (float)quadratic;
+}
+
+void ScopedLight::setIdealDistance(int distance) {
+ if (distance < 10) {
+ distance = 10;
+ }
+ if (distance > 3500) {
+ distance = 3500;
+ }
+ _idealDistance = distance;
+ updateLinear();
+ updateQuadratic();
+}
+
+void ScopedLight::setCutOffAngle(float angle) {
+ if (angle < 0.0f) {
+ angle = 0.0f;
+ }
+ if (angle > 180.0f) {
+ angle = 180.0f;
+ }
+ _cutOffAngle = angle;
+}
+
+inline float ScopedLight::innerCutOffAngle() const {
+ return 0.0011 * glm::pow(_cutOffAngle, 2) + 0.6440 * _cutOffAngle;
+}
+
+void ScopedLight::updateShader(ShaderProgram shader) const {
+ // Recall PointLight and SpotLight structure in fragment shader
+ // -------------
+ // struct PointLight {
+ // vec3 position;
+ // vec3 ambient;
+ // vec3 diffuse;
+ // vec3 specular;
+ // float constant;
+ // float linear;
+ // float quadratic;
+ // };
+ // ------------
+ // struct SpotLight {
+ // vec3 position;
+ // vec3 direction;
+ // vec3 ambient;
+ // vec3 diffuse;
+ // vec3 specular;
+ // float constant;
+ // float linear;
+ // float quadratic;
+ // float cutOff;
+ // float outerCutOff;
+ // };
+
+ // Check the cutoff angle to determine the type of light
+ if (abs(_cutOffAngle - 180.0f) < 1e-6) {
+ // Point light
+ shader.setUniform("PointLight.position", _position);
+ shader.setUniform("PointLight.ambient", ambientLightColor());
+ shader.setUniform("PointLight.diffuse", diffuseLightColor());
+ shader.setUniform("PointLight.specular", specularLightColor());
+ shader.setUniform("PointLight.constant", _attConstant);
+ shader.setUniform("PointLight.linear", _attLinear);
+ shader.setUniform("PointLight.quadratic", _attQuadratic);
+ }
+ else {
+ // Spot light
+ shader.setUniform("SpotLight.position", _position);
+ shader.setUniform("SpotLight.direction", -_direction);
+ shader.setUniform("SpotLight.ambient", ambientLightColor());
+ shader.setUniform("SpotLight.diffuse", diffuseLightColor());
+ shader.setUniform("SpotLight.specular", specularLightColor());
+ shader.setUniform("SpotLight.constant", _attConstant);
+ shader.setUniform("SpotLight.linear", _attLinear);
+ shader.setUniform("SpotLight.quadratic", _attQuadratic);
+ shader.setUniform("SpotLight.innercutoff", glm::cos(glm::radians(innerCutOffAngle())));
+ shader.setUniform("SpotLight.outercutoff", glm::cos(glm::radians(_cutOffAngle)));
+ }
+}
\ No newline at end of file
diff --git a/FinalProject/illuminer.h b/FinalProject/illuminer.h
index 8fd1524..1d07fb5 100644
--- a/FinalProject/illuminer.h
+++ b/FinalProject/illuminer.h
@@ -5,7 +5,6 @@
#include
#include "shader.h"
-#include "logger.h"
class Illuminer {
protected:
@@ -15,7 +14,7 @@ public:
Illuminer(glm::vec3 color);
~Illuminer();
-public:
+protected:
virtual glm::vec3 ambientLightColor() const = 0;
virtual glm::vec3 diffuseLightColor() const = 0;
virtual glm::vec3 specularLightColor() const = 0;
@@ -36,11 +35,13 @@ public:
DirLight(glm::vec3 direction = glm::vec3(0.0f, -1.0f, 0.0f), glm::vec3 color = glm::vec3(1.0f));
~DirLight();
+protected:
+ virtual glm::vec3 ambientLightColor() const override { return _lightColor * 0.2f; }
+ virtual glm::vec3 diffuseLightColor() const override { return _lightColor * 0.5f; }
+ virtual glm::vec3 specularLightColor() const override { return _lightColor * 0.9f; }
+
public:
- // Getter APIs
glm::vec3 lightDirection() const { return _direction; } // The same direction as the outgoing direction
-
- // Setter
void setLightDirection(glm::vec3 direction) { _direction = direction; }
// Render util function
@@ -56,8 +57,7 @@ protected:
// Light source status
glm::vec3 _position;
glm::vec3 _direction;
- float _innerCutOffAngle = 162.5f;
- float _outerCutOffAngle = 180.0f;
+ float _cutOffAngle = 180.0f;
// Light property
int _idealDistance = 32; // ideally calculated distance
@@ -67,16 +67,27 @@ protected:
public:
ScopedLight(glm::vec3 position, glm::vec3 direction = glm::vec3(0.0f, -1.0f, 0.0f), glm::vec3 color = glm::vec3(1.0f));
- ScopedLight(glm::vec3 distance, glm::vec3 position, glm::vec3 direction = glm::vec3(0.0f, -1.0f, 0.0f), glm::vec3 color = glm::vec3(1.0f));
+ ScopedLight(int distance, glm::vec3 position, glm::vec3 direction = glm::vec3(0.0f, -1.0f, 0.0f), glm::vec3 color = glm::vec3(1.0f));
~ScopedLight();
+private:
+ // Util function
+ inline void updateLinear();
+ inline void updateQuadratic();
+ inline float innerCutOffAngle() const;
+
+protected:
+ virtual glm::vec3 ambientLightColor() const override { return _lightColor * 0.2f; }
+ virtual glm::vec3 diffuseLightColor() const override { return _lightColor * 0.5f; }
+ virtual glm::vec3 specularLightColor() const override { return _lightColor * 0.9f; }
+
public:
// Property setters and getters
int idealDistance() const { return _idealDistance; }
void setIdealDistance(int distance);
glm::vec3 lightDirection() const { return _direction; }
void setLightDirection(glm::vec3 direction) { _direction = direction; }
- float cutOffAngle() const { return _outerCutOffAngle; }
+ float cutOffAngle() const { return _cutOffAngle; }
void setCutOffAngle(float angle);
// Render util function