From 18d8612a8a7661ca150a38f426d3a947065be843 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Mon, 10 Jul 2017 17:21:33 -0400 Subject: [PATCH] Initial implementation of multiple ATM's (still missing frustum culling and other small details). --- data/scene/atmosphereearth.scene | 2 +- include/openspace/rendering/abufferrenderer.h | 4 +- .../openspace/rendering/framebufferrenderer.h | 8 +- include/openspace/rendering/renderengine.h | 2 + include/openspace/rendering/renderer.h | 4 +- modules/atmosphere/atmospheremodule.cpp | 5 +- modules/atmosphere/atmospheremodule.h | 1 + .../rendering/atmospheredeferredcaster.cpp | 3 + .../shaders/atmosphere_deferred_fs.glsl | 34 ++-- shaders/framebuffer/hdrBackground.frag | 145 ++++++++++++++++++ shaders/framebuffer/hdrBackground.vert | 39 +++++ src/rendering/abufferrenderer.cpp | 10 +- src/rendering/framebufferrenderer.cpp | 64 ++++++-- src/rendering/renderengine.cpp | 11 +- 14 files changed, 299 insertions(+), 33 deletions(-) create mode 100644 shaders/framebuffer/hdrBackground.frag create mode 100644 shaders/framebuffer/hdrBackground.vert diff --git a/data/scene/atmosphereearth.scene b/data/scene/atmosphereearth.scene index 62cb22132a..06310c273d 100644 --- a/data/scene/atmosphereearth.scene +++ b/data/scene/atmosphereearth.scene @@ -93,7 +93,7 @@ return { --"moon", "lodglobes/earth", - --"lodglobes/mars", + "lodglobes/mars", "lodglobes/moon", --"toyvolume", diff --git a/include/openspace/rendering/abufferrenderer.h b/include/openspace/rendering/abufferrenderer.h index 2a3fc3a8fd..351ddba060 100644 --- a/include/openspace/rendering/abufferrenderer.h +++ b/include/openspace/rendering/abufferrenderer.h @@ -69,7 +69,8 @@ public: void setCamera(Camera* camera) override; void setScene(Scene* scene) override; void setResolution(glm::ivec2 res) override; - void setNAaSamples(int nAaSamples) override; + void setNAaSamples(const int nAaSamples) override; + void setHDRExposure(const float hdrExposure) override; void preRaycast(const RaycasterTask& raycasterTask); void postRaycast(const RaycasterTask& raycasterTask); @@ -130,6 +131,7 @@ private: GLuint _vertexPositionBuffer; int _nAaSamples; + float _hdrExposure; float _blackoutFactor; ghoul::Dictionary _rendererData; diff --git a/include/openspace/rendering/framebufferrenderer.h b/include/openspace/rendering/framebufferrenderer.h index 0117878855..ea29faf849 100644 --- a/include/openspace/rendering/framebufferrenderer.h +++ b/include/openspace/rendering/framebufferrenderer.h @@ -66,11 +66,13 @@ public: void updateResolution(); void updateRaycastData(); void updateDeferredcastData(); - + void updateHDRData(); + void setCamera(Camera* camera) override; void setScene(Scene* scene) override; void setResolution(glm::ivec2 res) override; - void setNAaSamples(int nAaSamples) override; + void setNAaSamples(const int nAaSamples) override; + void setHDRExposure(const float hdrExposure) override; void update() override; void render(float blackoutFactor, bool doPerformanceMeasurements) override; @@ -93,6 +95,7 @@ private: std::map _deferredcastData; std::map> _deferredcastPrograms; + std::unique_ptr _hdrBackGroundProgram; std::unique_ptr _resolveProgram; @@ -118,6 +121,7 @@ private: Scene* _scene; glm::vec2 _resolution; int _nAaSamples; + float _hdrExposure; ghoul::Dictionary _rendererData; }; diff --git a/include/openspace/rendering/renderengine.h b/include/openspace/rendering/renderengine.h index bdda2dbb97..7930dc8d5c 100644 --- a/include/openspace/rendering/renderengine.h +++ b/include/openspace/rendering/renderengine.h @@ -30,6 +30,7 @@ #include #include #include +#include #include @@ -220,6 +221,7 @@ private: float _currentFadeTime; int _fadeDirection; properties::IntProperty _nAaSamples; + properties::FloatProperty _hdrExposure; uint64_t _frameNumber; std::vector _programs; diff --git a/include/openspace/rendering/renderer.h b/include/openspace/rendering/renderer.h index 825a2ce5ad..513db8ac90 100644 --- a/include/openspace/rendering/renderer.h +++ b/include/openspace/rendering/renderer.h @@ -58,7 +58,9 @@ public: virtual void setCamera(Camera* camera) = 0; virtual void setScene(Scene* scene) = 0; virtual void setResolution(glm::ivec2 res) = 0; - virtual void setNAaSamples(int nAaSamples) = 0; + virtual void setNAaSamples(const int nAaSamples) = 0; + virtual void setHDRExposure(const float hdrExposure) = 0; + /** * Set raycasting uniforms on the program object, and setup raycasting. diff --git a/modules/atmosphere/atmospheremodule.cpp b/modules/atmosphere/atmospheremodule.cpp index 43f7c33d39..cc31ea82f2 100644 --- a/modules/atmosphere/atmospheremodule.cpp +++ b/modules/atmosphere/atmospheremodule.cpp @@ -27,11 +27,14 @@ #include #include + //#include namespace openspace { -AtmosphereModule::AtmosphereModule() : OpenSpaceModule("Atmosphere") {} +AtmosphereModule::AtmosphereModule() : + OpenSpaceModule("Atmosphere") +{} void AtmosphereModule::internalInitialize() { auto fRenderable = FactoryManager::ref().factory(); diff --git a/modules/atmosphere/atmospheremodule.h b/modules/atmosphere/atmospheremodule.h index 94b26f4bb7..2e99865d98 100644 --- a/modules/atmosphere/atmospheremodule.h +++ b/modules/atmosphere/atmospheremodule.h @@ -26,6 +26,7 @@ #define __ATMOSPHEREMODULE_H__ #include +#include namespace openspace { diff --git a/modules/atmosphere/rendering/atmospheredeferredcaster.cpp b/modules/atmosphere/rendering/atmospheredeferredcaster.cpp index df556126eb..a0561dd629 100644 --- a/modules/atmosphere/rendering/atmospheredeferredcaster.cpp +++ b/modules/atmosphere/rendering/atmospheredeferredcaster.cpp @@ -296,6 +296,9 @@ void AtmosphereDeferredcaster::preRaycast(const RenderData & renderData, const D glBindTexture(GL_TEXTURE_3D, _inScatteringTableTexture); program.setUniform("inscatterTexture", _inScatteringTableTextureUnit); + // Atmosphere Frustum Culling + + // DEBUG: /* if (_renderableClass == RenderablePlanet) { diff --git a/modules/atmosphere/shaders/atmosphere_deferred_fs.glsl b/modules/atmosphere/shaders/atmosphere_deferred_fs.glsl index f29d12b7e6..f818102528 100644 --- a/modules/atmosphere/shaders/atmosphere_deferred_fs.glsl +++ b/modules/atmosphere/shaders/atmosphere_deferred_fs.glsl @@ -261,7 +261,7 @@ void dCalculateRayRenderableGlobe(out dRay ray, out dvec4 planetPositionObjectCo // ============================ // ====== Building Ray ======== // Ray in object space (in KM) - ray.origin = cameraPositionInObject / dvec4(1000.0, 1000.0, 1000.0, 1.0); + ray.origin = cameraPositionInObject * dvec4(0.001, 0.001, 0.001, 1.0); ray.direction = dvec4(normalize(objectCoords.xyz - cameraPositionInObject.xyz), 0.0); } @@ -308,7 +308,7 @@ void dCalculateRayRenderablePlanet(out dRay ray, out dvec4 planetPositionObjectC // ============================ // ====== Building Ray ======== // Ray in object space (in KM) - ray.origin = cameraPositionInObject / dvec4(1000.0, 1000.0, 1000.0, 1.0); + ray.origin = cameraPositionInObject * dvec4(0.001, 0.001, 0.001, 1.0); ray.direction = dvec4(normalize(objectCoords.xyz - cameraPositionInObject.xyz), 0.0); } @@ -360,12 +360,13 @@ vec3 inscatterRadiance(inout vec3 x, inout float t, inout float irradianceFactor // observer in the space) we test if the light ray is hitting the atmosphere vec3 x0 = fragPosObj; float r0 = length(fragPosObj); - float muSun0 = dot(fragPosObj, s) / r0; + float invr0 = 1.0/r0; + float muSun0 = dot(fragPosObj, s) * invr0; //vec3 x0 = x + float(pixelDepth) * v; - float mu0 = dot(x0, v) / r0; + float mu0 = dot(x0, v) * invr0; bool groundHit = false; - if ((pixelDepth > 0.0) && pixelDepth < maxLength) { + if ((pixelDepth > 0.0) && (pixelDepth < maxLength)) { t = float(pixelDepth); groundHit = true; // Transmittance from point r, direction mu, distance t @@ -509,7 +510,7 @@ vec3 groundColor(const vec3 x, const float t, const vec3 v, const vec3 s, const //groundRadiance *= mix(5.0, 1.0, dot(n,s)); // Specular reflection from sun on oceans and rivers - if (waterReflectance > 0.1 && muSun > 0.0) { + if ((waterReflectance > 0.1) && (muSun > 0.0)) { vec3 h = normalize(s - v); // Fresnell Schlick's approximation float fresnel = 0.02f + 0.98f * pow(1.0f - dot(-v, h), 5.0f); @@ -573,10 +574,11 @@ void main() { //positionArray[i] = texelFetch(mainPositionTexture, ivec2(gl_FragCoord), i); //mainDepth += denormalizeFloat(texelFetch(mainDepthTexture, ivec2(gl_FragCoord), i).x); } - meanColor /= nAaSamples; - meanNormal /= nAaSamples; - meanPosition /= nAaSamples; - meanOtherData /= nAaSamples; + float invNaaSamples = 1.0/nAaSamples; + meanColor *= invNaaSamples; + meanNormal *= invNaaSamples; + meanPosition *= invNaaSamples; + meanOtherData *= invNaaSamples; //mainDepth /= nAaSamples; meanColor.a = maxAlpha; @@ -624,8 +626,8 @@ void main() { double pixelDepth = distance(cameraPositionInObject.xyz, fragObjectCoords.xyz); // All calculations are done in Km: - pixelDepth /= 1000.0; - fragObjectCoords.xyz /= 1000.0; + pixelDepth *= 0.001; + fragObjectCoords.xyz *= 0.001; // Now we check is if the atmosphere is occluded, i.e., if the distance to the pixel // in the depth buffer is less than the distance to the atmosphere then the atmosphere @@ -633,7 +635,7 @@ void main() { // Fragments positions into G-Buffer are written in OS Eye Space (Camera Rig Coords) // when using their positions later, one must convert them to the planet's coords - if ((pixelDepth > 0.0) && pixelDepth < offset) { + if ((pixelDepth > 0.0) && (pixelDepth < offset)) { renderTarget = vec4(HDR(meanColor.xyz * backgroundExposure), meanColor.a); } else { // Following paper nomenclature @@ -744,8 +746,8 @@ void main() { double pixelDepth = distance(cameraPositionInObject.xyz, fragObjectCoords.xyz); // All calculations are done in Km: - pixelDepth /= 1000.0; - fragObjectCoords.xyz /= 1000.0; + pixelDepth *= 0.001; + fragObjectCoords.xyz *= 0.001; if (meanPosition.xyz != vec3(0.0) && (pixelDepth < offset)) { renderTarget = vec4(HDR(meanColor.xyz * backgroundExposure), meanColor.a); @@ -799,7 +801,7 @@ void main() { renderTarget = finalRadiance; } } else { - renderTarget = vec4(HDR(meanColor.xyz * backgroundExposure), meanColor.a); + //renderTarget = vec4(HDR(meanColor.xyz * backgroundExposure), meanColor.a); //renderTarget = meanColor; } } diff --git a/shaders/framebuffer/hdrBackground.frag b/shaders/framebuffer/hdrBackground.frag new file mode 100644 index 0000000000..04f72bf720 --- /dev/null +++ b/shaders/framebuffer/hdrBackground.frag @@ -0,0 +1,145 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 - 2017 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#version __CONTEXT__ + +layout (location = 0) out vec4 finalColor; +uniform int nAaSamples; + +uniform sampler2DMS mainColorTexture; + +//uniform float exposure; +const float exposure = 0.4; +uniform float backgroundExposure; +//uniform float gamma; +const float gamma = 2.2; + +vec3 exponentialToneMapping(vec3 color) { + color *= exposure; + + color.r = color.r < 1.413 ? pow(color.r * 0.38317, 1.0 / gamma) : 1.0 - exp(-color.r); + color.g = color.g < 1.413 ? pow(color.g * 0.38317, 1.0 / gamma) : 1.0 - exp(-color.g); + color.b = color.b < 1.413 ? pow(color.b * 0.38317, 1.0 / gamma) : 1.0 - exp(-color.b); + + return color; + +} + +vec3 linearToneMapping(vec3 color) +{ + float tExposure = 1.0f; + color = clamp(tExposure * color, 0.0f, 1.0f); + color = pow(color, vec3(1.0f / gamma)); + return color; +} + +vec3 simpleReinhardToneMapping(vec3 color) +{ + float tExposure = 1.5f; + color *= tExposure/(1.0f + color / tExposure); + color = pow(color, vec3(1. / gamma)); + return color; +} + +vec3 lumaBasedReinhardToneMapping(vec3 color) +{ + float luma = dot(color, vec3(0.2126f, 0.7152f, 0.0722f)); + float toneMappedLuma = luma / (1.0f + luma); + color *= toneMappedLuma / luma; + color = pow(color, vec3(1.0f / gamma)); + return color; +} + +vec3 whitePreservingLumaBasedReinhardToneMapping(vec3 color) +{ + float white = 4.0f; + //float luma = dot(color, vec3(0.2126f, 0.7152f, 0.0722f)); + float luma = dot(color, vec3(0.4126f, 0.9152f, 0.2722f)); + float toneMappedLuma = luma * (1.0f + luma / (white * white)) / (1.0f + luma); + color *= toneMappedLuma / luma; + color = pow(color, vec3(1.0f / gamma)); + return color; +} + +vec3 RomBinDaHouseToneMapping(vec3 color) +{ + color = exp( -1.0f / ( 2.72f * color + 0.15f ) ); + color = pow(color, vec3(1.7 / gamma)); + return color; +} + +vec3 filmicToneMapping(vec3 color) +{ + color = max(vec3(0.0f), color - vec3(0.04f)); + color = (color * (6.2f * color + 0.5f)) / (color * (6.2f * color + 20.0f) + 0.06f); + return color; +} + +vec3 Uncharted2ToneMapping(vec3 color) +{ + float A = 0.15f; + float B = 0.50f; + float C = 0.10f; + float D = 0.20f; + float E = 0.02f; + float F = 0.30f; + float W = 11.2f; + float tExposure = 0.4f; + color *= tExposure; + color = ((color * (A * color + C * B) + D * E) / (color * (A * color + B) + D * F)) - E / F; + float white = ((W * (A * W + C * B) + D * E) / (W * (A * W + B) + D * F)) - E / F; + color /= white; + color = pow(color, vec3(1.0f / gamma)); + return color; +} + +vec3 jToneMapping(const vec3 color) { + return 1.0 - exp(-exposure * color); +} + +vec3 HDR(vec3 color) { + //return exponentialToneMapping(color); + //return linearToneMapping(color); + //return simpleReinhardToneMapping(color); + //return lumaBasedReinhardToneMapping(color); + //return whitePreservingLumaBasedReinhardToneMapping(color); + //return RomBinDaHouseToneMapping(color); + //return filmicToneMapping(color); + //return Uncharted2ToneMapping(color); + return jToneMapping(color); + +} + + +void main() { + vec4 color = vec4(0.0); + for (int i = 0; i < nAaSamples; i++) { + color += texelFetch(mainColorTexture, ivec2(gl_FragCoord), i); + } + + color /= nAaSamples; + //color.rgb *= blackoutFactor; + + finalColor = vec4(HDR(color.rgb * backgroundExposure), 1.0); +} diff --git a/shaders/framebuffer/hdrBackground.vert b/shaders/framebuffer/hdrBackground.vert new file mode 100644 index 0000000000..e974344115 --- /dev/null +++ b/shaders/framebuffer/hdrBackground.vert @@ -0,0 +1,39 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 - 2017 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#version __CONTEXT__ + +in vec4 position; + +out vec2 texCoord; +out vec3 vPosition; +out vec4 worldPosition; + +void main() { + gl_Position = position; + texCoord = 0.5 + position.xy * 0.5; + + vPosition = position.xyz; + worldPosition = position; +} diff --git a/src/rendering/abufferrenderer.cpp b/src/rendering/abufferrenderer.cpp index 5c0a7e9997..448689c179 100644 --- a/src/rendering/abufferrenderer.cpp +++ b/src/rendering/abufferrenderer.cpp @@ -386,7 +386,7 @@ void ABufferRenderer::setResolution(glm::ivec2 res) { } } -void ABufferRenderer::setNAaSamples(int nAaSamples) { +void ABufferRenderer::setNAaSamples(const int nAaSamples) { _nAaSamples = nAaSamples; if (_nAaSamples == 0) { _nAaSamples = 1; @@ -398,6 +398,14 @@ void ABufferRenderer::setNAaSamples(int nAaSamples) { _dirtyResolution = true; } +void ABufferRenderer::setHDRExposure(const float hdrExposure) { + _hdrExposure = hdrExposure; + if (_hdrExposure < 0.0) { + LERROR("HDR Exposure constant must be greater than zero."); + _hdrExposure = 1.0; + } +} + void ABufferRenderer::clear() { glBindBuffer(GL_PIXEL_UNPACK_BUFFER, _anchorPointerTextureInitializer); glBindTexture(GL_TEXTURE_2D, _anchorPointerTexture); diff --git a/src/rendering/framebufferrenderer.cpp b/src/rendering/framebufferrenderer.cpp index 37a938822e..8d93733d7d 100644 --- a/src/rendering/framebufferrenderer.cpp +++ b/src/rendering/framebufferrenderer.cpp @@ -127,6 +127,7 @@ void FramebufferRenderer::initialize() { updateRendererData(); updateRaycastData(); updateDeferredcastData(); + updateHDRData(); glBindFramebuffer(GL_FRAMEBUFFER, _mainFramebuffer); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, _mainColorTexture, 0); @@ -244,10 +245,19 @@ void FramebufferRenderer::update() { // If the resolve dictionary changed (or a file changed on disk) // then rebuild the resolve program. + if (_hdrBackGroundProgram && _hdrBackGroundProgram->isDirty()) { + try { + _hdrBackGroundProgram->rebuildFromFile(); + } catch (const ghoul::RuntimeError& error) { + LERRORC(error.component, error.message); + } + } + if (_resolveProgram->isDirty()) { try { _resolveProgram->rebuildFromFile(); - } catch (const ghoul::RuntimeError& error) { + } + catch (const ghoul::RuntimeError& error) { LERRORC(error.component, error.message); } } @@ -333,8 +343,8 @@ void FramebufferRenderer::updateResolution() { GL_FLOAT, nullptr); - //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, 0); - //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); #endif glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _mainOtherDataTexture); @@ -533,6 +543,19 @@ void FramebufferRenderer::updateDeferredcastData() { _dirtyDeferredcastData = false; } +void FramebufferRenderer::updateHDRData() { + try { + _hdrBackGroundProgram = ghoul::opengl::ProgramObject::Build( + "HDR Background Control", + "${SHADERS}/framebuffer/hdrBackground.vert", + "${SHADERS}/framebuffer/hdrBackground.frag" + ); + } + catch (const ghoul::RuntimeError& e) { + LERRORC(e.component, e.message); + } +} + void FramebufferRenderer::render(float blackoutFactor, bool doPerformanceMeasurements) { std::unique_ptr perf; if (doPerformanceMeasurements) { @@ -560,7 +583,7 @@ void FramebufferRenderer::render(float blackoutFactor, bool doPerformanceMeasure glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFbo); glBindFramebuffer(GL_FRAMEBUFFER, _mainFramebuffer); - // DEBUG: deferred g-buffer + // deferred g-buffer GLenum textureBuffers[4] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3 }; glDrawBuffers(4, textureBuffers); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -656,12 +679,29 @@ void FramebufferRenderer::render(float blackoutFactor, bool doPerformanceMeasure } } - // DEBUG: g-buffer + // g-buffer1 if (!tasks.deferredcasterTasks.empty()) { glBindFramebuffer(GL_FRAMEBUFFER, _deferredFramebuffer); GLenum dBuffer[1] = { GL_COLOR_ATTACHMENT0 }; glDrawBuffers(1, dBuffer); glClear(GL_COLOR_BUFFER_BIT); + + // HDR Background Image Control + _hdrBackGroundProgram->activate(); + + ghoul::opengl::TextureUnit mainColorTextureUnit; + mainColorTextureUnit.activate(); + + glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _mainColorTexture); + _hdrBackGroundProgram->setUniform("mainColorTexture", mainColorTextureUnit); + _hdrBackGroundProgram->setUniform("nAaSamples", _nAaSamples); + _hdrBackGroundProgram->setUniform("backgroundExposure", _hdrExposure); + glBindVertexArray(_screenQuad); + glDrawArrays(GL_TRIANGLES, 0, 6); + glBindVertexArray(0); + + _hdrBackGroundProgram->deactivate(); + } //} else { // glBindFramebuffer(GL_FRAMEBUFFER, _mainFramebuffer); @@ -685,7 +725,7 @@ void FramebufferRenderer::render(float blackoutFactor, bool doPerformanceMeasure deferredcastProgram->activate(); - // DEBUG: adding G-Buffer + // adding G-Buffer ghoul::opengl::TextureUnit mainDColorTextureUnit; mainDColorTextureUnit.activate(); glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _mainColorTexture); @@ -719,7 +759,6 @@ void FramebufferRenderer::render(float blackoutFactor, bool doPerformanceMeasure *deferredcastProgram); glDisable(GL_DEPTH_TEST); - //glDisable(GL_BLEND); glDepthMask(false); glBindVertexArray(_screenQuad); @@ -728,7 +767,6 @@ void FramebufferRenderer::render(float blackoutFactor, bool doPerformanceMeasure glDepthMask(true); glEnable(GL_DEPTH_TEST); - //glEnable(GL_BLEND); deferredcaster->postRaycast(deferredcasterTask.renderData, _deferredcastData[deferredcaster], @@ -812,7 +850,7 @@ void FramebufferRenderer::setResolution(glm::ivec2 res) { _dirtyResolution = true; } -void FramebufferRenderer::setNAaSamples(int nAaSamples) { +void FramebufferRenderer::setNAaSamples(const int nAaSamples) { _nAaSamples = nAaSamples; if (_nAaSamples == 0) { _nAaSamples = 1; @@ -824,6 +862,14 @@ void FramebufferRenderer::setNAaSamples(int nAaSamples) { _dirtyResolution = true; } +void FramebufferRenderer::setHDRExposure(const float hdrExposure) { + _hdrExposure = hdrExposure; + if (_hdrExposure < 0.0) { + LERROR("HDR Exposure constant must be greater than zero."); + _hdrExposure = 1.0; + } +} + void FramebufferRenderer::updateRendererData() { ghoul::Dictionary dict; dict.setValue("fragmentRendererPath", std::string(RenderFragmentShaderPath)); diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 4aaad12653..e1038e9ab4 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -130,6 +130,7 @@ RenderEngine::RenderEngine() , _currentFadeTime(0.f) , _fadeDirection(0) , _nAaSamples("nAaSamples", "Number of Antialiasing samples", 8, 1, 16) + , _hdrExposure("backgroundExposure", "HDR Exposure", 1.8f, 0.01f, 10.0f) , _frameNumber(0) { _performanceMeasurements.onChange([this]() { @@ -164,7 +165,14 @@ RenderEngine::RenderEngine() _renderer->setNAaSamples(_nAaSamples); } }); + _hdrExposure.onChange([this]() { + if (_renderer) { + _renderer->setHDRExposure(_hdrExposure); + } + }); + addProperty(_nAaSamples); + addProperty(_hdrExposure); addProperty(_applyWarping); _takeScreenshot.onChange([this](){ @@ -237,7 +245,7 @@ void RenderEngine::initialize() { _raycasterManager = std::make_unique(); _deferredcasterManager = std::make_unique(); _nAaSamples = OsEng.windowWrapper().currentNumberOfAaSamples(); - + LINFO("Seting renderer from string: " << renderingMethod); setRendererFromString(renderingMethod); @@ -685,6 +693,7 @@ void RenderEngine::setRenderer(std::unique_ptr renderer) { _renderer = std::move(renderer); _renderer->setResolution(renderingResolution()); _renderer->setNAaSamples(_nAaSamples); + _renderer->setHDRExposure(_hdrExposure); _renderer->initialize(); _renderer->setCamera(_camera); _renderer->setScene(_scene);