Commit 775f7022 authored by Dario Seyb's avatar Dario Seyb

simple shadow mapping

parent d5703203
# Blender MTL File: 'None'
# Material Count: 1
newmtl None
Ns 0
Ka 0.000000 0.000000 0.000000
Kd 0.8 0.8 0.8
Ks 0.8 0.8 0.8
d 1
illum 2
This diff is collapsed.
#version 330
#version 330 core
uniform sampler2D uSamplerColor;
uniform sampler2D uSamplerNormal;
uniform sampler2D uSamplerPosition;
uniform sampler2D uSamplerDepth;
uniform sampler2D uSamplerShadowMap;
uniform vec3 uLightPosition;
uniform vec4 uLightColor;
uniform mat4 uLightProjMatrix;
uniform float uNear;
uniform float uFar;
......@@ -14,7 +16,6 @@ uniform float uFar;
uniform mat4 uViewProjectionInverseMatrix;
in vec2 vTexCoord;
out vec4 oColor;
vec3 unpackNormal(vec4 norm) {
......@@ -27,18 +28,29 @@ float linearizeDepth(float depth) {
vec3 unpackWorldPosition(float depth) {
vec4 clipSpaceLocation;
clipSpaceLocation.xy = vTexCoord * 2.0f - 1.0f;
clipSpaceLocation.z = depth* 2.0f - 1.0f;;
clipSpaceLocation.w = 1.0f;
clipSpaceLocation.xy = vTexCoord * 2.0 - 1.0;
clipSpaceLocation.z = depth * 2.0 - 1.0;
clipSpaceLocation.w = 1.0;
vec4 homogenousLocation = uViewProjectionInverseMatrix * clipSpaceLocation;
return homogenousLocation.xyz / homogenousLocation.w;
}
vec3 projShadowCoord(vec3 worldPosition) {
vec4 shadowCoord = uLightProjMatrix * vec4(worldPosition, 1);
vec3 clipShadowCoord = shadowCoord.xyz/shadowCoord.w;
return clipShadowCoord;
}
float shadowFactor(vec3 worldPosition) {
vec3 shadowCoord = projShadowCoord(worldPosition.xyz);
float shadowDepth = texture(uSamplerShadowMap, shadowCoord.xy).r;
return shadowDepth < shadowCoord.z -0.01 ? 0 : 1;
}
void main()
{
vec4 color = texture(uSamplerColor, vTexCoord);
vec3 normal = unpackNormal(texture(uSamplerNormal, vTexCoord));
vec3 position = texture(uSamplerPosition, vTexCoord).xyz;
float depth = texture(uSamplerDepth, vTexCoord).r;
......@@ -50,10 +62,11 @@ void main()
float lightDistance = length(lightDir);
lightDir /= lightDistance;
float diffuseFactor = dot(lightDir, normal) * uLightColor.a/lightDistance;
float diffuseFactor = dot(lightDir, normal) * uLightColor.a/(lightDistance*lightDistance) ;
if(diffuseFactor < 0) diffuseFactor = 0;
vec3 diffuseColor = diffuseFactor * uLightColor.rgb * color.rgb;
vec3 diffuseColor = diffuseFactor * uLightColor.rgb * color.rgb * shadowFactor(worldPosition);;
oColor = vec4(diffuseColor, 1);
}
#version 330
#version 330 core
out vec2 vTexCoord;
......
#version 330 core
layout(location = 0) out vec4 oDepth;
void main()
{
oDepth = vec4(vec3(gl_FragCoord.z), 1);
}
#version 330 core
uniform mat4 uModelMatrix;
uniform mat4 uViewProjectionMatrix;
in vec3 aPosition;
void main()
{
gl_Position = uViewProjectionMatrix * uModelMatrix * vec4(aPosition, 1.0);
}
......@@ -11,6 +11,14 @@
#include <ACGL/OpenGL/Objects.hh>
struct Light {
glm::vec3 position;
glm::vec4 color;
ACGL::OpenGL::SharedFrameBufferObject shadowFbo;
ACGL::OpenGL::SharedTexture2D shadowMap;
glm::mat4 projMatrix;
};
class RendererSystem : public System {
private:
EventSystem *m_events;
......@@ -25,6 +33,11 @@ private:
SharedShaderProgram m_deferredCombineProgram;
SharedShaderProgram m_blitProgram;
SharedShaderProgram m_ShadowMapProg;
std::vector<Light> m_lights = {
{ { 0, 10, 10 },{ 0.2, 0.7, 0.2, 6 }, nullptr, nullptr },
{ { 10, 10, 10 },{ .5, .1, .1, 4 }, nullptr, nullptr },
};
public:
CONSTRUCT_SYSTEM(RendererSystem), m_submittedDrawCalls(kilobytes(4)) {}
......
......@@ -13,10 +13,14 @@
#include <engine/events/ResizeWindowEvent.hpp>
#include <glm/ext.hpp>
#include <engine/ui/imgui.h>
using namespace ACGL::OpenGL;
using namespace ACGL::Base;
using namespace ACGL::Utils;
const glm::vec2 SHADOW_MAP_RESOLUTION = { 2048, 2048 };
bool RendererSystem::startup() {
RESOLVE_DEPENDENCY(m_events);
RESOLVE_DEPENDENCY(m_window);
......@@ -28,10 +32,10 @@ bool RendererSystem::startup() {
auto windowSize = m_window->getSize();
glViewport(0, 0, windowSize.x, windowSize.y);
m_gBufferTextures.push_back(SharedTexture2D(
new Texture2D(windowSize, GL_SRGB8_ALPHA8))); // RGBA per default
m_gBufferTextures.push_back(
SharedTexture2D(new Texture2D(windowSize))); // RGBA per default
m_gBufferTextures.push_back(
SharedTexture2D(new Texture2D(windowSize))); // RGBA per default
SharedTexture2D(new Texture2D(windowSize, GL_RGBA8))); // RGBA per default
m_gBufferTextures.push_back(
SharedTexture2D(new Texture2D(windowSize, GL_DEPTH24_STENCIL8)));
......@@ -58,8 +62,9 @@ bool RendererSystem::startup() {
m_compositingBuffer->attachColorTexture("oColor", m_gBufferTextures[3]);
m_compositingBuffer->validate();
m_deferredCombineProgram = ShaderProgramCreator("DeferredCombine").create();
m_blitProgram = ShaderProgramCreator("Blit").create();
m_deferredCombineProgram = ShaderProgramFileManager::the()->get(ShaderProgramCreator("DeferredCombine"));
m_blitProgram = ShaderProgramFileManager::the()->get(ShaderProgramCreator("Blit"));
m_ShadowMapProg = ShaderProgramFileManager::the()->get(ShaderProgramCreator("ShadowMap"));
m_events->subscribe<ResizeWindowEvent>([this](const ResizeWindowEvent &e) {
glViewport(0, 0, e.newSize.x, e.newSize.y);
......@@ -68,6 +73,37 @@ bool RendererSystem::startup() {
}
});
for (auto &light : m_lights) {
light.shadowMap =
SharedTexture2D(new Texture2D(SHADOW_MAP_RESOLUTION));
light.shadowMap->setMinFilter(GL_NEAREST);
light.shadowMap->setMagFilter(GL_NEAREST);
light.shadowMap->setWrap(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
light.shadowFbo = SharedFrameBufferObject(new FrameBufferObject);
light.shadowFbo->attachColorTexture("oDepth", light.shadowMap);
light.shadowFbo->setDepthTexture(SharedTexture2D(new Texture2D(SHADOW_MAP_RESOLUTION, GL_DEPTH24_STENCIL8)));
light.shadowFbo->validate(); // always a good idea
}
m_events->subscribe<"DrawUI"_sh>([this]() {
ImGui::Begin("Reload");
if (ImGui::Button("Reload Shaders", { 100, 20 })) {
ShaderProgramFileManager::the()->updateAll();
}
ImGui::End();
int i = 0;
for (auto light : m_lights) {
ImGui::Begin("ShadowMap", 0, ImGuiWindowFlags_AlwaysAutoResize);
auto texSize = light.shadowMap->getSize();
ImGui::Image((void*)light.shadowMap->getObjectName(), { 256, 256 });
ImGui::End();
}
});
return true;
}
......@@ -90,10 +126,13 @@ void RendererSystem::frame(double interp, double totalTime) {
m_gBufferObject->clearBuffers();
glEnable(GL_DEPTH_TEST);
glBlendFunc(GL_ONE, GL_ZERO);
auto gBufferRes = m_gBufferObject->getSize();
glViewport(0, 0, gBufferRes.x, gBufferRes.y);
auto windowSize = m_window->getSize();
auto projectionMatrix =
glm::perspectiveFov<float>(cam->fov, windowSize.x, windowSize.y,
glm::perspectiveFov<float>(glm::radians(cam->fov), windowSize.x, windowSize.y,
cam->near, cam->far) *
glm::inverse(glm::translate<float>(trans->position) * trans->rotation);
......@@ -104,8 +143,8 @@ void RendererSystem::frame(double interp, double totalTime) {
drawCall.material.prog->setUniformBlockBinding("bGlobalMatrices", 0);
drawCall.material.prog->use();
auto bunnyTexture = Texture2DFileManager::the()->get(
Texture2DCreator("clownfishBunny.png"));
auto bunnyTexture =
Texture2DFileManager::the()->get(Texture2DCreator("checkerboard.png"));
drawCall.material.prog->setTexture("uTexture", bunnyTexture, 0);
drawCall.material.prog->setUniform("uModelMatrix", drawCall.transform);
......@@ -114,6 +153,36 @@ void RendererSystem::frame(double interp, double totalTime) {
drawCall.geometry.vao->render();
}
m_lights[0].position = {sin(totalTime) * 10, 10, cos(totalTime) * 10};
m_ShadowMapProg->use();
glCullFace(GL_FRONT);
for (auto& light : m_lights) {
light.shadowFbo->setClearColor(glm::vec4{ 0, 0, 0, 0 });
light.shadowFbo->bind();
light.shadowFbo->clearBuffers();
auto shadowRes = light.shadowFbo->getSize();
glViewport(0, 0, shadowRes.x, shadowRes.y);
auto viewMatrix = glm::lookAt<float>(light.position, light.position + glm::normalize(light.position), 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;
light.projMatrix = lightVP;
m_ShadowMapProg->setUniform("uViewProjectionMatrix", light.projMatrix);
for (size_t i = 0; i < m_submittedDrawCalls.size(); i++) {
auto drawCall = m_submittedDrawCalls[i];
m_ShadowMapProg->setUniform("uModelMatrix", drawCall.transform);
drawCall.geometry.vao->render();
}
}
// Deferred lighting
m_compositingBuffer->setClearColor(glm::vec4{0, 0, 0, 0});
m_compositingBuffer->bind();
......@@ -121,6 +190,10 @@ void RendererSystem::frame(double interp, double totalTime) {
glDisable(GL_DEPTH_TEST);
glBlendFunc(GL_ONE, GL_ONE);
glEnable(GL_BLEND);
glCullFace(GL_BACK);
auto compositingRes = m_compositingBuffer->getSize();
glViewport(0, 0, compositingRes.x, compositingRes.y);
m_deferredCombineProgram->use();
m_deferredCombineProgram->setTexture("uSamplerColor", m_gBufferTextures[0],
......@@ -139,19 +212,16 @@ void RendererSystem::frame(double interp, double totalTime) {
// attribute-less rendering:
VertexArrayObject vao;
vao.bind(); // 'empty' VAO -> no attributes are defined
glm::mat4 biasMatrix(
0.5, 0.0, 0.0, 0.0,
0.0, 0.5, 0.0, 0.0,
0.0, 0.0, 0.5, 0.0,
0.5, 0.5, 0.5, 1.0);
struct Light {
glm::vec3 position;
glm::vec4 color;
};
std::vector<Light> lights = {
{{sin(totalTime) * 10, 10, cos(totalTime) * 10}, {0.1, 0.6, 0.1, 6}},
{{10, 10, 10}, {.5, .1, .1, 4}},
{trans->position, {1, 1, 1, 1}},
};
for (auto light : m_lights) {
m_deferredCombineProgram->setUniform("uLightProjMatrix", biasMatrix * light.projMatrix);
m_deferredCombineProgram->setTexture("uSamplerShadowMap", light.shadowMap, 3);
for (auto light : lights) {
m_deferredCombineProgram->setUniform("uLightPosition", light.position);
m_deferredCombineProgram->setUniform("uLightColor", light.color);
glDrawArrays(
......@@ -159,6 +229,7 @@ void RendererSystem::frame(double interp, double totalTime) {
4); // create 2 triangles (defined in shader) with no attributes
}
// Bit to backbuffer with tonemapping
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDisable(GL_BLEND);
......@@ -167,9 +238,8 @@ void RendererSystem::frame(double interp, double totalTime) {
"uSamplerColor", m_compositingBuffer->getColorAttachments()[0].texture,
0);
glDrawArrays(
GL_TRIANGLE_STRIP, 0,
4); // create 2 triangles (defined in shader) with no attributes
glDrawArrays(GL_TRIANGLE_STRIP, 0,
4); // create 2 triangles (defined in shader) with no attributes
openGLCriticalError();
m_submittedDrawCalls.reset();
......
......@@ -65,7 +65,7 @@ int main(int argc, char *argv[]) {
auto vaoBunny = VertexArrayObjectCreator("test_scene.obj").create();
// load a texture:
auto bunnyTexture = Texture2DFileManager::the()->get(Texture2DCreator("clownfishBunny.png"));
auto bunnyTexture = Texture2DFileManager::the()->get(Texture2DCreator("checkerboard.png"));
// look up all shader files starting with 'PBR' and build a ShaderProgram from it:
auto pbrShader = ShaderProgramCreator("PBR").attributeLocations(vaoCube->getAttributeLocations()).create();
......@@ -108,7 +108,6 @@ int main(int argc, char *argv[]) {
auto camTransform = playerObj.assign<Transform>();
playerObj.assign<Camera>(75, 0.1f, 100);
camTransform->position = glm::vec3(0, 4, 35);
camTransform->rotation = glm::rotate<float>(M_PI, glm::vec3(0, 0, 1));
// Tell the renderer which entity should be used for drawing
// The renderer assumes that a camera and a transform component are attached to this entity
......@@ -168,8 +167,8 @@ int main(int argc, char *argv[]) {
// If the mouse is captured
if (SDL_GetRelativeMouseMode()) {
// Rotate the camera based on the mouse movement
auto mouseMove = glm::vec2((float)e.originalEvent.motion.xrel, (float)e.originalEvent.motion.yrel);
auto up = rotate(glm::vec3(0, -1, 0), glm::inverse(camTransform->rotation));
auto mouseMove = glm::vec2(-(float)e.originalEvent.motion.xrel, -(float)e.originalEvent.motion.yrel);
auto up = rotate(glm::vec3(0, 1, 0), glm::inverse(camTransform->rotation));
camTransform->rotation = glm::rotate(camTransform->rotation, mouseMove.x * 0.001f, up);
camTransform->rotation = glm::rotate(camTransform->rotation, mouseMove.y * 0.001f, glm::vec3(1, 0, 0));
......@@ -210,8 +209,8 @@ int main(int argc, char *argv[]) {
if (!ImGui::GetIO().WantCaptureKeyboard) {
if (wDown) moveDir -= glm::vec3(0, 0, 1);
if (sDown) moveDir += glm::vec3(0, 0, 1);
if (aDown) moveDir += glm::vec3(1, 0, 0);
if (dDown) moveDir -= glm::vec3(1, 0, 0);
if (aDown) moveDir -= glm::vec3(1, 0, 0);
if (dDown) moveDir += glm::vec3(1, 0, 0);
if (moveDir.x != 0 || moveDir.z != 0) {
moveDir = rotate(glm::normalize(moveDir), camTransform->rotation);
......
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