Properly add Depth of Field

This commit is contained in:
vlj 2014-04-23 22:08:37 +02:00
parent 22d993dfbe
commit b939d06be5
4 changed files with 128 additions and 0 deletions

72
data/shaders/dof.frag Normal file
View File

@ -0,0 +1,72 @@
uniform sampler2D tex;
uniform sampler2D dtex;
uniform mat4 invprojm;
uniform vec2 screen;
in vec2 uv;
out vec4 FragColor;
float focalDepth = 10.;
float maxblur = 1.;
float range = 100.;
void main()
{
float curdepth = texture(dtex, uv).x;
vec4 FragPos = invprojm * (2.0f * vec4(uv, curdepth, 1.0f) - 1.0f);
FragPos /= FragPos.w;
float depth = FragPos.z;
float blur = clamp(abs(depth - focalDepth) / range, -maxblur, maxblur);
vec2 offset = 10. / screen;
vec4 col = texture2D(tex, uv);
// Weight from here http://artmartinsh.blogspot.fr/2010/02/glsl-lens-blur-filter-with-bokeh.html
col += texture2D(tex, uv + (vec2(0.0, 0.4) * offset) * blur);
col += texture2D(tex, uv + (vec2(0.15, 0.37) * offset) * blur);
col += texture2D(tex, uv + (vec2(0.29,0.29) * offset) * blur);
col += texture2D(tex, uv + (vec2(-0.37,0.15) * offset) * blur);
col += texture2D(tex, uv + (vec2(0.4, 0.0) * offset) * blur);
col += texture2D(tex, uv + (vec2(0.37, -0.15) * offset) * blur);
col += texture2D(tex, uv + (vec2(0.29, -0.29) * offset) * blur);
col += texture2D(tex, uv + (vec2(-0.15, -0.37) * offset) * blur);
col += texture2D(tex, uv + (vec2(0.0, -0.4) * offset) * blur);
col += texture2D(tex, uv + (vec2(-0.15, 0.37) * offset) * blur);
col += texture2D(tex, uv + (vec2(-0.29, 0.29) * offset) * blur);
col += texture2D(tex, uv + (vec2(0.37, 0.15) * offset) * blur);
col += texture2D(tex, uv + (vec2(-0.4, 0.0) * offset) * blur);
col += texture2D(tex, uv + (vec2(-0.37, -0.15) * offset) * blur);
col += texture2D(tex, uv + (vec2(-0.29, -0.29) * offset) * blur);
col += texture2D(tex, uv + (vec2(0.15, -0.37) * offset) * blur);
col += texture2D(tex, uv + (vec2(0.15, 0.37) * offset) * blur * 0.9);
col += texture2D(tex, uv + (vec2(-0.37, 0.15) * offset) * blur * 0.9);
col += texture2D(tex, uv + (vec2(0.37, -0.15) * offset) * blur * 0.9);
col += texture2D(tex, uv + (vec2(-0.15, -0.37) * offset) * blur * 0.9);
col += texture2D(tex, uv + (vec2(-0.15, 0.37) * offset) * blur * 0.9);
col += texture2D(tex, uv + (vec2(0.37, 0.15) * offset) * blur * 0.9);
col += texture2D(tex, uv + (vec2(-0.37, -0.15) * offset) * blur * 0.9);
col += texture2D(tex, uv + (vec2(0.15, -0.37) * offset) * blur * 0.9);
col += texture2D(tex, uv + (vec2(0.29, 0.29) * offset) * blur * 0.7);
col += texture2D(tex, uv + (vec2(0.4, 0.0) * offset) * blur * 0.7);
col += texture2D(tex, uv + (vec2(0.29, -0.29) * offset) * blur * 0.7);
col += texture2D(tex, uv + (vec2(0.0, -0.4) * offset) * blur * 0.7);
col += texture2D(tex, uv + (vec2(-0.29, 0.29) * offset) * blur * 0.7);
col += texture2D(tex, uv + (vec2(-0.4, 0.0) * offset) * blur * 0.7);
col += texture2D(tex, uv + (vec2(-0.29, -0.29) * offset) * blur * 0.7);
col += texture2D(tex, uv + (vec2(0.0, 0.4) * offset) * blur *0.7);
col += texture2D(tex, uv + (vec2(0.29, 0.29) * offset) * blur * 0.4);
col += texture2D(tex, uv + (vec2(0.4, 0.0) * offset) * blur * 0.4);
col += texture2D(tex, uv + (vec2(0.29, -0.29) * offset) * blur * 0.4);
col += texture2D(tex, uv + (vec2(0.0, -0.4) * offset) * blur * 0.4);
col += texture2D(tex, uv + (vec2(-0.29, 0.29) * offset) * blur * 0.4);
col += texture2D(tex, uv + (vec2(-0.4, 0.0) * offset) * blur * 0.4);
col += texture2D(tex, uv + (vec2(-0.29, -0.29) * offset) * blur * 0.4);
col += texture2D(tex, uv + (vec2(0.0, 0.4) * offset) * blur * 0.4);
FragColor = vec4(col.xyz / 41.0, 1.);
}

View File

@ -535,6 +535,19 @@ static void toneMap(GLuint fbo, GLuint rtt)
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
} }
static void renderDoF(GLuint fbo, GLuint rtt)
{
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glViewport(0, 0, UserConfigParams::m_width, UserConfigParams::m_height);
glUseProgram(FullScreenShader::DepthOfFieldShader::Program);
glBindVertexArray(FullScreenShader::DepthOfFieldShader::vao);
setTexture(0, rtt, GL_LINEAR, GL_LINEAR);
setTexture(1, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
FullScreenShader::DepthOfFieldShader::setUniforms(irr_driver->getInvProjMatrix(), core::vector2df(UserConfigParams::m_width, UserConfigParams::m_height), 0, 1);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
static void averageTexture(GLuint tex) static void averageTexture(GLuint tex)
{ {
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
@ -637,6 +650,10 @@ void PostProcessing::render()
glDisable(GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST);
glDisable(GL_BLEND); glDisable(GL_BLEND);
renderDoF(out_fbo, in_rtt);
std::swap(in_rtt, out_rtt);
std::swap(in_fbo, out_fbo);
PROFILER_PUSH_CPU_MARKER("- Godrays", 0xFF, 0x00, 0x00); PROFILER_PUSH_CPU_MARKER("- Godrays", 0xFF, 0x00, 0x00);
if (UserConfigParams::m_light_shaft && m_sunpixels > 30)//World::getWorld()->getTrack()->hasGodRays() && ) // god rays if (UserConfigParams::m_light_shaft && m_sunpixels > 30)//World::getWorld()->getTrack()->hasGodRays() && ) // god rays
{ {

View File

@ -298,6 +298,7 @@ void Shaders::loadShaders()
initShadowVPMUBO(); initShadowVPMUBO();
FullScreenShader::BloomBlendShader::init(); FullScreenShader::BloomBlendShader::init();
FullScreenShader::BloomShader::init(); FullScreenShader::BloomShader::init();
FullScreenShader::DepthOfFieldShader::init();
FullScreenShader::ColorLevelShader::init(); FullScreenShader::ColorLevelShader::init();
FullScreenShader::FogShader::init(); FullScreenShader::FogShader::init();
FullScreenShader::Gaussian3HBlurShader::init(); FullScreenShader::Gaussian3HBlurShader::init();
@ -2088,6 +2089,33 @@ namespace FullScreenShader
glUniform1i(uniform_logluminancetex, TU_loglum); glUniform1i(uniform_logluminancetex, TU_loglum);
} }
GLuint DepthOfFieldShader::Program;
GLuint DepthOfFieldShader::uniform_tex;
GLuint DepthOfFieldShader::uniform_depth;
GLuint DepthOfFieldShader::uniform_invproj;
GLuint DepthOfFieldShader::uniform_screen;
GLuint DepthOfFieldShader::vao;
void DepthOfFieldShader::init()
{
Program = LoadProgram(
GL_VERTEX_SHADER, file_manager->getAsset("shaders/screenquad.vert").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/dof.frag").c_str());
uniform_tex = glGetUniformLocation(Program, "tex");
uniform_depth = glGetUniformLocation(Program, "dtex");
uniform_screen = glGetUniformLocation(Program, "screen");
uniform_invproj = glGetUniformLocation(Program, "invprojm");
vao = createVAO(Program);
}
void DepthOfFieldShader::setUniforms(const core::matrix4 &invproj, const core::vector2df &screen, unsigned TU_tex, unsigned TU_dtex)
{
glUniformMatrix4fv(uniform_invproj, 1, GL_FALSE, invproj.pointer());
glUniform2f(uniform_screen, screen.X, screen.Y);
glUniform1i(uniform_tex, TU_tex);
glUniform1i(uniform_depth, TU_dtex);
}
GLuint ColorLevelShader::Program; GLuint ColorLevelShader::Program;
GLuint ColorLevelShader::uniform_tex; GLuint ColorLevelShader::uniform_tex;
GLuint ColorLevelShader::uniform_inlevel; GLuint ColorLevelShader::uniform_inlevel;

View File

@ -531,6 +531,17 @@ public:
static void setUniforms(unsigned TU_tex, unsigned TU_logluminance); static void setUniforms(unsigned TU_tex, unsigned TU_logluminance);
}; };
class DepthOfFieldShader
{
public:
static GLuint Program;
static GLuint uniform_tex, uniform_depth, uniform_screen, uniform_invproj;
static GLuint vao;
static void init();
static void setUniforms(const core::matrix4 &invproj, const core::vector2df &screen, unsigned TU_tex, unsigned TU_depth);
};
class ColorLevelShader class ColorLevelShader
{ {
public: public: