-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added directional lights #2
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,37 @@ | ||
#pragma once | ||
|
||
#include <optional> | ||
|
||
#include <glm/glm.hpp> | ||
|
||
namespace rev { | ||
|
||
class Light { | ||
public: | ||
Light(); | ||
enum class Type | ||
{ | ||
Directional, | ||
Point | ||
}; | ||
|
||
Light(Type type); | ||
|
||
const glm::vec3& getBaseColor() const; | ||
void setBaseColor(const glm::vec3& color); | ||
void setBaseColor(const glm::vec3& baseColor); | ||
|
||
const glm::vec3& getDirection() const; | ||
void setDirection(const glm::vec3& direction); | ||
|
||
const glm::vec3& getPosition() const; | ||
void setPosition(const glm::vec3& position); | ||
|
||
Type getType() const; | ||
|
||
private: | ||
glm::vec3 _baseColor; | ||
glm::vec3 _position; | ||
std::optional<glm::vec3> _position; | ||
std::optional<glm::vec3> _direction; | ||
Type _type; | ||
}; | ||
|
||
} // namespace rev | ||
} // namespace rev |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,30 +1,54 @@ | ||
#include "rev/Light.h" | ||
|
||
using namespace std; | ||
using namespace glm; | ||
|
||
namespace rev | ||
{ | ||
Light::Light() | ||
: _baseColor(glm::vec3(1.0)) | ||
, _position(glm::vec3(0.0)) | ||
// Light | ||
Light::Light(Type type) | ||
: _baseColor(0.f), _type(type) | ||
{ | ||
} | ||
|
||
Light::Type Light::getType() const | ||
{ | ||
return _type; | ||
} | ||
|
||
const glm::vec3& Light::getBaseColor() const | ||
{ | ||
return _baseColor; | ||
} | ||
|
||
void Light::setBaseColor(const glm::vec3& color) | ||
void Light::setBaseColor(const glm::vec3& baseColor) | ||
{ | ||
_baseColor = color; | ||
_baseColor = baseColor; | ||
} | ||
|
||
const glm::vec3& Light::getPosition() const | ||
{ | ||
return _position; | ||
assert(_position.has_value()); | ||
return *_position; | ||
} | ||
|
||
void Light::setPosition(const glm::vec3& position) | ||
{ | ||
_position = position; | ||
assert(_type == Type::Point); | ||
_position = make_optional<glm::vec3>(position); | ||
} | ||
|
||
const glm::vec3& Light::getDirection() const | ||
{ | ||
assert(_direction.has_value()); | ||
return *_direction; | ||
} | ||
|
||
void Light::setDirection(const glm::vec3& direction) | ||
{ | ||
//TODO: Is there a way to ensure that the programmer is not | ||
// calling these methods on the wrong type of light statically? | ||
assert(_type == Type::Directional); | ||
_direction = make_optional<glm::vec3>(direction); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,7 +27,54 @@ constexpr const char *kDeferredVertexShader = R"vertexShader( | |
|
||
)vertexShader"; | ||
|
||
constexpr const char *kDeferredFragmentShader = R"fragmentShader( | ||
constexpr const char *kDeferredDirectionalLightFragmentShader = R"fragmentShader( | ||
#version 330 core | ||
|
||
in vec2 texCoord; | ||
|
||
uniform vec3 lightDirection; | ||
uniform vec3 lightBaseColor; | ||
uniform vec3 camPosition; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OMFG this uniform was never set before! I knew there was something weird about how the specular highlights were moving in relation to the camera. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually it was set above, nevermind. |
||
|
||
uniform sampler2D fragPosition; | ||
uniform sampler2D normals; | ||
|
||
uniform sampler2D ambient; | ||
uniform sampler2D emissive; | ||
uniform sampler2D diffuse; | ||
uniform sampler2D specular; | ||
uniform sampler2D specularExponent; | ||
|
||
out vec4 fragColor; | ||
void main() | ||
{ | ||
vec3 normal = texture(normals, texCoord).rgb; | ||
vec3 diffuse = texture(diffuse, texCoord).rgb; | ||
|
||
vec3 fragmentPosition = texture(fragPosition, texCoord).rgb; | ||
vec3 lightVector = -1.0f * lightDirection; | ||
float angleMultiplier = max(dot(normalize(lightVector), normalize(normal)), 0.0f); | ||
|
||
float specularExponent = texture(specularExponent, texCoord).r; | ||
vec3 specularCoefficient = texture(specular, texCoord).rgb; | ||
|
||
vec3 eyeVector = normalize(camPosition - fragmentPosition); | ||
vec3 reflectVector = normalize(reflect(lightVector, normalize(normal))); | ||
float specularComponent = max(dot(eyeVector, reflectVector), 0.0f); | ||
|
||
vec3 ambientLight = vec3(0.01f) * diffuse; | ||
vec3 diffuseLight = diffuse * lightBaseColor * angleMultiplier; | ||
vec3 specularLight = (specularExponent > 0.01) | ||
? lightBaseColor * specularCoefficient * pow(vec3(specularComponent) , vec3(specularExponent)) | ||
: vec3(0.0f); | ||
|
||
vec3 totalLight = diffuseLight + specularLight; | ||
|
||
fragColor = vec4(totalLight, 1.0f); | ||
} | ||
)fragmentShader"; | ||
|
||
constexpr const char *kDeferredPointLightFragmentShader = R"fragmentShader( | ||
#version 330 core | ||
|
||
in vec2 texCoord; | ||
|
@@ -87,22 +134,42 @@ constexpr glm::vec2 kFullScreenQuadVertices[] = { | |
|
||
SceneView::SceneView() : _camera(std::make_shared<Camera>()) | ||
{ | ||
_lightingProgram.buildWithSource(kDeferredVertexShader, | ||
kDeferredFragmentShader); | ||
_pointLightingProgram.buildWithSource(kDeferredVertexShader, | ||
kDeferredPointLightFragmentShader); | ||
{ | ||
ProgramContext programContext(_lightingProgram); | ||
_lightPosition = _lightingProgram.getUniform<glm::vec3>("lightPosition"); | ||
_lightBaseColor = _lightingProgram.getUniform<glm::vec3>("lightBaseColor"); | ||
_camPosition = _lightingProgram.getUniform<glm::vec3>("camPosition"); | ||
|
||
_lightingProgram.getUniform<GLint>("fragPosition").set(0); | ||
_lightingProgram.getUniform<GLint>("normals").set(1); | ||
|
||
_lightingProgram.getUniform<GLint>("ambient").set(2); | ||
_lightingProgram.getUniform<GLint>("emissive").set(3); | ||
_lightingProgram.getUniform<GLint>("diffuse").set(4); | ||
_lightingProgram.getUniform<GLint>("specular").set(5); | ||
_lightingProgram.getUniform<GLint>("specularExponent").set(6); | ||
ProgramContext programContext(_pointLightingProgram); | ||
|
||
_pointLightUniforms.lightPosition = _pointLightingProgram.getUniform<glm::vec3>("lightPosition"); | ||
_pointLightUniforms.lightBaseColor = _pointLightingProgram.getUniform<glm::vec3>("lightBaseColor"); | ||
_pointLightUniforms.camPosition = _pointLightingProgram.getUniform<glm::vec3>("camPosition"); | ||
|
||
_pointLightingProgram.getUniform<GLint>("fragPosition").set(0); | ||
_pointLightingProgram.getUniform<GLint>("normals").set(1); | ||
|
||
_pointLightingProgram.getUniform<GLint>("ambient").set(2); | ||
_pointLightingProgram.getUniform<GLint>("emissive").set(3); | ||
_pointLightingProgram.getUniform<GLint>("diffuse").set(4); | ||
_pointLightingProgram.getUniform<GLint>("specular").set(5); | ||
_pointLightingProgram.getUniform<GLint>("specularExponent").set(6); | ||
} | ||
|
||
_directionalLightingProgram.buildWithSource(kDeferredVertexShader, | ||
kDeferredDirectionalLightFragmentShader); | ||
{ | ||
ProgramContext programContext(_directionalLightingProgram); | ||
|
||
_directionalLightUniforms.lightDirection = _directionalLightingProgram.getUniform<glm::vec3>("lightDirection"); | ||
_directionalLightUniforms.lightBaseColor = _directionalLightingProgram.getUniform<glm::vec3>("lightBaseColor"); | ||
_directionalLightUniforms.camPosition = _directionalLightingProgram.getUniform<glm::vec3>("camPosition"); | ||
|
||
_directionalLightingProgram.getUniform<GLint>("fragPosition").set(0); | ||
_directionalLightingProgram.getUniform<GLint>("normals").set(1); | ||
|
||
_directionalLightingProgram.getUniform<GLint>("ambient").set(2); | ||
_directionalLightingProgram.getUniform<GLint>("emissive").set(3); | ||
_directionalLightingProgram.getUniform<GLint>("diffuse").set(4); | ||
_directionalLightingProgram.getUniform<GLint>("specular").set(5); | ||
_directionalLightingProgram.getUniform<GLint>("specularExponent").set(6); | ||
} | ||
|
||
VertexArrayContext vaoContext(_fullScreenVao); | ||
|
@@ -162,10 +229,8 @@ void SceneView::render() | |
|
||
// Lighting pass | ||
{ | ||
ProgramContext programContext(_lightingProgram); | ||
auto fbContext = _lightingStage.getRenderContext(); | ||
|
||
_camPosition.set(_camera->getPosition()); | ||
glViewport(0, 0, _outputSize.width, _outputSize.height); | ||
|
||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); | ||
|
@@ -192,7 +257,19 @@ void SceneView::render() | |
|
||
VertexArrayContext vaoContext(_fullScreenVao); | ||
|
||
_scene->renderAllLights(_lightPosition, _lightBaseColor); | ||
// Render all point lights | ||
{ | ||
ProgramContext programContext(_pointLightingProgram); | ||
_pointLightUniforms.camPosition.set(_camera->getPosition()); | ||
_scene->renderAllPointLights(_pointLightUniforms.lightPosition, _pointLightUniforms.lightBaseColor); | ||
} | ||
|
||
// Render all directional lights | ||
{ | ||
ProgramContext programContext(_directionalLightingProgram); | ||
_directionalLightUniforms.camPosition.set(_camera->getPosition()); | ||
_scene->renderAllDirectionalLights(_directionalLightUniforms.lightDirection, _directionalLightUniforms.lightBaseColor); | ||
} | ||
} | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think having a shared base class here isn't really worth it, IMO. They only really share the one member and some getters, and the inheritance looks kind of like polymorphism even though they can't be polymorphic (no virtual functions). I they do share some properties and there may be a way to leverage that at some point, but let's not worry about that right now. After all, the fragment shaders they use are mostly copy/pasted anyway even though they share a lot of the same code.