Merge branch 'tonemap'

Conflicts:
	data/shaders/tonemap.frag
This commit is contained in:
vlj 2014-04-23 18:20:30 +02:00
commit 22d993dfbe
9 changed files with 112 additions and 120 deletions

View File

@ -9,7 +9,6 @@ void main()
{
vec3 weight = vec3(0.2125f, 0.7154f, 0.0721f);
vec3 col = texture(tex, uv).xyz;
// TODO: Investigate why color buffer has negative value sometimes
float luma = max(dot(col, weight), 0.);
float luma = dot(col, weight);
FragColor = vec4(log(luma + delta));
}

View File

@ -1,31 +1,24 @@
uniform sampler2D normalMap;
uniform sampler2D DiffuseForAlpha;
#if __VERSION__ >= 130
in vec3 tangent;
in vec3 bitangent;
in vec2 uv;
out vec3 EncodedNormal;
#else
varying vec3 tangent;
varying vec3 bitangent;
varying vec2 uv;
#define EncodedNormal gl_FragColor.xy
#endif
vec2 EncodeNormal(vec3 n);
void main()
{
// normal in Tangent Space
vec3 TS_normal = 2.0 * texture(normalMap, uv).rgb - 1.0;
// Because of interpolation, we need to renormalize
vec3 Frag_tangent = normalize(tangent);
vec3 Frag_normal = normalize(cross(Frag_tangent, bitangent));
vec3 Frag_bitangent = cross(Frag_normal, Frag_tangent);
// normal in Tangent Space
vec3 TS_normal = 2.0 * texture(normalMap, uv).rgb - 1.0;
float alpha = texture(DiffuseForAlpha, uv).a;
// Because of interpolation, we need to renormalize
vec3 Frag_tangent = normalize(tangent);
vec3 Frag_normal = normalize(cross(Frag_tangent, bitangent));
vec3 Frag_bitangent = cross(Frag_normal, Frag_tangent);
vec3 FragmentNormal = TS_normal.x * Frag_tangent + TS_normal.y * Frag_bitangent - TS_normal.z * Frag_normal;
EncodedNormal.xy = 0.5 * EncodeNormal(normalize(FragmentNormal)) + 0.5;
EncodedNormal.z = 1.;
vec3 FragmentNormal = TS_normal.x * Frag_tangent + TS_normal.y * Frag_bitangent - TS_normal.z * Frag_normal;
EncodedNormal.xy = 0.5 * EncodeNormal(normalize(FragmentNormal)) + 0.5;
EncodedNormal.z = exp2(10. * (1. - alpha) + 1.);
}

View File

@ -66,5 +66,5 @@ void main(void)
bl += isOccluded ? samplePoints[i].z * smoothstep(5 * radius, 0, distance(samplePos, FragPos)) : 0.;
}
AO = 1.0 - bl * invSamples;
AO = max(1.0 - bl * invSamples, 0.);
}

View File

@ -1,4 +1,4 @@
#define AUTO_EXPOSURE
// From http://www.ceng.metu.edu.tr/~akyuz/files/hdrgpu.pdf
uniform sampler2D tex;
uniform sampler2D logluminancetex;
@ -9,19 +9,23 @@ out vec4 FragColor;
vec3 getCIEYxy(vec3 rgbColor);
vec3 getRGBFromCIEXxy(vec3 YxyColor);
float exposure = .2;
float whitePoint = 10.;
float exposure = .09;
float Lwhite = 1.;
float delta = .0001;
float saturation = 1.;
void main()
{
vec4 col = texture(tex, uv);
float avgLuminance = textureLod(logluminancetex, uv, 10.).x;
avgLuminance = max(exp(avgLuminance) - delta, delta);
float avgLw = textureLod(logluminancetex, uv, 10.).x;
avgLw = max(exp(avgLw) - delta, delta);
vec3 Yxy = getCIEYxy(col.xyz);
float Lp = Yxy.r * exposure / avgLuminance;
Yxy.r = (Lp * (1. + Lp / (whitePoint * whitePoint))) / (1. + Lp);
FragColor = vec4(getRGBFromCIEXxy(Yxy), 1.);
vec3 Cw = getCIEYxy(col.xyz);
float Lw = Cw.y;
float L = Lw * exposure / avgLw;
float Ld = L * (1. + L / (Lwhite * Lwhite));
Ld /= (1. + L);
FragColor = vec4(Ld * pow(col.xyz / Lw, vec3(saturation)), 1.);
}

View File

@ -3,15 +3,10 @@
vec3 getCIEYxy(vec3 rgbColor)
{
// convert rgb to srgb
vec3 sRGBColor = rgbColor;//vec3(pow(rgbColor.x, 1. / 2.2), pow(rgbColor.y, 1. / 2.2), pow(rgbColor.z, 1. / 2.2));
mat3 sRGB2XYZ = transpose(mat3(
vec3(.4125, .2126, .0193),
vec3(.3576, .7152, .1192),
vec3(.1805, .0722, .9505)));
vec3 XYZ = sRGB2XYZ * sRGBColor;
float sum = dot(vec3(1.), XYZ);
return vec3(XYZ.y, XYZ.xy / sum);
}
return sRGB2XYZ * rgbColor;
}

View File

@ -637,10 +637,77 @@ void PostProcessing::render()
glDisable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
computeLogLuminance(in_rtt);
toneMap(out_fbo, in_rtt);
std::swap(in_rtt, out_rtt);
std::swap(in_fbo, out_fbo);
PROFILER_PUSH_CPU_MARKER("- Godrays", 0xFF, 0x00, 0x00);
if (UserConfigParams::m_light_shaft && m_sunpixels > 30)//World::getWorld()->getTrack()->hasGodRays() && ) // god rays
{
glEnable(GL_DEPTH_TEST);
// Grab the sky
glBindFramebuffer(GL_FRAMEBUFFER, out_fbo);
glClear(GL_COLOR_BUFFER_BIT);
irr_driver->renderSkybox();
// Set the sun's color
const SColor col = World::getWorld()->getTrack()->getSunColor();
ColorizeProvider * const colcb = (ColorizeProvider *)irr_driver->getCallback(ES_COLORIZE);
colcb->setColor(col.getRed() / 255.0f, col.getGreen() / 255.0f, col.getBlue() / 255.0f);
// The sun interposer
STKMeshSceneNode *sun = irr_driver->getSunInterposer();
irr_driver->getSceneManager()->drawAll(ESNRP_CAMERA);
irr_driver->setPhase(GLOW_PASS);
sun->render();
glDisable(GL_DEPTH_TEST);
// Fade to quarter
glBindFramebuffer(GL_FRAMEBUFFER, irr_driver->getFBO(FBO_QUARTER1));
glViewport(0, 0, UserConfigParams::m_width / 4, UserConfigParams::m_height / 4);
renderGodFade(out_rtt, col);
// Blur
renderGaussian3Blur(irr_driver->getFBO(FBO_QUARTER1), irr_driver->getRenderTargetTexture(RTT_QUARTER1),
irr_driver->getFBO(FBO_QUARTER2), irr_driver->getRenderTargetTexture(RTT_QUARTER2),
UserConfigParams::m_width / 4,
UserConfigParams::m_height / 4);
// Calculate the sun's position in texcoords
const core::vector3df pos = sun->getPosition();
float ndc[4];
core::matrix4 trans = camnode->getProjectionMatrix();
trans *= camnode->getViewMatrix();
trans.transformVect(ndc, pos);
const float texh = m_vertices[cam].v1.TCoords.Y - m_vertices[cam].v0.TCoords.Y;
const float texw = m_vertices[cam].v3.TCoords.X - m_vertices[cam].v0.TCoords.X;
const float sunx = ((ndc[0] / ndc[3]) * 0.5f + 0.5f) * texw;
const float suny = ((ndc[1] / ndc[3]) * 0.5f + 0.5f) * texh;
// Rays please
glBindFramebuffer(GL_FRAMEBUFFER, irr_driver->getFBO(FBO_QUARTER2));
renderGodRay(irr_driver->getRenderTargetTexture(RTT_QUARTER1), core::vector2df(sunx, suny));
// Blur
renderGaussian3Blur(irr_driver->getFBO(FBO_QUARTER2), irr_driver->getRenderTargetTexture(RTT_QUARTER2),
irr_driver->getFBO(FBO_QUARTER1), irr_driver->getRenderTargetTexture(RTT_QUARTER1),
UserConfigParams::m_width / 4,
UserConfigParams::m_height / 4);
glViewport(0, 0, UserConfigParams::m_width, UserConfigParams::m_height);
// Blend
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE);
glBlendEquation(GL_FUNC_ADD);
glBindFramebuffer(GL_FRAMEBUFFER, in_fbo);
renderPassThrough(irr_driver->getRenderTargetTexture(RTT_QUARTER2));
glDisable(GL_BLEND);
}
PROFILER_POP_CPU_MARKER();
// Simulate camera defects from there
PROFILER_PUSH_CPU_MARKER("- Bloom", 0xFF, 0x00, 0x00);
if (UserConfigParams::m_bloom)
@ -696,78 +763,12 @@ void PostProcessing::render()
renderPassThrough(irr_driver->getRenderTargetTexture(RTT_BLOOM_512));
glDisable(GL_BLEND);
} // end if bloom
PROFILER_POP_CPU_MARKER();
PROFILER_PUSH_CPU_MARKER("- Godrays", 0xFF, 0x00, 0x00);
if (UserConfigParams::m_light_shaft && m_sunpixels > 30)//World::getWorld()->getTrack()->hasGodRays() && ) // god rays
{
glEnable(GL_DEPTH_TEST);
// Grab the sky
glBindFramebuffer(GL_FRAMEBUFFER, out_fbo);
glClear(GL_COLOR_BUFFER_BIT);
irr_driver->renderSkybox();
// Set the sun's color
const SColor col = World::getWorld()->getTrack()->getSunColor();
ColorizeProvider * const colcb = (ColorizeProvider *) irr_driver->getCallback(ES_COLORIZE);
colcb->setColor(col.getRed() / 255.0f, col.getGreen() / 255.0f, col.getBlue() / 255.0f);
// The sun interposer
STKMeshSceneNode *sun = irr_driver->getSunInterposer();
irr_driver->getSceneManager()->drawAll(ESNRP_CAMERA);
irr_driver->setPhase(GLOW_PASS);
sun->render();
glDisable(GL_DEPTH_TEST);
// Fade to quarter
glBindFramebuffer(GL_FRAMEBUFFER, irr_driver->getFBO(FBO_QUARTER1));
glViewport(0, 0, UserConfigParams::m_width / 4, UserConfigParams::m_height / 4);
renderGodFade(out_rtt, col);
// Blur
renderGaussian3Blur(irr_driver->getFBO(FBO_QUARTER1), irr_driver->getRenderTargetTexture(RTT_QUARTER1),
irr_driver->getFBO(FBO_QUARTER2), irr_driver->getRenderTargetTexture(RTT_QUARTER2),
UserConfigParams::m_width / 4,
UserConfigParams::m_height / 4);
// Calculate the sun's position in texcoords
const core::vector3df pos = sun->getPosition();
float ndc[4];
core::matrix4 trans = camnode->getProjectionMatrix();
trans *= camnode->getViewMatrix();
trans.transformVect(ndc, pos);
const float texh = m_vertices[cam].v1.TCoords.Y - m_vertices[cam].v0.TCoords.Y;
const float texw = m_vertices[cam].v3.TCoords.X - m_vertices[cam].v0.TCoords.X;
const float sunx = ((ndc[0] / ndc[3]) * 0.5f + 0.5f) * texw;
const float suny = ((ndc[1] / ndc[3]) * 0.5f + 0.5f) * texh;
// Rays please
glBindFramebuffer(GL_FRAMEBUFFER, irr_driver->getFBO(FBO_QUARTER2));
renderGodRay(irr_driver->getRenderTargetTexture(RTT_QUARTER1), core::vector2df(sunx, suny));
// Blur
renderGaussian3Blur(irr_driver->getFBO(FBO_QUARTER2), irr_driver->getRenderTargetTexture(RTT_QUARTER2),
irr_driver->getFBO(FBO_QUARTER1), irr_driver->getRenderTargetTexture(RTT_QUARTER1),
UserConfigParams::m_width / 4,
UserConfigParams::m_height / 4);
glViewport(0, 0, UserConfigParams::m_width, UserConfigParams::m_height);
// Blend
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE);
glBlendEquation(GL_FUNC_ADD);
glBindFramebuffer(GL_FRAMEBUFFER, in_fbo);
renderPassThrough(irr_driver->getRenderTargetTexture(RTT_QUARTER2));
glDisable(GL_BLEND);
}
PROFILER_POP_CPU_MARKER();
computeLogLuminance(in_rtt);
toneMap(out_fbo, in_rtt);
std::swap(in_rtt, out_rtt);
std::swap(in_fbo, out_fbo);
if (UserConfigParams::m_motionblur && m_any_boost) // motion blur
{
@ -778,11 +779,6 @@ void PostProcessing::render()
PROFILER_POP_CPU_MARKER();
}
glBindFramebuffer(GL_FRAMEBUFFER, out_fbo);
renderColorLevel(in_rtt);
std::swap(in_fbo, out_fbo);
std::swap(in_rtt, out_rtt);
if (irr_driver->getNormals())
{
glEnable(GL_FRAMEBUFFER_SRGB);

View File

@ -518,6 +518,7 @@ namespace MeshShader
GLuint NormalMapShader::uniform_MM;
GLuint NormalMapShader::uniform_IMM;
GLuint NormalMapShader::uniform_normalMap;
GLuint NormalMapShader::uniform_DiffuseForAlpha;
void NormalMapShader::init()
{
@ -532,17 +533,19 @@ namespace MeshShader
uniform_MM = glGetUniformLocation(Program, "ModelMatrix");
uniform_IMM = glGetUniformLocation(Program, "InverseModelMatrix");
uniform_normalMap = glGetUniformLocation(Program, "normalMap");
uniform_DiffuseForAlpha = glGetUniformLocation(Program, "DiffuseForAlpha");
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
}
void NormalMapShader::setUniforms(const core::matrix4 &ModelMatrix, const core::matrix4 &InverseModelMatrix, unsigned TU_normalMap)
void NormalMapShader::setUniforms(const core::matrix4 &ModelMatrix, const core::matrix4 &InverseModelMatrix, unsigned TU_normalMap, unsigned TU_uniform_DiffuseForAlpha)
{
if (UserConfigParams::m_ubo_disabled)
bypassUBO(Program);
glUniformMatrix4fv(uniform_MM, 1, GL_FALSE, ModelMatrix.pointer());
glUniformMatrix4fv(uniform_IMM, 1, GL_FALSE, InverseModelMatrix.pointer());
glUniform1i(uniform_normalMap, TU_normalMap);
glUniform1i(uniform_DiffuseForAlpha, TU_uniform_DiffuseForAlpha);
}
GLuint InstancedObjectPass1Shader::Program;

View File

@ -72,10 +72,10 @@ class NormalMapShader
public:
static GLuint Program;
static GLuint attrib_position, attrib_texcoord, attrib_tangent, attrib_bitangent;
static GLuint uniform_MM, uniform_IMM, uniform_normalMap;
static GLuint uniform_MM, uniform_IMM, uniform_normalMap, uniform_DiffuseForAlpha;
static void init();
static void setUniforms(const core::matrix4 &ModelMatrix, const core::matrix4 &InverseModelMatrix, unsigned TU_normalMap);
static void setUniforms(const core::matrix4 &ModelMatrix, const core::matrix4 &InverseModelMatrix, unsigned TU_normalMap, unsigned TU_uniform_DiffuseForAlpha);
};
class InstancedObjectPass1Shader

View File

@ -292,8 +292,10 @@ void drawNormalPass(const GLMesh &mesh, const core::matrix4 & ModelMatrix, const
assert(mesh.textures[1]);
compressTexture(mesh.textures[1], false);
setTexture(0, getTextureGLuint(mesh.textures[1]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
compressTexture(mesh.textures[0], true);
setTexture(1, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
MeshShader::NormalMapShader::setUniforms(ModelMatrix, InverseModelMatrix, 0);
MeshShader::NormalMapShader::setUniforms(ModelMatrix, InverseModelMatrix, 0, 1);
assert(mesh.vao_first_pass);
glBindVertexArray(mesh.vao_first_pass);