Commit 1766b59a authored by Dario Seyb's avatar Dario Seyb

motion vectors

parent 37b587c2
......@@ -3,6 +3,7 @@
uniform sampler2D uSamplerColor;
uniform sampler2D uSamplerEmissive;
uniform sampler2D uSamplerNormal;
uniform sampler2D uSamplerMotion;
uniform sampler2D uSamplerDepth;
uniform sampler2DShadow uSamplerShadowMap;
......
......@@ -4,6 +4,9 @@ in vec3 vNormal;
in vec2 vTexCoord;
in vec3 vPosition;
in vec2 vThisFragCoord;
in vec2 vPrevFragCoord;
uniform sampler2D uTexture;
uniform vec4 uEmissiveColor;
uniform vec4 uTintColor;
......@@ -12,21 +15,25 @@ uniform float uTime;
out vec4 oColor;
out vec4 oEmissive;
out vec4 oNormal;
out vec2 oMotion;
float rand(vec2 co){
return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
}
void main()
{
vec4 color = texture(uTexture, vTexCoord).rgba * uTintColor;
float sample = rand(gl_FragCoord.xy * vPosition.xy * vPosition.z * uTime);
if(sample > color.a) discard;
oMotion = vThisFragCoord - vPrevFragCoord;
oColor = color;
oEmissive = uEmissiveColor * color;
oNormal = vec4(normalize(vNormal) * 0.5 + 0.5, 0.0);
oNormal = vec4(normalize(vNormal) * 0.5 + 0.5, 0);
}
#version 330
uniform mat4 uPrevModelMatrix;
uniform mat4 uPrevViewProjectionMatrix;
uniform mat4 uModelMatrix;
uniform mat4 uViewProjectionMatrix;
......@@ -11,11 +14,19 @@ out vec3 vNormal;
out vec2 vTexCoord;
out vec3 vPosition;
out vec2 vThisFragCoord;
out vec2 vPrevFragCoord;
void main()
{
vNormal = inverse(transpose(mat3(uModelMatrix))) * aNormal;
vTexCoord = aTexCoord;
vec4 worldPosition = uModelMatrix * vec4(aPosition, 1.0);
vPosition = worldPosition.xyz;
vec4 prevPosition = uPrevViewProjectionMatrix * uPrevModelMatrix * vec4(aPosition, 1.0);
gl_Position = uViewProjectionMatrix * worldPosition;
vPrevFragCoord = prevPosition.xy/prevPosition.w;
vThisFragCoord = gl_Position.xy/gl_Position.w;
}
#version 330
uniform sampler2D uSamplerColor;
uniform sampler2D uSamplerMotion;
in vec2 vTexCoord;
......@@ -8,6 +9,8 @@ out vec4 oColor;
void main()
{
vec3 texColor = texture(uSamplerColor, vTexCoord).rgb;
oColor = vec4(texColor,0.0);
vec2 motion = texture(uSamplerMotion, vTexCoord).rg;
vec3 texColor = texture(uSamplerColor, vTexCoord-motion).rgb;
oColor = vec4(texColor, 0.6);
}
......@@ -56,6 +56,8 @@ private:
SharedShaderProgram m_blitProgram;
SharedShaderProgram m_shadowMapProg;
SharedShaderProgram m_pbrProg;
SharedShaderProgram m_txaaProg;
public:
......@@ -69,6 +71,10 @@ public:
m_submittedDrawCalls.push(drawCall);
}
inline SharedLocationMappings getGBufferLocations() {
return m_gBufferObject->getAttachmentLocations();
}
inline void submit(LightData light) {
if (light.castShadow && m_submittedLights.size() < m_shadowMaps.size()) {
light.shadowFbo = m_shadowMaps[m_submittedLights.size()];
......
......@@ -7,6 +7,7 @@
#include <engine/core/SimulateEvent.hpp>
#include <engine/scene/Entity.hpp>
#include <engine/scene/Planet.hpp>
#include <engine/graphics/RendererSystem.hpp>
......@@ -14,6 +15,7 @@ class OrbitalSimulationSystem : public System {
private:
EventSystem* m_events;
SceneGraphSystem *m_scene;
RendererSystem *m_renderer;
Geometry defaultGeom;
Material defaultMat;
......
......@@ -27,10 +27,7 @@ private:
Entity player;
Transform::Handle cameraTransform;
bool wDown = false;
bool aDown = false;
bool sDown = false;
bool dDown = false;
bool m_keyState[SDL_NUM_SCANCODES];
void handleKeyboard(KeyboardEvent e);
void handleMouse(MouseEvent e);
......
......@@ -38,6 +38,9 @@ bool RendererSystem::startup() {
new Texture2D(windowSize, GL_SRGB8_ALPHA8))); // RGBA per default
m_gBufferTextures.push_back(
SharedTexture2D(new Texture2D(windowSize, GL_RGBA8))); // RGBA per default
m_gBufferTextures.push_back(SharedTexture2D(
new Texture2D(windowSize, GL_RG32F))); // RGBA per default
m_gBufferTextures.push_back(
SharedTexture2D(new Texture2D(windowSize, GL_DEPTH24_STENCIL8)));
......@@ -56,21 +59,24 @@ bool RendererSystem::startup() {
m_gBufferObject->attachColorTexture("oColor", m_gBufferTextures[0]);
m_gBufferObject->attachColorTexture("oEmissive", m_gBufferTextures[1]);
m_gBufferObject->attachColorTexture("oNormal", m_gBufferTextures[2]);
m_gBufferObject->setDepthTexture(m_gBufferTextures[3]);
m_gBufferObject->attachColorTexture("oMotion", m_gBufferTextures[3]);
m_gBufferObject->setDepthTexture(m_gBufferTextures[4]);
m_gBufferObject->validate(); // always a good idea
m_primaryCompositingBuffer = SharedFrameBufferObject(new FrameBufferObject());
m_primaryCompositingBuffer->attachColorTexture("oColor", m_gBufferTextures[4]);
m_primaryCompositingBuffer->attachColorTexture("oColor", m_gBufferTextures[5]);
m_primaryCompositingBuffer->validate();
m_secondaryCompositingBuffer = SharedFrameBufferObject(new FrameBufferObject());
m_secondaryCompositingBuffer->attachColorTexture("oColor", m_gBufferTextures[5]);
m_secondaryCompositingBuffer->attachColorTexture("oColor", m_gBufferTextures[6]);
m_secondaryCompositingBuffer->validate();
m_deferredCombineProgram = ShaderProgramFileManager::the()->get(ShaderProgramCreator("DeferredCombine"));
m_blitProgram = ShaderProgramFileManager::the()->get(ShaderProgramCreator("Blit"));
m_shadowMapProg = ShaderProgramFileManager::the()->get(ShaderProgramCreator("ShadowMap"));
m_txaaProg = ShaderProgramFileManager::the()->get(ShaderProgramCreator("TXAA"));
m_pbrProg = ShaderProgramFileManager::the()->get(ShaderProgramCreator("PBR"));
m_pbrProg->setFragmentDataLocations(m_gBufferObject->getAttachmentLocations());
m_events->subscribe<ResizeWindowEvent>([this](const ResizeWindowEvent &e) {
glViewport(0, 0, e.newSize.x, e.newSize.y);
......@@ -150,8 +156,12 @@ void RendererSystem::frame(double interp, double totalTime) {
auto gBufferRes = m_gBufferObject->getSize();
glViewport(0, 0, gBufferRes.x, gBufferRes.y);
double thisInterp = interp;
double prevInterp = interp;
// Prepare camera coords
auto camTransform = interpolate(trans->lastGlobalTransform, trans->thisGlobalTransform, interp);
auto camTransform = interpolate(trans->lastGlobalTransform, trans->thisGlobalTransform, thisInterp);
auto prevCamTransform = interpolate(trans->lastGlobalTransform, trans->thisGlobalTransform, prevInterp);
auto windowSize = m_window->getSize();
static bool offset = false;
......@@ -165,6 +175,11 @@ void RendererSystem::frame(double interp, double totalTime) {
windowSize.y, cam->near, cam->far) *
glm::inverse(camTransform);
auto prevProjectionMatrix =
glm::translate(glm::vec3{ 0.5/gBufferRes.x, 0.5/gBufferRes.y, 0 }*offsetDir) *
glm::perspectiveFov<float>(glm::radians(cam->fov), windowSize.x,
windowSize.y, cam->near, cam->far) *
glm::inverse(prevCamTransform);
for (size_t i = 0; i < m_submittedDrawCalls.size(); i++) {
auto drawCall = m_submittedDrawCalls[i];
......@@ -176,9 +191,16 @@ void RendererSystem::frame(double interp, double totalTime) {
drawCall.material.prog->setUniform(
"uModelMatrix", interpolate(drawCall.lastFrameTransform,
drawCall.thisFrameTransform, interp));
drawCall.thisFrameTransform, thisInterp));
drawCall.material.prog->setUniform("uViewProjectionMatrix",
projectionMatrix);
drawCall.material.prog->setUniform(
"uPrevModelMatrix", interpolate(drawCall.lastFrameTransform,
drawCall.thisFrameTransform, prevInterp));
drawCall.material.prog->setUniform("uPrevViewProjectionMatrix",
prevProjectionMatrix);
drawCall.geometry.vao->render();
}
......@@ -234,7 +256,8 @@ void RendererSystem::frame(double interp, double totalTime) {
m_deferredCombineProgram->setTexture("uSamplerColor", m_gBufferTextures[0], 0);
m_deferredCombineProgram->setTexture("uSamplerEmissive", m_gBufferTextures[1], 1);
m_deferredCombineProgram->setTexture("uSamplerNormal", m_gBufferTextures[2], 2);
m_deferredCombineProgram->setTexture("uSamplerDepth", m_gBufferTextures[3], 3);
m_deferredCombineProgram->setTexture("uSamplerMotion", m_gBufferTextures[3], 3);
m_deferredCombineProgram->setTexture("uSamplerDepth", m_gBufferTextures[4], 4);
m_deferredCombineProgram->setUniform("uNear", cam->near);
m_deferredCombineProgram->setUniform("uFar", cam->far);
......@@ -254,7 +277,7 @@ void RendererSystem::frame(double interp, double totalTime) {
0.0, 0.5, 0.0, 0.0,
0.0, 0.0, 0.5, 0.0,
0.5, 0.5, 0.5, 1.0);
m_deferredCombineProgram->setTexture("uSamplerShadowMap", m_dummyShadowMap, 4);
m_deferredCombineProgram->setTexture("uSamplerShadowMap", m_dummyShadowMap, 5);
for (size_t i = 0; i < m_submittedLights.size(); i++) {
auto light = m_submittedLights[i];
......@@ -267,7 +290,7 @@ void RendererSystem::frame(double interp, double totalTime) {
m_deferredCombineProgram->setUniform("uLightProjMatrix",
biasMatrix * light.projMatrix);
m_deferredCombineProgram->setTexture("uSamplerShadowMap", light.shadowMap,
3);
5);
auto size = light.shadowMap->getSize();
m_deferredCombineProgram->setUniform(
......@@ -288,6 +311,9 @@ void RendererSystem::frame(double interp, double totalTime) {
m_txaaProg->setTexture(
"uSamplerColor", m_secondaryCompositingBuffer->getColorAttachments()[0].texture,
0);
m_txaaProg->setTexture("uSamplerMotion", m_gBufferTextures[3], 1);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); // create 2 triangles (defined in shader) with no attributes
// Blit to backbuffer with tonemapping
......@@ -296,7 +322,7 @@ void RendererSystem::frame(double interp, double totalTime) {
m_blitProgram->use();
m_blitProgram->setTexture(
"uSamplerColor", m_primaryCompositingBuffer->getColorAttachments()[0].texture,
"uSamplerColor", m_primaryCompositingBuffer->getColorAttachments()[0].texture,
0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); // create 2 triangles (defined in shader) with no attributes
......
......@@ -20,6 +20,7 @@
bool OrbitalSimulationSystem::startup() {
RESOLVE_DEPENDENCY(m_events);
RESOLVE_DEPENDENCY(m_scene);
RESOLVE_DEPENDENCY(m_renderer);
m_events->subscribe<SimulateEvent>([this](const SimulateEvent &e) { simulateOrbitals(e.dt, e.totalTime); });
......@@ -29,7 +30,9 @@ bool OrbitalSimulationSystem::startup() {
defaultGeom = { vaoSphere };
auto pbrShader = ShaderProgramFileManager::the()->get(ShaderProgramCreator("PBR").attributeLocations(vaoSphere->getAttributeLocations()));
auto pbrShader = ShaderProgramFileManager::the()->get(ShaderProgramCreator("PBR").
attributeLocations(vaoSphere->getAttributeLocations()).
fragmentDataLocations(m_renderer->getGBufferLocations()));
defaultMat = { glm::vec4(1, 1, 1, 1), glm::vec4(0.1, 0.1, 0.1, 1), texture, pbrShader };
......
......@@ -23,6 +23,11 @@ bool PlayerSystem::startup() {
m_events->subscribe<KeyboardEvent>([this](const KeyboardEvent& e) { handleKeyboard(e); });
m_events->subscribe<MouseEvent>([this](const MouseEvent& e) { handleMouse(e); });
m_events->subscribe<SimulateEvent>([this](const SimulateEvent& e) { update(e.dt); });
for (int i = 0; i < SDL_NUM_SCANCODES; i++) {
m_keyState[i] = false;
}
return true;
}
......@@ -31,6 +36,10 @@ void PlayerSystem::handleKeyboard(KeyboardEvent e) {
return;
}
if (e.originalEvent.key.keysym.scancode < SDL_NUM_SCANCODES && e.originalEvent.key.keysym.scancode >= 0) {
m_keyState[e.originalEvent.key.keysym.scancode] = e.originalEvent.key.type == SDL_KEYDOWN;
}
switch (e.originalEvent.key.keysym.scancode) {
case SDL_SCANCODE_ESCAPE:
// Make the mouse freely movable on escape
......@@ -38,18 +47,6 @@ void PlayerSystem::handleKeyboard(KeyboardEvent e) {
SDL_SetRelativeMouseMode(SDL_FALSE);
}
break;
case SDL_SCANCODE_W:
wDown = e.originalEvent.key.type == SDL_KEYDOWN;
break;
case SDL_SCANCODE_S:
sDown = e.originalEvent.key.type == SDL_KEYDOWN;
break;
case SDL_SCANCODE_D:
dDown = e.originalEvent.key.type == SDL_KEYDOWN;
break;
case SDL_SCANCODE_A:
aDown = e.originalEvent.key.type == SDL_KEYDOWN;
break;
default:
break;
}
......@@ -83,12 +80,23 @@ void PlayerSystem::handleMouse(MouseEvent e) {
void PlayerSystem::update(float dt) {
glm::vec3 moveDir(0);
// Move the camera based on WASD keyboard input
glm::vec2 rotDir(0);
// Move the camera based on WASD keyboard input
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 (m_keyState[SDL_SCANCODE_W]) moveDir -= glm::vec3(0, 0, 1);
if (m_keyState[SDL_SCANCODE_S]) moveDir += glm::vec3(0, 0, 1);
if (m_keyState[SDL_SCANCODE_A]) moveDir -= glm::vec3(1, 0, 0);
if (m_keyState[SDL_SCANCODE_D]) moveDir += glm::vec3(1, 0, 0);
if (m_keyState[SDL_SCANCODE_LEFT]) rotDir += glm::vec2(1, 0);
if (m_keyState[SDL_SCANCODE_RIGHT]) rotDir -= glm::vec2(1, 0);
if (m_keyState[SDL_SCANCODE_UP]) rotDir += glm::vec2(0, 1);
if (m_keyState[SDL_SCANCODE_DOWN]) rotDir -= glm::vec2(0, 1);
// Rotate the camera based on the mouse movement
auto up = rotate(glm::vec3(0, 1, 0), glm::inverse(cameraTransform->rotation));
cameraTransform->rotation = glm::rotate(cameraTransform->rotation, rotDir.x * 0.05f, up);
cameraTransform->rotation = glm::rotate(cameraTransform->rotation, rotDir.y * 0.05f, glm::vec3(1, 0, 0));
if (moveDir.x != 0 || moveDir.z != 0) {
moveDir = rotate(glm::normalize(moveDir), cameraTransform->rotation);
......
......@@ -71,14 +71,16 @@ int main(int argc, char *argv[]) {
// load a test scene
auto vaoCube = VertexArrayObjectCreator("cube.obj").create();
auto vaoSun = VertexArrayObjectCreator("uvsphere.obj").create();
auto vaoSun = VertexArrayObjectCreator("test_scene.obj").create();
// load a texture:
auto checkboardTexture = Texture2DFileManager::the()->get(Texture2DCreator("checkerboard.png"));
auto testTransparencyTexture = Texture2DFileManager::the()->get(Texture2DCreator("transparency_test.png"));
// look up all shader files starting with 'PBR' and build a ShaderProgram from it:
auto pbrShader = ShaderProgramCreator("PBR").attributeLocations(vaoTeapot->getAttributeLocations()).create();
auto pbrShader = ShaderProgramCreator("PBR").
attributeLocations(vaoTeapot->getAttributeLocations()).
fragmentDataLocations(renderer.getGBufferLocations()).create();
// Create geometry objects that point to the previously initialized vaos
Geometry geom1 = { vaoSun };
......
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