STKMesh: Improve displace effect.

This commit is contained in:
Vincent Lejeune 2014-03-03 23:58:01 +01:00
parent 4ac634bb11
commit e1d879a1f2
9 changed files with 93 additions and 127 deletions

View File

@ -1,4 +1,7 @@
uniform sampler2D tex;
uniform sampler2D displacement_tex;
uniform sampler2D mask_tex;
uniform sampler2D color_tex;
uniform vec2 screen;
uniform vec2 dir;
uniform vec2 dir2;
@ -19,8 +22,8 @@ const float maxlen = 0.02;
void main()
{
float horiz = texture(tex, uv + dir).x;
float vert = texture(tex, (uv.yx + dir2) * vec2(0.9)).x;
float horiz = texture(displacement_tex, uv + dir).x;
float vert = texture(displacement_tex, (uv.yx + dir2) * vec2(0.9)).x;
vec2 offset = vec2(horiz, vert);
offset *= 2.0;
@ -37,11 +40,20 @@ void main()
offset *= 50.0 * fade * maxlen;
vec4 col;
col.r = step(offset.x, 0.0) * -offset.x;
col.g = step(0.0, offset.x) * offset.x;
col.b = step(offset.y, 0.0) * -offset.y;
col.a = step(0.0, offset.y) * offset.y;
vec4 shiftval;
shiftval.r = step(offset.x, 0.0) * -offset.x;
shiftval.g = step(0.0, offset.x) * offset.x;
shiftval.b = step(offset.y, 0.0) * -offset.y;
shiftval.a = step(0.0, offset.y) * offset.y;
FragColor = col;
vec2 shift;
shift.x = -shiftval.x + shiftval.y;
shift.y = -shiftval.z + shiftval.w;
shift /= 50.;
vec2 tc = gl_FragCoord.xy / screen;
float mask = texture(mask_tex, tc + shift).x;
tc += (mask < 1.) ? vec2(0.) : shift;
FragColor = texture(color_tex, tc);
}

View File

@ -1,35 +0,0 @@
uniform sampler2D tex;
uniform sampler2D dtex;
uniform int viz;
#if __VERSION__ >= 130
in vec2 uv;
out vec4 FragColor;
#else
varying vec2 uv;
#define FragColor gl_FragColor
#endif
void main()
{
vec2 tc = uv;
vec4 shiftval = texture(dtex, tc) / vec4(50.0);
vec2 shift;
shift.x = -shiftval.x + shiftval.y;
shift.y = -shiftval.z + shiftval.w;
tc += shift;
vec4 newcol = texture(tex, tc);
if (viz < 1)
{
FragColor = newcol;
} else
{
FragColor = shiftval * vec4(50.0);
}
}

View File

@ -249,37 +249,6 @@ void renderBloomBlend(ITexture *in)
glDisable(GL_BLEND);
}
static
void renderPPDisplace(ITexture *in)
{
glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_ONE, GL_ONE);
glDisable(GL_DEPTH_TEST);
glUseProgram(FullScreenShader::PPDisplaceShader::Program);
glBindVertexArray(FullScreenShader::PPDisplaceShader::vao);
glUniform1i(FullScreenShader::PPDisplaceShader::uniform_viz, irr_driver->getDistortViz());
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, getTextureGLuint(in));
glUniform1i(FullScreenShader::PPDisplaceShader::uniform_tex, 0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, getTextureGLuint(irr_driver->getRTT(RTT_DISPLACE)));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glUniform1i(FullScreenShader::PPDisplaceShader::uniform_dtex, 1);
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);
}
static
void renderColorLevel(ITexture *in)
{
@ -820,18 +789,6 @@ void PostProcessing::render()
PROFILER_POP_CPU_MARKER();
}
if (irr_driver->getDisplacingNodes().size()) // Displacement
{
PROFILER_PUSH_CPU_MARKER("- Displacement", 0xFF, 0x00, 0x00);
drv->setRenderTarget(out, true, false);
renderPPDisplace(in);
ITexture *tmp = in;
in = out;
out = tmp;
PROFILER_POP_CPU_MARKER();
}
/* m_material.MaterialType = irr_driver->getShader(ES_RAIN);
drv->setMaterial(m_material);
static_cast<irr::video::COpenGLDriver*>(drv)->setRenderStates3DMode();*/

View File

@ -995,9 +995,8 @@ void IrrDriver::renderSkybox()
void IrrDriver::renderDisplacement(video::SOverrideMaterial &overridemat,
int cam)
{
m_video_driver->setRenderTarget(m_rtts->getRTT(RTT_DISPLACE), false, false);
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_TMP4), true, false);
irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_DISPLACE), true, false);
DisplaceProvider * const cb = (DisplaceProvider *)irr_driver->getCallback(ES_DISPLACE);
cb->update();
@ -1008,6 +1007,10 @@ void IrrDriver::renderDisplacement(video::SOverrideMaterial &overridemat,
glDisable(GL_ALPHA_TEST);
glDepthMask(GL_FALSE);
glDisable(GL_BLEND);
glClear(GL_STENCIL_BITS);
glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_ALWAYS, 1, 0xFF);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
for (int i = 0; i < displacingcount; i++)
{
@ -1018,8 +1021,8 @@ void IrrDriver::renderDisplacement(video::SOverrideMaterial &overridemat,
m_displacing[i]->render();
}
// Blur it
m_post_processing->renderGaussian3Blur(m_rtts->getRTT(RTT_DISPLACE), m_rtts->getRTT(RTT_TMP2), 1.f / UserConfigParams::m_width, 1.f / UserConfigParams::m_height);
m_video_driver->setRenderTarget(m_rtts->getRTT(RTT_COLOR), false, false);
glStencilFunc(GL_EQUAL, 1, 0xFF);
m_post_processing->renderPassThrough(m_rtts->getRTT(RTT_DISPLACE));
glDisable(GL_STENCIL_TEST);
}

View File

@ -229,7 +229,6 @@ void Shaders::loadShaders()
FullScreenShader::GlowShader::init();
FullScreenShader::PassThroughShader::init();
FullScreenShader::PointLightShader::init();
FullScreenShader::PPDisplaceShader::init();
FullScreenShader::SSAOShader::init();
FullScreenShader::SunLightShader::init();
FullScreenShader::ShadowedSunLightShader::init();
@ -255,6 +254,7 @@ void Shaders::loadShaders()
MeshShader::TransparentFogShader::init();
MeshShader::BillboardShader::init();
MeshShader::DisplaceShader::init();
MeshShader::DisplaceMaskShader::init();
MeshShader::ShadowShader::init();
MeshShader::RefShadowShader::init();
MeshShader::GrassShadowShader::init();
@ -968,15 +968,34 @@ namespace MeshShader
glUniform3f(uniform_windDir, windDirection.X, windDirection.Y, windDirection.Z);
}
GLuint DisplaceMaskShader::Program;
GLuint DisplaceMaskShader::attrib_position;
GLuint DisplaceMaskShader::uniform_MVP;
void DisplaceMaskShader::init()
{
Program = LoadProgram(file_manager->getAsset("shaders/displace.vert").c_str(), file_manager->getAsset("shaders/white.frag").c_str());
attrib_position = glGetAttribLocation(Program, "Position");
uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix");
}
void DisplaceMaskShader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix)
{
glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer());
}
GLuint DisplaceShader::Program;
GLuint DisplaceShader::attrib_position;
GLuint DisplaceShader::attrib_texcoord;
GLuint DisplaceShader::attrib_second_texcoord;
GLuint DisplaceShader::uniform_MVP;
GLuint DisplaceShader::uniform_MV;
GLuint DisplaceShader::uniform_tex;
GLuint DisplaceShader::uniform_displacement_tex;
GLuint DisplaceShader::uniform_mask_tex;
GLuint DisplaceShader::uniform_color_tex;
GLuint DisplaceShader::uniform_dir;
GLuint DisplaceShader::uniform_dir2;
GLuint DisplaceShader::uniform_screen;
void DisplaceShader::init()
{
@ -986,18 +1005,24 @@ namespace MeshShader
attrib_second_texcoord = glGetAttribLocation(Program, "SecondTexcoord");
uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix");
uniform_MV = glGetUniformLocation(Program, "ModelViewMatrix");
uniform_tex = glGetUniformLocation(Program, "tex");
uniform_displacement_tex = glGetUniformLocation(Program, "displacement_tex");
uniform_color_tex = glGetUniformLocation(Program, "color_tex");
uniform_mask_tex = glGetUniformLocation(Program, "mask_tex");
uniform_dir = glGetUniformLocation(Program, "dir");
uniform_dir2 = glGetUniformLocation(Program, "dir2");
uniform_screen = glGetUniformLocation(Program, "screen");
}
void DisplaceShader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &ModelViewMatrix, float dirX, float dirY, float dir2X, float dir2Y, unsigned TU_tex)
void DisplaceShader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &ModelViewMatrix, const core::vector2df &dir, const core::vector2df &dir2, const core::vector2df &screen, unsigned TU_displacement_tex, unsigned TU_mask_tex, unsigned TU_color_tex)
{
glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer());
glUniformMatrix4fv(uniform_MV, 1, GL_FALSE, ModelViewMatrix.pointer());
glUniform2f(uniform_dir, dirX, dirY);
glUniform2f(uniform_dir2, dir2X, dir2Y);
glUniform1i(uniform_tex, TU_tex);
glUniform2f(uniform_dir, dir.X, dir.Y);
glUniform2f(uniform_dir2, dir2.X, dir2.Y);
glUniform2f(uniform_screen, screen.X, screen.Y);
glUniform1i(uniform_displacement_tex, TU_displacement_tex);
glUniform1i(uniform_mask_tex, TU_mask_tex);
glUniform1i(uniform_color_tex, TU_color_tex);
}
GLuint SkyboxShader::Program;
@ -1245,20 +1270,6 @@ namespace FullScreenShader
vao = createVAO(Program);
}
GLuint PPDisplaceShader::Program;
GLuint PPDisplaceShader::uniform_tex;
GLuint PPDisplaceShader::uniform_dtex;
GLuint PPDisplaceShader::uniform_viz;
GLuint PPDisplaceShader::vao;
void PPDisplaceShader::init()
{
Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/ppdisplace.frag").c_str());
uniform_tex = glGetUniformLocation(Program, "tex");
uniform_dtex = glGetUniformLocation(Program, "dtex");
uniform_viz = glGetUniformLocation(Program, "viz");
vao = createVAO(Program);
}
GLuint ColorLevelShader::Program;
GLuint ColorLevelShader::uniform_tex;
GLuint ColorLevelShader::uniform_inlevel;

View File

@ -258,15 +258,26 @@ public:
static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::vector3df &windDirection, unsigned TU_tex);
};
class DisplaceMaskShader
{
public:
static GLuint Program;
static GLuint attrib_position;
static GLuint uniform_MVP;
static void init();
static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix);
};
class DisplaceShader
{
public:
static GLuint Program;
static GLuint attrib_position, attrib_texcoord, attrib_second_texcoord;
static GLuint uniform_MVP, uniform_MV, uniform_tex, uniform_dir, uniform_dir2;
static GLuint uniform_MVP, uniform_MV, uniform_displacement_tex, uniform_mask_tex, uniform_color_tex, uniform_screen, uniform_dir, uniform_dir2;
static void init();
static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &ModelViewMatrix, float dirX, float dirY, float dir2X, float dir2Y, unsigned TU_tex);
static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &ModelViewMatrix, const core::vector2df &dir, const core::vector2df &dir2, const core::vector2df &screen, unsigned TU_displacement_tex, unsigned TU_mask_tex, unsigned TU_color_tex);
};
class SkyboxShader
@ -354,16 +365,6 @@ public:
static void init();
};
class PPDisplaceShader
{
public:
static GLuint Program;
static GLuint uniform_tex, uniform_dtex, uniform_viz;
static GLuint vao;
static void init();
};
class ColorLevelShader
{
public:

View File

@ -738,6 +738,7 @@ void initvaostate(GLMesh &mesh, video::E_MATERIAL_TYPE type)
case DISPLACEMENT_PASS:
if (mesh.vao_displace_pass)
return;
mesh.vao_displace_mask_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::DisplaceShader::attrib_position,-1, -1, -1, -1, -1, -1, mesh.Stride);
mesh.vao_displace_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::DisplaceShader::attrib_position, MeshShader::DisplaceShader::attrib_texcoord, MeshShader::DisplaceShader::attrib_second_texcoord, -1, -1, -1, -1, mesh.Stride);
return;
case SHADOW_PASS:

View File

@ -13,6 +13,7 @@ struct GLMesh {
GLuint vao_second_pass;
GLuint vao_glow_pass;
GLuint vao_displace_pass;
GLuint vao_displace_mask_pass;
GLuint vao_shadow_pass;
GLuint vertex_buffer;
GLuint index_buffer;

View File

@ -104,9 +104,24 @@ void STKMeshSceneNode::drawDisplace(const GLMesh &mesh)
computeMVP(ModelViewProjectionMatrix);
core::matrix4 ModelViewMatrix = irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW);
ModelViewMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD);
// Generate displace mask
// Use RTT_TMP4 as displace mask
irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_TMP4), false, false);
glUseProgram(MeshShader::DisplaceMaskShader::Program);
MeshShader::DisplaceMaskShader::setUniforms(ModelViewProjectionMatrix);
glBindVertexArray(mesh.vao_displace_mask_pass);
glDrawElements(ptype, count, itype, 0);
// Render the effect
irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_DISPLACE), false, false);
setTexture(0, getTextureGLuint(irr_driver->getTexture(FileManager::TEXTURE, "displace.png")), GL_LINEAR, GL_LINEAR, true);
setTexture(1, getTextureGLuint(irr_driver->getRTT(RTT_TMP4)), GL_LINEAR, GL_LINEAR, true);
setTexture(2, getTextureGLuint(irr_driver->getRTT(RTT_COLOR)), GL_LINEAR, GL_LINEAR, true);
glUseProgram(MeshShader::DisplaceShader::Program);
MeshShader::DisplaceShader::setUniforms(ModelViewProjectionMatrix, ModelViewMatrix, cb->getDirX(), cb->getDirY(), cb->getDir2X(), cb->getDir2Y(), 0);
MeshShader::DisplaceShader::setUniforms(ModelViewProjectionMatrix, ModelViewMatrix, core::vector2df(cb->getDirX(), cb->getDirY()), core::vector2df(cb->getDir2X(), cb->getDir2Y()), core::vector2df(UserConfigParams::m_width, UserConfigParams::m_height), 0, 1, 2);
glBindVertexArray(mesh.vao_displace_pass);
glDrawElements(ptype, count, itype, 0);