Commit 88178002 authored by Dario Seyb's avatar Dario Seyb

proper lighting

parent 2ad5d733
Pipeline #316 skipped
#version 330 core
uniform sampler2D uSamplerColor;
uniform sampler2D uSamplerEmissive;
uniform sampler2D uSamplerNormal;
uniform sampler2D uSamplerDepth;
uniform sampler2DShadow uSamplerShadowMap;
uniform bool uLightHasShadow;
uniform vec2 uOneOverShadowTexSize;
uniform vec3 uLightPosition;
uniform vec4 uLightColor;
......@@ -44,6 +46,8 @@ vec3 projShadowCoord(vec3 worldPosition) {
}
float shadowFactor(vec3 worldPosition) {
if(!uLightHasShadow) return 1;
vec3 shadowCoord = projShadowCoord(worldPosition.xyz);
float x,y;
float shadow = 0;
......@@ -61,6 +65,7 @@ float shadowFactor(vec3 worldPosition) {
void main()
{
vec4 color = texture(uSamplerColor, vTexCoord);
vec4 emissive = texture(uSamplerEmissive, vTexCoord);
vec3 normal = unpackNormal(texture(uSamplerNormal, vTexCoord));
float depth = texture(uSamplerDepth, vTexCoord).r;
......@@ -85,5 +90,5 @@ void main()
vec3 specularColor = pow(specularFactor, 210) * uLightColor.rgb;
oColor = vec4((diffuseColor + specularColor) * color.rgb * uLightColor.a/(lightDistance*lightDistance) * shadowFactor(worldPosition), 1);
oColor = vec4((diffuseColor + specularColor) * color.rgb * uLightColor.a * shadowFactor(worldPosition) + emissive.rgb, 1);
}
......@@ -5,10 +5,12 @@ in vec2 vTexCoord;
in vec3 vPosition;
uniform sampler2D uTexture;
uniform vec4 uEmissiveColor;
uniform vec4 uTintColor;
uniform float uTime;
out vec4 oColor;
out vec4 oEmissive;
out vec4 oNormal;
float rand(vec2 co){
......@@ -25,5 +27,6 @@ void main()
if(sample > color.a) discard;
oColor = color;
oEmissive = uEmissiveColor * color;
oNormal = vec4(normalize(vNormal) * 0.5 + 0.5, 0.0);
}
......@@ -9,5 +9,5 @@ out vec4 oColor;
void main()
{
vec3 texColor = texture(uSamplerColor, vTexCoord).rgb;
oColor = vec4(texColor,0.8);
oColor = vec4(texColor,0.1);
}
......@@ -4,8 +4,9 @@
#include <engine/graphics/Material.hpp>
struct Light : Component<Light> {
Light(glm::vec4 color, glm::vec3 dir, bool castShadow) : color(color), dir(dir), castShadow(castShadow) {}
glm::vec4 color;
ACGL::OpenGL::SharedFrameBufferObject shadowFbo;
ACGL::OpenGL::SharedTexture2D shadowMap;
glm::mat4 projMatrix;
glm::vec3 dir;
bool castShadow;
};
\ No newline at end of file
......@@ -7,6 +7,7 @@ using namespace ACGL::OpenGL;
struct Material {
glm::vec4 tintColor;
glm::vec4 emissiveColor;
SharedTexture2D mainTexture;
SharedShaderProgram prog;
bool castShadow;
......
......@@ -13,6 +13,17 @@
#include <engine/graphics/Light.hpp>
struct LightData {
glm::vec4 color;
bool castShadow;
TransformData lastFrameTransform;
TransformData thisFrameTransform;
glm::mat4 projMatrix;
ACGL::OpenGL::SharedFrameBufferObject shadowFbo;
ACGL::OpenGL::SharedTexture2D shadowMap;
};
#undef OPAQUE
#undef TRANSPARENT
......@@ -28,7 +39,11 @@ private:
WindowSystem *m_window;
Stack<DrawCall> m_submittedDrawCalls;
Stack<Light> m_submittedLights;
Stack<LightData> m_submittedLights;
const int SHADOW_MAP_COUNT = 10;
std::vector<ACGL::OpenGL::SharedFrameBufferObject> m_shadowMaps;
ACGL::OpenGL::SharedTexture2D m_dummyShadowMap;
Entity m_mainCamera;
std::vector<ACGL::OpenGL::SharedTexture2D> m_gBufferTextures;
......@@ -44,7 +59,7 @@ private:
SharedShaderProgram m_txaaProg;
public:
CONSTRUCT_SYSTEM(RendererSystem), m_submittedDrawCalls(kilobytes(4)) {}
CONSTRUCT_SYSTEM(RendererSystem), m_submittedDrawCalls(kilobytes(4)), m_submittedLights(kilobytes(4)) {}
bool startup() override;
void shutdown() override;
......@@ -54,7 +69,12 @@ public:
m_submittedDrawCalls.push(drawCall);
}
inline void submit(Light light) {
inline void submit(LightData light) {
if (light.castShadow && m_submittedLights.size() < m_shadowMaps.size()) {
light.shadowFbo = m_shadowMaps[m_submittedLights.size()];
light.shadowMap = SharedTexture2D((Texture2D*)(light.shadowFbo->getDepthAttachment().texture.get()));
}
m_submittedLights.push(light);
}
......
......@@ -13,6 +13,10 @@ struct Transform : Component<Transform> {
glm::mat4 rotation;
glm::vec3 scale;
TransformData lastGlobalTransform;
TransformData thisGlobalTransform;
Transform() : lastScale(glm::vec3(1.0, 1.0, 1.0)), scale(glm::vec3(1.0, 1.0, 1.0)) {};
};
......@@ -30,10 +30,8 @@ bool OrbitalSimulationSystem::startup() {
defaultGeom = { vaoSphere };
auto pbrShader = ShaderProgramFileManager::the()->get(ShaderProgramCreator("PBR").attributeLocations(vaoSphere->getAttributeLocations()));
pbrShader->use();
pbrShader->setTexture("uTexture", texture, 0);
defaultMat = { pbrShader };
defaultMat = { glm::vec4(1, 1, 1, 1), glm::vec4(0.1, 0.1, 0.1, 1), texture, pbrShader };
return true;
}
......
......@@ -34,12 +34,11 @@ void SceneGraphSystem::startSimulate() {
}
void SceneGraphSystem::prepareDraw() {
auto drawableEntities = m_entityManager.entities_with_components<Drawable, Transform>();
auto transformEntities = m_entityManager.entities_with_components<Transform>();
Drawable::Handle drawable;
Transform::Handle transform;
for (auto e : drawableEntities) {
e.unpack<Drawable, Transform>(drawable, transform);
for (auto e : transformEntities) {
e.unpack<Transform>(transform);
Transform::Handle parent = transform->parent;
TransformData lastGlobalTransform = { transform->lastPosition, glm::quat_cast(transform->lastRotation), transform->lastScale };
......@@ -59,7 +58,16 @@ void SceneGraphSystem::prepareDraw() {
parent = parent->parent;
}
m_renderer->submit({ drawable->material, drawable->geometry, lastGlobalTransform, thisGlobalTransform }, RenderQueue::OPAQUE);
transform->lastGlobalTransform = lastGlobalTransform;
transform->thisGlobalTransform = thisGlobalTransform;
}
auto drawableEntities = m_entityManager.entities_with_components<Drawable, Transform>();
Drawable::Handle drawable;
for (auto e : drawableEntities) {
e.unpack<Drawable, Transform>(drawable, transform);
m_renderer->submit({ drawable->material, drawable->geometry, transform->lastGlobalTransform, transform->thisGlobalTransform }, RenderQueue::OPAQUE);
}
auto lightEntities = m_entityManager.entities_with_components<Light, Transform>();
......@@ -67,7 +75,11 @@ void SceneGraphSystem::prepareDraw() {
Light::Handle light;
for (auto e : lightEntities) {
e.unpack<Light, Transform>(light, transform);
m_renderer->submit(*light.get());
auto viewMatrix = glm::lookAt<float>(-light->dir, { 0,0,0 }, glm::vec3(0.0f, 1.0f, 0.0f));
auto lightVP = glm::ortho<float>(-15.0f, +15.0f, 15.0f, -15.0f, 0.0f, -40.0f) * viewMatrix;
m_renderer->submit({light->color, light->castShadow, transform->lastGlobalTransform, transform->thisGlobalTransform, lightVP, nullptr, nullptr});
}
}
......
......@@ -57,7 +57,6 @@ int main(int argc, char *argv[]) {
PlayerSystem player(&context); // Should be the last one
// Call the startup functions of the systems above in the order they are listed.
// This means it's safe to access other systems in a startup function as long
// as you depend on them
......@@ -71,7 +70,6 @@ int main(int argc, char *argv[]) {
auto vaoTeapot = VertexArrayObjectCreator("teapot.obj").create();
// load a test scene
auto vaoScene = VertexArrayObjectCreator("test_scene.obj").create();
auto vaoCube = VertexArrayObjectCreator("cube.obj").create();
auto vaoSun = VertexArrayObjectCreator("uvsphere.obj").create();
......@@ -83,32 +81,23 @@ int main(int argc, char *argv[]) {
auto pbrShader = ShaderProgramCreator("PBR").attributeLocations(vaoTeapot->getAttributeLocations()).create();
// Create geometry objects that point to the previously initialized vaos
Geometry geom1 = { vaoScene };
Geometry geom1 = { vaoSun };
Geometry geom2 = { vaoTeapot };
Geometry geom3 = { vaoCube };
// Create a material that uses the loaded shader program
Material checkerboardMat = { glm::vec4{1, 1, 1, 1}, checkboardTexture, pbrShader };
Material transparentMat = { glm::vec4{ 1, 1, 1, 1 }, testTransparencyTexture, pbrShader };
Material checkerboardMat = { glm::vec4{1, 1, 1, 1}, glm::vec4{ 1, 1, 1, 1 }, checkboardTexture, pbrShader };
Material transparentMat = { glm::vec4{ 1, 1, 1, 1 }, glm::vec4{ 0, 0, 0, 1 }, testTransparencyTexture, pbrShader };
// Same entity creation code as for cube1
auto teapotEntity = sceneGraph.create();
auto teapotTransform = teapotEntity.assign<Transform>();
teapotEntity.assign<Drawable>(geom2, checkerboardMat);
// Let's create a placeholder sun
auto sun = sceneGraph.create();
// Add a transform component to it so we are able to position it in space
auto sunTransform = sun.assign<Transform>();
// Add a Drawable component to it so the renderer has something to draw
sun.assign<Drawable>(geom1, checkerboardMat);
sunTransform->scale = glm::vec3(2, 2, 2);
sun.assign<Light>(glm::vec4(1, 1, 1, 1), glm::vec3(1, 0, 0), false);
auto cube2 = sceneGraph.create();
auto cube2Transform = cube2.assign<Transform>();
cube2.assign<Drawable>(geom2, checkerboardMat);
// create a planet!
// Mass in solar masses, Radius in solar radii, Eccentricity, Semimajor axis, Inclination, Ascending Node, Arg. of Periapsis, time at perihelion
......@@ -135,7 +124,7 @@ int main(int argc, char *argv[]) {
// Attach a component to the entity that plays the loaded sound
// A sound can be referenced by multiple sound sources
auto soundSource = teapotEntity.assign<SoundSource>(testSound);
auto soundSource = sun.assign<SoundSource>(testSound);
// Subscribe to the UI drawing event.
// This is called once per frame
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment