MotionBlur: Use direct GL calls.

This commit is contained in:
Vincent Lejeune 2014-02-23 00:13:22 +01:00
parent 58ef59dcd9
commit a00abffb01
6 changed files with 103 additions and 20 deletions

View File

@ -17,11 +17,11 @@
// motion_blur.frag // motion_blur.frag
#version 330
// The actual boost amount (which linearly scales the blur to be shown). // The actual boost amount (which linearly scales the blur to be shown).
// should be in the range [0.0, 1.0], though a larger value might make // should be in the range [0.0, 1.0], though a larger value might make
// the blurring too string. Atm we are using [0, 0.5]. // the blurring too string. Atm we are using [0, 0.5].
#version 330 compatibility
uniform float boost_amount; uniform float boost_amount;
// The color buffer to use. // The color buffer to use.
@ -41,6 +41,7 @@ uniform float mask_radius;
// Maximum height of texture used // Maximum height of texture used
uniform float max_tex_height; uniform float max_tex_height;
in vec2 uv;
out vec4 FragColor; out vec4 FragColor;
// Number of samples used for blurring // Number of samples used for blurring
@ -48,7 +49,7 @@ out vec4 FragColor;
void main() void main()
{ {
vec2 texcoords = gl_TexCoord[0].st; vec2 texcoords = uv;
// Sample the color buffer // Sample the color buffer
vec3 color = texture(color_buffer, texcoords).rgb; vec3 color = texture(color_buffer, texcoords).rgb;

View File

@ -229,12 +229,22 @@ public:
m_maxheight[who] = height; m_maxheight[who] = height;
} }
float getMaxHeight(u32 who) const
{
return m_maxheight[who];
}
void setBoostTime(u32 who, float time) void setBoostTime(u32 who, float time)
{ {
assert(who < MAX_PLAYER_COUNT); assert(who < MAX_PLAYER_COUNT);
m_boost_time[who] = time; m_boost_time[who] = time;
} }
float getBoostTime(u32 who) const
{
return m_boost_time[who];
}
void setCenter(u32 who, float X, float Y) void setCenter(u32 who, float X, float Y)
{ {
assert(who < MAX_PLAYER_COUNT); assert(who < MAX_PLAYER_COUNT);
@ -242,6 +252,11 @@ public:
m_center[who].Y = Y; m_center[who].Y = Y;
} }
core::vector2df getCenter(u32 who) const
{
return core::vector2df(m_center[who].X, m_center[who].Y);
}
void setDirection(u32 who, float X, float Y) void setDirection(u32 who, float X, float Y)
{ {
assert(who < MAX_PLAYER_COUNT); assert(who < MAX_PLAYER_COUNT);
@ -249,6 +264,11 @@ public:
m_direction[who].Y = Y; m_direction[who].Y = Y;
} }
core::vector2df getDirection(u32 who) const
{
return core::vector2df(m_direction[who].X, m_direction[who].Y);
}
void setCurrentCamera(u32 who) void setCurrentCamera(u32 who)
{ {
m_current_camera = who; m_current_camera = who;

View File

@ -578,6 +578,41 @@ void PostProcessing::renderFog(const core::matrix4 &ipvmat)
glDisable(GL_BLEND); glDisable(GL_BLEND);
} }
void PostProcessing::renderMotionBlur(unsigned cam, ITexture *in, ITexture *out)
{
MotionBlurProvider * const cb = (MotionBlurProvider *)irr_driver->
getCallback(ES_MOTIONBLUR);
scene::ICameraSceneNode * const camnode =
Camera::getCamera(cam)->getCameraSceneNode();
// Calculate the kart's Y position on screen
const core::vector3df pos =
Camera::getCamera(cam)->getKart()->getNode()->getPosition();
float ndc[4];
core::matrix4 trans = camnode->getProjectionMatrix();
trans *= camnode->getViewMatrix();
trans.transformVect(ndc, pos);
const float karty = (ndc[1] / ndc[3]) * 0.5f + 0.5f;
setMotionBlurCenterY(cam, karty);
irr_driver->getVideoDriver()->setRenderTarget(out, true, false);
glUseProgram(FullScreenShader::MotionBlurShader::Program);
glBindVertexArray(FullScreenShader::MotionBlurShader::vao);
setTexture(0, getTextureGLuint(in), GL_NEAREST, GL_NEAREST);
FullScreenShader::MotionBlurShader::setUniforms(cb->getBoostTime(cam), cb->getCenter(cam), cb->getDirection(cam), 0.15, cb->getMaxHeight(cam) * 0.7, 0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glEnable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/** Render the post-processed scene */ /** Render the post-processed scene */
void PostProcessing::render() void PostProcessing::render()
@ -751,24 +786,7 @@ void PostProcessing::render()
if (UserConfigParams::m_motionblur && m_any_boost) // motion blur if (UserConfigParams::m_motionblur && m_any_boost) // motion blur
{ {
PROFILER_PUSH_CPU_MARKER("- Motion blur", 0xFF, 0x00, 0x00); PROFILER_PUSH_CPU_MARKER("- Motion blur", 0xFF, 0x00, 0x00);
// Calculate the kart's Y position on screen renderMotionBlur(cam, in, out);
const core::vector3df pos =
Camera::getCamera(cam)->getKart()->getNode()->getPosition();
float ndc[4];
core::matrix4 trans = camnode->getProjectionMatrix();
trans *= camnode->getViewMatrix();
trans.transformVect(ndc, pos);
const float karty = (ndc[1] / ndc[3]) * 0.5f + 0.5f;
setMotionBlurCenterY(cam, karty);
m_material.MaterialType = irr_driver->getShader(ES_MOTIONBLUR);
m_material.setTexture(0, in);
drv->setRenderTarget(out, true, false);
drawQuad(cam, m_material);
ITexture *tmp = in; ITexture *tmp = in;
in = out; in = out;
out = tmp; out = tmp;

View File

@ -88,6 +88,7 @@ public:
void renderPassThrough(video::ITexture *tex); void renderPassThrough(video::ITexture *tex);
void renderPassThrough(unsigned tex); void renderPassThrough(unsigned tex);
void renderMotionBlur(unsigned cam, video::ITexture *in, video::ITexture *out);
void renderGlow(video::ITexture *tex); void renderGlow(video::ITexture *tex);
/** Render the post-processed scene */ /** Render the post-processed scene */

View File

@ -238,6 +238,7 @@ void Shaders::loadShaders()
FullScreenShader::SSAOShader::init(); FullScreenShader::SSAOShader::init();
FullScreenShader::SunLightShader::init(); FullScreenShader::SunLightShader::init();
FullScreenShader::ShadowedSunLightShader::init(); FullScreenShader::ShadowedSunLightShader::init();
FullScreenShader::MotionBlurShader::init();
MeshShader::ColorizeShader::init(); MeshShader::ColorizeShader::init();
MeshShader::NormalMapShader::init(); MeshShader::NormalMapShader::init();
MeshShader::ObjectPass1Shader::init(); MeshShader::ObjectPass1Shader::init();
@ -1692,6 +1693,37 @@ namespace FullScreenShader
glUniformMatrix4fv(uniform_ipvmat, 1, GL_FALSE, ipvmat.pointer()); glUniformMatrix4fv(uniform_ipvmat, 1, GL_FALSE, ipvmat.pointer());
glUniform1i(uniform_tex, TU_ntex); glUniform1i(uniform_tex, TU_ntex);
} }
GLuint MotionBlurShader::Program;
GLuint MotionBlurShader::uniform_boost_amount;
GLuint MotionBlurShader::uniform_center;
GLuint MotionBlurShader::uniform_color_buffer;
GLuint MotionBlurShader::uniform_direction;
GLuint MotionBlurShader::uniform_mask_radius;
GLuint MotionBlurShader::uniform_max_tex_height;
GLuint MotionBlurShader::vao;
void MotionBlurShader::init()
{
Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/motion_blur.frag").c_str());
uniform_boost_amount = glGetUniformLocation(Program, "boost_amount");
uniform_center = glGetUniformLocation(Program, "center");
uniform_color_buffer = glGetUniformLocation(Program, "color_buffer");
uniform_direction = glGetUniformLocation(Program, "direction");
uniform_mask_radius = glGetUniformLocation(Program, "mask_radius");
uniform_max_tex_height = glGetUniformLocation(Program, "max_tex_height");
vao = createVAO(Program);
}
void MotionBlurShader::setUniforms(float boost_amount, const core::vector2df &center, const core::vector2df &direction, float mask_radius, float max_tex_height, unsigned TU_cb)
{
glUniform1f(uniform_boost_amount, boost_amount);
glUniform2f(uniform_center, center.X, center.Y);
glUniform2f(uniform_direction, direction.X, direction.Y);
glUniform1f(uniform_mask_radius, mask_radius);
glUniform1f(uniform_max_tex_height, max_tex_height);
glUniform1i(uniform_color_buffer, TU_cb);
}
} }
namespace UIShader namespace UIShader

View File

@ -523,6 +523,17 @@ public:
static void setUniforms(const core::matrix4 &ipvmat, float fogmax, float startH, float endH, float start, float end, const core::vector3df &col, unsigned TU_ntex); static void setUniforms(const core::matrix4 &ipvmat, float fogmax, float startH, float endH, float start, float end, const core::vector3df &col, unsigned TU_ntex);
}; };
class MotionBlurShader
{
public:
static GLuint Program;
static GLuint uniform_boost_amount, uniform_color_buffer, uniform_center, uniform_direction, uniform_mask_radius, uniform_max_tex_height;
static GLuint vao;
static void init();
static void setUniforms(float boost_amount, const core::vector2df &center, const core::vector2df &direction, float mask_radius, float max_tex_height, unsigned TU_cb);
};
} }
namespace UIShader namespace UIShader