Fix motion blur in multiplayer

This commit is contained in:
Flakebi 2015-03-28 22:30:10 +01:00
parent 17039141e4
commit 7c697e76e5
5 changed files with 28 additions and 15 deletions

View File

@ -55,6 +55,7 @@ Camera::Camera(int camera_index, AbstractKart* kart) : m_kart(NULL)
m_index = camera_index; m_index = camera_index;
m_original_kart = kart; m_original_kart = kart;
m_camera = irr_driver->addCameraSceneNode(); m_camera = irr_driver->addCameraSceneNode();
m_previous_pv_matrix = core::matrix4();
#ifdef DEBUG #ifdef DEBUG
if (kart != NULL) if (kart != NULL)

View File

@ -28,9 +28,10 @@
#include "utils/log.hpp" #include "utils/log.hpp"
#include "utils/vec3.hpp" #include "utils/vec3.hpp"
#include "matrix4.h"
#include "rect.h"
#include "SColor.h" #include "SColor.h"
#include "vector2d.h" #include "vector2d.h"
#include "rect.h"
#include <vector> #include <vector>
@ -64,6 +65,8 @@ private:
/** The camera scene node. */ /** The camera scene node. */
scene::ICameraSceneNode *m_camera; scene::ICameraSceneNode *m_camera;
/** The project-view matrix of the previous frame, used for the blur shader. */
core::matrix4 m_previous_pv_matrix;
/** Camera's mode. */ /** Camera's mode. */
Mode m_mode; Mode m_mode;
@ -272,7 +275,15 @@ public:
void setInitialTransform(); void setInitialTransform();
void activate(bool alsoActivateInIrrlicht=true); void activate(bool alsoActivateInIrrlicht=true);
void update (float dt); void update (float dt);
void setKart (AbstractKart *new_kart); void setKart(AbstractKart *new_kart);
// ------------------------------------------------------------------------
/** Returns the project-view matrix of the previous frame. */
core::matrix4 getPreviousPVMatrix() const { return m_previous_pv_matrix; }
// ------------------------------------------------------------------------
/** Returns the project-view matrix of the previous frame. */
void setPreviousPVMatrix(core::matrix4 mat) { m_previous_pv_matrix = mat; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns the kart to which this camera is attached. */ /** Returns the kart to which this camera is attached. */

View File

@ -218,7 +218,7 @@ private:
core::array<video::IRenderTarget> m_mrt; core::array<video::IRenderTarget> m_mrt;
/** Matrixes used in several places stored here to avoid recomputation. */ /** Matrixes used in several places stored here to avoid recomputation. */
core::matrix4 m_ViewMatrix, m_InvViewMatrix, m_ProjMatrix, m_InvProjMatrix, m_ProjViewMatrix, m_previousProjViewMatrix, m_InvProjViewMatrix; core::matrix4 m_ViewMatrix, m_InvViewMatrix, m_ProjMatrix, m_InvProjMatrix, m_ProjViewMatrix, m_InvProjViewMatrix;
std::vector<video::ITexture *> SkyboxTextures; std::vector<video::ITexture *> SkyboxTextures;
std::vector<video::ITexture *> SphericalHarmonicsTextures; std::vector<video::ITexture *> SphericalHarmonicsTextures;
@ -678,8 +678,7 @@ public:
void setProjMatrix(core::matrix4 matrix) { m_ProjMatrix = matrix; matrix.getInverse(m_InvProjMatrix); } void setProjMatrix(core::matrix4 matrix) { m_ProjMatrix = matrix; matrix.getInverse(m_InvProjMatrix); }
const core::matrix4 &getProjMatrix() const { return m_ProjMatrix; } const core::matrix4 &getProjMatrix() const { return m_ProjMatrix; }
const core::matrix4 &getInvProjMatrix() const { return m_InvProjMatrix; } const core::matrix4 &getInvProjMatrix() const { return m_InvProjMatrix; }
void genProjViewMatrix() { m_previousProjViewMatrix = m_ProjViewMatrix; m_ProjViewMatrix = m_ProjMatrix * m_ViewMatrix; m_InvProjViewMatrix = m_ProjViewMatrix; m_InvProjViewMatrix.makeInverse(); } void genProjViewMatrix() { m_ProjViewMatrix = m_ProjMatrix * m_ViewMatrix; m_InvProjViewMatrix = m_ProjViewMatrix; m_InvProjViewMatrix.makeInverse(); }
const core::matrix4 & getPreviousPVMatrix() { return m_previousProjViewMatrix; }
const core::matrix4 &getProjViewMatrix() const { return m_ProjViewMatrix; } const core::matrix4 &getProjViewMatrix() const { return m_ProjViewMatrix; }
const core::matrix4 &getInvProjViewMatrix() const { return m_InvProjViewMatrix; } const core::matrix4 &getInvProjViewMatrix() const { return m_InvProjViewMatrix; }
const core::vector2df &getCurrentScreenSize() const { return m_current_screen_size; } const core::vector2df &getCurrentScreenSize() const { return m_current_screen_size; }

View File

@ -520,25 +520,25 @@ void PostProcessing::renderMotionBlur(unsigned , FrameBuffer &in_fbo, FrameBuffe
{ {
MotionBlurProvider * const cb = (MotionBlurProvider *)irr_driver-> MotionBlurProvider * const cb = (MotionBlurProvider *)irr_driver->
getCallback(ES_MOTIONBLUR); getCallback(ES_MOTIONBLUR);
unsigned cam = Camera::getActiveCamera()->getIndex(); Camera *cam = Camera::getActiveCamera();
unsigned camID = cam->getIndex();
scene::ICameraSceneNode * const camnode = scene::ICameraSceneNode * const camnode = cam->getCameraSceneNode();
Camera::getCamera(cam)->getCameraSceneNode();
// Calculate the kart's Y position on screen // Calculate the kart's Y position on screen
if (Camera::getCamera(cam)->getKart()) if (cam->getKart())
{ {
const core::vector3df pos = Camera::getCamera(cam)->getKart()->getNode()->getPosition(); const core::vector3df pos = cam->getKart()->getNode()->getPosition();
float ndc[4]; float ndc[4];
core::matrix4 trans = camnode->getProjectionMatrix(); core::matrix4 trans = camnode->getProjectionMatrix();
trans *= camnode->getViewMatrix(); trans *= camnode->getViewMatrix();
trans.transformVect(ndc, pos); trans.transformVect(ndc, pos);
const float karty = (ndc[1] / ndc[3]) * 0.5f + 0.5f; const float karty = (ndc[1] / ndc[3]) * 0.5f + 0.5f;
setMotionBlurCenterY(cam, karty); setMotionBlurCenterY(camID, karty);
} }
else else
setMotionBlurCenterY(cam, 0.5f); setMotionBlurCenterY(camID, 0.5f);
out_fbo.Bind(); out_fbo.Bind();
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
@ -546,9 +546,9 @@ void PostProcessing::renderMotionBlur(unsigned , FrameBuffer &in_fbo, FrameBuffe
FullScreenShader::MotionBlurShader::getInstance()->SetTextureUnits(in_fbo.getRTT()[0], irr_driver->getDepthStencilTexture()); FullScreenShader::MotionBlurShader::getInstance()->SetTextureUnits(in_fbo.getRTT()[0], irr_driver->getDepthStencilTexture());
DrawFullScreenEffect<FullScreenShader::MotionBlurShader>( DrawFullScreenEffect<FullScreenShader::MotionBlurShader>(
// Todo : use a previousPVMatrix per cam, not global // Todo : use a previousPVMatrix per cam, not global
irr_driver->getPreviousPVMatrix(), cam->getPreviousPVMatrix(),
core::vector2df(0.5, 0.5), core::vector2df(0.5, 0.5),
cb->getBoostTime(Camera::getActiveCamera()->getIndex()) * 10, // Todo : should be framerate dependent cb->getBoostTime(cam->getIndex()) * 10, // Todo : should be framerate dependent
0.15f); 0.15f);
} }
@ -730,7 +730,7 @@ FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode, boo
// Downsample // Downsample
FrameBuffer::Blit(irr_driver->getFBO(FBO_BLOOM_512), irr_driver->getFBO(FBO_BLOOM_256), GL_COLOR_BUFFER_BIT, GL_LINEAR); FrameBuffer::Blit(irr_driver->getFBO(FBO_BLOOM_512), irr_driver->getFBO(FBO_BLOOM_256), GL_COLOR_BUFFER_BIT, GL_LINEAR);
FrameBuffer::Blit(irr_driver->getFBO(FBO_BLOOM_256), irr_driver->getFBO(FBO_BLOOM_128), GL_COLOR_BUFFER_BIT, GL_LINEAR); FrameBuffer::Blit(irr_driver->getFBO(FBO_BLOOM_256), irr_driver->getFBO(FBO_BLOOM_128), GL_COLOR_BUFFER_BIT, GL_LINEAR);
// Copy for lens flare // Copy for lens flare
FrameBuffer::Blit(irr_driver->getFBO(FBO_BLOOM_512), irr_driver->getFBO(FBO_LENS_512), GL_COLOR_BUFFER_BIT, GL_LINEAR); FrameBuffer::Blit(irr_driver->getFBO(FBO_BLOOM_512), irr_driver->getFBO(FBO_LENS_512), GL_COLOR_BUFFER_BIT, GL_LINEAR);
FrameBuffer::Blit(irr_driver->getFBO(FBO_BLOOM_256), irr_driver->getFBO(FBO_LENS_256), GL_COLOR_BUFFER_BIT, GL_LINEAR); FrameBuffer::Blit(irr_driver->getFBO(FBO_BLOOM_256), irr_driver->getFBO(FBO_LENS_256), GL_COLOR_BUFFER_BIT, GL_LINEAR);

View File

@ -276,6 +276,8 @@ void IrrDriver::renderGLSL(float dt)
glDisable(GL_FRAMEBUFFER_SRGB); glDisable(GL_FRAMEBUFFER_SRGB);
} }
} }
// Save projection-view matrix for the next frame
camera->setPreviousPVMatrix(m_ProjViewMatrix);
PROFILER_POP_CPU_MARKER(); PROFILER_POP_CPU_MARKER();
} // for i<world->getNumKarts() } // for i<world->getNumKarts()