diff --git a/data/shaders/mlaa_blend2.frag b/data/shaders/mlaa_blend2.frag index 9514f2e2a..66392a439 100644 --- a/data/shaders/mlaa_blend2.frag +++ b/data/shaders/mlaa_blend2.frag @@ -1,14 +1,11 @@ -#version 330 compatibility -#define MAX_SEARCH_STEPS 8.0 -#define MAX_DISTANCE 33.0 - -#extension GL_ARB_shader_texture_lod: enable - uniform sampler2D edgesMap; uniform sampler2D areaMap; uniform vec2 PIXEL_SIZE; +#define MAX_SEARCH_STEPS 8.0 +#define MAX_DISTANCE 33.0 + out vec4 FragColor; /** @@ -17,7 +14,7 @@ out vec4 FragColor; * bit. */ vec4 tex2Doffset(sampler2D map, vec2 texcoord, vec2 offset) { - return texture2DLod(map, texcoord + PIXEL_SIZE * offset, 0.0); + return textureLod(map, texcoord + PIXEL_SIZE * offset, 0.0); } float SearchXLeft(vec2 texcoord) { diff --git a/data/shaders/mlaa_color1.frag b/data/shaders/mlaa_color1.frag index 0b8a80141..661acf486 100644 --- a/data/shaders/mlaa_color1.frag +++ b/data/shaders/mlaa_color1.frag @@ -1,8 +1,8 @@ -#version 330 compatibility +uniform sampler2D colorMapG; + in vec4 offset[2]; in vec2 uv; -uniform sampler2D colorMapG; const float threshold = 0.1; out vec4 FragColor; @@ -22,8 +22,8 @@ void main() { vec4 delta = abs(vec4(L) - vec4(Lleft, Ltop, Lright, Lbottom)); vec4 edges = step(vec4(threshold), delta); - if (dot(edges, vec4(1.0)) == 0.0) - discard; +// if (dot(edges, vec4(1.0)) == 0.0) +// discard; FragColor = edges; } diff --git a/data/shaders/mlaa_neigh3.frag b/data/shaders/mlaa_neigh3.frag index 68929c321..8217d28cd 100644 --- a/data/shaders/mlaa_neigh3.frag +++ b/data/shaders/mlaa_neigh3.frag @@ -1,11 +1,11 @@ -#version 330 compatibility -in vec4 offset[2]; -in vec2 uv; -out vec4 FragColor; - uniform sampler2D blendMap; uniform sampler2D colorMap; +in vec4 offset[2]; +in vec2 uv; + +out vec4 FragColor; + void main() { // Fetch the blending weights for current pixel: vec4 topLeft = texture(blendMap, uv); diff --git a/data/shaders/mlaa_offset.vert b/data/shaders/mlaa_offset.vert index d1c36cd99..22f24c523 100644 --- a/data/shaders/mlaa_offset.vert +++ b/data/shaders/mlaa_offset.vert @@ -1,13 +1,14 @@ -#version 330 compatibility uniform vec2 PIXEL_SIZE; -uniform mat4 ModelViewProjectionMatrix; + +in vec2 Position; +in vec2 Texcoord; out vec4 offset[2]; out vec2 uv; void main() { - gl_Position = ModelViewProjectionMatrix * gl_Vertex; - vec4 invy = gl_MultiTexCoord0; + gl_Position = vec4(Position, 0., 1.); + vec4 invy = vec4(Texcoord, Texcoord); // invy.y = 1.0 - invy.y; uv = invy.st; diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index ffeb61315..1d04e17f2 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -627,6 +627,54 @@ static void computeLogLuminance(GLuint tex) averageTexture(getTextureGLuint(irr_driver->getRTT(RTT_LOG_LUMINANCE))); } +void PostProcessing::applyMLAA(video::ITexture *in, video::ITexture *out) +{ + const core::vector2df &PIXEL_SIZE = core::vector2df(1.0f / UserConfigParams::m_width, 1.0f / UserConfigParams::m_height); + IVideoDriver *const drv = irr_driver->getVideoDriver(); + glEnable(GL_STENCIL_TEST); + glClearColor(0.0, 0.0, 0.0, 1.0); + glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + glStencilFunc(GL_ALWAYS, 1, ~0); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + + // Pass 1: color edge detection + setTexture(0, getTextureGLuint(in), GL_NEAREST, GL_NEAREST); + glUseProgram(FullScreenShader::MLAAColorEdgeDetectionSHader::Program); + FullScreenShader::MLAAColorEdgeDetectionSHader::setUniforms(PIXEL_SIZE, 0); + + glBindVertexArray(FullScreenShader::MLAAColorEdgeDetectionSHader::vao); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + glStencilFunc(GL_EQUAL, 1, ~0); + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + + // Pass 2: blend weights + drv->setRenderTarget(irr_driver->getRTT(RTT_TMP3), true, false); + + glUseProgram(FullScreenShader::MLAABlendWeightSHader::Program); + setTexture(0, getTextureGLuint(out), GL_LINEAR, GL_LINEAR); + setTexture(1, getTextureGLuint(m_areamap), GL_NEAREST, GL_NEAREST); + FullScreenShader::MLAABlendWeightSHader::setUniforms(PIXEL_SIZE, 0, 1); + + glBindVertexArray(FullScreenShader::MLAABlendWeightSHader::vao); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + // Pass 3: gather + drv->setRenderTarget(in, false, false); + + glUseProgram(FullScreenShader::MLAAGatherSHader::Program); + setTexture(0, getTextureGLuint(irr_driver->getRTT(RTT_TMP3)), GL_NEAREST, GL_NEAREST); + setTexture(1, getTextureGLuint(irr_driver->getRTT(RTT_COLOR)), GL_NEAREST, GL_NEAREST); + FullScreenShader::MLAAGatherSHader::setUniforms(PIXEL_SIZE, 1, 0); + + glBindVertexArray(FullScreenShader::MLAAGatherSHader::vao); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + // Done. + glDisable(GL_STENCIL_TEST); + +} + // ---------------------------------------------------------------------------- /** Render the post-processed scene */ void PostProcessing::render() @@ -799,58 +847,7 @@ void PostProcessing::render() { PROFILER_PUSH_CPU_MARKER("- MLAA", 0xFF, 0x00, 0x00); drv->setRenderTarget(out, false, false); - - glEnable(GL_STENCIL_TEST); - glClearColor(0.0, 0.0, 0.0, 1.0); - glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT); - glStencilFunc(GL_ALWAYS, 1, ~0); - glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); - - // Pass 1: color edge detection - m_material.setFlag(EMF_BILINEAR_FILTER, false); - m_material.setFlag(EMF_TRILINEAR_FILTER, false); - m_material.MaterialType = irr_driver->getShader(ES_MLAA_COLOR1); - m_material.setTexture(0, in); - - drawQuad(cam, m_material); - m_material.setFlag(EMF_BILINEAR_FILTER, true); - m_material.setFlag(EMF_TRILINEAR_FILTER, true); - - glStencilFunc(GL_EQUAL, 1, ~0); - glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); - - // Pass 2: blend weights - drv->setRenderTarget(irr_driver->getRTT(RTT_TMP3), true, false); - - m_material.MaterialType = irr_driver->getShader(ES_MLAA_BLEND2); - m_material.setTexture(0, out); - m_material.setTexture(1, m_areamap); - m_material.TextureLayer[1].BilinearFilter = false; - m_material.TextureLayer[1].TrilinearFilter = false; - - drawQuad(cam, m_material); - - m_material.TextureLayer[1].BilinearFilter = true; - m_material.TextureLayer[1].TrilinearFilter = true; - m_material.setTexture(1, 0); - - // Pass 3: gather - drv->setRenderTarget(in, false, false); - - m_material.setFlag(EMF_BILINEAR_FILTER, false); - m_material.setFlag(EMF_TRILINEAR_FILTER, false); - m_material.MaterialType = irr_driver->getShader(ES_MLAA_NEIGH3); - m_material.setTexture(0, irr_driver->getRTT(RTT_TMP3)); - m_material.setTexture(1, irr_driver->getRTT(RTT_COLOR)); - - drawQuad(cam, m_material); - - m_material.setFlag(EMF_BILINEAR_FILTER, true); - m_material.setFlag(EMF_TRILINEAR_FILTER, true); - m_material.setTexture(1, 0); - - // Done. - glDisable(GL_STENCIL_TEST); + applyMLAA(in, out); PROFILER_POP_CPU_MARKER(); } diff --git a/src/graphics/post_processing.hpp b/src/graphics/post_processing.hpp index e64598864..8fc6de144 100644 --- a/src/graphics/post_processing.hpp +++ b/src/graphics/post_processing.hpp @@ -87,6 +87,7 @@ public: /** Render tex. Used for blit/texture resize */ void renderPassThrough(video::ITexture *tex); void renderPassThrough(unsigned tex); + void applyMLAA(video::ITexture *in, video::ITexture *out); void renderMotionBlur(unsigned cam, video::ITexture *in, video::ITexture *out); void renderGlow(video::ITexture *tex); diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index 40b90537b..d9a108e18 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -229,11 +229,11 @@ void Shaders::loadShaders() m_shaders[ES_SUNLIGHT] = glsl_noinput(dir + "pass.vert", dir + "pass.frag"); - m_shaders[ES_MLAA_COLOR1] = glsl(dir + "mlaa_offset.vert", dir + "mlaa_color1.frag", + m_shaders[ES_MLAA_COLOR1] = glsl(dir + "pass.vert", dir + "pass.frag", m_callbacks[ES_MLAA_COLOR1]); - m_shaders[ES_MLAA_BLEND2] = glsl(dir + "pass.vert", dir + "mlaa_blend2.frag", + m_shaders[ES_MLAA_BLEND2] = glsl(dir + "pass.vert", dir + "pass.frag", m_callbacks[ES_MLAA_BLEND2]); - m_shaders[ES_MLAA_NEIGH3] = glsl(dir + "mlaa_offset.vert", dir + "mlaa_neigh3.frag", + m_shaders[ES_MLAA_NEIGH3] = glsl(dir + "pass.vert", dir + "pass.frag", m_callbacks[ES_MLAA_NEIGH3]); m_shaders[ES_SHADOWPASS] = glsl(dir + "pass.vert", dir + "pass.frag", @@ -315,6 +315,9 @@ void Shaders::loadShaders() FullScreenShader::GodFadeShader::init(); FullScreenShader::GodRayShader::init(); FullScreenShader::LogLuminanceShader::init(); + FullScreenShader::MLAAColorEdgeDetectionSHader::init(); + FullScreenShader::MLAABlendWeightSHader::init(); + FullScreenShader::MLAAGatherSHader::init(); MeshShader::ColorizeShader::init(); MeshShader::NormalMapShader::init(); MeshShader::ObjectPass1Shader::init(); @@ -2550,6 +2553,75 @@ namespace FullScreenShader { glUniform1i(uniform_tex, TU_tex); } + + GLuint MLAAColorEdgeDetectionSHader::Program; + GLuint MLAAColorEdgeDetectionSHader::uniform_colorMapG; + GLuint MLAAColorEdgeDetectionSHader::uniform_PIXEL_SIZE; + GLuint MLAAColorEdgeDetectionSHader::vao; + + void MLAAColorEdgeDetectionSHader::init() + { + Program = LoadProgram( + GL_VERTEX_SHADER, file_manager->getAsset("shaders/mlaa_offset.vert").c_str(), + GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/mlaa_color1.frag").c_str()); + uniform_colorMapG = glGetUniformLocation(Program, "colorMapG"); + uniform_PIXEL_SIZE = glGetUniformLocation(Program, "PIXEL_SIZE"); + vao = createVAO(Program); + } + + void MLAAColorEdgeDetectionSHader::setUniforms(const core::vector2df &PIXEL_SIZE, unsigned TU_colorMapG) + { + glUniform1i(uniform_colorMapG, TU_colorMapG); + glUniform2f(uniform_PIXEL_SIZE, PIXEL_SIZE.X, PIXEL_SIZE.Y); + } + + GLuint MLAABlendWeightSHader::Program; + GLuint MLAABlendWeightSHader::uniform_edgesMap; + GLuint MLAABlendWeightSHader::uniform_areaMap; + GLuint MLAABlendWeightSHader::uniform_PIXEL_SIZE; + GLuint MLAABlendWeightSHader::vao; + + void MLAABlendWeightSHader::init() + { + Program = LoadProgram( + GL_VERTEX_SHADER, file_manager->getAsset("shaders/screenquad.vert").c_str(), + GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/mlaa_color1.frag").c_str()); + uniform_edgesMap = glGetUniformLocation(Program, "edgesMap"); + uniform_areaMap = glGetUniformLocation(Program, "areaMap"); + uniform_PIXEL_SIZE = glGetUniformLocation(Program, "PIXEL_SIZE"); + vao = createVAO(Program); + } + + void MLAABlendWeightSHader::setUniforms(const core::vector2df &PIXEL_SIZE, unsigned TU_edgesMap, unsigned TU_areaMap) + { + glUniform1i(uniform_edgesMap, TU_edgesMap); + glUniform1i(uniform_areaMap, TU_areaMap); + glUniform2f(uniform_PIXEL_SIZE, PIXEL_SIZE.X, PIXEL_SIZE.Y); + } + + GLuint MLAAGatherSHader::Program; + GLuint MLAAGatherSHader::uniform_colorMap; + GLuint MLAAGatherSHader::uniform_blendMap; + GLuint MLAAGatherSHader::uniform_PIXEL_SIZE; + GLuint MLAAGatherSHader::vao; + + void MLAAGatherSHader::init() + { + Program = LoadProgram( + GL_VERTEX_SHADER, file_manager->getAsset("shaders/mlaa_offset.vert").c_str(), + GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/mlaa_neigh3.frag").c_str()); + uniform_colorMap = glGetUniformLocation(Program, "colorMap"); + uniform_blendMap = glGetUniformLocation(Program, "blendMap"); + uniform_PIXEL_SIZE = glGetUniformLocation(Program, "PIXEL_SIZE"); + vao = createVAO(Program); + } + + void MLAAGatherSHader::setUniforms(const core::vector2df &PIXEL_SIZE, unsigned TU_colormap, unsigned TU_blendmap) + { + glUniform1i(uniform_colorMap, TU_colormap); + glUniform1i(uniform_blendMap, TU_blendmap); + glUniform2f(uniform_PIXEL_SIZE, PIXEL_SIZE.X, PIXEL_SIZE.Y); + } } namespace UIShader diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index f4dd33a5c..6e36e76cd 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -723,6 +723,41 @@ public: static void setUniforms(unsigned TU_tex); }; +class MLAAColorEdgeDetectionSHader +{ +public: + static GLuint Program; + static GLuint uniform_colorMapG, uniform_PIXEL_SIZE; + static GLuint vao; + + static void init(); + static void setUniforms(const core::vector2df &PIXEL_SIZE, unsigned TU_colorMapG); +}; + +class MLAABlendWeightSHader +{ +public: + static GLuint Program; + static GLuint uniform_PIXEL_SIZE, uniform_edgesMap, uniform_areaMap; + + static GLuint vao; + + static void init(); + static void setUniforms(const core::vector2df &PIXEL_SIZE, unsigned TU_edgesMap, unsigned TU_areaMap); + +}; + +class MLAAGatherSHader +{ +public: + static GLuint Program; + static GLuint uniform_PIXEL_SIZE, uniform_colorMap, uniform_blendMap; + static GLuint vao; + + static void init(); + static void setUniforms(const core::vector2df &PIXEL_SIZE, unsigned TU_colormap, unsigned TU_blendmap); +}; + } namespace UIShader