Added deferred rendering support files. Fixed Volume rendering in framebufferrender.

This commit is contained in:
Jonathas Costa
2017-04-18 00:04:29 -04:00
parent 9e69a9b42e
commit 454e530ad6
16 changed files with 623 additions and 344 deletions

View File

@@ -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 <string>
#include <vector>
#include <openspace/util/updatestructures.h>
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__

View File

@@ -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__

View File

@@ -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 <vector>
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<Deferredcaster*>& deferredcasters();
void addListener(DeferredcasterListener& listener);
void removeListener(DeferredcasterListener& listener);
private:
std::vector<Deferredcaster*> _deferredcasters;
std::vector<DeferredcasterListener*> _listeners;
};
} // namespace openspace
#endif // __OPENSPACE_CORE___DEFERREDCASTERMANAGER___H__

View File

@@ -32,6 +32,7 @@
#include <vector>
#include <map>
#include <openspace/rendering/deferredcasterlistener.h>
#include <openspace/rendering/raycasterlistener.h>
#include <openspace/rendering/renderer.h>
#include <openspace/util/updatestructures.h>
@@ -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<VolumeRaycaster*, RaycastData> _raycastData;
@@ -87,6 +91,9 @@ private:
std::map<VolumeRaycaster*, std::unique_ptr<ghoul::opengl::ProgramObject>> _raycastPrograms;
std::map<VolumeRaycaster*, std::unique_ptr<ghoul::opengl::ProgramObject>> _insideRaycastPrograms;
std::map<Deferredcaster*, DeferredcastData> _deferredcastData;
std::map<Deferredcaster*, std::unique_ptr<ghoul::opengl::ProgramObject>> _deferredcastPrograms;
std::unique_ptr<ghoul::opengl::ProgramObject> _resolveProgram;
GLuint _screenQuad;
@@ -98,6 +105,7 @@ private:
GLuint _exitDepthTexture;
GLuint _exitFramebuffer;
bool _dirtyDeferredcastData;
bool _dirtyRaycastData;
bool _dirtyResolution;

View File

@@ -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<performance::PerformanceManager> _performanceManager;

View File

@@ -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<RaycasterTask> raycasterTasks;
std::vector<DeferredcasterTask> 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__

View File

@@ -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<double>(data.camera.scaling().x) * pow(10.0, static_cast<double>(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<double>(data.camera.scaling().x) * pow(10.0, static_cast<double>(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<float>(_mieScatteringExtinctionPropCoefficientP));

View File

@@ -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;

View File

@@ -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 ==============//
//================================================//

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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

View File

@@ -30,6 +30,7 @@
#include <openspace/rendering/renderengine.h>
#include <openspace/rendering/renderable.h>
#include <openspace/rendering/volumeraycaster.h>
#include <openspace/rendering/deferredcaster.h>
#include <openspace/scene/scene.h>
#include <openspace/util/camera.h>
#include <openspace/util/updatestructures.h>

View File

@@ -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 <openspace/rendering/deferredcastermanager.h>
#include <openspace/rendering/deferredcasterlistener.h>
#include <algorithm>
#include <string>
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<Deferredcaster*>& DeferredcasterManager::deferredcasters() {
return _deferredcasters;
}
}

View File

@@ -31,6 +31,8 @@
#include <openspace/util/camera.h>
#include <openspace/engine/openspaceengine.h>
#include <openspace/rendering/renderable.h>
#include <openspace/rendering/deferredcaster.h>
#include <openspace/rendering/deferredcastermanager.h>
#include <openspace/rendering/volumeraycaster.h>
#include <openspace/rendering/raycastermanager.h>
@@ -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<Deferredcaster*>& 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<performance::PerformanceMeasurement> 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();

View File

@@ -36,6 +36,7 @@
#include <openspace/performance/performancemanager.h>
#include <openspace/rendering/abufferrenderer.h>
#include <openspace/rendering/framebufferrenderer.h>
#include <openspace/rendering/deferredcastermanager.h>
#include <openspace/rendering/raycastermanager.h>
#include <openspace/rendering/renderer.h>
#include <openspace/rendering/screenspacerenderable.h>
@@ -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;
}