diff --git a/data/shaders/bloom.frag b/data/shaders/bloom.frag index 3be3cb60f..2bccf2dfc 100644 --- a/data/shaders/bloom.frag +++ b/data/shaders/bloom.frag @@ -9,12 +9,12 @@ varying vec2 uv; #define FragColor gl_FragColor #endif +vec3 getCIEYxy(vec3 rgbColor); void main() { - vec3 weights = vec3(0.2126, 0.7152, 0.0722); // ITU-R BT. 709 vec3 col = texture(tex, uv).xyz; - float luma = dot(weights, col); + float luma = getCIEYxy(col).x; col *= smoothstep(1., 2., luma); diff --git a/data/shaders/color_levels.frag b/data/shaders/color_levels.frag index 6dbbf69b7..d1758d762 100644 --- a/data/shaders/color_levels.frag +++ b/data/shaders/color_levels.frag @@ -204,11 +204,15 @@ void main() #else + +//#define AUTO_EXPOSURE + uniform sampler2D tex; uniform sampler2D dtex; uniform vec3 inlevel; uniform vec2 outlevel; uniform mat4 invprojm; +uniform sampler2D logluminancetex; #if __VERSION__ >= 130 in vec2 uv; @@ -218,11 +222,26 @@ varying vec2 uv; #define FragColor gl_FragColor #endif +vec3 getCIEYxy(vec3 rgbColor); +vec3 getRGBFromCIEXxy(vec3 YxyColor); +float exposure = .1; +float whitePoint = 2.5; +float delta = 0.0001; void main() { vec4 col = texture(tex, uv); +#ifdef AUTO_EXPOSURE + float avgLuminance = textureLod(logluminancetex, uv, 10.).x; + avgLuminance = exp(avgLuminance) - delta; + + vec3 Yxy = getCIEYxy(col.xyz); + float a = max(0, 1.5 - 1.5 / (avgLuminance * .1 + 1)) + .1; + float Lp = Yxy.r * a / avgLuminance; + Yxy.r = (Lp * (1. * Lp / (whitePoint * whitePoint))) / (1. + Lp); + col.xyz = getRGBFromCIEXxy(Yxy); +#endif float curdepth = texture(dtex, uv).x; vec4 FragPos = invprojm * (2.0 * vec4(uv, curdepth, 1.0f) - 1.0f); diff --git a/data/shaders/diffuseenvmap.frag b/data/shaders/diffuseenvmap.frag index 0c9f70777..6403f2b06 100644 --- a/data/shaders/diffuseenvmap.frag +++ b/data/shaders/diffuseenvmap.frag @@ -42,6 +42,6 @@ void main(void) float g = dot(extendednormal, gmat * extendednormal); float b = dot(extendednormal, bmat * extendednormal); - Diff = 0.25 * vec4(r, g, b, .1); + Diff = max(0.25 * vec4(r, g, b, .1), vec4(0.)); Spec = vec4(0.); } diff --git a/data/shaders/logluminance.frag b/data/shaders/logluminance.frag new file mode 100644 index 000000000..b257103bc --- /dev/null +++ b/data/shaders/logluminance.frag @@ -0,0 +1,14 @@ +uniform sampler2D tex; + +in vec2 uv; +out vec4 FragColor; + +float delta = 0.0001; + +void main() +{ + vec3 weight = vec3(0.2125f, 0.7154f, 0.0721f); + vec3 col = texture(tex, uv).xyz; + float luma = dot(col, weight); + FragColor = vec4(log(luma + delta)); +} \ No newline at end of file diff --git a/data/shaders/utils/getCIEXYZ.frag b/data/shaders/utils/getCIEXYZ.frag new file mode 100644 index 000000000..607f4e396 --- /dev/null +++ b/data/shaders/utils/getCIEXYZ.frag @@ -0,0 +1,17 @@ +// Using numerical value from here +// http://content.gpwiki.org/index.php/D3DBook:High-Dynamic_Range_Rendering + +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); +} \ No newline at end of file diff --git a/data/shaders/utils/getLightFactor.frag b/data/shaders/utils/getLightFactor.frag index 9132b6bc3..47763c531 100644 --- a/data/shaders/utils/getLightFactor.frag +++ b/data/shaders/utils/getLightFactor.frag @@ -11,5 +11,5 @@ vec3 getLightFactor(float specMapValue) vec3 SpecularComponent = texture(SpecularMap, tc).xyz; float ao = texture(SSAO, tc).x; vec3 tmp = ao * ambient + DiffuseComponent + SpecularComponent * specMapValue; - return tmp * (0.4 + ao*0.6); + return tmp * ao; } \ No newline at end of file diff --git a/data/shaders/utils/getRGBfromCIEXxy.frag b/data/shaders/utils/getRGBfromCIEXxy.frag new file mode 100644 index 000000000..60919787f --- /dev/null +++ b/data/shaders/utils/getRGBfromCIEXxy.frag @@ -0,0 +1,17 @@ +// Using numerical value from here +// http://content.gpwiki.org/index.php/D3DBook:High-Dynamic_Range_Rendering + +vec3 getRGBFromCIEXxy(vec3 YxyColor) +{ + float Yovery = YxyColor.x / YxyColor.z; + vec3 XYZ = vec3(YxyColor.y * Yovery, YxyColor.x, (1. - YxyColor.y - YxyColor.z) * Yovery); + + mat3 XYZ2sRGB = transpose(mat3( + vec3(3.2405, -.9693, .0556), + vec3(-1.5371, 1.8760, -.2040), + vec3(-.4985, .0416, 1.0572))); + + vec3 sRGBColor = XYZ2sRGB * XYZ; + return sRGBColor;//vec3(pow(sRGBColor.x, 2.2), pow(sRGBColor.y, 2.2), pow(sRGBColor.z, 2.2)); +} + diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index b29155187..7795e0183 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -59,6 +59,7 @@ PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers; PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer; PFNGLFRAMEBUFFERTEXTUREPROC glFramebufferTexture; PFNGLTEXIMAGE3DPROC glTexImage3D; +PFNGLGENERATEMIPMAPPROC glGenerateMipmap; PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus; #endif @@ -198,6 +199,7 @@ void initGL() glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)IRR_OGL_LOAD_EXTENSION("glBindFramebuffer"); glFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREPROC)IRR_OGL_LOAD_EXTENSION("glFramebufferTexture"); glTexImage3D = (PFNGLTEXIMAGE3DPROC)IRR_OGL_LOAD_EXTENSION("glTexImage3D"); + glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC)IRR_OGL_LOAD_EXTENSION("glGenerateMipmap"); glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)IRR_OGL_LOAD_EXTENSION("glCheckFramebufferStatus"); #ifdef DEBUG glDebugMessageCallbackARB = (PFNGLDEBUGMESSAGECALLBACKARBPROC)IRR_OGL_LOAD_EXTENSION("glDebugMessageCallbackARB"); @@ -291,6 +293,26 @@ GLuint getDepthTexture(irr::video::ITexture *tex) return static_cast(tex)->DepthBufferTexture; } +std::set AlreadyTransformedTexture; + +void transformTexturesTosRGB(irr::video::ITexture *tex) +{ + if (AlreadyTransformedTexture.find(tex) != AlreadyTransformedTexture.end()) + return; + AlreadyTransformedTexture.insert(tex); + size_t w = tex->getSize().Width, h = tex->getSize().Height; + char *data = new char[w * h * 4]; + memcpy(data, tex->lock(), w * h * 4); + tex->unlock(); + glBindTexture(GL_TEXTURE_2D, getTextureGLuint(tex)); + if (tex->hasAlpha()) + glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB_ALPHA, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid *)data); + else + glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB, w, h, 0, GL_BGR, GL_UNSIGNED_BYTE, (GLvoid *)data); + glGenerateMipmap(GL_TEXTURE_2D); + delete[] data; +} + void setTexture(unsigned TextureUnit, GLuint TextureId, GLenum MagFilter, GLenum MinFilter, bool allowAF) { glActiveTexture(GL_TEXTURE0 + TextureUnit); diff --git a/src/graphics/glwrap.hpp b/src/graphics/glwrap.hpp index a2c7d954f..96ac80700 100644 --- a/src/graphics/glwrap.hpp +++ b/src/graphics/glwrap.hpp @@ -76,6 +76,7 @@ extern PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers; extern PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer; extern PFNGLFRAMEBUFFERTEXTUREPROC glFramebufferTexture; extern PFNGLTEXIMAGE3DPROC glTexImage3D; +extern PFNGLGENERATEMIPMAPPROC glGenerateMipmap; extern PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus; #ifdef DEBUG extern PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARB; @@ -151,6 +152,7 @@ GLint LoadProgram(Types ... args) GLuint getTextureGLuint(irr::video::ITexture *tex); GLuint getDepthTexture(irr::video::ITexture *tex); +void transformTexturesTosRGB(irr::video::ITexture *tex); void draw2DImage(const irr::video::ITexture* texture, const irr::core::rect& destRect, const irr::core::rect& sourceRect, const irr::core::rect* clipRect, diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index d962d410a..03b0b7037 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -382,7 +382,8 @@ void ParticleSystemProxy::setEmitter(scene::IParticleEmitter* emitter) glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); - + video::ITexture *tex = getMaterial(0).getTexture(0); + transformTexturesTosRGB(tex); texture = getTextureGLuint(getMaterial(0).getTexture(0)); } diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index 62c7a98e2..ffeb61315 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -256,6 +256,8 @@ void renderColorLevel(ITexture *in) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glUniform1i(FullScreenShader::ColorLevelShader::uniform_tex, 0); glUniform1i(FullScreenShader::ColorLevelShader::uniform_dtex, 1); + setTexture(2, getTextureGLuint(irr_driver->getRTT(RTT_LOG_LUMINANCE)), GL_NEAREST, GL_NEAREST_MIPMAP_NEAREST); + glUniform1i(FullScreenShader::ColorLevelShader::uniform_logluminancetex, 2); glUniformMatrix4fv(FullScreenShader::ColorLevelShader::uniform_invprojm, 1, GL_FALSE, irr_driver->getInvProjMatrix().pointer()); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); @@ -426,11 +428,6 @@ void PostProcessing::renderPassThrough(ITexture *tex) glUniform1i(FullScreenShader::PassThroughShader::uniform_texture, 0); 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); } void PostProcessing::renderPassThrough(GLuint tex) @@ -608,6 +605,28 @@ static void renderGodRay(GLuint tex, const core::vector2df &sunpos) glEnable(GL_DEPTH_TEST); } +static void averageTexture(GLuint tex) +{ + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, tex); + glGenerateMipmap(GL_TEXTURE_2D); +} + +static void computeLogLuminance(GLuint tex) +{ + glDisable(GL_DEPTH_TEST); + glDisable(GL_BLEND); + IVideoDriver *const drv = irr_driver->getVideoDriver(); + drv->setRenderTarget(irr_driver->getRTT(RTT_LOG_LUMINANCE), false, false); + glUseProgram(FullScreenShader::LogLuminanceShader::Program); + glBindVertexArray(FullScreenShader::LogLuminanceShader::vao); + setTexture(0, tex, GL_LINEAR, GL_LINEAR); + FullScreenShader::LogLuminanceShader::setUniforms(0); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + averageTexture(getTextureGLuint(irr_driver->getRTT(RTT_LOG_LUMINANCE))); +} + // ---------------------------------------------------------------------------- /** Render the post-processed scene */ void PostProcessing::render() @@ -650,19 +669,8 @@ void PostProcessing::render() { drv->setRenderTarget(irr_driver->getRTT(RTT_TMP3), true, false); renderBloom(in); - } - - if (globalbloom) - { - // Clear the alpha to a suitable value, stencil - glClearColor(0, 0, 0, 0.1f); - glColorMask(0, 0, 0, 1); - - glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT); - - glClearColor(0, 0, 0, 0); - glColorMask(1, 1, 1, 1); + glClear(GL_STENCIL_BUFFER_BIT); // To half drv->setRenderTarget(irr_driver->getRTT(RTT_HALF1), true, false); @@ -678,11 +686,18 @@ void PostProcessing::render() renderPassThrough(irr_driver->getRTT(RTT_QUARTER1)); // Blur it for distribution. + renderGaussian6Blur(irr_driver->getRTT(RTT_HALF1), irr_driver->getRTT(RTT_HALF2), 2.f / UserConfigParams::m_width, 2.f / UserConfigParams::m_height); + renderGaussian6Blur(irr_driver->getRTT(RTT_QUARTER1), irr_driver->getRTT(RTT_QUARTER2), 4.f / UserConfigParams::m_width, 4.f / UserConfigParams::m_height); renderGaussian6Blur(irr_driver->getRTT(RTT_EIGHTH1), irr_driver->getRTT(RTT_EIGHTH2), 8.f / UserConfigParams::m_width, 8.f / UserConfigParams::m_height); // Additively blend on top of tmp1 drv->setRenderTarget(out, false, false); - renderBloomBlend(irr_driver->getRTT(RTT_EIGHTH1)); + glEnable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE); + glBlendEquation(GL_FUNC_ADD); + renderPassThrough(irr_driver->getRTT(RTT_HALF1)); + renderPassThrough(irr_driver->getRTT(RTT_QUARTER1)); + renderPassThrough(irr_driver->getRTT(RTT_EIGHTH1)); } // end if bloom in = irr_driver->getRTT(RTT_TMP1); @@ -693,6 +708,8 @@ void PostProcessing::render() PROFILER_PUSH_CPU_MARKER("- Godrays", 0xFF, 0x00, 0x00); if (m_sunpixels > 30)//World::getWorld()->getTrack()->hasGodRays() && ) // god rays { + glDisable(GL_BLEND); + glEnable(GL_DEPTH_TEST); // Grab the sky drv->setRenderTarget(out, true, false); // irr_driver->getSceneManager()->drawAll(ESNRP_SKY_BOX); @@ -837,15 +854,19 @@ void PostProcessing::render() PROFILER_POP_CPU_MARKER(); } + computeLogLuminance(getTextureGLuint(in)); + // Final blit // TODO : Use glBlitFramebuffer drv->setRenderTarget(ERT_FRAME_BUFFER, false, false); + glEnable(GL_FRAMEBUFFER_SRGB); if (irr_driver->getNormals()) renderPassThrough(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)); else if (irr_driver->getSSAOViz()) renderPassThrough(irr_driver->getRTT(RTT_SSAO)); else renderColorLevel(in); + glDisable(GL_FRAMEBUFFER_SRGB); } } // render diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 443e4097b..ed019fb96 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -1026,9 +1026,10 @@ static void projectSH(float *color[], size_t width, size_t height, // Constant obtained by projecting unprojected ref values float solidangle = 2.75 / (wh * pow(d, 1.5f)); - float b = color[face][4 * height * i + 4 * j] / 255.; - float g = color[face][4 * height * i + 4 * j + 1] / 255.; - float r = color[face][4 * height * i + 4 * j + 2] / 255.; + // pow(., 2.2) to convert from srgb + float b = pow(color[face][4 * height * i + 4 * j] / 255., 2.2); + float g = pow(color[face][4 * height * i + 4 * j + 1] / 255., 2.2); + float r = pow(color[face][4 * height * i + 4 * j + 2] / 255., 2.2); assert(b >= 0.); @@ -1241,7 +1242,7 @@ void IrrDriver::generateSkyboxCubemap() image->drop(); glBindTexture(GL_TEXTURE_CUBE_MAP, SkyboxCubeMap); - glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid*)rgba[i]); + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_SRGB_ALPHA, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid*)rgba[i]); } /* @@ -1250,7 +1251,7 @@ void IrrDriver::generateSkyboxCubemap() for (unsigned i = 0; i < 6; i++) { glBindTexture(GL_TEXTURE_CUBE_MAP, ConvolutedSkyboxCubeMap); - glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid*)rgba[i]); + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_SRGB_ALPHA, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid*)rgba[i]); } for (unsigned i = 0; i < 6; i++) delete[] rgba[i]; diff --git a/src/graphics/rtts.cpp b/src/graphics/rtts.cpp index 3860a7094..0eca3b7dc 100644 --- a/src/graphics/rtts.cpp +++ b/src/graphics/rtts.cpp @@ -53,46 +53,34 @@ RTT::RTT() // Optionally, the collapse ones use a smaller format. bool stencil = true; - rtts[RTT_TMP1] = drv->addRenderTargetTexture(res, "rtt.tmp1", ECF_A8R8G8B8, stencil); - if(!rtts[RTT_TMP1]) - { - // Work around for intel hd3000 cards :( - stencil = false; - rtts[RTT_TMP1] = drv->addRenderTargetTexture(res, "rtt.tmp1", ECF_A8R8G8B8, stencil); - Log::error("rtts", "Stencils for rtt not available, most likely a driver bug."); - if(UserConfigParams::m_pixel_shaders) - { - Log::error("rtts", "This requires pixel shaders to be disabled."); - UserConfigParams::m_pixel_shaders = false; - } - irr_driver->disableGLSL(); - } - rtts[RTT_TMP2] = drv->addRenderTargetTexture(res, "rtt.tmp2", ECF_A8R8G8B8, stencil); - rtts[RTT_TMP3] = drv->addRenderTargetTexture(res, "rtt.tmp3", ECF_A8R8G8B8, stencil); - rtts[RTT_TMP4] = drv->addRenderTargetTexture(res, "rtt.tmp4", ECF_R8, stencil); + rtts[RTT_TMP1] = drv->addRenderTargetTexture(res, "rtt.tmp1", ECF_A16B16G16R16F, stencil); + rtts[RTT_TMP2] = drv->addRenderTargetTexture(res, "rtt.tmp2", ECF_A16B16G16R16F, stencil); + rtts[RTT_TMP3] = drv->addRenderTargetTexture(res, "rtt.tmp3", ECF_A16B16G16R16F, stencil); + rtts[RTT_TMP4] = drv->addRenderTargetTexture(res, "rtt.tmp4", ECF_R16F, stencil); rtts[RTT_NORMAL_AND_DEPTH] = drv->addRenderTargetTexture(res, "rtt.normal_and_depth", ECF_G16R16F, stencil); rtts[RTT_COLOR] = drv->addRenderTargetTexture(res, "rtt.color", ECF_A16B16G16R16F, stencil); + rtts[RTT_LOG_LUMINANCE] = drv->addRenderTargetTexture(shadowsize0, "rtt.logluminance", ECF_R16F, stencil); - rtts[RTT_HALF1] = drv->addRenderTargetTexture(half, "rtt.half1", ECF_A8R8G8B8, stencil); - rtts[RTT_HALF2] = drv->addRenderTargetTexture(half, "rtt.half2", ECF_A8R8G8B8, stencil); + rtts[RTT_HALF1] = drv->addRenderTargetTexture(half, "rtt.half1", ECF_A16B16G16R16F, stencil); + rtts[RTT_HALF2] = drv->addRenderTargetTexture(half, "rtt.half2", ECF_A16B16G16R16F, stencil); - rtts[RTT_QUARTER1] = drv->addRenderTargetTexture(quarter, "rtt.q1", ECF_A8R8G8B8, stencil); - rtts[RTT_QUARTER2] = drv->addRenderTargetTexture(quarter, "rtt.q2", ECF_A8R8G8B8, stencil); - rtts[RTT_QUARTER3] = drv->addRenderTargetTexture(quarter, "rtt.q3", ECF_A8R8G8B8, stencil); - rtts[RTT_QUARTER4] = drv->addRenderTargetTexture(quarter, "rtt.q4", ECF_R8, stencil); + rtts[RTT_QUARTER1] = drv->addRenderTargetTexture(quarter, "rtt.q1", ECF_A16B16G16R16F, stencil); + rtts[RTT_QUARTER2] = drv->addRenderTargetTexture(quarter, "rtt.q2", ECF_A16B16G16R16F, stencil); + rtts[RTT_QUARTER3] = drv->addRenderTargetTexture(quarter, "rtt.q3", ECF_A16B16G16R16F, stencil); + rtts[RTT_QUARTER4] = drv->addRenderTargetTexture(quarter, "rtt.q4", ECF_R16F, stencil); - rtts[RTT_EIGHTH1] = drv->addRenderTargetTexture(eighth, "rtt.e1", ECF_A8R8G8B8, stencil); - rtts[RTT_EIGHTH2] = drv->addRenderTargetTexture(eighth, "rtt.e2", ECF_A8R8G8B8, stencil); + rtts[RTT_EIGHTH1] = drv->addRenderTargetTexture(eighth, "rtt.e1", ECF_A16B16G16R16F, stencil); + rtts[RTT_EIGHTH2] = drv->addRenderTargetTexture(eighth, "rtt.e2", ECF_A16B16G16R16F, stencil); - rtts[RTT_SIXTEENTH1] = drv->addRenderTargetTexture(sixteenth, "rtt.s1", ECF_A8R8G8B8, stencil); - rtts[RTT_SIXTEENTH2] = drv->addRenderTargetTexture(sixteenth, "rtt.s2", ECF_A8R8G8B8, stencil); + rtts[RTT_SIXTEENTH1] = drv->addRenderTargetTexture(sixteenth, "rtt.s1", ECF_A16B16G16R16F, stencil); + rtts[RTT_SIXTEENTH2] = drv->addRenderTargetTexture(sixteenth, "rtt.s2", ECF_A16B16G16R16F, stencil); - rtts[RTT_SSAO] = drv->addRenderTargetTexture(ssaosize, "rtt.ssao", ECF_R8, stencil); + rtts[RTT_SSAO] = drv->addRenderTargetTexture(ssaosize, "rtt.ssao", ECF_R16F, stencil); rtts[RTT_WARPV] = drv->addRenderTargetTexture(warpvsize, "rtt.warpv", ECF_A8R8G8B8, stencil); rtts[RTT_WARPH] = drv->addRenderTargetTexture(warphsize, "rtt.warph", ECF_A8R8G8B8, stencil); - rtts[RTT_DISPLACE] = drv->addRenderTargetTexture(res, "rtt.displace", ECF_A8R8G8B8, stencil); + rtts[RTT_DISPLACE] = drv->addRenderTargetTexture(res, "rtt.displace", ECF_A16B16G16R16F, stencil); if (((COpenGLDriver *) drv)->queryOpenGLFeature(COpenGLDriver::IRR_ARB_texture_rg)) { diff --git a/src/graphics/rtts.hpp b/src/graphics/rtts.hpp index 74ad51c09..98d835ff1 100644 --- a/src/graphics/rtts.hpp +++ b/src/graphics/rtts.hpp @@ -33,6 +33,7 @@ enum TypeRTT RTT_TMP4, RTT_NORMAL_AND_DEPTH, RTT_COLOR, + RTT_LOG_LUMINANCE, RTT_HALF1, RTT_HALF2, diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index 4a05532f3..0a223c7c0 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -314,6 +314,7 @@ void Shaders::loadShaders() FullScreenShader::MotionBlurShader::init(); FullScreenShader::GodFadeShader::init(); FullScreenShader::GodRayShader::init(); + FullScreenShader::LogLuminanceShader::init(); MeshShader::ColorizeShader::init(); MeshShader::NormalMapShader::init(); MeshShader::ObjectPass1Shader::init(); @@ -1767,6 +1768,7 @@ namespace FullScreenShader { Program = LoadProgram( GL_VERTEX_SHADER, file_manager->getAsset("shaders/screenquad.vert").c_str(), + GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getCIEXYZ.frag").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/bloom.frag").c_str()); uniform_texture = glGetUniformLocation(Program, "tex"); vao = createVAO(Program); @@ -1796,6 +1798,7 @@ namespace FullScreenShader GLuint ColorLevelShader::Program; GLuint ColorLevelShader::uniform_tex; + GLuint ColorLevelShader::uniform_logluminancetex; GLuint ColorLevelShader::uniform_inlevel; GLuint ColorLevelShader::uniform_outlevel; GLuint ColorLevelShader::vao; @@ -1805,8 +1808,11 @@ namespace FullScreenShader { Program = LoadProgram( GL_VERTEX_SHADER, file_manager->getAsset("shaders/screenquad.vert").c_str(), + GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getRGBfromCIEXxy.frag").c_str(), + GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getCIEXYZ.frag").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/color_levels.frag").c_str()); uniform_tex = glGetUniformLocation(Program, "tex"); + uniform_logluminancetex = glGetUniformLocation(Program, "logluminancetex"); uniform_dtex = glGetUniformLocation(Program, "dtex"); uniform_inlevel = glGetUniformLocation(Program, "inlevel"); uniform_outlevel = glGetUniformLocation(Program, "outlevel"); @@ -2325,6 +2331,24 @@ namespace FullScreenShader glUniform2f(uniform_sunpos, sunpos.X, sunpos.Y); glUniform1i(uniform_tex, TU_tex); } + + GLuint LogLuminanceShader::Program; + GLuint LogLuminanceShader::uniform_tex; + GLuint LogLuminanceShader::vao; + + void LogLuminanceShader::init() + { + Program = LoadProgram( + GL_VERTEX_SHADER, file_manager->getAsset("shaders/screenquad.vert").c_str(), + GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/logluminance.frag").c_str()); + uniform_tex = glGetUniformLocation(Program, "tex"); + vao = createVAO(Program); + } + + void LogLuminanceShader::setUniforms(unsigned TU_tex) + { + glUniform1i(uniform_tex, TU_tex); + } } namespace UIShader diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index f9b531472..96016cc98 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -479,7 +479,7 @@ class ColorLevelShader { public: static GLuint Program; - static GLuint uniform_tex, uniform_invprojm, uniform_dtex, uniform_inlevel, uniform_outlevel; + static GLuint uniform_tex, uniform_invprojm, uniform_dtex, uniform_inlevel, uniform_outlevel, uniform_logluminancetex; static GLuint vao; static void init(); @@ -667,6 +667,17 @@ public: static void setUniforms(const core::vector2df &sunpos, unsigned TU_tex); }; +class LogLuminanceShader +{ +public: + static GLuint Program; + static GLuint uniform_tex; + static GLuint vao; + + static void init(); + static void setUniforms(unsigned TU_tex); +}; + } namespace UIShader diff --git a/src/graphics/stkbillboard.cpp b/src/graphics/stkbillboard.cpp index d6de5085f..12bf85e92 100644 --- a/src/graphics/stkbillboard.cpp +++ b/src/graphics/stkbillboard.cpp @@ -34,7 +34,9 @@ void STKBillboard::render() return; core::vector3df pos = getAbsolutePosition(); glBindVertexArray(billboardvao); - GLuint texid = getTextureGLuint(Material.getTexture(0)); + video::ITexture *tex = Material.getTexture(0); + transformTexturesTosRGB(tex); + GLuint texid = getTextureGLuint(tex); setTexture(0, texid, GL_LINEAR, GL_LINEAR); glUseProgram(MeshShader::BillboardShader::Program); MeshShader::BillboardShader::setUniforms(irr_driver->getViewMatrix(), irr_driver->getProjMatrix(), pos, Size, 0); diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp index 36635ff50..ab2733512 100644 --- a/src/graphics/stkmesh.cpp +++ b/src/graphics/stkmesh.cpp @@ -180,8 +180,11 @@ GLMesh allocateMeshBuffer(scene::IMeshBuffer* mb) for (unsigned i = 0; i < 6; i++) { tex = mb->getMaterial().getTexture(i); - if (tex) - result.textures[i] = getTextureGLuint(tex); + if (tex) + { + transformTexturesTosRGB(tex); + result.textures[i] = getTextureGLuint(tex); + } else result.textures[i] = 0; }