diff --git a/include/openspace/rendering/deferredcaster.h b/include/openspace/rendering/deferredcaster.h new file mode 100644 index 0000000000..3547e3a8ec --- /dev/null +++ b/include/openspace/rendering/deferredcaster.h @@ -0,0 +1,114 @@ +/***************************************************************************************** + * * + * 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. * + ****************************************************************************************/ + +#ifndef __OPENSPACE_CORE___DEFERREDCASTER___H +#define __OPENSPACE_CORE___DEFERREDCASTER___H + +#include +#include +#include + +namespace ghoul { + namespace opengl { + class Texture; + class ProgramObject; + } +} + +namespace openspace { + +struct RenderData; +struct RaycastData; + +class Deferredcaster { +public: + /** + * Destructor + */ + virtual ~Deferredcaster() {}; + + /** + * Prepare the volume for the ABuffer's resolve step. + * Make sure textures are up to date, bind them to texture units, set program uniforms etc. + */ + virtual void preRaycast(const RaycastData& data, ghoul::opengl::ProgramObject& program) {}; + + /** + * Clean up for the volume after the ABuffer's resolve step. + * Make sure texture units are deinitialized, etc. + */ + virtual void postRaycast(const RaycastData& data, ghoul::opengl::ProgramObject& program) {}; + + /** + * Return a path the file to use as vertex shader + * + * The shader preprocessor will have acceess to + * A #{namespace} variable (unique per helper file) + */ + virtual std::string getBoundsVsPath() const = 0; + + /* + * Return a path to a file with the functions, uniforms and fragment shader in variables + * required to generate the fragment color and depth. + * + * Should define the function: + * Fragment getFragment() + * + * The shader preprocessor will have acceess to + * A #{namespace} variable (unique per helper file) + */ + virtual std::string getBoundsFsPath() const = 0 ; + + /** + * Return a path to a file with all the uniforms, functions etc + * required to perform ray casting through this volume. + * + * The header should define the following two functions: + * vec4 sample#{id}(vec3 samplePos, vec3 dir, float occludingAlpha, inout float maxStepSize) + * (return color of sample) + * float stepSize#{id}(vec3 samplePos, vec3 dir) + * (return the preferred step size at this sample position) + * + * The shader preprocessor will have acceess to + * An #{id} variable (unique per volume) + * A #{namespace} variable (unique per helper file) + */ + virtual std::string getRaycastPath() const = 0; + + /** + * Return a path to a glsl file with helper functions required for the + * transformation and raycast steps. + * This file will be included once per shader program generated, + * regardless of how many volumes say they require the file. + * Ideal to avoid redefinitions of helper functions. + * + * The shader preprocessor will have access to the #{namespace} variable (unique per helper file) + * which should be a prefix to all symbols defined by the helper + */ + virtual std::string getHelperPath() const = 0; +}; + +} // namespace openspace + +#endif // __OPENSPACE_CORE___DEFERREDCASTER___H__ diff --git a/include/openspace/rendering/deferredcasterlistener.h b/include/openspace/rendering/deferredcasterlistener.h new file mode 100644 index 0000000000..5cdde2965c --- /dev/null +++ b/include/openspace/rendering/deferredcasterlistener.h @@ -0,0 +1,40 @@ +/***************************************************************************************** + * * + * 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. * + ****************************************************************************************/ + +#ifndef __OPENSPACE_CORE___DEFERREDCASTERLISTENER___H__ +#define __OPENSPACE_CORE___DEFERREDCASTERLISTENER___H__ + +namespace openspace { + +class Deferredcaster; + +class DeferredcasterListener { +public: + virtual void deferredcastersChanged(Deferredcaster& deferredcaster, bool attached) = 0; +}; + +} // openspace + + +#endif // __OPENSPACE_CORE___DEFERREDCASTERLISTENER___H__ diff --git a/include/openspace/rendering/deferredcastermanager.h b/include/openspace/rendering/deferredcastermanager.h new file mode 100644 index 0000000000..4097bef8c5 --- /dev/null +++ b/include/openspace/rendering/deferredcastermanager.h @@ -0,0 +1,54 @@ +/***************************************************************************************** + * * + * 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. * + ****************************************************************************************/ + +#ifndef __OPENSPACE_CORE___DEFERREDCASTERMANAGER___H__ +#define __OPENSPACE_CORE___DEFERREDCASTERMANAGER___H__ + +#include + +namespace openspace { + +class Deferredcaster; +class DeferredcasterListener; + +class DeferredcasterManager { +public: + DeferredcasterManager(); + ~DeferredcasterManager(); + void attachDeferredcaster(Deferredcaster& deferredcaster); + void detachDeferredcaster(Deferredcaster& deferredcaster); + bool isAttached(Deferredcaster& deferredcaster); + const std::vector& deferredcasters(); + + void addListener(DeferredcasterListener& listener); + void removeListener(DeferredcasterListener& listener); +private: + std::vector _deferredcasters; + std::vector _listeners; +}; + +} // namespace openspace + + +#endif // __OPENSPACE_CORE___DEFERREDCASTERMANAGER___H__ diff --git a/include/openspace/rendering/framebufferrenderer.h b/include/openspace/rendering/framebufferrenderer.h index 2bc0ec760e..fe34b5db27 100644 --- a/include/openspace/rendering/framebufferrenderer.h +++ b/include/openspace/rendering/framebufferrenderer.h @@ -32,6 +32,7 @@ #include #include +#include #include #include #include @@ -54,7 +55,7 @@ class RenderableVolume; class Camera; class Scene; -class FramebufferRenderer : public Renderer, public RaycasterListener { +class FramebufferRenderer : public Renderer, public RaycasterListener, public DeferredcasterListener { public: FramebufferRenderer(); virtual ~FramebufferRenderer(); @@ -64,6 +65,7 @@ public: void updateResolution(); void updateRaycastData(); + void updateDeferredcastData(); void setCamera(Camera* camera) override; void setScene(Scene* scene) override; @@ -80,6 +82,8 @@ public: virtual void updateRendererData() override; virtual void raycastersChanged(VolumeRaycaster& raycaster, bool attached) override; + virtual void deferredcastersChanged(Deferredcaster& deferredcaster, bool attached) override; + private: std::map _raycastData; @@ -87,6 +91,9 @@ private: std::map> _raycastPrograms; std::map> _insideRaycastPrograms; + std::map _deferredcastData; + std::map> _deferredcastPrograms; + std::unique_ptr _resolveProgram; GLuint _screenQuad; @@ -98,6 +105,7 @@ private: GLuint _exitDepthTexture; GLuint _exitFramebuffer; + bool _dirtyDeferredcastData; bool _dirtyRaycastData; bool _dirtyResolution; diff --git a/include/openspace/rendering/renderengine.h b/include/openspace/rendering/renderengine.h index d93b5a000f..373a7a4b58 100644 --- a/include/openspace/rendering/renderengine.h +++ b/include/openspace/rendering/renderengine.h @@ -58,6 +58,7 @@ class SyncBuffer; class Scene; class Renderer; +class DeferredcasterManager; class RaycasterManager; class ScreenLog; class ScreenSpaceRenderable; @@ -90,6 +91,7 @@ public: Renderer* renderer() const; RendererImplementation rendererImplementation() const; RaycasterManager& raycasterManager(); + DeferredcasterManager& deferredcasterManager(); // sgct wrapped functions @@ -184,6 +186,7 @@ private: Camera* _mainCamera; Scene* _sceneGraph; RaycasterManager* _raycasterManager; + DeferredcasterManager* _deferredcasterManager; properties::BoolProperty _performanceMeasurements; std::unique_ptr _performanceManager; diff --git a/include/openspace/util/updatestructures.h b/include/openspace/util/updatestructures.h index 423b30e37a..e6a922575b 100644 --- a/include/openspace/util/updatestructures.h +++ b/include/openspace/util/updatestructures.h @@ -30,6 +30,7 @@ namespace openspace { +class Deferredcaster; class VolumeRaycaster; struct InitializeData { @@ -67,8 +68,14 @@ struct RaycasterTask { RenderData renderData; }; +struct DeferredcasterTask { + Deferredcaster* deferredcaster; + RenderData renderData; +}; + struct RendererTasks { std::vector raycasterTasks; + std::vector deferredTasks; }; struct RaycastData { @@ -76,6 +83,12 @@ struct RaycastData { std::string namespaceName; }; +struct DeferredcastData { + int id; + std::string namespaceName; +}; + + } // namespace openspace #endif // __OPENSPACE_CORE___UPDATESTRUCTURES___H__ diff --git a/modules/atmosphere/rendering/renderableplanetatmosphere.cpp b/modules/atmosphere/rendering/renderableplanetatmosphere.cpp index b24cd3fe04..94d0949ecf 100644 --- a/modules/atmosphere/rendering/renderableplanetatmosphere.cpp +++ b/modules/atmosphere/rendering/renderableplanetatmosphere.cpp @@ -118,6 +118,7 @@ namespace openspace { , _deltaJTableTexture(0) , _atmosphereTexture(0) , _atmosphereDepthTexture(0) + , _cameraDistanceTexture(0) , _atmosphereFBO(0) , _atmosphereRenderVAO(0) , _atmosphereRenderVBO(0) @@ -142,13 +143,16 @@ namespace openspace { , _atmosphereHeightP("atmmosphereHeight", "Atmosphere Height (KM)", 60.0f, 0.1f, 100.0f) , _groundAverageReflectanceP("averageGroundReflectance", "Average Ground Reflectance (%)", 0.1f, 0.0f, 1.0f) , _rayleighHeightScaleP("rayleighHeightScale", "Rayleigh Height Scale (KM)", 8.0f, 0.1f, 20.0f) + , _rayleighScatteringCoeffXP("rayleighScatteringCoeffX", "Rayleigh Scattering Coeff X (x10e-3)", 1.0f, 0.01f, 100.0f) + , _rayleighScatteringCoeffYP("rayleighScatteringCoeffY", "Rayleigh Scattering Coeff Y (x10e-3)", 1.0f, 0.01f, 100.0f) + , _rayleighScatteringCoeffZP("rayleighScatteringCoeffZ", "Rayleigh Scattering Coeff Z (x10e-3)", 1.0f, 0.01f, 100.0f) , _mieHeightScaleP("mieHeightScale", "Mie Height Scale (KM)", 1.2f, 0.1f, 5.0f) , _mieScatteringCoefficientP("mieScatteringCoefficient", "Mie Scattering Coefficient (x10e-3)", 4.0f, 1.0f, 20.0f) , _mieScatteringExtinctionPropCoefficientP("mieScatteringExtinctionPropCoefficient", "Mie Scattering/Extinction Proportion Coefficient (%)", 0.9f, 0.1f, 1.0f) , _mieAsymmetricFactorGP("mieAsymmetricFactorG", "Mie Asymmetric Factor G", 1.0f, -1.0f, 1.0f) - , _sunIntensityP("sunIntensity", "Sun Intensity", 50.0f, 0.1f, 100.0f) - , _hdrExpositionP("hdrExposition", "HDR", 0.0f, 0.05f, 1.0f) + , _sunIntensityP("sunIntensity", "Sun Intensity", 50.0f, 0.1f, 200.0f) + , _hdrExpositionP("hdrExposition", "HDR", 0.0f, 0.05f, 5.0f) { std::string name; bool success = dictionary.getValue(SceneGraphNode::KeyName, name); @@ -334,7 +338,7 @@ namespace openspace { } //================================================================ - //=========== Reads Atmosphere Entries in mod file =============== + //========== Reads Atmosphere Entries from mod file ============== //================================================================ bool errorReadingAtmosphereData = false; ghoul::Dictionary atmosphereDictionary; @@ -436,6 +440,18 @@ namespace openspace { _rayleighHeightScaleP.onChange(std::bind(&RenderablePlanetAtmosphere::updateAtmosphereParameters, this)); addProperty(_rayleighHeightScaleP); + _rayleighScatteringCoeffXP.set(_rayleighScatteringCoeff.x * 1000.0f); + _rayleighScatteringCoeffXP.onChange(std::bind(&RenderablePlanetAtmosphere::updateAtmosphereParameters, this)); + addProperty(_rayleighScatteringCoeffXP); + + _rayleighScatteringCoeffYP.set(_rayleighScatteringCoeff.y * 1000.0f); + _rayleighScatteringCoeffYP.onChange(std::bind(&RenderablePlanetAtmosphere::updateAtmosphereParameters, this)); + addProperty(_rayleighScatteringCoeffYP); + + _rayleighScatteringCoeffZP.set(_rayleighScatteringCoeff.z * 1000.0f); + _rayleighScatteringCoeffZP.onChange(std::bind(&RenderablePlanetAtmosphere::updateAtmosphereParameters, this)); + addProperty(_rayleighScatteringCoeffZP); + _mieHeightScaleP.set(_mieHeightScale); _mieHeightScaleP.onChange(std::bind(&RenderablePlanetAtmosphere::updateAtmosphereParameters, this)); addProperty(_mieHeightScaleP); @@ -550,7 +566,7 @@ namespace openspace { //======================================================================== //============ Pre-compute all necessary Atmosphere Tables ============== //======================================================================== - if (_atmosphereEnabled && !_atmosphereCalculated) { + if (_atmosphereEnabled && !_atmosphereCalculated) { preCalculateAtmosphereParam(); #ifdef _ATMOSPHERE_DEBUG // DEBUG: FBO for atmosphere deferred rendering. @@ -559,6 +575,8 @@ namespace openspace { count = 0; #endif _atmosphereCalculated = true; + + glGenTextures(1, &_cameraDistanceTexture); } return isReady(); @@ -655,6 +673,11 @@ namespace openspace { } void RenderablePlanetAtmosphere::render(const RenderData& data) { + + GLint defaultFBO; + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO); + + // activate shader _programObject->activate(); @@ -815,8 +838,7 @@ namespace openspace { } counter++; } - } - + } //============================================================================= //================== Atmosphere Rendering and Uniforms Loading ================ @@ -947,28 +969,29 @@ namespace openspace { glBindFramebuffer(GL_FRAMEBUFFER, _atmosphereFBO); GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }; - glDrawBuffers(2, drawBuffers); + //glDrawBuffers(2, drawBuffers); + glDrawBuffers(1, drawBuffers); - ghoul::opengl::TextureUnit dummyTextureUnit; - if (!glIsTexture(_dummyTexture)) { - dummyTextureUnit.activate(); - glGenTextures(1, &_dummyTexture); - //glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _dummyTexture); - glBindTexture(GL_TEXTURE_2D, _dummyTexture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_viewport[2], - m_viewport[3], 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr); - /*glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 8, GL_RGBA, - m_viewport[2], m_viewport[3], true);*/ - } +// ghoul::opengl::TextureUnit dummyTextureUnit; +// if (!glIsTexture(_dummyTexture)) { +// dummyTextureUnit.activate(); +// glGenTextures(1, &_dummyTexture); +// //glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _dummyTexture); +// glBindTexture(GL_TEXTURE_2D, _dummyTexture); +// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); +// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); +// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); +// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); +// glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); +// glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_viewport[2], +// m_viewport[3], 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr); +// /*glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 8, GL_RGBA, +// m_viewport[2], m_viewport[3], true);*/ +// } - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _dummyTexture, 0); - checkFrameBufferState("dummy framebuffer - line 955"); - //glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, _atmosphereTexture, 0); + //glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _dummyTexture, 0); + //checkFrameBufferState("dummy framebuffer - line 955"); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _atmosphereTexture, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, _atmosphereDepthTexture, 0); checkFrameBufferState("deferred atmosphere framebuffer - line 958"); @@ -1003,83 +1026,83 @@ namespace openspace { // The following scale comes from PSC transformations. float fScaleFactor = data.camera.scaling().x * pow(10.0, data.camera.scaling().y); //std::cout << "\n Scaling Factor: " << fScaleFactor << std::endl; - glm::mat4 fScaleCamTransf = glm::scale(glm::vec3(fScaleFactor)); + //glm::mat4 fScaleCamTransf = glm::scale(glm::vec3(fScaleFactor)); glm::dmat4 dfScaleCamTransf = glm::scale(glm::dvec3(fScaleFactor)); - _deferredAtmosphereProgramObject->setUniform("scaleTransformMatrix", fScaleCamTransf); + //_deferredAtmosphereProgramObject->setUniform("scaleTransformMatrix", fScaleCamTransf); _deferredAtmosphereProgramObject->setUniform("dScaleTransformMatrix", dfScaleCamTransf); - _deferredAtmosphereProgramObject->setUniform("inverseScaleTransformMatrix", glm::inverse(fScaleCamTransf)); + //_deferredAtmosphereProgramObject->setUniform("inverseScaleTransformMatrix", glm::inverse(fScaleCamTransf)); _deferredAtmosphereProgramObject->setUniform("dInverseScaleTransformMatrix", glm::inverse(dfScaleCamTransf)); //std::cout << "\n fScaleCamTransf: " << glm::to_string(fScaleCamTransf) << std::endl; // Object Space to World Space (in meters) - glm::mat4 obj2World = glm::translate(glm::mat4(1.0), data.position.vec3()) * transform; + //glm::mat4 obj2World = glm::translate(glm::mat4(1.0), data.position.vec3()) * transform; glm::dmat4 dObj2World = glm::translate(data.position.dvec3()) * glm::dmat4(transform); - glm::mat4 world2Obj = glm::inverse(obj2World); + //glm::mat4 world2Obj = glm::inverse(obj2World); glm::dmat4 dWorld2Obj = glm::inverse(dObj2World); - _deferredAtmosphereProgramObject->setUniform("objToWorldTransform", obj2World); - _deferredAtmosphereProgramObject->setUniform("worldToObjectTransform", world2Obj); + //_deferredAtmosphereProgramObject->setUniform("objToWorldTransform", obj2World); + //_deferredAtmosphereProgramObject->setUniform("worldToObjectTransform", world2Obj); _deferredAtmosphereProgramObject->setUniform("dObjToWorldTransform", dObj2World); _deferredAtmosphereProgramObject->setUniform("dWorldToObjectTransform", dWorld2Obj); // World to Eye Space in OS - glm::mat4 world2Eye = fScaleCamTransf * glm::mat4(data.camera.viewRotationMatrix()) * - glm::translate(-data.camera.position().vec3()); + //glm::mat4 world2Eye = fScaleCamTransf * glm::mat4(data.camera.viewRotationMatrix()) * + // glm::translate(-data.camera.position().vec3()); glm::dmat4 dWorld2Eye = dfScaleCamTransf * data.camera.viewRotationMatrix() * glm::translate(-data.camera.position().dvec3()); - glm::mat4 eye2World = glm::inverse(world2Eye); + //glm::mat4 eye2World = glm::inverse(world2Eye); glm::dmat4 dEye2World = glm::inverse(dWorld2Eye); - _deferredAtmosphereProgramObject->setUniform("inverseCamRotTransform", glm::inverse(glm::mat4(data.camera.viewRotationMatrix()))); + //_deferredAtmosphereProgramObject->setUniform("inverseCamRotTransform", glm::inverse(glm::mat4(data.camera.viewRotationMatrix()))); _deferredAtmosphereProgramObject->setUniform("dInverseCamRotTransform", glm::inverse(data.camera.viewRotationMatrix())); - _deferredAtmosphereProgramObject->setUniform("worldToOsEyeTransform", world2Eye); - _deferredAtmosphereProgramObject->setUniform("osEyeToWorldTransform", eye2World); + //_deferredAtmosphereProgramObject->setUniform("worldToOsEyeTransform", world2Eye); + //_deferredAtmosphereProgramObject->setUniform("osEyeToWorldTransform", eye2World); _deferredAtmosphereProgramObject->setUniform("dWorldToOsEyeTransform", dWorld2Eye); _deferredAtmosphereProgramObject->setUniform("dOsEyeToWorldTransform", dEye2World); // Eye Space in OS to Eye Space in SGCT - glm::mat4 osEye2SGCTEye = data.camera.viewMatrix(); + //glm::mat4 osEye2SGCTEye = data.camera.viewMatrix(); glm::dmat4 dOsEye2SGCTEye = glm::dmat4(data.camera.viewMatrix()); - glm::mat4 sgctEye2OSEye = glm::inverse(osEye2SGCTEye); + //glm::mat4 sgctEye2OSEye = glm::inverse(osEye2SGCTEye); glm::dmat4 dSgctEye2OSEye = glm::inverse(dOsEye2SGCTEye); - _deferredAtmosphereProgramObject->setUniform("osEyeToSGCTEyeTranform", osEye2SGCTEye); - _deferredAtmosphereProgramObject->setUniform("sgctEyeToOSEyeTranform", sgctEye2OSEye); + //_deferredAtmosphereProgramObject->setUniform("osEyeToSGCTEyeTranform", osEye2SGCTEye); + //_deferredAtmosphereProgramObject->setUniform("sgctEyeToOSEyeTranform", sgctEye2OSEye); _deferredAtmosphereProgramObject->setUniform("dOsEyeToSGCTEyeTranform", dOsEye2SGCTEye); _deferredAtmosphereProgramObject->setUniform("dSgctEyeToOSEyeTranform", dSgctEye2OSEye); // Eye Space in SGCT to Projection (Clip) Space in SGCT - glm::mat4 sgctEye2Clip = data.camera.projectionMatrix(); + //glm::mat4 sgctEye2Clip = data.camera.projectionMatrix(); glm::dmat4 dSgctEye2Clip = glm::dmat4(data.camera.projectionMatrix()); - glm::mat4 inverseProjection = glm::inverse(sgctEye2Clip); + //glm::mat4 inverseProjection = glm::inverse(sgctEye2Clip); glm::dmat4 dInverseProjection = glm::inverse(dSgctEye2Clip); - _deferredAtmosphereProgramObject->setUniform("sgctEyeToClipTranform", sgctEye2Clip); - _deferredAtmosphereProgramObject->setUniform("inverseSgctProjectionMatrix", inverseProjection); + //_deferredAtmosphereProgramObject->setUniform("sgctEyeToClipTranform", sgctEye2Clip); + //_deferredAtmosphereProgramObject->setUniform("inverseSgctProjectionMatrix", inverseProjection); _deferredAtmosphereProgramObject->setUniform("dSgctEyeToClipTranform", dSgctEye2Clip); _deferredAtmosphereProgramObject->setUniform("dInverseSgctProjectionMatrix", dInverseProjection); /*std::cout << "\nProjection: " << glm::to_string(data.camera.projectionMatrix()) << std::endl; std::cout << "\nInverse Projection: " << glm::to_string(inverseProjection) << std::endl;*/ - glm::mat4 completeVertexTransformations = data.camera.viewProjectionMatrix() * - glm::mat4(data.camera.viewRotationMatrix()) * - glm::translate(glm::mat4(1.0), -data.camera.position().vec3()) * - glm::translate(glm::mat4(1.0), data.position.vec3()) - * transform; - glm::mat4 inverseCompleteVertexTransformations = glm::inverse(completeVertexTransformations); + //glm::mat4 completeVertexTransformations = data.camera.viewProjectionMatrix() * + // glm::mat4(data.camera.viewRotationMatrix()) * + // glm::translate(glm::mat4(1.0), -data.camera.position().vec3()) * + // glm::translate(glm::mat4(1.0), data.position.vec3()) + // * transform; + //glm::mat4 inverseCompleteVertexTransformations = glm::inverse(completeVertexTransformations); - glm::dmat4 dCompleteVertexTransformations = glm::dmat4(data.camera.viewProjectionMatrix()) * - data.camera.viewRotationMatrix() * - glm::translate(glm::dmat4(1.0), -data.camera.position().dvec3()) * - glm::translate(glm::dmat4(1.0), data.position.dvec3()) - * glm::dmat4(transform); - glm::dmat4 dInverseCompleteVertexTransformations = glm::inverse(dCompleteVertexTransformations); + //glm::dmat4 dCompleteVertexTransformations = glm::dmat4(data.camera.viewProjectionMatrix()) * + // data.camera.viewRotationMatrix() * + // glm::translate(glm::dmat4(1.0), -data.camera.position().dvec3()) * + // glm::translate(glm::dmat4(1.0), data.position.dvec3()) + // * glm::dmat4(transform); + //glm::dmat4 dInverseCompleteVertexTransformations = glm::inverse(dCompleteVertexTransformations); - _deferredAtmosphereProgramObject->setUniform("completeVertexTransform", completeVertexTransformations); - _deferredAtmosphereProgramObject->setUniform("inverseCompleteVertexTransform", inverseCompleteVertexTransformations); - _deferredAtmosphereProgramObject->setUniform("dCompleteVertexTransform", dCompleteVertexTransformations); - _deferredAtmosphereProgramObject->setUniform("dInverseCompleteVertexTransform", dInverseCompleteVertexTransformations); + //_deferredAtmosphereProgramObject->setUniform("completeVertexTransform", completeVertexTransformations); + //_deferredAtmosphereProgramObject->setUniform("inverseCompleteVertexTransform", inverseCompleteVertexTransformations); + //_deferredAtmosphereProgramObject->setUniform("dCompleteVertexTransform", dCompleteVertexTransformations); + //_deferredAtmosphereProgramObject->setUniform("dInverseCompleteVertexTransform", dInverseCompleteVertexTransformations); - _deferredAtmosphereProgramObject->setUniform("sgctProjectionMatrix", data.camera.projectionMatrix()); - _deferredAtmosphereProgramObject->setUniform("inverseSgctProjectionMatrix", inverseProjection); + //_deferredAtmosphereProgramObject->setUniform("sgctProjectionMatrix", data.camera.projectionMatrix()); + //_deferredAtmosphereProgramObject->setUniform("inverseSgctProjectionMatrix", inverseProjection); _deferredAtmosphereProgramObject->setUniform("dSgctProjectionMatrix", glm::dmat4(data.camera.projectionMatrix())); _deferredAtmosphereProgramObject->setUniform("dInverseSgctProjectionMatrix", dInverseProjection); /*std::cout << "\nProjection: " << glm::to_string(data.camera.projectionMatrix()) << std::endl; @@ -1091,46 +1114,46 @@ namespace openspace { // Testing Transformations: //=========================== // Origin - glm::vec4 planetCenterOrigin = glm::vec4(1000.0, 1000.0, 1000.0, 1.0); - glm::dvec4 dPlanetCenterOrigin = glm::vec4(1000.0, 1000.0, 1000.0, 1.0); + //glm::vec4 planetCenterOrigin = glm::vec4(1000.0, 1000.0, 1000.0, 1.0); + //glm::dvec4 dPlanetCenterOrigin = glm::vec4(1000.0, 1000.0, 1000.0, 1.0); //std::cout << "Planet Position in OS Object Space: " << glm::to_string(planetCenterOrigin) << std::endl; // Object Coords to World Coords - glm::vec4 planetCenterTmp = transform * planetCenterOrigin; - glm::dvec4 dPlanetCenterTmp = glm::dmat4(transform) * dPlanetCenterOrigin; + //glm::vec4 planetCenterTmp = transform * planetCenterOrigin; + //glm::dvec4 dPlanetCenterTmp = glm::dmat4(transform) * dPlanetCenterOrigin; //std::cout << "Planet Position in OS World Space After Transf: " << glm::to_string(dPlanetCenterTmp) << std::endl; - glm::vec4 planetCenterTmpWorld = planetCenterTmp + glm::vec4(data.position.vec3(), 0.0); - glm::dvec4 dPlanetCenterTmpWorld = dPlanetCenterTmp + glm::dvec4(data.position.dvec3(), 0.0); + //glm::vec4 planetCenterTmpWorld = planetCenterTmp + glm::vec4(data.position.vec3(), 0.0); + //glm::dvec4 dPlanetCenterTmpWorld = dPlanetCenterTmp + glm::dvec4(data.position.dvec3(), 0.0); //std::cout << "Planet Position in OS World Space After Transl: " << glm::to_string(dPlanetCenterTmpWorld) << std::endl; //std::cout << "Object Translation Vector: " << glm::to_string(data.position.dvec3()) << std::endl; //std::cout << "Planet Position in OS World Space (f): " << glm::to_string(planetCenterTmpWorld) << std::endl; //std::cout << "Planet Position in OS World Space (d): " << glm::to_string(dPlanetCenterTmpWorld) << std::endl; // World Coords to Camera Rig (OS Eye) Coords - glm::vec4 planetCenterTmpOSEye = planetCenterTmpWorld + glm::vec4(-data.camera.positionVec3(), 0.0); - glm::dvec4 dPlanetCenterTmpOSEye = dPlanetCenterTmpWorld + glm::dvec4(-data.camera.positionVec3(), 0.0); - glm::vec3 tt = glm::mat3(data.camera.viewRotationMatrix()) * glm::vec3(planetCenterTmpOSEye); - glm::dvec3 dtt = glm::dmat3(data.camera.viewRotationMatrix()) * glm::dvec3(dPlanetCenterTmpOSEye); - planetCenterTmpOSEye.x = tt.x; planetCenterTmpOSEye.y = tt.y; planetCenterTmpOSEye.z = tt.z; planetCenterTmpOSEye.w = 1.0; - dPlanetCenterTmpOSEye.x = dtt.x; dPlanetCenterTmpOSEye.y = dtt.y; dPlanetCenterTmpOSEye.z = dtt.z; dPlanetCenterTmpOSEye.w = 1.0; - float scaleF = data.camera.scaling().x * powf(10.0, data.camera.scaling().y); - double dScaleF = static_cast(data.camera.scaling().x) * pow(10.0, static_cast(data.camera.scaling().y)); - glm::mat4 scaleM = glm::scale(glm::vec3(scaleF)); - glm::dmat4 dScaleM = glm::scale(glm::dvec3(dScaleF)); - planetCenterTmpOSEye = scaleM * planetCenterTmpOSEye; - dPlanetCenterTmpOSEye = dScaleM * dPlanetCenterTmpOSEye; + //glm::vec4 planetCenterTmpOSEye = planetCenterTmpWorld + glm::vec4(-data.camera.positionVec3(), 0.0); + //glm::dvec4 dPlanetCenterTmpOSEye = dPlanetCenterTmpWorld + glm::dvec4(-data.camera.positionVec3(), 0.0); + //glm::vec3 tt = glm::mat3(data.camera.viewRotationMatrix()) * glm::vec3(planetCenterTmpOSEye); + //glm::dvec3 dtt = glm::dmat3(data.camera.viewRotationMatrix()) * glm::dvec3(dPlanetCenterTmpOSEye); + //planetCenterTmpOSEye.x = tt.x; planetCenterTmpOSEye.y = tt.y; planetCenterTmpOSEye.z = tt.z; planetCenterTmpOSEye.w = 1.0; + //dPlanetCenterTmpOSEye.x = dtt.x; dPlanetCenterTmpOSEye.y = dtt.y; dPlanetCenterTmpOSEye.z = dtt.z; dPlanetCenterTmpOSEye.w = 1.0; + //float scaleF = data.camera.scaling().x * powf(10.0, data.camera.scaling().y); + //double dScaleF = static_cast(data.camera.scaling().x) * pow(10.0, static_cast(data.camera.scaling().y)); + //glm::mat4 scaleM = glm::scale(glm::vec3(scaleF)); + //glm::dmat4 dScaleM = glm::scale(glm::dvec3(dScaleF)); + //planetCenterTmpOSEye = scaleM * planetCenterTmpOSEye; + //dPlanetCenterTmpOSEye = dScaleM * dPlanetCenterTmpOSEye; //std::cout << "Planet Position in OS Eye Space (f): " << glm::to_string(planetCenterTmpOSEye) << std::endl; //std::cout << "Planet Position in OS Eye Space (d): " << glm::to_string(dPlanetCenterTmpOSEye) << std::endl; // Camera Rig (OS Eye) to SGCT Eye Coords - glm::vec4 planetCenterTmpSGCTEye = data.camera.viewMatrix() * planetCenterTmpOSEye; - glm::dvec4 dPlanetCenterTmpSGCTEye = glm::dmat4(data.camera.viewMatrix()) * dPlanetCenterTmpOSEye; + //glm::vec4 planetCenterTmpSGCTEye = data.camera.viewMatrix() * planetCenterTmpOSEye; + //glm::dvec4 dPlanetCenterTmpSGCTEye = glm::dmat4(data.camera.viewMatrix()) * dPlanetCenterTmpOSEye; //std::cout << "Planet Position in SGCT Eye Space (f): " << glm::to_string(planetCenterTmpSGCTEye) << std::endl; //std::cout << "Planet Position in SGCT Eye Space (d): " << glm::to_string(dPlanetCenterTmpSGCTEye) << std::endl; // SGCT Eye Coords to SGCT Clip Coords - glm::vec4 planetCenterTmpSGCTView = data.camera.projectionMatrix() * planetCenterTmpSGCTEye; - glm::dvec4 dPlanetCenterTmpSGCTView = glm::dmat4(data.camera.projectionMatrix()) * dPlanetCenterTmpSGCTEye; + //glm::vec4 planetCenterTmpSGCTView = data.camera.projectionMatrix() * planetCenterTmpSGCTEye; + //glm::dvec4 dPlanetCenterTmpSGCTView = glm::dmat4(data.camera.projectionMatrix()) * dPlanetCenterTmpSGCTEye; //std::cout << "Planet Position in SGCT Clip Space (f): " << glm::to_string(planetCenterTmpSGCTView) << std::endl; //std::cout << "Planet Position in SGCT Clip Space (d): " << glm::to_string(dPlanetCenterTmpSGCTView) << std::endl; @@ -2136,6 +2159,8 @@ namespace openspace { _atmosphereRadius = _atmospherePlanetRadius + _atmosphereHeightP; _planetAverageGroundReflectance = _groundAverageReflectanceP; _rayleighHeightScale = _rayleighHeightScaleP; + _rayleighScatteringCoeff = glm::vec3(_rayleighScatteringCoeffXP * 0.001f, _rayleighScatteringCoeffYP * 0.001f, + _rayleighScatteringCoeffZP * 0.001f); _mieHeightScale = _mieHeightScaleP; _mieScatteringCoeff = glm::vec3(_mieScatteringCoefficientP * 0.001f); _mieExtinctionCoeff = _mieScatteringCoeff * (1.0f / static_cast(_mieScatteringExtinctionPropCoefficientP)); diff --git a/modules/atmosphere/rendering/renderableplanetatmosphere.h b/modules/atmosphere/rendering/renderableplanetatmosphere.h index a028817b56..bc768fba24 100644 --- a/modules/atmosphere/rendering/renderableplanetatmosphere.h +++ b/modules/atmosphere/rendering/renderableplanetatmosphere.h @@ -79,16 +79,18 @@ namespace openspace { const unsigned int DELTA_E_TABLE_WIDTH = 64; const unsigned int DELTA_E_TABLE_HEIGHT = 16; + - - /*const unsigned int TRANSMITTANCE_TABLE_WIDTH = 512; + /* + const unsigned int TRANSMITTANCE_TABLE_WIDTH = 512; const unsigned int TRANSMITTANCE_TABLE_HEIGHT = 128; const unsigned int IRRADIANCE_TABLE_WIDTH = 128; const unsigned int IRRADIANCE_TABLE_HEIGHT = 32; const unsigned int DELTA_E_TABLE_WIDTH = 128; - const unsigned int DELTA_E_TABLE_HEIGHT = 32;*/ + const unsigned int DELTA_E_TABLE_HEIGHT = 32; + */ const unsigned int R_SAMPLES = 32; const unsigned int MU_SAMPLES = 128; @@ -174,6 +176,8 @@ namespace openspace { GLuint _atmosphereTexture; GLuint _atmosphereDepthTexture; + GLuint _cameraDistanceTexture; + // Deferred debug rendering GLuint _atmosphereFBO; GLuint _atmosphereRenderVAO; @@ -191,6 +195,9 @@ namespace openspace { properties::FloatProperty _atmosphereHeightP; properties::FloatProperty _groundAverageReflectanceP; properties::FloatProperty _rayleighHeightScaleP; + properties::FloatProperty _rayleighScatteringCoeffXP; + properties::FloatProperty _rayleighScatteringCoeffYP; + properties::FloatProperty _rayleighScatteringCoeffZP; properties::FloatProperty _mieHeightScaleP; properties::FloatProperty _mieScatteringCoefficientP; properties::FloatProperty _mieScatteringExtinctionPropCoefficientP; diff --git a/modules/atmosphere/shaders/atmosphere_common.glsl b/modules/atmosphere/shaders/atmosphere_common.glsl index dd3c6b2ed6..e8a300bd3c 100644 --- a/modules/atmosphere/shaders/atmosphere_common.glsl +++ b/modules/atmosphere/shaders/atmosphere_common.glsl @@ -79,6 +79,16 @@ const int SKY_H = 16; const int OTHER_TEXTURES_W = 64; const int OTHER_TEXTURES_H = 16; +// const int TRANSMITTANCE_W = 512; +// const int TRANSMITTANCE_H = 128; + +// const int SKY_W = 128; +// const int SKY_H = 32; + +// const int OTHER_TEXTURES_W = 128; +// const int OTHER_TEXTURES_H = 32; + + // cosines sampling const int SAMPLES_R = 32; const int SAMPLES_MU = 128; @@ -87,6 +97,28 @@ const int SAMPLES_NU = 8; uniform sampler2D transmittanceTexture; +float opticalDepth(float H, float r, float mu, float d) { + float a = sqrt((0.5/H)*r); + vec2 a01 = a*vec2(mu, mu + d / r); + vec2 a01s = sign(a01); + vec2 a01sq = a01*a01; + float x = a01s.y > a01s.x ? exp(a01sq.x) : 0.0; + vec2 y = a01s / (2.3193*abs(a01) + sqrt(1.52*a01sq + 4.0)) * vec2(1.0, exp(-d/H*(d/(2.0*r)+mu))); + return sqrt((6.2831*H)*r) * exp((Rg-r)/H) * (x + dot(y, vec2(1.0, -1.0))); +} + +vec3 analyticTransmittance(float r, float mu, float d) { + return exp(- betaRayleigh * opticalDepth(HR, r, mu, d) - + betaMieExtinction * opticalDepth(HM, r, mu, d)); +} + +vec3 irradiance(sampler2D sampler, const float r, const float muSun) { + float u_r = (r - Rg) / (Rt - Rg); + float u_muSun = (muSun + 0.2) / (1.0 + 0.2); + return texture(sampler, vec2(u_muSun, u_r)).rgb; +} + + //================================================// //=============== General Functions ==============// //================================================// diff --git a/modules/atmosphere/shaders/atmosphere_deferred_fs.glsl b/modules/atmosphere/shaders/atmosphere_deferred_fs.glsl index c4325d552c..d34c57e475 100644 --- a/modules/atmosphere/shaders/atmosphere_deferred_fs.glsl +++ b/modules/atmosphere/shaders/atmosphere_deferred_fs.glsl @@ -217,34 +217,6 @@ bool dAtmosphereIntersection(const dvec3 planetPosition, const dRay ray, const d return true; } - -float opticalDepth(float H, float r, float mu, float d) { - float a = sqrt((0.5/H)*r); - vec2 a01 = a*vec2(mu, mu + d / r); - vec2 a01s = sign(a01); - vec2 a01sq = a01*a01; - float x = a01s.y > a01s.x ? exp(a01sq.x) : 0.0; - vec2 y = a01s / (2.3193*abs(a01) + sqrt(1.52*a01sq + 4.0)) * vec2(1.0, exp(-d/H*(d/(2.0*r)+mu))); - return sqrt((6.2831*H)*r) * exp((Rg-r)/H) * (x + dot(y, vec2(1.0, -1.0))); -} - -vec3 analyticTransmittance(float r, float mu, float d) { - return exp(- betaRayleigh * opticalDepth(HR, r, mu, d) - - betaMieExtinction * opticalDepth(HM, r, mu, d)); -} - -// vec2 getIrradianceUV(float r, float muSun) { -// float uR = (r - Rg) / (Rt - Rg); -// float uMuS = (muSun + 0.2) / (1.0 + 0.2); -// return vec2(uMuS, uR); -// } - -vec3 irradiance(sampler2D sampler, const float r, const float muSun) { - float u_r = (r - Rg) / (Rt - Rg); - float u_muSun = (muSun + 0.2) / (1.0 + 0.2); - return texture(sampler, vec2(u_muSun, u_r)).rgb; -} - /* * Calculates the light scattering in the view direction comming from other * light rays scattered in the atmosphere. @@ -255,7 +227,7 @@ vec3 irradiance(sampler2D sampler, const float r, const float muSun) { * x := camera position * t := ray displacement variable after calculating the intersection with the * atmosphere. It is the distance from the camera to the last intersection with - * the atmosphere + * the atmosphere. If the ray hits the ground, t is updated to the correct value * v := view direction (ray's direction) (normalized) * s := Sun direction (normalized) * r := out of ||x|| inside atmosphere (or top of atmosphere) @@ -321,8 +293,8 @@ vec3 inscatterRadiance(inout vec3 x, inout float t, const vec3 v, const vec3 s, if (t > 0.0) { // Here we must test if we are hitting the ground: bool insideATM = false; - double offset = 0.0f; - double maxLength = 0.0f; + double offset = 0.0; + double maxLength = 0.0; dRay ray; ray.direction = vec4(v, 0.0); ray.origin = vec4(x, 1.0); @@ -619,8 +591,8 @@ void main() { //dCalculateInterpolatedRay(ray, planetPositionObjectCoords); bool insideATM = false; - double offset = 0.0f; - double maxLength = 0.0f; + double offset = 0.0; + double maxLength = 0.0; bool intersectATM = dAtmosphereIntersection(planetPositionObjectCoords.xyz, ray, Rt, insideATM, offset, maxLength ); if ( intersectATM ) { @@ -664,12 +636,12 @@ void main() { vec3 groundColor = groundColor(x, tF, v, s, r, mu, attenuation); vec3 sunColor = sunColor(x, tF, v, s, r, mu); - //renderTarget = vec4(HDR(inscatterColor), 1.0); + renderTarget = vec4(HDR(inscatterColor), 1.0); //renderTarget = vec4(HDR(groundColor), 1.0); //renderTarget = vec4(groundColor, 1.0); //renderTarget = vec4(HDR(sunColor), 1.0); //renderTarget = vec4(HDR(sunColor), 1.0); - renderTarget = vec4(HDR(inscatterColor + groundColor + inscatterColor), 1.0); + //renderTarget = vec4(HDR(inscatterColor + groundColor + inscatterColor), 1.0); } else { renderTarget = vec4(0.0, 0.0, 0.0, 1.0); diff --git a/modules/atmosphere/shaders/atmosphere_fs.glsl b/modules/atmosphere/shaders/atmosphere_fs.glsl index 9a34aa12af..fcbba33652 100644 --- a/modules/atmosphere/shaders/atmosphere_fs.glsl +++ b/modules/atmosphere/shaders/atmosphere_fs.glsl @@ -62,7 +62,6 @@ uniform sampler2D nightTex; uniform sampler2D cloudsTexture; uniform sampler2D reflectanceTexture; -//uniform sampler2D transmittanceTexture; uniform sampler2D irradianceTexture; uniform sampler3D inscatterTexture; @@ -79,6 +78,8 @@ in vec4 vs_posWorld; #include "fragment.glsl" #include "atmosphere_common.glsl" +layout(location = 1) out vec4 cameraDistanceTextureTarget; + vec4 butterworthFunc(const float d, const float r, const float n) { return vec4(vec3(sqrt(r/(r + pow(d, 2*n)))), 1.0); } @@ -99,73 +100,6 @@ struct Ray { vec4 direction; }; -struct Ellipsoid { - vec4 center; - vec4 size; -}; - -bool intersectEllipsoid(const Ray ray, const Ellipsoid ellipsoid, out float offset, out float maxLength) { - vec4 O_C = ray.origin-ellipsoid.center; - vec4 dir = normalize(ray.direction); - - offset = 0.0f; - maxLength = 0.0f; - - float a = - ((dir.x*dir.x)/(ellipsoid.size.x*ellipsoid.size.x)) - + ((dir.y*dir.y)/(ellipsoid.size.y*ellipsoid.size.y)) - + ((dir.z*dir.z)/(ellipsoid.size.z*ellipsoid.size.z)); - float b = - ((2.f*O_C.x*dir.x)/(ellipsoid.size.x*ellipsoid.size.x)) - + ((2.f*O_C.y*dir.y)/(ellipsoid.size.y*ellipsoid.size.y)) - + ((2.f*O_C.z*dir.z)/(ellipsoid.size.z*ellipsoid.size.z)); - float c = - ((O_C.x*O_C.x)/(ellipsoid.size.x*ellipsoid.size.x)) - + ((O_C.y*O_C.y)/(ellipsoid.size.y*ellipsoid.size.y)) - + ((O_C.z*O_C.z)/(ellipsoid.size.z*ellipsoid.size.z)) - - 1.f; - - float d = ((b*b)-(4.f*a*c)); - if ( d<0.f || a==0.f || b==0.f || c==0.f ) - return false; - - d = sqrt(d); - - float t1 = (-b+d)/(2.f*a); - float t2 = (-b-d)/(2.f*a); - - if( t1<=EPSILON && t2<=EPSILON ) - return false; // both intersections are behind the ray origin - - // If only one intersection (t>0) then we are inside the ellipsoid and - // the intersection is at the back of the ellipsoid - bool back = (t1<=EPSILON || t2<=EPSILON); - float t = 0.f; - - if( t1 <= EPSILON ) { - t = t2; - } else { - if( t2 <= EPSILON ) - t = t1; - else - t = (t1 < t2) ? t1 : t2; - } - if( t < EPSILON ) return false; // Too close to intersection - - vec4 intersection = ray.origin + t*dir; - vec4 normal = intersection - ellipsoid.center; - - normal.x = 2.f*normal.x/(ellipsoid.size.x*ellipsoid.size.x); - normal.y = 2.f*normal.y/(ellipsoid.size.y*ellipsoid.size.y); - normal.z = 2.f*normal.z/(ellipsoid.size.z*ellipsoid.size.z); - - normal.w = 0.f; - normal *= (back) ? -1.f : 1.f; - normal = normalize(normal); - - return true; -} - bool intersectAtmosphere(const vec4 planetPos, const vec3 rayDirection, const float sphereRadius, out float offset, out float maxLength) { offset = 0.0f; @@ -202,125 +136,6 @@ bool intersectAtmosphere(const vec4 planetPos, const vec3 rayDirection, const fl return false; } -bool intersectATM(const vec4 cameraPos, const vec3 rayDirection, - out float t) { - vec3 x = cameraPos.xyz; - vec3 v = normalize(rayDirection); - - float r = length(x); - float mu = dot(x, v) / r; - t = -r * mu - sqrt(r * r * (mu * mu - 1.0) + Rg * Rg); - - vec3 g = x - vec3(0.0, 0.0, Rg + 10.0); - float a = v.x * v.x + v.y * v.y - v.z * v.z; - float b = 2.0 * (g.x * v.x + g.y * v.y - g.z * v.z); - float c = g.x * g.x + g.y * g.y - g.z * g.z; - float d = -(b + sqrt(b * b - 4.0 * a * c)) / (2.0 * a); - bool cone = d > 0.0 && abs(x.z + d * v.z - Rg) <= 10.0; - - if (t > 0.0) { - if (cone && d < t) { - t = d; - return true; - } else { - return false; - } - } else if (cone) { - t = d; - } else { - return false; - } -} - -/* Function to calculate the initial intersection of the eye (camera) ray - * with the atmosphere. - * In (all parameters in the same coordinate system and same units): - * - planet position - * - ray direction (normalized) - * - eye position - * - atmosphere radius - * Out: true if an intersection happens, false otherwise - * - inside: true if the ray origin is inside atmosphere, false otherwise - * - offset: the initial intersection distance from eye position when - * the eye is outside the atmosphere - * - maxLength : the second intersection distance from eye position when the - * eye is inside the atmosphere or the initial (and only) - * intersection of the ray with atmosphere when the eye position - * is inside atmosphere. - */ -bool atmosphereIntersection(const vec3 planetPosition, const vec3 rayDirection, - const vec3 rayOrigin, const float atmRadius, - out bool inside, out float offset, out float maxLength ) { - vec3 l = planetPosition - rayOrigin; - float s = dot(l, rayDirection); - float l2 = dot(l, l); - float r2 = (atmRadius - EPSILON) * (atmRadius - EPSILON); // avoiding surface acne - - // Ray origin (eye position) is behind sphere - if ((s < 0.0f) && (l2 > r2)) { - inside = false; - offset = 0.0f; - maxLength = 0.0f; - return false; - } - - float m2 = l2 - s*s; - - // Ray misses atmospere - if (m2 > r2) { - inside = false; - offset = 0.0f; - maxLength = 0.0f; - return false; - } - - // We already now the ray hits the atmosphere - - // If q = 0.0f, there is only one intersection - float q = sqrt(r2 - m2); - - // If l2 < r2, the ray origin is inside the sphere - if (l2 > r2) { - inside = false; - offset = s - q; - maxLength = s + q; - } else { - inside = true; - offset = 0.0f; - maxLength = s + q; - } - - return true; -} - - - -float opticalDepth(float H, float r, float mu, float d) { - float a = sqrt((0.5/H)*r); - vec2 a01 = a*vec2(mu, mu + d / r); - vec2 a01s = sign(a01); - vec2 a01sq = a01*a01; - float x = a01s.y > a01s.x ? exp(a01sq.x) : 0.0; - vec2 y = a01s / (2.3193*abs(a01) + sqrt(1.52*a01sq + 4.0)) * vec2(1.0, exp(-d/H*(d/(2.0*r)+mu))); - return sqrt((6.2831*H)*r) * exp((Rg-r)/H) * (x + dot(y, vec2(1.0, -1.0))); -} - -vec3 analyticTransmittance(float r, float mu, float d) { - return exp(- betaRayleigh * opticalDepth(HR, r, mu, d) - - betaMieExtinction * opticalDepth(HM, r, mu, d)); -} - -vec2 getIrradianceUV(float r, float muSun) { - float uR = (r - Rg) / (Rt - Rg); - float uMuS = (muSun + 0.2) / (1.0 + 0.2); - return vec2(uMuS, uR); -} - -vec3 irradiance(sampler2D sampler, float r, float muSun) { - vec2 uv = getIrradianceUV(r, muSun); - return texture(sampler, uv).rgb; -} - /* * Calculates the light scattering in the view direction comming from other * light rays scattered in the atmosphere. @@ -645,29 +460,21 @@ Fragment getFragment() { vec4 viewport = vec4(screenX, screenY, screenWIDTH, screenHEIGHT); vec4 ndcPos; ndcPos.xy = ((2.0f * gl_FragCoord.xy) - (2.0f * viewport.xy)) / (viewport.zw) - 1.0f; - //ndcPos.x = ((2.0f * gl_FragCoord.x) - (2.0f * viewport.x)) / viewport.z - 1.0f; - //ndcPos.y = 1.0f - (2.0f * gl_FragCoord.y) / viewport.w; ndcPos.z = (2.0f * gl_FragCoord.z - gl_DepthRange.near - gl_DepthRange.far) / (gl_DepthRange.far - gl_DepthRange.near); ndcPos.w = 1.0f; vec4 clipPos = ndcPos / gl_FragCoord.w; - //vec4 clipPos = ndcPos; - //clipPos.z = -1.0; - //clipPos.w = 1.0; vec4 projCoords = projInverse * clipPos; vec4 viewDirection = normalize(completeInverse * vec4(projCoords.xyz, 0.0)); vec3 v = normalize(viewDirection.xyz); float offset, maxLength; vec4 ppos = vec4(0.0); - //float t = 0.0f; - //if ( intersectATM(cameraPos, v, t) ) { + if (intersectAtmosphere(ppos, v, Rg, offset, maxLength)) { - //if (true){ // Following paper nomenclature float t = offset; - // float t = maxLength + offset; - vec3 x = cameraPosObj.xyz;// + offset * v; + vec3 x = cameraPosObj.xyz; float r = length(x); float mu = dot(x, v) / r; vec3 s = normalize(sunPositionObj); @@ -677,39 +484,24 @@ Fragment getFragment() { vec3 groundColor = groundColor(x, t, v, s, r, mu, attenuation); vec3 sunColor = sunColor(x, t, v, s, r, mu); - //diffuse = HDR(vec4(sunColor + groundColor + inscatterColor, 1.0)); - //diffuse = HDR(vec4(sunColor, 1.0)); + //diffuse = vec4(HDR(sunColor + groundColor + inscatterColor), 1.0)); + //diffuse = vec4(HDR(inscatterColor), 1.0)); //diffuse = vec4(HDR(groundColor), 1.0); - //diffuse = HDR(vec4(inscatterColor, 1.0)); + //diffuse = vec4(HDR(sunColor), 1.0)); //diffuse = HDR(vec4(sunColor + groundColor + inscatterColor, 1.0) + diffuse2); vec4 finalRadiance = calcShadow(shadowDataArray, vs_posWorld.xyz) * (vec4(sunColor + groundColor + inscatterColor, 1.0) + diffuse2); diffuse = vec4(HDR(finalRadiance.xyz), finalRadiance.w); - } - // else - // diffuse = HDR(diffuse); + } } - // Testing Uniforms: - //diffuse.xyz = vec3(1.0f); - //diffuse.xyz = vec3(Rg/6378.1366); - //diffuse.xyz = vec3(Rt/6420.0); - //diffuse.xyz = vec3(AverageGroundReflectance/0.1f); - //diffuse.xyz = vec3(HR/8.0f); - //diffuse.xyz = vec3(HM/1.2f); - //diffuse.xyz = vec3(mieG/1.0f); - //diffuse.xyz = vec3(sunRadiance/50.0f); - //diffuse.xyz = vec3(betaRayleigh.x/5.8e-3, betaRayleigh.y/1.35e-2, betaRayleigh.z/3.31e-2); - //diffuse.xyz = vec3(betaMieScattering.x/4e-3, betaMieScattering.y/4e-3, betaMieScattering.z/4e-3); - //diffuse.xyz = vec3(betaMieExtinction.x/(betaMieScattering.x/0.9), betaMieExtinction.y/(betaMieScattering.y/0.9), - // betaMieExtinction.z/(betaMieScattering.z/0.9)); - //diffuse.xyz = vec3(mieG); - diffuse[3] = transparency; frag.color = diffuse; frag.depth = depth; + cameraDistanceTextureTarget = vec4(vec3(0.0), 1.0); + return frag; } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d4bae91e69..ebd5d2854c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -112,6 +112,7 @@ set(OPENSPACE_SOURCE ${OPENSPACE_BASE_DIR}/src/query/query.cpp ${OPENSPACE_BASE_DIR}/src/rendering/abufferrenderer.cpp ${OPENSPACE_BASE_DIR}/src/rendering/framebufferrenderer.cpp + ${OPENSPACE_BASE_DIR}/src/rendering/deferredcastermanager.cpp ${OPENSPACE_BASE_DIR}/src/rendering/raycastermanager.cpp ${OPENSPACE_BASE_DIR}/src/rendering/renderable.cpp ${OPENSPACE_BASE_DIR}/src/rendering/renderengine.cpp @@ -254,6 +255,8 @@ set(OPENSPACE_HEADER ${OPENSPACE_BASE_DIR}/include/openspace/query/query.h ${OPENSPACE_BASE_DIR}/include/openspace/rendering/abufferrenderer.h ${OPENSPACE_BASE_DIR}/include/openspace/rendering/framebufferrenderer.h + ${OPENSPACE_BASE_DIR}/include/openspace/rendering/deferredcasterlistener.h + ${OPENSPACE_BASE_DIR}/include/openspace/rendering/deferredcastermanager.h ${OPENSPACE_BASE_DIR}/include/openspace/rendering/raycasterlistener.h ${OPENSPACE_BASE_DIR}/include/openspace/rendering/raycastermanager.h ${OPENSPACE_BASE_DIR}/include/openspace/rendering/renderable.h @@ -261,6 +264,7 @@ set(OPENSPACE_HEADER ${OPENSPACE_BASE_DIR}/include/openspace/rendering/renderengine.h ${OPENSPACE_BASE_DIR}/include/openspace/rendering/volume.h ${OPENSPACE_BASE_DIR}/include/openspace/rendering/screenspacerenderable.h + ${OPENSPACE_BASE_DIR}/include/openspace/rendering/deferredcaster.h ${OPENSPACE_BASE_DIR}/include/openspace/rendering/volumeraycaster.h ${OPENSPACE_BASE_DIR}/include/openspace/rendering/transferfunction.h ${OPENSPACE_BASE_DIR}/include/openspace/scene/translation.h diff --git a/src/rendering/abufferrenderer.cpp b/src/rendering/abufferrenderer.cpp index a29a4fd69f..c9f062e161 100644 --- a/src/rendering/abufferrenderer.cpp +++ b/src/rendering/abufferrenderer.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include diff --git a/src/rendering/deferredcastermanager.cpp b/src/rendering/deferredcastermanager.cpp new file mode 100644 index 0000000000..b5ace445f4 --- /dev/null +++ b/src/rendering/deferredcastermanager.cpp @@ -0,0 +1,82 @@ +/***************************************************************************************** + * * + * 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. * + ****************************************************************************************/ + +#include +#include +#include +#include + +namespace { + const std::string _loggerCat = "DeferredcasterManager"; +} + +namespace openspace { + +DeferredcasterManager::DeferredcasterManager() {} + +DeferredcasterManager::~DeferredcasterManager() {} + +void DeferredcasterManager::attachDeferredcaster(Deferredcaster& deferredcaster) { + if (!isAttached(deferredcaster)) { + _deferredcasters.push_back(&deferredcaster); + } + for (auto &listener : _listeners) { + listener->deferredcastersChanged(deferredcaster, true); + } +} + +void DeferredcasterManager::detachDeferredcaster(Deferredcaster& deferredcaster) { + auto it = std::find(_deferredcasters.begin(), _deferredcasters.end(), &deferredcaster); + if (it != _deferredcasters.end()) { + _deferredcasters.erase(it); + for (auto &listener : _listeners) { + listener->deferredcastersChanged(deferredcaster, false); + } + } +} + +bool DeferredcasterManager::isAttached(Deferredcaster& deferredcaster) { + auto it = std::find(_deferredcasters.begin(), _deferredcasters.end(), &deferredcaster); + return it != _deferredcasters.end(); +} + +void DeferredcasterManager::addListener(DeferredcasterListener& listener) { + auto it = std::find(_listeners.begin(), _listeners.end(), &listener); + if (it == _listeners.end()) { + _listeners.push_back(&listener); + } +} + +void DeferredcasterManager::removeListener(DeferredcasterListener& listener) { + auto it = std::find(_listeners.begin(), _listeners.end(), &listener); + if (it != _listeners.end()) { + _listeners.erase(it); + } +} + +const std::vector& DeferredcasterManager::deferredcasters() { + return _deferredcasters; +} + +} diff --git a/src/rendering/framebufferrenderer.cpp b/src/rendering/framebufferrenderer.cpp index 9c241472bd..20408ab0e5 100644 --- a/src/rendering/framebufferrenderer.cpp +++ b/src/rendering/framebufferrenderer.cpp @@ -31,6 +31,8 @@ #include #include #include +#include +#include #include #include @@ -101,6 +103,7 @@ void FramebufferRenderer::initialize() { updateResolution(); updateRendererData(); updateRaycastData(); + updateDeferredcastData(); glBindFramebuffer(GL_FRAMEBUFFER, _mainFramebuffer); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, _mainColorTexture, 0); @@ -126,6 +129,7 @@ void FramebufferRenderer::initialize() { } OsEng.renderEngine().raycasterManager().addListener(*this); + OsEng.renderEngine().deferredcasterManager().addListener(*this); } void FramebufferRenderer::deinitialize() { @@ -143,6 +147,7 @@ void FramebufferRenderer::deinitialize() { glDeleteVertexArrays(1, &_screenQuad); OsEng.renderEngine().raycasterManager().removeListener(*this); + OsEng.renderEngine().deferredcasterManager().removeListener(*this); } void FramebufferRenderer::raycastersChanged(VolumeRaycaster& raycaster, bool attached) { @@ -151,6 +156,13 @@ void FramebufferRenderer::raycastersChanged(VolumeRaycaster& raycaster, bool att _dirtyRaycastData = true; } +void FramebufferRenderer::deferredcastersChanged(Deferredcaster& deferredcaster, bool attached) { + // TODO + (void) deferredcaster; + (void) attached; + _dirtyDeferredcastData = true; +} + void FramebufferRenderer::update() { if (_dirtyResolution) { updateResolution(); @@ -160,6 +172,10 @@ void FramebufferRenderer::update() { updateRaycastData(); } + if (_dirtyRaycastData) { + updateDeferredcastData(); + } + // If the resolve dictionary changed (or a file changed on disk) // then rebuild the resolve program. if (_resolveProgram->isDirty()) { @@ -200,6 +216,16 @@ void FramebufferRenderer::update() { } } } + + for (auto &program : _deferredcastPrograms) { + if (program.second->isDirty()) { + try { + program.second->rebuildFromFile(); + } catch (ghoul::RuntimeError e) { + LERROR(e.message); + } + } + } } void FramebufferRenderer::updateResolution() { @@ -318,6 +344,52 @@ void FramebufferRenderer::updateRaycastData() { _dirtyRaycastData = false; } +void FramebufferRenderer::updateDeferredcastData() { + // TODO + _deferredcastData.clear(); + _deferredcastPrograms.clear(); + + const std::vector& deferredcasters = OsEng.renderEngine().deferredcasterManager().deferredcasters(); + int nextId = 0; + for (auto &deferredcaster : deferredcasters) { + DeferredcastData data; + data.id = nextId++; + data.namespaceName = "HELPER"; + + //std::string vsPath = raycaster->getBoundsVsPath(); + //std::string fsPath = raycaster->getBoundsFsPath(); + + ghoul::Dictionary dict; + dict.setValue("rendererData", _rendererData); + //dict.setValue("fragmentPath", fsPath); + dict.setValue("id", data.id); + std::string helperPath = deferredcaster->getHelperPath(); + ghoul::Dictionary helpersDict; + if (helperPath != "") { + helpersDict.setValue("0", helperPath); + } + dict.setValue("helperPaths", helpersDict); + //dict.setValue("deferredcastPath", deferredcaster->getDeferredcastPath()); + + _deferredcastData[deferredcaster] = data; + + try { + ghoul::Dictionary outsideDict = dict; + //outsideDict.setValue("getEntryPath", GetEntryOutsidePath); + //_deferredcastPrograms[deferredcaster] = ghoul::opengl::ProgramObject::Build( + // "Deferred " + std::to_string(data.id) + " raycast", + // vsPath, + // RaycastFragmentShaderPath, + // outsideDict); + } + catch (ghoul::RuntimeError e) { + LERROR(e.message); + } + + } + _dirtyDeferredcastData = false; +} + void FramebufferRenderer::render(float blackoutFactor, bool doPerformanceMeasurements) { std::unique_ptr perf; if (doPerformanceMeasurements) { @@ -377,10 +449,17 @@ void FramebufferRenderer::render(float blackoutFactor, bool doPerformanceMeasure if (raycastProgram == _insideRaycastPrograms[raycaster].get()) { raycastProgram->activate(); raycastProgram->setUniform("cameraPosInRaycaster", cameraPosition); + } else { + raycastProgram = _insideRaycastPrograms[raycaster].get(); + raycastProgram->activate(); + raycastProgram->setUniform("cameraPosInRaycaster", cameraPosition); } } else { if (raycastProgram == _raycastPrograms[raycaster].get()) { raycastProgram->activate(); + } else { + raycastProgram = _raycastPrograms[raycaster].get(); + raycastProgram->activate(); } } @@ -427,6 +506,50 @@ void FramebufferRenderer::render(float blackoutFactor, bool doPerformanceMeasure } } + for (const DeferredcasterTask& deferredcasterTask : tasks.deferredTasks) { + // TODO + Deferredcaster* deferredcaster = deferredcasterTask.deferredcaster; + + glBindFramebuffer(GL_FRAMEBUFFER, _mainFramebuffer); + glm::vec3 cameraPosition; + ghoul::opengl::ProgramObject* deferredcastProgram = nullptr; + + if (deferredcastProgram == _deferredcastPrograms[deferredcaster].get()) { + deferredcastProgram->activate(); + } else { + deferredcastProgram = _deferredcastPrograms[deferredcaster].get(); + deferredcastProgram->activate(); + } + + if (deferredcastProgram) { + //deferredcaster->preRaycast(_deferredcastData[deferredcaster], *deferredcastProgram); + + ghoul::opengl::TextureUnit mainDepthTextureUnit; + mainDepthTextureUnit.activate(); + glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _mainDepthTexture); + deferredcastProgram->setUniform("mainDepthTexture", mainDepthTextureUnit); + + deferredcastProgram->setUniform("nAaSamples", _nAaSamples); + deferredcastProgram->setUniform("windowSize", glm::vec2(_resolution)); + + glDisable(GL_DEPTH_TEST); + glDepthMask(false); + + glBindVertexArray(_screenQuad); + glDrawArrays(GL_TRIANGLES, 0, 6); + glBindVertexArray(0); + + glDepthMask(true); + glEnable(GL_DEPTH_TEST); + + //deferredcaster->postRaycast(_deferredcastData[deferredcaster], *deferredcastProgram); + deferredcastProgram->deactivate(); + + } else { + LWARNING("Deferredcaster is not attached when trying to perform raycaster task"); + } + } + glBindFramebuffer(GL_FRAMEBUFFER, defaultFbo); _resolveProgram->activate(); diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index c5ae3e1d8b..07f540c855 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -95,6 +96,7 @@ RenderEngine::RenderEngine() : properties::PropertyOwner("RenderEngine") , _mainCamera(nullptr) , _raycasterManager(nullptr) + , _deferredcasterManager(nullptr) , _performanceMeasurements("performanceMeasurements", "Performance Measurements") , _frametimeType( "frametimeType", @@ -174,6 +176,7 @@ RenderEngine::~RenderEngine() { delete _mainCamera; delete _raycasterManager; + delete _deferredcasterManager; } void RenderEngine::initialize() { @@ -202,6 +205,7 @@ void RenderEngine::initialize() { } _raycasterManager = new RaycasterManager(); + _deferredcasterManager = new DeferredcasterManager(); _nAaSamples = OsEng.windowWrapper().currentNumberOfAaSamples(); LINFO("Seting renderer from string: " << renderingMethod); @@ -570,6 +574,11 @@ RaycasterManager& RenderEngine::raycasterManager() { return *_raycasterManager; } +DeferredcasterManager& RenderEngine::deferredcasterManager() { + return *_deferredcasterManager; +} + + void RenderEngine::setSceneGraph(Scene* sceneGraph) { _sceneGraph = sceneGraph; }