Port MLAA to new pipeline.

This commit is contained in:
Vincent Lejeune 2014-04-03 00:14:53 +02:00
parent 712d4cf84e
commit 33b44c8c97
8 changed files with 178 additions and 75 deletions

View File

@ -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) {

View File

@ -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;
}

View File

@ -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);

View File

@ -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;

View File

@ -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();
}

View File

@ -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);

View File

@ -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

View File

@ -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