mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-05-05 10:59:47 -05:00
Merge commit 'a9661f681e115ebed096f5d25343dc99aad0f33f' into feature/data-management
# Conflicts: # data/scene/default.scene # data/scene/digitaluniverse/abell/abell.mod # data/scene/digitaluniverse/backgroundradiation/backgroundradiation.mod # data/scene/digitaluniverse/constellations/constellations.mod # data/scene/digitaluniverse/grids/grids.mod # data/scene/digitaluniverse/quasars/quasars.mod # data/scene/digitaluniverse/sloandss/sloandss.mod # data/scene/digitaluniverse/tully/tully.data # data/scene/digitaluniverse/tully/tully.mod # data/scene/earth/earth.mod # data/scene/grids/grids.mod # data/scene/mars/mars.mod # data/scene/milkyway/digitaluniverse/digitaluniverse.mod # data/scene/moon/moon.mod # data/scene/satellites/tle/geo.txt # data/scene/satellites/tle/gps-ops.txt # data/scene/satellites/tle/stations.txt # modules/imgui/src/renderproperties.cpp # modules/sync/ext/libtorrent # openspace.cfg # src/rendering/renderengine.cpp
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
#########################################################################################
|
||||
# #
|
||||
# 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_CMAKE_EXT_DIR}/module_definition.cmake)
|
||||
|
||||
set(HEADER_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/atmospheredeferredcaster.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderableatmosphere.h
|
||||
)
|
||||
source_group("Header Files" FILES ${HEADER_FILES})
|
||||
|
||||
set(SOURCE_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/atmospheredeferredcaster.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderableatmosphere.cpp
|
||||
)
|
||||
source_group("Source Files" FILES ${SOURCE_FILES})
|
||||
|
||||
set(SHADER_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/atmosphere_common.glsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/atmosphere_deferred_vs.glsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/atmosphere_deferred_fs.glsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/deltaE_calc_vs.glsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/deltaE_calc_fs.glsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/deltaJ_calc_vs.glsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/deltaJ_calc_fs.glsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/deltaJ_calc_gs.glsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/deltaS_calc_vs.glsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/deltaS_calc_gs.glsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/deltaS_calc_fs.glsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/deltaS_sup_calc_vs.glsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/deltaS_sup_calc_gs.glsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/deltaS_sup_calc_fs.glsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/inScattering_calc_vs.glsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/inScattering_calc_gs.glsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/inScattering_calc_fs.glsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/inScattering_sup_calc_vs.glsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/inScattering_sup_calc_gs.glsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/inScattering_sup_calc_fs.glsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/irradiance_calc_vs.glsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/irradiance_calc_fs.glsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/irradiance_final_vs.glsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/irradiance_final_fs.glsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/irradiance_sup_calc_vs.glsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/irradiance_sup_calc_fs.glsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/transmittance_calc_vs.glsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/transmittance_calc_fs.glsl
|
||||
)
|
||||
source_group("Shader Files" FILES ${SHADER_FILES})
|
||||
|
||||
create_new_module(
|
||||
"Atmosphere"
|
||||
atmosphere_module
|
||||
STATIC
|
||||
${HEADER_FILES} ${SOURCE_FILES} ${SHADER_FILES}
|
||||
)
|
||||
@@ -0,0 +1,45 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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 <modules/atmosphere/atmospheremodule.h>
|
||||
#include <openspace/util/factorymanager.h>
|
||||
#include <ghoul/misc/assert.h>
|
||||
|
||||
#include <openspace/rendering/renderable.h>
|
||||
|
||||
#include <modules/atmosphere/rendering/renderableatmosphere.h>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
AtmosphereModule::AtmosphereModule() :
|
||||
OpenSpaceModule("Atmosphere")
|
||||
{}
|
||||
|
||||
void AtmosphereModule::internalInitialize() {
|
||||
auto fRenderable = FactoryManager::ref().factory<Renderable>();
|
||||
ghoul_assert(fRenderable, "No renderable factory existed");
|
||||
fRenderable->registerClass<RenderableAtmosphere>("RenderableAtmosphere");
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
@@ -0,0 +1,41 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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_MODULE_ATMOSPHERE___ATMOSPHERE_MODULE___H__
|
||||
#define __OPENSPACE_MODULE_ATMOSPHERE___ATMOSPHERE_MODULE___H__
|
||||
|
||||
#include <openspace/util/openspacemodule.h>
|
||||
#include <openspace/properties/scalar/floatproperty.h>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
class AtmosphereModule : public OpenSpaceModule {
|
||||
public:
|
||||
AtmosphereModule();
|
||||
void internalInitialize() override;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_MODULE_ATMOSPHERE___ATMOSPHERE_MODULE___H__
|
||||
@@ -0,0 +1 @@
|
||||
#set (DEFAULT_MODULE ON)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,187 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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_MODULE_ATMOSPHERE___ATMOSPHEREDEFERREDCASTER___H__
|
||||
#define __OPENSPACE_MODULE_ATMOSPHERE___ATMOSPHEREDEFERREDCASTER___H__
|
||||
|
||||
#include <ghoul/glm.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <openspace/rendering/deferredcaster.h>
|
||||
#include <ghoul/opengl/textureunit.h>
|
||||
|
||||
//#include <modules/atmosphere/rendering/renderableatmosphere.h>
|
||||
|
||||
namespace ghoul::opengl {
|
||||
class Texture;
|
||||
class ProgramObject;
|
||||
} // namespace ghoul::opengl
|
||||
|
||||
namespace openspace {
|
||||
|
||||
struct RenderData;
|
||||
struct DeferredcastData;
|
||||
struct ShadowConfiguration;
|
||||
|
||||
class AtmosphereDeferredcaster : public Deferredcaster {
|
||||
public:
|
||||
AtmosphereDeferredcaster();
|
||||
virtual ~AtmosphereDeferredcaster() = default;
|
||||
|
||||
void initialize();
|
||||
void deinitialize();
|
||||
void preRaycast(const RenderData& renderData, const DeferredcastData& deferredData,
|
||||
ghoul::opengl::ProgramObject& program) override;
|
||||
void postRaycast(const RenderData& renderData, const DeferredcastData& deferredData,
|
||||
ghoul::opengl::ProgramObject& program) override;
|
||||
|
||||
std::string deferredcastPath() const override;
|
||||
std::string deferredcastVSPath() const override;
|
||||
std::string deferredcastFSPath() const override;
|
||||
std::string helperPath() const override;
|
||||
|
||||
void preCalculateAtmosphereParam();
|
||||
|
||||
void setModelTransform(const glm::dmat4 &transform);
|
||||
void setTime(double time);
|
||||
void setAtmosphereRadius(float atmRadius);
|
||||
void setPlanetRadius(float planetRadius);
|
||||
void setPlanetAverageGroundReflectance(float averageGReflectance);
|
||||
void setPlanetGroundRadianceEmittion(float groundRadianceEmittion);
|
||||
void setRayleighHeightScale(float rayleighHeightScale);
|
||||
void enableOzone(bool enable);
|
||||
void setOzoneHeightScale(float ozoneHeightScale);
|
||||
void setMieHeightScale(float mieHeightScale);
|
||||
void setMiePhaseConstant(float miePhaseConstant);
|
||||
void setSunRadianceIntensity(float sunRadiance);
|
||||
void setRayleighScatteringCoefficients(const glm::vec3& rayScattCoeff);
|
||||
void setOzoneExtinctionCoefficients(const glm::vec3& ozoneExtCoeff);
|
||||
void setMieScatteringCoefficients(const glm::vec3& mieScattCoeff);
|
||||
void setMieExtinctionCoefficients(const glm::vec3& mieExtCoeff);
|
||||
void setEllipsoidRadii(const glm::dvec3& radii);
|
||||
void setShadowConfigArray(const std::vector<ShadowConfiguration>& shadowConfigArray);
|
||||
void setHardShadows(bool enabled);
|
||||
void enableSunFollowing(bool enable);
|
||||
|
||||
void setPrecalculationTextureScale(float preCalculatedTexturesScale);
|
||||
void enablePrecalculationTexturesSaving();
|
||||
|
||||
private:
|
||||
void loadComputationPrograms();
|
||||
void unloadComputationPrograms();
|
||||
void createComputationTextures();
|
||||
void deleteComputationTextures();
|
||||
void deleteUnusedComputationTextures();
|
||||
void executeCalculations(GLuint quadCalcVAO, GLenum drawBuffers[1],
|
||||
GLsizei vertexSize);
|
||||
void resetAtmosphereTextures();
|
||||
void createRenderQuad(GLuint* vao, GLuint* vbo, GLfloat size);
|
||||
void step3DTexture(std::unique_ptr<ghoul::opengl::ProgramObject>& shaderProg,
|
||||
int layer, bool doCalc = true);
|
||||
void checkFrameBufferState(const std::string& codePosition) const;
|
||||
void loadAtmosphereDataIntoShaderProgram(
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> & shaderProg
|
||||
);
|
||||
void renderQuadForCalc(GLuint vao, GLsizei numberOfVertices);
|
||||
void saveTextureToPPMFile(GLenum color_buffer_attachment, const std::string& fileName,
|
||||
int width, int height) const;
|
||||
bool isAtmosphereInFrustum(const double* MVMatrix, const glm::dvec3& position,
|
||||
double radius) const;
|
||||
|
||||
|
||||
const double DISTANCE_CULLING = 1e10;
|
||||
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _transmittanceProgramObject;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _irradianceProgramObject;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _irradianceSupTermsProgramObject;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _irradianceFinalProgramObject;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _inScatteringProgramObject;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _inScatteringSupTermsProgramObject;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _deltaEProgramObject;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _deltaSProgramObject;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _deltaSSupTermsProgramObject;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _deltaJProgramObject;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _atmosphereProgramObject;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _deferredAtmosphereProgramObject;
|
||||
|
||||
GLuint _transmittanceTableTexture;
|
||||
GLuint _irradianceTableTexture;
|
||||
GLuint _inScatteringTableTexture;
|
||||
GLuint _deltaETableTexture;
|
||||
GLuint _deltaSRayleighTableTexture;
|
||||
GLuint _deltaSMieTableTexture;
|
||||
GLuint _deltaJTableTexture;
|
||||
GLuint _atmosphereTexture;
|
||||
|
||||
ghoul::opengl::TextureUnit _transmittanceTableTextureUnit;
|
||||
ghoul::opengl::TextureUnit _irradianceTableTextureUnit;
|
||||
ghoul::opengl::TextureUnit _inScatteringTableTextureUnit;
|
||||
|
||||
// Atmosphere Data
|
||||
bool _atmosphereCalculated;
|
||||
bool _ozoneEnabled;
|
||||
bool _sunFollowingCameraEnabled;
|
||||
float _atmosphereRadius;
|
||||
float _atmospherePlanetRadius;
|
||||
float _planetAverageGroundReflectance;
|
||||
float _planetGroundRadianceEmittion;
|
||||
float _rayleighHeightScale;
|
||||
float _ozoneHeightScale;
|
||||
float _mieHeightScale;
|
||||
float _miePhaseConstant;
|
||||
float _sunRadianceIntensity;
|
||||
|
||||
glm::vec3 _rayleighScatteringCoeff;
|
||||
glm::vec3 _ozoneExtinctionCoeff;
|
||||
glm::vec3 _mieScatteringCoeff;
|
||||
glm::vec3 _mieExtinctionCoeff;
|
||||
glm::dvec3 _ellipsoidRadii;
|
||||
|
||||
// Atmosphere Textures Dimmensions
|
||||
int _transmittance_table_width;
|
||||
int _transmittance_table_height;
|
||||
int _irradiance_table_width;
|
||||
int _irradiance_table_height;
|
||||
int _delta_e_table_width;
|
||||
int _delta_e_table_height;
|
||||
int _r_samples;
|
||||
int _mu_samples;
|
||||
int _mu_s_samples;
|
||||
int _nu_samples;
|
||||
|
||||
glm::dmat4 _modelTransform;
|
||||
double _time;
|
||||
|
||||
// Eclipse Shadows
|
||||
std::vector<ShadowConfiguration> _shadowConfArray;
|
||||
bool _hardShadowsEnabled;
|
||||
|
||||
// Atmosphere Debugging
|
||||
float _calculationTextureScale;
|
||||
bool _saveCalculationTextures;
|
||||
};
|
||||
|
||||
} // openspace
|
||||
|
||||
#endif // __OPENSPACE_MODULE_ATMOSPHERE___ATMOSPHEREDEFERREDCASTER___H__
|
||||
@@ -0,0 +1,763 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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 <modules/atmosphere/rendering/renderableatmosphere.h>
|
||||
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/documentation/verifier.h>
|
||||
|
||||
#include <modules/space/rendering/planetgeometry.h>
|
||||
#include <openspace/util/time.h>
|
||||
#include <openspace/util/spicemanager.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/misc/assert.h>
|
||||
#include <ghoul/io/texture/texturereader.h>
|
||||
#include <ghoul/opengl/programobject.h>
|
||||
#include <ghoul/opengl/texture.h>
|
||||
#include <ghoul/opengl/textureunit.h>
|
||||
#include <ghoul/misc/invariants.h>
|
||||
|
||||
#include <openspace/rendering/deferredcastermanager.h>
|
||||
#include <modules/atmosphere/rendering/atmospheredeferredcaster.h>
|
||||
#include <openspace/engine/configurationmanager.h>
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/rendering/renderer.h>
|
||||
|
||||
#include <glm/gtx/string_cast.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <fstream>
|
||||
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <math.h>
|
||||
|
||||
namespace {
|
||||
static const char* _loggerCat = "RenderableAtmosphere";
|
||||
|
||||
const char* keyShadowGroup = "ShadowGroup";
|
||||
const char* keyShadowSource = "Source";
|
||||
const char* keyShadowCaster = "Caster";
|
||||
|
||||
const char* keyAtmosphere = "Atmosphere";
|
||||
const char* keyAtmosphereRadius = "AtmosphereRadius";
|
||||
const char* keyPlanetRadius = "PlanetRadius";
|
||||
const char* keyAverageGroundReflectance = "PlanetAverageGroundReflectance";
|
||||
const char* keyRayleigh = "Rayleigh";
|
||||
const char* keyRayleighHeightScale = "H_R";
|
||||
const char* keyOzone = "Ozone";
|
||||
const char* keyOzoneHeightScale = "H_O";
|
||||
const char* keyMie = "Mie";
|
||||
const char* keyMieHeightScale = "H_M";
|
||||
const char* keyMiePhaseConstant = "G";
|
||||
const char* keyImage = "Image";
|
||||
const char* keyToneMappingOp = "ToneMapping";
|
||||
const char* keyATMDebug = "Debug";
|
||||
const char* keyTextureScale = "PreCalculatedTextureScale";
|
||||
const char* keySaveTextures = "SaveCalculatedTextures";
|
||||
|
||||
static const openspace::properties::Property::PropertyInfo AtmosphereHeightInfo = {
|
||||
"atmmosphereHeight",
|
||||
"Atmosphere Height (KM)",
|
||||
"The thickness of the atmosphere in Km"
|
||||
};
|
||||
|
||||
static const openspace::properties::Property::PropertyInfo AverageGroundReflectanceInfo = {
|
||||
"AverageGroundReflectance",
|
||||
"Average Ground Reflectance (%)",
|
||||
"Average percentage of light reflected by the ground during the pre-calculation phase"
|
||||
};
|
||||
|
||||
static const openspace::properties::Property::PropertyInfo GroundRadianceEmittioninfo = {
|
||||
"GroundRadianceEmittion",
|
||||
"Percentage of initial radiance emitted from ground",
|
||||
"Multiplier of the ground radiance color during the rendering phase"
|
||||
};
|
||||
|
||||
static const openspace::properties::Property::PropertyInfo RayleighHeightScaleInfo = {
|
||||
"RayleighHeightScale",
|
||||
"Rayleigh Scale Height (KM)",
|
||||
"It is the vertical distance over which the density and pressure fall by a constant factor"
|
||||
};
|
||||
|
||||
static const openspace::properties::Property::PropertyInfo RayleighScatteringCoeffXInfo = {
|
||||
"RayleighScatteringCoeffX",
|
||||
"Rayleigh Scattering Coeff X (x10e-3)",
|
||||
"Rayleigh sea-level scattering coefficients in meters"
|
||||
};
|
||||
|
||||
static const openspace::properties::Property::PropertyInfo RayleighScatteringCoeffYInfo = {
|
||||
"RayleighScatteringCoeffY",
|
||||
"Rayleigh Scattering Coeff Y (x10e-3)",
|
||||
"Rayleigh sea-level scattering coefficients in meters"
|
||||
};
|
||||
|
||||
static const openspace::properties::Property::PropertyInfo RayleighScatteringCoeffZInfo = {
|
||||
"RayleighScatteringCoeffZ",
|
||||
"Rayleigh Scattering Coeff Z (x10e-3)",
|
||||
"Rayleigh sea-level scattering coefficients in meters"
|
||||
};
|
||||
|
||||
static const openspace::properties::Property::PropertyInfo OzoneLayerInfo = {
|
||||
"Ozone",
|
||||
"Ozone Layer Enabled",
|
||||
"Enables/Disable Ozone Layer during pre-calculation phase"
|
||||
};
|
||||
|
||||
static const openspace::properties::Property::PropertyInfo OzoneHeightScaleInfo = {
|
||||
"OzoneLayerHeightScale",
|
||||
"Ozone Scale Height (KM)",
|
||||
"It is the vertical distance over which the density and pressure fall by a constant factor"
|
||||
};
|
||||
|
||||
static const openspace::properties::Property::PropertyInfo OzoneLayerCoeffXInfo = {
|
||||
"OzoneLayerCoeffX",
|
||||
"Ozone Layer Extinction Coeff X (x10e-5)",
|
||||
"Ozone scattering coefficients in meters"
|
||||
};
|
||||
|
||||
static const openspace::properties::Property::PropertyInfo OzoneLayerCoeffYInfo = {
|
||||
"OzoneLayerCoeffY",
|
||||
"Ozone Layer Extinction Coeff Y (x10e-5)",
|
||||
"Ozone scattering coefficients in meters"
|
||||
};
|
||||
|
||||
static const openspace::properties::Property::PropertyInfo OzoneLayerCoeffZInfo = {
|
||||
"OzoneLayerCoeffZ",
|
||||
"Ozone Layer Extinction Coeff Z (x10e-5)",
|
||||
"Ozone scattering coefficients in meters"
|
||||
};
|
||||
|
||||
static const openspace::properties::Property::PropertyInfo MieHeightScaleInfo = {
|
||||
"MieHeightScale",
|
||||
"Mie Scale Height (KM)",
|
||||
"It is the vertical distance over which the density and pressure fall by a constant factor"
|
||||
};
|
||||
|
||||
static const openspace::properties::Property::PropertyInfo MieScatteringCoeffXInfo = {
|
||||
"MieScatteringCoeffX",
|
||||
"Mie Scattering Coeff X (x10e-3)",
|
||||
"Mie sea-level scattering coefficients in meters"
|
||||
};
|
||||
|
||||
static const openspace::properties::Property::PropertyInfo MieScatteringCoeffYInfo = {
|
||||
"MieScatteringCoeffY",
|
||||
"Mie Scattering Coeff Y (x10e-3)",
|
||||
"Mie sea-level scattering coefficients in meters"
|
||||
};
|
||||
|
||||
static const openspace::properties::Property::PropertyInfo MieScatteringCoeffZInfo = {
|
||||
"MieScatteringCoeffZ",
|
||||
"Mie Scattering Coeff Z (x10e-3)",
|
||||
"Mie sea-level scattering coefficients in meters"
|
||||
};
|
||||
|
||||
static const openspace::properties::Property::PropertyInfo MieScatteringExtinctionPropCoeffInfo = {
|
||||
"MieScatteringExtinctionPropCoefficient",
|
||||
"Mie Scattering/Extinction Proportion Coefficient (%)",
|
||||
"Mie Scattering/Extinction Proportion Coefficient (%)"
|
||||
};
|
||||
|
||||
static const openspace::properties::Property::PropertyInfo MieAsymmetricFactorGInfo = {
|
||||
"MieAsymmetricFactorG",
|
||||
"Mie Asymmetric Factor G",
|
||||
"Averaging of the scattering angle over a high number of scattering events"
|
||||
};
|
||||
|
||||
static const openspace::properties::Property::PropertyInfo SunIntensityInfo = {
|
||||
"SunIntensity",
|
||||
"Sun Intensity",
|
||||
"Unitless for now"
|
||||
};
|
||||
|
||||
static const openspace::properties::Property::PropertyInfo AtmosphereExposureInfo = {
|
||||
"HdrExposure",
|
||||
"Atmosphere Exposure",
|
||||
"Constant to controls the exposure of the radiance range"
|
||||
};
|
||||
|
||||
static const openspace::properties::Property::PropertyInfo AtmosphereGammaInfo = {
|
||||
"Gamma",
|
||||
"Gamma Correction",
|
||||
"Gamma Correction"
|
||||
};
|
||||
|
||||
static const openspace::properties::Property::PropertyInfo EnableSunOnCameraPositionInfo = {
|
||||
"SunFollowingCamera",
|
||||
"Enable Sun On Camera Position",
|
||||
"When selected the Sun is artificially positioned behind the observer all times"
|
||||
};
|
||||
|
||||
static const openspace::properties::Property::PropertyInfo EclipseHardShadowsInfo = {
|
||||
"EclipseHardShadowsInfo",
|
||||
"Enable Hard Shadows for Eclipses",
|
||||
"Enable/Disables hard shadows through the atmosphere"
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation RenderableAtmosphere::Documentation() {
|
||||
using namespace documentation;
|
||||
return {
|
||||
"RenderableAtmosphere",
|
||||
"atmosphere_renderable_atmosphere",
|
||||
{ /*
|
||||
{
|
||||
keyAtmosphereRadius,
|
||||
new ReferencingVerifier("atmosphere"),
|
||||
"Specifies the atmosphere's height in this RenderableAtmosphere.",
|
||||
Optional::No
|
||||
},
|
||||
|
||||
{
|
||||
KeyShading,
|
||||
new BoolVerifier,
|
||||
"Specifies whether the atmosphere should be rendered shaded by the Sun. If "
|
||||
"this value is 'false', any existing night texture will not be used. "
|
||||
"This value defaults to 'true'.",
|
||||
Optional::Yes
|
||||
}
|
||||
*/
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
RenderableAtmosphere::RenderableAtmosphere(const ghoul::Dictionary& dictionary)
|
||||
: Renderable(dictionary)
|
||||
, _atmosphereHeightP(AtmosphereHeightInfo, 60.0f, 0.1f, 99.0f)
|
||||
, _groundAverageReflectanceP(AverageGroundReflectanceInfo, 0.1f, 0.0f, 1.0f)
|
||||
, _groundRadianceEmittionP(GroundRadianceEmittioninfo, 0.3f, 0.0f, 1.0f)
|
||||
, _rayleighHeightScaleP(RayleighHeightScaleInfo, 8.0f, 0.1f, 20.0f)
|
||||
, _rayleighScatteringCoeffXP(RayleighScatteringCoeffXInfo, 1.0f, 0.01f, 100.0f)
|
||||
, _rayleighScatteringCoeffYP(RayleighScatteringCoeffYInfo, 1.0f, 0.01f, 100.0f)
|
||||
, _rayleighScatteringCoeffZP(RayleighScatteringCoeffZInfo, 1.0f, 0.01f, 100.0f)
|
||||
, _ozoneEnabledP(OzoneLayerInfo, true)
|
||||
, _ozoneHeightScaleP(OzoneHeightScaleInfo, 8.0f, 0.1f, 20.0f)
|
||||
, _ozoneCoeffXP(OzoneLayerCoeffXInfo, 3.426f, 0.01f, 100.0f)
|
||||
, _ozoneCoeffYP(OzoneLayerCoeffYInfo, 8.298f, 0.01f, 100.0f)
|
||||
, _ozoneCoeffZP(OzoneLayerCoeffZInfo, 0.356f, 0.01f, 100.0f)
|
||||
, _mieHeightScaleP(MieHeightScaleInfo, 1.2f, 0.1f, 20.0f)
|
||||
, _mieScatteringCoeffXP(MieScatteringCoeffXInfo, 4.0f, 0.01f, 1000.0f)
|
||||
, _mieScatteringCoeffYP(MieScatteringCoeffYInfo, 4.0f, 0.01f, 1000.0f)
|
||||
, _mieScatteringCoeffZP(MieScatteringCoeffZInfo, 4.0f, 0.01f, 1000.0f)
|
||||
, _mieScatteringExtinctionPropCoefficientP(MieScatteringExtinctionPropCoeffInfo, 0.9f, 0.01f, 1.0f)
|
||||
, _mieAsymmetricFactorGP(MieAsymmetricFactorGInfo, 0.85f, -1.0f, 1.0f)
|
||||
, _sunIntensityP(SunIntensityInfo, 50.0f, 0.1f, 1000.0f)
|
||||
, _sunFollowingCameraEnabledP(EnableSunOnCameraPositionInfo, false)
|
||||
, _hardShadowsEnabledP(EclipseHardShadowsInfo, false)
|
||||
, _atmosphereEnabled(false)
|
||||
, _ozoneLayerEnabled(false)
|
||||
, _sunFollowingCameraEnabled(false)
|
||||
, _atmosphereRadius(0.f)
|
||||
, _atmospherePlanetRadius(0.f)
|
||||
, _planetAverageGroundReflectance(0.f)
|
||||
, _planetGroundRadianceEmittion(0.f)
|
||||
, _rayleighHeightScale(0.f)
|
||||
, _ozoneHeightScale(0.f)
|
||||
, _mieHeightScale(0.f)
|
||||
, _miePhaseConstant(0.f)
|
||||
, _sunRadianceIntensity(50.f)
|
||||
, _mieExtinctionCoeff(glm::vec3(0.f))
|
||||
, _rayleighScatteringCoeff(glm::vec3(0.f))
|
||||
, _ozoneExtinctionCoeff(glm::vec3(0.f))
|
||||
, _mieScatteringCoeff(glm::vec3(0.f))
|
||||
, _saveCalculationsToTexture(false)
|
||||
, _preCalculatedTexturesScale(1.0)
|
||||
, _shadowEnabled(false)
|
||||
, _hardShadows(false)
|
||||
{
|
||||
ghoul_precondition(
|
||||
dictionary.hasKeyAndValue<std::string>(SceneGraphNode::KeyName),
|
||||
"RenderableAtmosphere needs the name to be specified"
|
||||
);
|
||||
|
||||
documentation::testSpecificationAndThrow(
|
||||
Documentation(),
|
||||
dictionary,
|
||||
"RenderableAtmosphere"
|
||||
);
|
||||
|
||||
const std::string name = dictionary.value<std::string>(SceneGraphNode::KeyName);
|
||||
|
||||
//================================================================
|
||||
//======== Reads Shadow (Eclipses) Entries in mod file ===========
|
||||
//================================================================
|
||||
ghoul::Dictionary shadowDictionary;
|
||||
bool success = dictionary.getValue(keyShadowGroup, shadowDictionary);
|
||||
bool disableShadows = false;
|
||||
if (success) {
|
||||
std::vector<std::pair<std::string, double>> sourceArray;
|
||||
unsigned int sourceCounter = 1;
|
||||
while (success) {
|
||||
std::string sourceName;
|
||||
success = shadowDictionary.getValue(keyShadowSource +
|
||||
std::to_string(sourceCounter) + ".Name", sourceName);
|
||||
if (success) {
|
||||
double sourceRadius;
|
||||
success = shadowDictionary.getValue(keyShadowSource +
|
||||
std::to_string(sourceCounter) + ".Radius", sourceRadius);
|
||||
if (success) {
|
||||
sourceArray.emplace_back(sourceName, sourceRadius);
|
||||
}
|
||||
else {
|
||||
LWARNING("No Radius value expecified for Shadow Source Name "
|
||||
<< sourceName << " from " << name
|
||||
<< " planet.\nDisabling shadows for this planet.");
|
||||
disableShadows = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
sourceCounter++;
|
||||
}
|
||||
|
||||
if (!disableShadows && !sourceArray.empty()) {
|
||||
success = true;
|
||||
std::vector<std::pair<std::string, double>> casterArray;
|
||||
unsigned int casterCounter = 1;
|
||||
while (success) {
|
||||
std::string casterName;
|
||||
success = shadowDictionary.getValue(keyShadowCaster +
|
||||
std::to_string(casterCounter) + ".Name", casterName);
|
||||
if (success) {
|
||||
double casterRadius;
|
||||
success = shadowDictionary.getValue(keyShadowCaster +
|
||||
std::to_string(casterCounter) + ".Radius", casterRadius);
|
||||
if (success) {
|
||||
casterArray.emplace_back(casterName, casterRadius);
|
||||
}
|
||||
else {
|
||||
LWARNING("No Radius value expecified for Shadow Caster Name "
|
||||
<< casterName << " from " << name
|
||||
<< " planet.\nDisabling shadows for this planet.");
|
||||
disableShadows = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
casterCounter++;
|
||||
}
|
||||
|
||||
if (!disableShadows && (!sourceArray.empty() && !casterArray.empty())) {
|
||||
for (const auto & source : sourceArray) {
|
||||
for (const auto & caster : casterArray) {
|
||||
ShadowConfiguration sc;
|
||||
sc.source = source;
|
||||
sc.caster = caster;
|
||||
_shadowConfArray.push_back(sc);
|
||||
}
|
||||
}
|
||||
_shadowEnabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//================================================================
|
||||
//========== Reads Atmosphere Entries from mod file ==============
|
||||
//================================================================
|
||||
bool errorReadingAtmosphereData = false;
|
||||
ghoul::Dictionary atmosphereDictionary;
|
||||
success = dictionary.getValue(keyAtmosphere, atmosphereDictionary);
|
||||
if (success) {
|
||||
if (!atmosphereDictionary.getValue(keyAtmosphereRadius, _atmosphereRadius)) {
|
||||
errorReadingAtmosphereData = true;
|
||||
LWARNING("No Atmosphere Radius value expecified for Atmosphere Effects of "
|
||||
<< name << " planet.\nDisabling atmosphere effects for this planet.");
|
||||
}
|
||||
|
||||
if (!atmosphereDictionary.getValue(keyPlanetRadius, _atmospherePlanetRadius)) {
|
||||
errorReadingAtmosphereData = true;
|
||||
LWARNING("No Planet Radius value expecified for Atmosphere Effects of "
|
||||
<< name << " planet.\nDisabling atmosphere effects for this planet.");
|
||||
}
|
||||
|
||||
if (!atmosphereDictionary.getValue(keyAverageGroundReflectance, _planetAverageGroundReflectance)) {
|
||||
errorReadingAtmosphereData = true;
|
||||
LWARNING("No Average Atmosphere Ground Reflectance value expecified for Atmosphere Effects of "
|
||||
<< name << " planet.\nDisabling atmosphere effects for this planet.");
|
||||
}
|
||||
|
||||
if (!atmosphereDictionary.getValue(GroundRadianceEmittioninfo.identifier, _planetGroundRadianceEmittion)) {
|
||||
errorReadingAtmosphereData = true;
|
||||
LWARNING("No Ground Radiance Emitted percentage value expecified for Atmosphere Effects of "
|
||||
<< name << " planet.\nDisabling atmosphere effects for this planet.");
|
||||
}
|
||||
|
||||
ghoul::Dictionary rayleighDictionary;
|
||||
success = atmosphereDictionary.getValue(keyRayleigh, rayleighDictionary);
|
||||
|
||||
if (success) {
|
||||
// Not using right now.
|
||||
glm::vec3 rayleighWavelengths;
|
||||
success = rayleighDictionary.getValue("Coefficients.Wavelengths", rayleighWavelengths);
|
||||
|
||||
if (!rayleighDictionary.getValue("Coefficients.Scattering", _rayleighScatteringCoeff)) {
|
||||
errorReadingAtmosphereData = true;
|
||||
LWARNING("No Rayleigh Scattering parameters expecified for Atmosphere Effects of "
|
||||
<< name << " planet.\nDisabling atmosphere effects for this planet.");
|
||||
}
|
||||
|
||||
if (!rayleighDictionary.getValue(keyRayleighHeightScale, _rayleighHeightScale)) {
|
||||
errorReadingAtmosphereData = true;
|
||||
LWARNING("No Rayleigh Height Scale value expecified for Atmosphere Effects of "
|
||||
<< name << " planet.\nDisabling atmosphere effects for this planet.");
|
||||
}
|
||||
}
|
||||
else {
|
||||
errorReadingAtmosphereData = true;
|
||||
LWARNING("No Rayleigh parameters expecified for Atmosphere Effects of "
|
||||
<< name << " planet.\nDisabling atmosphere effects for this planet.");
|
||||
}
|
||||
|
||||
ghoul::Dictionary ozoneDictionary;
|
||||
success = atmosphereDictionary.getValue(keyOzone, ozoneDictionary);
|
||||
if (success) {
|
||||
_ozoneLayerEnabled = true;
|
||||
if (!ozoneDictionary.getValue(keyOzoneHeightScale, _ozoneHeightScale)) {
|
||||
_ozoneLayerEnabled = false;
|
||||
}
|
||||
|
||||
if (!ozoneDictionary.getValue("Coefficients.Extinction", _ozoneExtinctionCoeff)) {
|
||||
_ozoneLayerEnabled = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
_ozoneLayerEnabled = false;
|
||||
}
|
||||
|
||||
ghoul::Dictionary mieDictionary;
|
||||
success = atmosphereDictionary.getValue(keyMie, mieDictionary);
|
||||
if (success) {
|
||||
if (!mieDictionary.getValue(keyMieHeightScale, _mieHeightScale)) {
|
||||
errorReadingAtmosphereData = true;
|
||||
LWARNING("No Mie Height Scale value expecified for Atmosphere Effects of "
|
||||
<< name << " planet.\nDisabling atmosphere effects for this planet.");
|
||||
}
|
||||
|
||||
if (!mieDictionary.getValue("Coefficients.Scattering", _mieScatteringCoeff)) {
|
||||
errorReadingAtmosphereData = true;
|
||||
LWARNING("No Mie Scattering parameters expecified for Atmosphere Effects of "
|
||||
<< name << " planet.\nDisabling atmosphere effects for this planet.");
|
||||
}
|
||||
|
||||
if (!mieDictionary.getValue("Coefficients.Extinction", _mieExtinctionCoeff)) {
|
||||
errorReadingAtmosphereData = true;
|
||||
LWARNING("No Mie Extinction parameters expecified for Atmosphere Effects of "
|
||||
<< name << " planet.\nDisabling atmosphere effects for this planet.");
|
||||
}
|
||||
|
||||
if (!mieDictionary.getValue(keyMiePhaseConstant, _miePhaseConstant)) {
|
||||
errorReadingAtmosphereData = true;
|
||||
LWARNING("No Mie Phase Constant value expecified for Atmosphere Effects of "
|
||||
<< name << " planet.\nDisabling atmosphere effects for this planet.");
|
||||
}
|
||||
}
|
||||
else {
|
||||
errorReadingAtmosphereData = true;
|
||||
LWARNING("No Mie parameters expecified for Atmosphere Effects of "
|
||||
<< name << " planet.\nDisabling atmosphere effects for this planet.");
|
||||
}
|
||||
|
||||
ghoul::Dictionary ImageDictionary;
|
||||
success = atmosphereDictionary.getValue(keyImage, ImageDictionary);
|
||||
if (success) {
|
||||
if (ImageDictionary.getValue(keyToneMappingOp, _preCalculatedTexturesScale)) {
|
||||
LDEBUG("Atmosphere Texture Scaled to " << _preCalculatedTexturesScale);
|
||||
}
|
||||
}
|
||||
|
||||
ghoul::Dictionary debugDictionary;
|
||||
success = atmosphereDictionary.getValue(keyATMDebug, debugDictionary);
|
||||
if (success) {
|
||||
if (debugDictionary.getValue(keyTextureScale, _preCalculatedTexturesScale)) {
|
||||
LDEBUG("Atmosphere Texture Scaled to " << _preCalculatedTexturesScale);
|
||||
}
|
||||
|
||||
if (debugDictionary.getValue(keySaveTextures, _saveCalculationsToTexture)) {
|
||||
LDEBUG("Saving Precalculated Atmosphere Textures.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!errorReadingAtmosphereData) {
|
||||
_atmosphereEnabled = true;
|
||||
|
||||
//========================================================
|
||||
//============== Atmosphere Properties ===================
|
||||
//========================================================
|
||||
|
||||
auto updateAtmosphere = [this]() { updateAtmosphereParameters(); };
|
||||
|
||||
_atmosphereHeightP =_atmosphereRadius - _atmospherePlanetRadius;
|
||||
_atmosphereHeightP.onChange(updateAtmosphere);
|
||||
addProperty(_atmosphereHeightP);
|
||||
|
||||
_groundAverageReflectanceP = _planetAverageGroundReflectance;
|
||||
_groundAverageReflectanceP.onChange(updateAtmosphere);
|
||||
addProperty(_groundAverageReflectanceP);
|
||||
|
||||
_groundRadianceEmittionP = _planetGroundRadianceEmittion;
|
||||
_groundRadianceEmittionP.onChange(updateAtmosphere);
|
||||
addProperty(_groundRadianceEmittionP);
|
||||
|
||||
_rayleighHeightScaleP = _rayleighHeightScale;
|
||||
_rayleighHeightScaleP.onChange(updateAtmosphere);
|
||||
addProperty(_rayleighHeightScaleP);
|
||||
|
||||
_rayleighScatteringCoeffXP = _rayleighScatteringCoeff.x * 1000.0f;
|
||||
_rayleighScatteringCoeffXP.onChange(updateAtmosphere);
|
||||
addProperty(_rayleighScatteringCoeffXP);
|
||||
|
||||
_rayleighScatteringCoeffYP = _rayleighScatteringCoeff.y * 1000.0f;
|
||||
_rayleighScatteringCoeffYP.onChange(updateAtmosphere);
|
||||
addProperty(_rayleighScatteringCoeffYP);
|
||||
|
||||
_rayleighScatteringCoeffZP = _rayleighScatteringCoeff.z * 1000.0f;
|
||||
_rayleighScatteringCoeffZP.onChange(updateAtmosphere);
|
||||
addProperty(_rayleighScatteringCoeffZP);
|
||||
|
||||
_ozoneEnabledP = _ozoneLayerEnabled;
|
||||
_ozoneEnabledP.onChange(updateAtmosphere);
|
||||
addProperty(_ozoneEnabledP);
|
||||
|
||||
_ozoneHeightScaleP = _ozoneHeightScale;
|
||||
_ozoneHeightScaleP.onChange(updateAtmosphere);
|
||||
addProperty(_ozoneHeightScaleP);
|
||||
|
||||
_ozoneCoeffXP = _ozoneExtinctionCoeff.x * 100000.0f;
|
||||
_ozoneCoeffXP.onChange(updateAtmosphere);
|
||||
addProperty(_ozoneCoeffXP);
|
||||
|
||||
_ozoneCoeffYP = _ozoneExtinctionCoeff.y * 100000.0f;
|
||||
_ozoneCoeffYP.onChange(updateAtmosphere);
|
||||
addProperty(_ozoneCoeffYP);
|
||||
|
||||
|
||||
_ozoneCoeffZP = _ozoneExtinctionCoeff.z * 100000.0f;
|
||||
_ozoneCoeffZP.onChange(updateAtmosphere);
|
||||
addProperty(_ozoneCoeffZP);
|
||||
|
||||
_mieHeightScaleP = _mieHeightScale;
|
||||
_mieHeightScaleP.onChange(updateAtmosphere);
|
||||
addProperty(_mieHeightScaleP);
|
||||
|
||||
_mieScatteringCoeffXP = _mieScatteringCoeff.x * 1000.0f;
|
||||
_mieScatteringCoeffXP.onChange(updateAtmosphere);
|
||||
addProperty(_mieScatteringCoeffXP);
|
||||
|
||||
_mieScatteringCoeffYP = _mieScatteringCoeff.y * 1000.0f;
|
||||
_mieScatteringCoeffYP.onChange(updateAtmosphere);
|
||||
addProperty(_mieScatteringCoeffYP);
|
||||
|
||||
_mieScatteringCoeffZP = _mieScatteringCoeff.z * 1000.0f;
|
||||
_mieScatteringCoeffZP.onChange(updateAtmosphere);
|
||||
addProperty(_mieScatteringCoeffZP);
|
||||
|
||||
_mieScatteringExtinctionPropCoefficientP =
|
||||
_mieScatteringCoeff.x / _mieExtinctionCoeff.x;
|
||||
_mieScatteringExtinctionPropCoefficientP.onChange(updateAtmosphere);
|
||||
addProperty(_mieScatteringExtinctionPropCoefficientP);
|
||||
|
||||
_mieAsymmetricFactorGP = _miePhaseConstant;
|
||||
_mieAsymmetricFactorGP.onChange(updateAtmosphere);
|
||||
addProperty(_mieAsymmetricFactorGP);
|
||||
|
||||
_sunIntensityP = _sunRadianceIntensity;
|
||||
_sunIntensityP.onChange(updateAtmosphere);
|
||||
addProperty(_sunIntensityP);
|
||||
|
||||
_sunFollowingCameraEnabledP = _sunFollowingCameraEnabled;
|
||||
_sunFollowingCameraEnabledP.onChange(updateAtmosphere);
|
||||
addProperty(_sunFollowingCameraEnabledP);
|
||||
|
||||
_hardShadowsEnabledP = _hardShadows;
|
||||
_hardShadowsEnabledP.onChange(updateAtmosphere);
|
||||
if (_shadowEnabled) {
|
||||
addProperty(_hardShadowsEnabledP);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RenderableAtmosphere::deinitialize() {
|
||||
if (_deferredcaster) {
|
||||
OsEng.renderEngine().deferredcasterManager().detachDeferredcaster(
|
||||
*_deferredcaster
|
||||
);
|
||||
_deferredcaster = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void RenderableAtmosphere::initializeGL() {
|
||||
if (_atmosphereEnabled) {
|
||||
_deferredcaster = std::make_unique<AtmosphereDeferredcaster>();
|
||||
if (_deferredcaster) {
|
||||
_deferredcaster->setAtmosphereRadius(_atmosphereRadius);
|
||||
_deferredcaster->setPlanetRadius(_atmospherePlanetRadius);
|
||||
_deferredcaster->setPlanetAverageGroundReflectance(
|
||||
_planetAverageGroundReflectance
|
||||
);
|
||||
_deferredcaster->setPlanetGroundRadianceEmittion(
|
||||
_planetGroundRadianceEmittion
|
||||
);
|
||||
_deferredcaster->setRayleighHeightScale(_rayleighHeightScale);
|
||||
_deferredcaster->enableOzone(_ozoneLayerEnabled);
|
||||
_deferredcaster->setOzoneHeightScale(_ozoneHeightScale);
|
||||
_deferredcaster->setMieHeightScale(_mieHeightScale);
|
||||
_deferredcaster->setMiePhaseConstant(_miePhaseConstant);
|
||||
_deferredcaster->setSunRadianceIntensity(_sunRadianceIntensity);
|
||||
_deferredcaster->setRayleighScatteringCoefficients(_rayleighScatteringCoeff);
|
||||
_deferredcaster->setOzoneExtinctionCoefficients(_ozoneExtinctionCoeff);
|
||||
_deferredcaster->setMieScatteringCoefficients(_mieScatteringCoeff);
|
||||
_deferredcaster->setMieExtinctionCoefficients(_mieExtinctionCoeff);
|
||||
// TODO: Fix the ellipsoid nature of the renderable globe (JCC)
|
||||
//_deferredcaster->setEllipsoidRadii(_ellipsoid.radii());
|
||||
_deferredcaster->enableSunFollowing(_sunFollowingCameraEnabled);
|
||||
|
||||
_deferredcaster->setPrecalculationTextureScale(_preCalculatedTexturesScale);
|
||||
if (_saveCalculationsToTexture)
|
||||
_deferredcaster->enablePrecalculationTexturesSaving();
|
||||
|
||||
if (_shadowEnabled) {
|
||||
_deferredcaster->setShadowConfigArray(_shadowConfArray);
|
||||
_deferredcaster->setHardShadows(_hardShadows);
|
||||
}
|
||||
|
||||
_deferredcaster->initialize();
|
||||
}
|
||||
|
||||
OsEng.renderEngine().deferredcasterManager().attachDeferredcaster(
|
||||
*_deferredcaster
|
||||
);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void RenderableAtmosphere::deinitializeGL() {
|
||||
}
|
||||
|
||||
bool RenderableAtmosphere::isReady() const {
|
||||
bool ready = true;
|
||||
ready &= (_deferredcaster != nullptr);
|
||||
return ready;
|
||||
}
|
||||
|
||||
glm::dmat4 RenderableAtmosphere::computeModelTransformMatrix(
|
||||
const openspace::TransformData& transformData)
|
||||
{
|
||||
// scale the planet to appropriate size since the planet is a unit sphere
|
||||
return glm::translate(glm::dmat4(1.0), transformData.translation) * // Translation
|
||||
glm::dmat4(transformData.rotation) * // Spice rotation
|
||||
glm::dmat4(glm::scale(glm::dmat4(1.0), glm::dvec3(transformData.scale)));
|
||||
}
|
||||
|
||||
void RenderableAtmosphere::render(const RenderData& data, RendererTasks& renderTask) {
|
||||
if (_atmosphereEnabled) {
|
||||
DeferredcasterTask task{ _deferredcaster.get(), data };
|
||||
renderTask.deferredcasterTasks.push_back(task);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderableAtmosphere::update(const UpdateData& data) {
|
||||
_stateMatrix = data.modelTransform.rotation;
|
||||
|
||||
if (_deferredcaster) {
|
||||
_deferredcaster->setTime(data.time.j2000Seconds());
|
||||
glm::dmat4 modelTransform = computeModelTransformMatrix(data.modelTransform);
|
||||
_deferredcaster->setModelTransform(modelTransform);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderableAtmosphere::updateAtmosphereParameters() {
|
||||
bool executeComputation = true;
|
||||
|
||||
if (_sunRadianceIntensity != _sunIntensityP ||
|
||||
_planetGroundRadianceEmittion != _groundRadianceEmittionP ||
|
||||
_sunFollowingCameraEnabled != _sunFollowingCameraEnabledP ||
|
||||
_hardShadows != _hardShadowsEnabledP) {
|
||||
executeComputation = false;
|
||||
}
|
||||
|
||||
_atmosphereRadius = _atmospherePlanetRadius + _atmosphereHeightP;
|
||||
_planetAverageGroundReflectance = _groundAverageReflectanceP;
|
||||
_planetGroundRadianceEmittion = _groundRadianceEmittionP;
|
||||
_rayleighHeightScale = _rayleighHeightScaleP;
|
||||
_rayleighScatteringCoeff = glm::vec3(
|
||||
_rayleighScatteringCoeffXP * 0.001f,
|
||||
_rayleighScatteringCoeffYP * 0.001f,
|
||||
_rayleighScatteringCoeffZP * 0.001f
|
||||
);
|
||||
_ozoneLayerEnabled = _ozoneEnabledP;
|
||||
_ozoneHeightScale = _ozoneHeightScaleP;
|
||||
_ozoneExtinctionCoeff = glm::vec3(_ozoneCoeffXP.value() * 0.00001f,
|
||||
_ozoneCoeffYP.value() * 0.00001f,
|
||||
_ozoneCoeffZP.value() * 0.00001f);
|
||||
_mieHeightScale = _mieHeightScaleP;
|
||||
_mieScatteringCoeff = glm::vec3(
|
||||
_mieScatteringCoeffXP * 0.001f,
|
||||
_mieScatteringCoeffYP * 0.001f,
|
||||
_mieScatteringCoeffZP * 0.001f
|
||||
);
|
||||
_mieExtinctionCoeff = _mieScatteringCoeff * (1.0f /
|
||||
static_cast<float>(_mieScatteringExtinctionPropCoefficientP));
|
||||
_miePhaseConstant = _mieAsymmetricFactorGP;
|
||||
_sunRadianceIntensity = _sunIntensityP;
|
||||
_sunFollowingCameraEnabled = _sunFollowingCameraEnabledP;
|
||||
_hardShadows = _hardShadowsEnabledP;
|
||||
|
||||
|
||||
if (_deferredcaster) {
|
||||
_deferredcaster->setAtmosphereRadius(_atmosphereRadius);
|
||||
_deferredcaster->setPlanetRadius(_atmospherePlanetRadius);
|
||||
_deferredcaster->setPlanetAverageGroundReflectance(
|
||||
_planetAverageGroundReflectance
|
||||
);
|
||||
_deferredcaster->setPlanetGroundRadianceEmittion(_planetGroundRadianceEmittion);
|
||||
_deferredcaster->setRayleighHeightScale(_rayleighHeightScale);
|
||||
_deferredcaster->enableOzone(_ozoneLayerEnabled);
|
||||
_deferredcaster->setOzoneHeightScale(_ozoneHeightScale);
|
||||
_deferredcaster->setMieHeightScale(_mieHeightScale);
|
||||
_deferredcaster->setMiePhaseConstant(_miePhaseConstant);
|
||||
_deferredcaster->setSunRadianceIntensity(_sunRadianceIntensity);
|
||||
_deferredcaster->setRayleighScatteringCoefficients(_rayleighScatteringCoeff);
|
||||
_deferredcaster->setOzoneExtinctionCoefficients(_ozoneExtinctionCoeff);
|
||||
_deferredcaster->setMieScatteringCoefficients(_mieScatteringCoeff);
|
||||
_deferredcaster->setMieExtinctionCoefficients(_mieExtinctionCoeff);
|
||||
_deferredcaster->enableSunFollowing(_sunFollowingCameraEnabled);
|
||||
//_deferredcaster->setEllipsoidRadii(_ellipsoid.radii());
|
||||
|
||||
if (_shadowEnabled) {
|
||||
_deferredcaster->setHardShadows(_hardShadows);
|
||||
}
|
||||
|
||||
if (executeComputation) {
|
||||
_deferredcaster->preCalculateAtmosphereParam();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
@@ -0,0 +1,153 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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_MODULE_SPACE___RENDERABLEATMOSPHERE___H__
|
||||
#define __OPENSPACE_MODULE_SPACE___RENDERABLEATMOSPHERE___H__
|
||||
|
||||
#include <openspace/rendering/renderable.h>
|
||||
|
||||
#include <openspace/properties/stringproperty.h>
|
||||
#include <openspace/properties/scalar/boolproperty.h>
|
||||
#include <openspace/properties/scalar/intproperty.h>
|
||||
#include <openspace/properties/scalar/floatproperty.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
|
||||
#include <ghoul/opengl/textureunit.h>
|
||||
|
||||
#include <modules/atmosphere/rendering/atmospheredeferredcaster.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace ghoul::opengl {
|
||||
class ProgramObject;
|
||||
class Texture;
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
|
||||
class AtmosphereDeferredcaster;
|
||||
|
||||
struct TransformData;
|
||||
|
||||
// Shadow structure
|
||||
struct ShadowConfiguration {
|
||||
std::pair<std::string, double> source;
|
||||
std::pair<std::string, double> caster;
|
||||
};
|
||||
|
||||
struct ShadowRenderingStruct {
|
||||
double xu,
|
||||
xp;
|
||||
double rs,
|
||||
rc;
|
||||
glm::dvec3 sourceCasterVec;
|
||||
glm::dvec3 casterPositionVec;
|
||||
bool isShadowing;
|
||||
};
|
||||
|
||||
namespace planetgeometry {
|
||||
class PlanetGeometry;
|
||||
}
|
||||
|
||||
namespace documentation { struct Documentation; }
|
||||
namespace planetgeometry { class PlanetGeometry; }
|
||||
|
||||
class RenderableAtmosphere : public Renderable {
|
||||
public:
|
||||
|
||||
RenderableAtmosphere(const ghoul::Dictionary& dictionary);
|
||||
|
||||
void deinitialize() override;
|
||||
void initializeGL() override;
|
||||
void deinitializeGL() override;
|
||||
bool isReady() const override;
|
||||
|
||||
void render(const RenderData& data, RendererTasks& rendererTask) override;
|
||||
void update(const UpdateData& data) override;
|
||||
|
||||
static documentation::Documentation Documentation();
|
||||
|
||||
private:
|
||||
glm::dmat4 computeModelTransformMatrix(const openspace::TransformData& transformData);
|
||||
void updateAtmosphereParameters();
|
||||
|
||||
properties::FloatProperty _atmosphereHeightP;
|
||||
properties::FloatProperty _groundAverageReflectanceP;
|
||||
properties::FloatProperty _groundRadianceEmittionP;
|
||||
properties::FloatProperty _rayleighHeightScaleP;
|
||||
properties::FloatProperty _rayleighScatteringCoeffXP;
|
||||
properties::FloatProperty _rayleighScatteringCoeffYP;
|
||||
properties::FloatProperty _rayleighScatteringCoeffZP;
|
||||
properties::BoolProperty _ozoneEnabledP;
|
||||
properties::FloatProperty _ozoneHeightScaleP;
|
||||
properties::FloatProperty _ozoneCoeffXP;
|
||||
properties::FloatProperty _ozoneCoeffYP;
|
||||
properties::FloatProperty _ozoneCoeffZP;
|
||||
properties::FloatProperty _mieHeightScaleP;
|
||||
properties::FloatProperty _mieScatteringCoeffXP;
|
||||
properties::FloatProperty _mieScatteringCoeffYP;
|
||||
properties::FloatProperty _mieScatteringCoeffZP;
|
||||
properties::FloatProperty _mieScatteringExtinctionPropCoefficientP;
|
||||
properties::FloatProperty _mieAsymmetricFactorGP;
|
||||
properties::FloatProperty _sunIntensityP;
|
||||
properties::BoolProperty _sunFollowingCameraEnabledP;
|
||||
properties::BoolProperty _hardShadowsEnabledP;
|
||||
|
||||
bool _atmosphereEnabled;
|
||||
bool _ozoneLayerEnabled;
|
||||
bool _sunFollowingCameraEnabled;
|
||||
float _atmosphereRadius;
|
||||
float _atmospherePlanetRadius;
|
||||
float _planetAverageGroundReflectance;
|
||||
float _planetGroundRadianceEmittion;
|
||||
float _rayleighHeightScale;
|
||||
float _ozoneHeightScale;
|
||||
float _mieHeightScale;
|
||||
float _miePhaseConstant;
|
||||
float _sunRadianceIntensity;
|
||||
|
||||
glm::vec3 _mieExtinctionCoeff;
|
||||
glm::vec3 _rayleighScatteringCoeff;
|
||||
glm::vec3 _ozoneExtinctionCoeff;
|
||||
glm::vec3 _mieScatteringCoeff;
|
||||
|
||||
// Atmosphere Debug
|
||||
bool _saveCalculationsToTexture;
|
||||
float _preCalculatedTexturesScale;
|
||||
|
||||
std::unique_ptr<AtmosphereDeferredcaster> _deferredcaster;
|
||||
|
||||
bool _shadowEnabled;
|
||||
bool _hardShadows;
|
||||
|
||||
glm::dmat3 _stateMatrix;
|
||||
|
||||
std::vector<ShadowConfiguration> _shadowConfArray;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_MODULE_SPACE___RENDERABLEATMOSPHERE___H__
|
||||
@@ -0,0 +1,375 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
****************************************************************************************/
|
||||
|
||||
/*****************************************************************************************
|
||||
* Modified parts of the code (4D texture mechanism, analytical transmittance etc) *
|
||||
* from Eric Bruneton is used in the following code. *
|
||||
****************************************************************************************/
|
||||
|
||||
/**
|
||||
* Precomputed Atmospheric Scattering
|
||||
* Copyright (c) 2008 INRIA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
// Atmosphere Rendering Parameters
|
||||
uniform float Rg;
|
||||
uniform float Rt;
|
||||
uniform float AverageGroundReflectance;
|
||||
uniform float groundRadianceEmittion;
|
||||
uniform float HR;
|
||||
uniform vec3 betaRayleigh;
|
||||
uniform float HO;
|
||||
uniform vec3 betaOzoneExtinction;
|
||||
uniform float HM;
|
||||
uniform vec3 betaMieScattering;
|
||||
uniform vec3 betaMieExtinction;
|
||||
uniform float mieG;
|
||||
uniform float sunRadiance;
|
||||
|
||||
uniform bool ozoneLayerEnabled;
|
||||
|
||||
uniform int TRANSMITTANCE_W;
|
||||
uniform int TRANSMITTANCE_H;
|
||||
uniform int SKY_W;
|
||||
uniform int SKY_H;
|
||||
uniform int OTHER_TEXTURES_W;
|
||||
uniform int OTHER_TEXTURES_H;
|
||||
uniform int SAMPLES_R;
|
||||
uniform int SAMPLES_MU;
|
||||
uniform int SAMPLES_MU_S;
|
||||
uniform int SAMPLES_NU;
|
||||
|
||||
const float ATM_EPSILON = 1.0;
|
||||
|
||||
// Integration steps
|
||||
const int TRANSMITTANCE_STEPS = 500;
|
||||
const int INSCATTER_INTEGRAL_SAMPLES = 50;
|
||||
const int IRRADIANCE_INTEGRAL_SAMPLES = 32;
|
||||
const int INSCATTER_SPHERICAL_INTEGRAL_SAMPLES = 16;
|
||||
|
||||
const float M_PI = 3.141592657;
|
||||
|
||||
uniform sampler2D transmittanceTexture;
|
||||
|
||||
float opticalDepth(const float H, const float r, const float mu, const 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(const float r, const float mu, const float d) {
|
||||
if (ozoneLayerEnabled) {
|
||||
return exp(-betaRayleigh * opticalDepth(HR, r, mu, d) -
|
||||
betaOzoneExtinction * (0.0000006) * opticalDepth(HO, r, mu, d) -
|
||||
betaMieExtinction * opticalDepth(HM, r, mu, d));
|
||||
} else {
|
||||
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 ==============//
|
||||
//================================================//
|
||||
// In the following shaders r (altitude) is the length of vector/position x in the
|
||||
// atmosphere (or on the top of it when considering an observer in space),
|
||||
// where the light is comming from the opposite direction of the view direction,
|
||||
// here the vector v or viewDirection.
|
||||
// Rg is the planet radius and Rt the atmosphere radius.
|
||||
|
||||
//--- Calculate the distance of the ray starting at x (height r)
|
||||
// until the planet's ground or top of atmosphere. ---
|
||||
// r := || vec(x) || e [0, Rt]
|
||||
// mu := cosine of the zeith angle of vec(v). Or mu = (vec(x) * vec(v))/r
|
||||
float rayDistance(const float r, const float mu) {
|
||||
// The light ray starting at the observer in/on the atmosphere can
|
||||
// have to possible end points: the top of the atmosphere or the
|
||||
// planet ground. So the shortest path is the one we are looking for,
|
||||
// otherwise we may be passing through the ground.
|
||||
|
||||
// cosine law
|
||||
float atmRadiusEps = Rt + ATM_EPSILON;
|
||||
float rayDistanceAtmosphere = -r * mu +
|
||||
sqrt(r * r * (mu * mu - 1.0f) + atmRadiusEps * atmRadiusEps);
|
||||
float delta = r * r * (mu * mu - 1.0f) + Rg * Rg;
|
||||
|
||||
// Ray may be hitting ground
|
||||
if (delta >= 0.0f) {
|
||||
float rayDistanceGround = -r * mu - sqrt(delta);
|
||||
if (rayDistanceGround >= 0.0f) {
|
||||
return min(rayDistanceAtmosphere, rayDistanceGround);
|
||||
}
|
||||
}
|
||||
return rayDistanceAtmosphere;
|
||||
}
|
||||
|
||||
//-- Given the window's fragment coordinates, for a defined
|
||||
// viewport, gives back the interpolated r e [Rg, Rt] and
|
||||
// mu e [-1, 1] --
|
||||
// r := height of starting point vect(x)
|
||||
// mu := cosine of the zeith angle of vec(v). Or mu = (vec(x) * vec(v))/r
|
||||
void unmappingRAndMu(out float r, out float mu) {
|
||||
float u_mu = gl_FragCoord.x / float(TRANSMITTANCE_W);
|
||||
float u_r = gl_FragCoord.y / float(TRANSMITTANCE_H);
|
||||
|
||||
// In the paper u_r^2 = (r^2-Rg^2)/(Rt^2-Rg^2)
|
||||
// So, extracting r from u_r in the above equation:
|
||||
//r = sqrt( Rg * Rg + (u_r * u_r) * (Rt * Rt - Rg * Rg) );
|
||||
r = Rg + (u_r * u_r) * (Rt - Rg);
|
||||
|
||||
// In the paper the Bruneton suggest mu = dot(v,x)/||x|| with ||v|| = 1.0
|
||||
// Later he proposes u_mu = (1-exp(-3mu-0.6))/(1-exp(-3.6))
|
||||
// But the below one is better. See Colliene.
|
||||
// One must remember that mu is defined from 0 to PI/2 + epsillon.
|
||||
mu = -0.15f + tan(1.5f * u_mu) / tan(1.5f) * (1.0f + 0.15f);
|
||||
}
|
||||
|
||||
//-- Given the windows's fragment coordinates, for a defined view port,
|
||||
// gives back the interpolated r e [Rg, Rt] and muSun e [-1, 1] --
|
||||
// r := height of starting point vect(x)
|
||||
// muSun := cosine of the zeith angle of vec(s). Or muSun = (vec(s) * vec(v))
|
||||
void unmappingRAndMuSun(out float r, out float muSun) {
|
||||
// See Bruneton and Colliene to understand the mapping.
|
||||
muSun = -0.2f + (gl_FragCoord.x - 0.5f) / (float(OTHER_TEXTURES_W) - 1.0f) * (1.0f + 0.2f);
|
||||
//r = Rg + (gl_FragCoord.y - 0.5f) / (float(OTHER_TEXTURES_H) - 1.0f) * (Rt - Rg);
|
||||
r = Rg + (gl_FragCoord.y - 0.5f) / (float(OTHER_TEXTURES_H) ) * (Rt - Rg);
|
||||
}
|
||||
|
||||
//-- Given the windows's fragment coordinates, for a defined view port,
|
||||
// gives back the interpolated r e [Rg, Rt] and muSun e [-1, 1] for the
|
||||
// Irradiance deltaE texture table --
|
||||
// r := height of starting point vect(x)
|
||||
// muSun := cosine of the zeith angle of vec(s). Or muSun = (vec(s) * vec(v))
|
||||
void unmappingRAndMuSunIrradiance(out float r, out float muSun) {
|
||||
// See Bruneton and Colliene to understand the mapping.
|
||||
muSun = -0.2f + (gl_FragCoord.x - 0.5f) / (float(SKY_W) - 1.0f) * (1.0f + 0.2f);
|
||||
r = Rg + (gl_FragCoord.y - 0.5f) / (float(SKY_H) - 1.0f) * (Rt - Rg);
|
||||
}
|
||||
|
||||
//-- Given the windows's fragment coordinates, for a defined view port,
|
||||
// gives back the interpolated r e [Rg, Rt] and mu, muSun amd nu e [-1, 1] --
|
||||
// r := height of starting point vect(x)
|
||||
// mu := cosine of the zeith angle of vec(v). Or mu = (vec(x) * vec(v))/r
|
||||
// muSun := cosine of the zeith angle of vec(s). Or muSun = (vec(s) * vec(v))
|
||||
// nu := cosone of the angle between vec(s) and vec(v)
|
||||
// dhdH := it is a vec4. dhdH.x stores the dminT := Rt - r, dhdH.y stores the dH value (see paper),
|
||||
// dhdH.z stores dminG := r - Rg and dhdH.w stores dh (see paper).
|
||||
void unmappingMuMuSunNu(const float r, vec4 dhdH, out float mu, out float muSun, out float nu) {
|
||||
// Window coordinates of pixel (uncentering also)
|
||||
float fragmentX = gl_FragCoord.x - 0.5f;
|
||||
float fragmentY = gl_FragCoord.y - 0.5f;
|
||||
|
||||
// Pre-calculations
|
||||
float Rg2 = Rg * Rg;
|
||||
float Rt2 = Rt * Rt;
|
||||
float r2 = r * r;
|
||||
|
||||
float halfSAMPLE_MU = float(SAMPLES_MU) / 2.0f;
|
||||
// If the (vec(x) dot vec(v))/r is negative, i.e.,
|
||||
// the light ray has great probability to touch
|
||||
// the ground, we obtain mu considering the geometry
|
||||
// of the ground
|
||||
if (fragmentY < halfSAMPLE_MU) {
|
||||
float ud = 1.0f - (fragmentY / (halfSAMPLE_MU - 1.0f));
|
||||
float d = min(max(dhdH.z, ud * dhdH.w), dhdH.w * 0.999);
|
||||
// cosine law: Rg^2 = r^2 + d^2 - 2rdcos(pi-theta)
|
||||
// where cosine(theta) = mu
|
||||
mu = (Rg2 - r2 - d * d) / (2.0 * r * d);
|
||||
// We can't handle a ray inside the planet, i.e.,
|
||||
// when r ~ Rg, so we check against it.
|
||||
// If that is the case, we approximate to
|
||||
// a ray touching the ground.
|
||||
// cosine(pi-theta) = dh/r = sqrt(r^2-Rg^2)
|
||||
// cosine(theta) = - sqrt(1 - Rg^2/r^2)
|
||||
mu = min(mu, -sqrt(1.0 - (Rg2 / r2)) - 0.001);
|
||||
}
|
||||
// The light ray is touching the atmosphere and
|
||||
// not the ground
|
||||
else {
|
||||
float d = (fragmentY - halfSAMPLE_MU) / (halfSAMPLE_MU - 1.0f);
|
||||
d = min(max(dhdH.x, d * dhdH.y), dhdH.y * 0.999);
|
||||
// cosine law: Rt^2 = r^2 + d^2 - 2rdcos(pi-theta)
|
||||
// whre cosine(theta) = mu
|
||||
mu = (Rt2 - r2 - d * d) / (2.0f * r * d);
|
||||
}
|
||||
|
||||
float modValueMuSun = mod(fragmentX, float(SAMPLES_MU_S)) / (float(SAMPLES_MU_S) - 1.0f);
|
||||
// The following mapping is different from the paper. See Colliene for an details.
|
||||
muSun = tan((2.0f * modValueMuSun - 1.0f + 0.26f) * 1.1f) / tan(1.26f * 1.1f);
|
||||
nu = -1.0f + floor(fragmentX / float(SAMPLES_MU_S)) / (float(SAMPLES_NU) - 1.0f) * 2.0f;
|
||||
}
|
||||
|
||||
|
||||
//-- Function to access the transmittance texture. Given r
|
||||
// and mu, returns the transmittance of a ray starting at vec(x),
|
||||
// height r, and direction vec(v), mu, and length until it hits
|
||||
// the ground or the top of atmosphere. --
|
||||
// r := height of starting point vect(x)
|
||||
// mu := cosine of the zeith angle of vec(v). Or mu = (vec(x) * vec(v))/r
|
||||
vec3 transmittanceLUT(const float r, const float mu) {
|
||||
// Given the position x (here the altitude r) and the view
|
||||
// angle v (here the cosine(v)= mu), we map this
|
||||
float u_r = sqrt((r - Rg) / (Rt - Rg));
|
||||
//float u_r = sqrt((r*r - Rg*Rg) / (Rt*Rt - Rg*Rg));
|
||||
// See Colliene to understand the different mapping.
|
||||
float u_mu = atan((mu + 0.15f) / (1.0f + 0.15f) * tan(1.5f)) / 1.5f;
|
||||
|
||||
return texture(transmittanceTexture, vec2(u_mu, u_r)).rgb;
|
||||
}
|
||||
|
||||
// -- Given a position r and direction mu, calculates de transmittance
|
||||
// along the ray with length d. This function uses the propriety
|
||||
// of Transmittance: T(a,b) = TableT(a,v)/TableT(b, v) --
|
||||
// r := height of starting point vect(x)
|
||||
// mu := cosine of the zeith angle of vec(v). Or mu = (vec(x) * vec(v))/r
|
||||
vec3 transmittance(const float r, const float mu, const float d) {
|
||||
// Here we use the transmittance property: T(x,v) = T(x,d)*T(d,v)
|
||||
// to, given a distance d, calculates that transmittance along
|
||||
// that distance starting in x (hight r): T(x,d) = T(x,v)/T(d,v).
|
||||
//
|
||||
// From cosine law: c^2 = a^2 + b^2 - 2*a*b*cos(ab)
|
||||
float ri = sqrt(d * d + r * r + 2.0 * r * d * mu);
|
||||
// mu_i = (vec(d) dot vec(v)) / r_i
|
||||
// = ((vec(x) + vec(d-x)) dot vec(v))/ r_i
|
||||
// = (r*mu + d) / r_i
|
||||
float mui = (d + r * mu) / ri;
|
||||
|
||||
// It's important to remember that we calculate the Transmittance
|
||||
// table only for zenith angles between 0 and pi/2+episilon.
|
||||
// Then, if mu < 0.0, we just need to invert the view direction
|
||||
// and the start and end points between them, i.e., if
|
||||
// x --> x0, then x0-->x.
|
||||
// Also, let's use the property: T(a,c) = T(a,b)*T(b,c)
|
||||
// Because T(a,c) and T(b,c) are already in the table T,
|
||||
// T(a,b) = T(a,c)/T(b,c).
|
||||
if (mu > 0.0f) {
|
||||
return min(transmittanceLUT(r, mu) /
|
||||
transmittanceLUT(ri, mui), 1.0f);
|
||||
} else {
|
||||
return min(transmittanceLUT(ri, -mui) /
|
||||
transmittanceLUT(r, -mu), 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
// -- Calculates Rayleigh phase function given the
|
||||
// scattering cosine angle mu --
|
||||
// mu := cosine of the zeith angle of vec(v). Or mu = (vec(x) * vec(v))/r
|
||||
float rayleighPhaseFunction(const float mu) {
|
||||
return (3.0f / (16.0f * M_PI)) * (1.0f + mu * mu);
|
||||
}
|
||||
|
||||
// -- Calculates Mie phase function given the
|
||||
// scattering cosine angle mu --
|
||||
// mu := cosine of the zeith angle of vec(v). Or mu = (vec(x) * vec(v))/r
|
||||
float miePhaseFunction(const float mu) {
|
||||
//return (3.0f / (8.0f * M_PI)) *
|
||||
// ( ( (1.0f - (mieG * mieG) ) * (1.0f + mu * mu) ) /
|
||||
// ( (2.0f + mieG * mieG) *
|
||||
// pow(1.0f + mieG * mieG - 2.0f * mieG * mu, 3.0f/2.0f) ) );
|
||||
return 1.5f * 1.0f / (4.0f * M_PI) * (1.0f - mieG * mieG) *
|
||||
pow(1.0f + (mieG * mieG) - 2.0f * mieG * mu, -3.0f/2.0f) * (1.0f + mu * mu) / (2.0f + mieG*mieG);
|
||||
}
|
||||
|
||||
// -- Given the height rm view-zenith angle (cosine) mu,
|
||||
// sun-zenith angle (cosine) muSun and the angle (cosine)
|
||||
// between the vec(s) and vec(v), nu, we access the 3D textures
|
||||
// and interpolate between them (r) to find the value for the
|
||||
// 4D texture. --
|
||||
// r := height of starting point vect(x)
|
||||
// mu := cosine of the zeith angle of vec(v). Or mu = (vec(x) * vec(v))/r
|
||||
// muSun := cosine of the zeith angle of vec(s). Or muSun = (vec(s) * vec(v))
|
||||
// nu := cosine of the angle between vec(s) and vec(v)
|
||||
vec4 texture4D(sampler3D table, const float r, const float mu,
|
||||
const float muSun, const float nu)
|
||||
{
|
||||
float Rg2 = Rg * Rg;
|
||||
float Rt2 = Rt * Rt;
|
||||
float r2 = r * r;
|
||||
float H = sqrt(Rt2 - Rg2);
|
||||
float rho = sqrt(r2 - Rg2);
|
||||
float rmu = r * mu;
|
||||
float delta = rmu * rmu - r2 + Rg2;
|
||||
vec4 cst = rmu < 0.0f && delta > 0.0f ?
|
||||
vec4(1.0f, 0.0f, 0.0f, 0.5f - 0.5f / float(SAMPLES_MU)) :
|
||||
vec4(-1.0f, H * H, H, 0.5f + 0.5f / float(SAMPLES_MU));
|
||||
float u_r = 0.5f / float(SAMPLES_R) + rho / H * (1.0f - 1.0f / float(SAMPLES_R));
|
||||
float u_mu = cst.w + (rmu * cst.x + sqrt(delta + cst.y)) / (rho + cst.z) * (0.5f - 1.0f / float(SAMPLES_MU));
|
||||
float u_mu_s = 0.5f / float(SAMPLES_MU_S) +
|
||||
(atan(max(muSun, -0.1975) * tan(1.26f * 1.1f)) / 1.1f + (1.0f - 0.26f)) * 0.5f * (1.0f - 1.0f / float(SAMPLES_MU_S));
|
||||
float lerp = (nu + 1.0f) / 2.0f * (float(SAMPLES_NU) - 1.0f);
|
||||
float u_nu = floor(lerp);
|
||||
lerp = lerp - u_nu;
|
||||
return texture(table, vec3((u_nu + u_mu_s) / float(SAMPLES_NU), u_mu, u_r)) * (1.0f - lerp) +
|
||||
texture(table, vec3((u_nu + u_mu_s + 1.0f) / float(SAMPLES_NU), u_mu, u_r)) * lerp;
|
||||
}
|
||||
|
||||
// -- Given the irradiance texture table, the cosine of zenith sun vector
|
||||
// and the height of the observer (ray's stating point x), calculates the
|
||||
// mapping for u_r and u_muSun and returns the value in the LUT. --
|
||||
// lut := OpenGL texture2D sampler (the irradiance texture deltaE)
|
||||
// muSun := cosine of the zeith angle of vec(s). Or muSun = (vec(s) * vec(v))
|
||||
// r := height of starting point vect(x)
|
||||
vec3 irradianceLUT(sampler2D lut, const float muSun, const float r) {
|
||||
// See Bruneton paper and Coliene to understand the mapping
|
||||
float u_muSun = (muSun + 0.2f) / (1.0f + 0.2f);
|
||||
float u_r = (r - Rg) / (Rt - Rg);
|
||||
return texture(lut, vec2(u_muSun, u_r)).rgb;
|
||||
}
|
||||
@@ -0,0 +1,744 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
****************************************************************************************/
|
||||
|
||||
/*****************************************************************************************
|
||||
* Modified parts of the code (4D texture mechanism) from Eric Bruneton is used in the *
|
||||
* following code. *
|
||||
****************************************************************************************/
|
||||
|
||||
/**
|
||||
* Precomputed Atmospheric Scattering
|
||||
* Copyright (c) 2008 INRIA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
#include "floatoperations.glsl"
|
||||
|
||||
#include "hdr.glsl"
|
||||
#include "atmosphere_common.glsl"
|
||||
|
||||
out vec4 renderTarget;
|
||||
in vec3 interpolatedNDCPos;
|
||||
|
||||
uniform int nAaSamples;
|
||||
uniform double msaaSamplePatter[48];
|
||||
uniform int cullAtmosphere;
|
||||
|
||||
// The following uniforms are
|
||||
// set into the current Renderer
|
||||
// Background exposure hack
|
||||
uniform float backgroundConstant;
|
||||
uniform bool firstPaint;
|
||||
uniform float atmExposure;
|
||||
|
||||
uniform sampler2D irradianceTexture;
|
||||
uniform sampler3D inscatterTexture;
|
||||
uniform sampler2DMS mainPositionTexture;
|
||||
uniform sampler2DMS mainNormalTexture;
|
||||
uniform sampler2DMS mainColorTexture;
|
||||
uniform sampler2DMS otherDataTexture;
|
||||
|
||||
// Model Transform Matrix Used for Globe Rendering
|
||||
uniform dmat4 dInverseSgctEyeToWorldTranform; // SGCT Eye to OS World
|
||||
uniform dmat4 dSgctEyeToOSEyeTranform; // SGCT Eye to OS Eye *
|
||||
uniform dmat4 dInverseSgctProjectionMatrix; // Clip to SGCT Eye *
|
||||
uniform dmat4 dInverseCamRotTransform;
|
||||
uniform dmat4 dInverseModelTransformMatrix;
|
||||
uniform dmat4 dModelTransformMatrix;
|
||||
//uniform dmat4 dSGCTEyeToOSWorldTransformMatrix;
|
||||
|
||||
uniform dvec4 dObjpos;
|
||||
uniform dvec3 dCampos;
|
||||
uniform dvec3 sunDirectionObj;
|
||||
uniform dvec3 ellipsoidRadii;
|
||||
|
||||
/*******************************************************************************
|
||||
***** ALL CALCULATIONS FOR ECLIPSE ARE IN METERS AND IN WORLD SPACE SYSTEM ****
|
||||
*******************************************************************************/
|
||||
// JCC: Remove and use dictionary to
|
||||
// decides the number of shadows
|
||||
const uint numberOfShadows = 1;
|
||||
|
||||
struct ShadowRenderingStruct {
|
||||
double xu, xp;
|
||||
double rs, rc;
|
||||
dvec3 sourceCasterVec;
|
||||
dvec3 casterPositionVec;
|
||||
bool isShadowing;
|
||||
};
|
||||
|
||||
// Eclipse shadow data
|
||||
// JCC: Remove and use dictionary to
|
||||
// decides the number of shadows
|
||||
uniform ShadowRenderingStruct shadowDataArray[numberOfShadows];
|
||||
uniform int shadows;
|
||||
uniform bool hardShadows;
|
||||
|
||||
vec4 butterworthFunc(const float d, const float r, const float n) {
|
||||
return vec4(vec3(sqrt(r/(r + pow(d, 2*n)))), 1.0);
|
||||
}
|
||||
|
||||
vec4 calcShadow(const ShadowRenderingStruct shadowInfoArray[numberOfShadows], const dvec3 position,
|
||||
const bool ground) {
|
||||
if (shadowInfoArray[0].isShadowing) {
|
||||
dvec3 pc = shadowInfoArray[0].casterPositionVec - position;
|
||||
dvec3 sc_norm = shadowInfoArray[0].sourceCasterVec;
|
||||
dvec3 pc_proj = dot(pc, sc_norm) * sc_norm;
|
||||
dvec3 d = pc - pc_proj;
|
||||
|
||||
float length_d = float(length(d));
|
||||
double length_pc_proj = length(pc_proj);
|
||||
|
||||
float r_p_pi = float(shadowInfoArray[0].rc * (length_pc_proj + shadowInfoArray[0].xp) / shadowInfoArray[0].xp);
|
||||
float r_u_pi = float(shadowInfoArray[0].rc * (shadowInfoArray[0].xu - length_pc_proj) / shadowInfoArray[0].xu);
|
||||
|
||||
if ( length_d < r_u_pi ) { // umbra
|
||||
if (ground) {
|
||||
if (hardShadows) {
|
||||
return vec4(0.2, 0.2, 0.2, 1.0);
|
||||
} else {
|
||||
return butterworthFunc(length_d, r_u_pi, 4.0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (hardShadows) {
|
||||
return vec4(0.5, 0.5, 0.5, 1.0);
|
||||
} else {
|
||||
return vec4(vec3(length_d/r_p_pi), 1.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( length_d < r_p_pi ) {// penumbra
|
||||
if (hardShadows) {
|
||||
return vec4(0.5, 0.5, 0.5, 1.0);
|
||||
} else {
|
||||
return vec4(vec3(length_d/r_p_pi), 1.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return vec4(1.0);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
******* ALL CALCULATIONS FOR ATMOSPHERE ARE KM AND IN WORLD SPACE SYSTEM ******
|
||||
*******************************************************************************/
|
||||
|
||||
struct dRay {
|
||||
dvec4 origin;
|
||||
dvec4 direction;
|
||||
};
|
||||
|
||||
/* 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 outside the atmosphere or the initial (and only)
|
||||
* intersection of the ray with atmosphere when the eye position
|
||||
* is inside atmosphere.
|
||||
*/
|
||||
bool dAtmosphereIntersection(const dvec3 planetPosition, const dRay ray, const double atmRadius,
|
||||
out bool inside, out double offset, out double maxLength ) {
|
||||
dvec3 l = planetPosition - ray.origin.xyz;
|
||||
double s = dot(l, ray.direction.xyz);
|
||||
double l2 = dot(l, l);
|
||||
double r2 = atmRadius * atmRadius; // avoiding surface acne
|
||||
|
||||
// Ray origin (eye position) is behind sphere
|
||||
if ((s < 0.0) && (l2 > r2)) {
|
||||
inside = false;
|
||||
offset = 0.0;
|
||||
maxLength = 0.0;
|
||||
return false;
|
||||
}
|
||||
|
||||
double m2 = l2 - s*s;
|
||||
|
||||
// Ray misses atmospere
|
||||
if (m2 > r2) {
|
||||
inside = false;
|
||||
offset = 0.0;
|
||||
maxLength = 0.0;
|
||||
return false;
|
||||
}
|
||||
|
||||
// We already now the ray hits the atmosphere
|
||||
|
||||
// If q = 0.0f, there is only one intersection
|
||||
double 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.0;
|
||||
maxLength = s + q;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculates Intersection Ray by walking through
|
||||
* all the graphic pipile transformations in the
|
||||
* opposite direction.
|
||||
* Instead of passing through all the pipeline,
|
||||
* it starts at NDC from the interpolated
|
||||
* positions from the screen quad.
|
||||
* This method avoids matrices multiplications
|
||||
* wherever is possible.
|
||||
*/
|
||||
void dCalculateRayRenderableGlobe(in int mssaSample, out dRay ray,
|
||||
out dvec4 planetPositionObjectCoords,
|
||||
out dvec4 cameraPositionInObject) {
|
||||
// ======================================
|
||||
// ======= Avoiding Some Matrices =======
|
||||
|
||||
// NDC to clip coordinates (gl_FragCoord.w = 1.0/w_clip)
|
||||
// Using the interpolated coords:
|
||||
// Assuming Red Book is right: z_ndc e [0, 1] and not [-1, 1]
|
||||
dvec2 samplePos = dvec2(msaaSamplePatter[mssaSample],
|
||||
msaaSamplePatter[mssaSample+1]);
|
||||
dvec4 clipCoords = dvec4(interpolatedNDCPos.xy + samplePos, interpolatedNDCPos.z, 1.0) / gl_FragCoord.w;
|
||||
|
||||
// Clip to SGCT Eye
|
||||
dvec4 sgctEyeCoords = dInverseSgctProjectionMatrix * clipCoords;
|
||||
sgctEyeCoords.w = 1.0;
|
||||
|
||||
// SGCT Eye to OS Eye
|
||||
dvec4 tOSEyeCoordsInv = dSgctEyeToOSEyeTranform * sgctEyeCoords;
|
||||
|
||||
// OS Eye to World coords
|
||||
dvec4 tmpRInv = dInverseCamRotTransform * tOSEyeCoordsInv;
|
||||
dvec4 worldCoords = dvec4(dvec3(tmpRInv) + dCampos, 1.0);
|
||||
|
||||
// World to Object
|
||||
dvec4 objectCoords = dInverseModelTransformMatrix * worldCoords;
|
||||
|
||||
// Planet Position in Object Space
|
||||
// JCC: Applying the inverse of the model transformation on the object postion in World
|
||||
// space results in imprecision.
|
||||
planetPositionObjectCoords = dvec4(0.0, 0.0, 0.0, 1.0);
|
||||
//planetPositionObjectCoords = dInverseModelTransformMatrix * dvec4(dObjpos.xyz, 1.0);
|
||||
|
||||
// Camera Position in Object Space
|
||||
cameraPositionInObject = dInverseModelTransformMatrix * dvec4(dCampos, 1.0);
|
||||
|
||||
// ============================
|
||||
// ====== Building Ray ========
|
||||
// Ray in object space (in KM)
|
||||
ray.origin = cameraPositionInObject * dvec4(0.001, 0.001, 0.001, 1.0);
|
||||
ray.direction = dvec4(normalize(objectCoords.xyz - cameraPositionInObject.xyz), 0.0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculates the light scattering in the view direction comming from other
|
||||
* light rays scattered in the atmosphere.
|
||||
* Following the paper: S[L]|x - T(x,xs) * S[L]|xs
|
||||
* The view direction here is the ray: x + tv, s is the sun direction,
|
||||
* r and mu the position and zenith cosine angle as in the paper.
|
||||
* Arguments:
|
||||
* 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. 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)
|
||||
* mu := out of cosine of the zenith view angle
|
||||
* attenuation := out of transmittance T(x,x0). This will be used later when
|
||||
* calculating the reflectance R[L].
|
||||
*/
|
||||
vec3 inscatterRadiance(inout vec3 x, inout float t, inout float irradianceFactor,
|
||||
const vec3 v, const vec3 s, out float r, out float mu,
|
||||
out vec3 attenuation, const vec3 fragPosObj,
|
||||
const double maxLength, const double pixelDepth,
|
||||
const vec4 spaceColor, const float sunIntensity) {
|
||||
vec3 radiance;
|
||||
|
||||
r = length(x);
|
||||
mu = dot(x, v) / r;
|
||||
|
||||
float mu2 = mu * mu;
|
||||
float r2 = r * r;
|
||||
float Rt2 = Rt * Rt;
|
||||
float Rg2 = Rg * Rg;
|
||||
float nu = dot(v, s);
|
||||
float muSun = dot(x, s) / r;
|
||||
float rayleighPhase = rayleighPhaseFunction(nu);
|
||||
float miePhase = miePhaseFunction(nu);
|
||||
|
||||
// S[L](x,s,v)
|
||||
// I.e. the next line has the scattering light for the "infinite" ray passing
|
||||
// through the atmosphere. If this ray hits something inside the atmosphere,
|
||||
// we will subtract the attenuated scattering light from that path in the
|
||||
// current path.
|
||||
vec4 inscatterRadiance = max(texture4D(inscatterTexture, r, mu, muSun, nu), 0.0);
|
||||
|
||||
// After removing the initial path from camera pos to top of atmosphere (for an
|
||||
// observer in the space) we test if the light ray is hitting the atmosphere
|
||||
vec3 x0 = fragPosObj;
|
||||
float r0 = length(fragPosObj);
|
||||
float invr0 = 1.0/r0;
|
||||
float muSun0 = dot(fragPosObj, s) * invr0;
|
||||
//vec3 x0 = x + float(pixelDepth) * v;
|
||||
float mu0 = dot(x0, v) * invr0;
|
||||
|
||||
bool groundHit = false;
|
||||
if ((pixelDepth > 0.0) && (pixelDepth < maxLength)) {
|
||||
t = float(pixelDepth);
|
||||
groundHit = true;
|
||||
|
||||
// Transmittance from point r, direction mu, distance t
|
||||
// By Analytical calculation
|
||||
//attenuation = analyticTransmittance(r, mu, t);
|
||||
// JCC: change from analytical to LUT transmittance to avoid
|
||||
// acme on planet surface when looking from far away. (11/02/2017)
|
||||
attenuation = transmittance(r, mu, t);
|
||||
|
||||
// Here we use the idea of S[L](a->b) = S[L](b->a), and get the S[L](x0, v, s)
|
||||
// Then we calculate S[L] = S[L]|x - T(x, x0)*S[L]|x0
|
||||
// The "infinite" ray hist something inside the atmosphere, so we need to remove
|
||||
// the unsused contribution to the final radiance.
|
||||
vec4 inscatterFromSurface = texture4D(inscatterTexture, r0, mu0, muSun0, nu);
|
||||
inscatterRadiance = max(inscatterRadiance - attenuation.rgbr * inscatterFromSurface, 0.0);
|
||||
|
||||
// We set the irradianceFactor to 1.0 so the reflected irradiance will be considered
|
||||
// when calculating the reflected light on the ground.
|
||||
irradianceFactor = 1.0;
|
||||
} else {
|
||||
attenuation = analyticTransmittance(r, mu, t);
|
||||
//attenuation = transmittance(r, mu, t);
|
||||
}
|
||||
|
||||
// cos(PI-thetaH) = dist/r
|
||||
// cos(thetaH) = - dist/r
|
||||
// muHorizon = -sqrt(r^2-Rg^2)/r = -sqrt(1-(Rg/r)^2)
|
||||
float muHorizon = -sqrt(1.0f - (Rg2 / r2));
|
||||
|
||||
// In order to avoid imprecision problems near horizon,
|
||||
// we interpolate between two points: above and below horizon
|
||||
const float INTERPOLATION_EPS = 0.004f; // precision const from Brunetton
|
||||
if (abs(mu - muHorizon) < INTERPOLATION_EPS) {
|
||||
// We want an interpolation value close to 1/2, so the
|
||||
// contribution of each radiance value is almost the same
|
||||
// or it has a havey weight if from above or below horizon
|
||||
float interpolationValue = ((mu - muHorizon) + INTERPOLATION_EPS) / (2.0f * INTERPOLATION_EPS);
|
||||
|
||||
float t2 = t * t;
|
||||
|
||||
// Above Horizon
|
||||
mu = muHorizon - INTERPOLATION_EPS;
|
||||
//r0 = sqrt(r * r + t * t + 2.0f * r * t * mu);
|
||||
// From cosine law where t = distance between x and x0
|
||||
// r0^2 = r^2 + t^2 - 2 * r * t * cos(PI-theta)
|
||||
r0 = sqrt(r2 + t2 + 2.0f * r * t * mu);
|
||||
// From the dot product: cos(theta0) = (x0 dot v)/(||ro||*||v||)
|
||||
// mu0 = ((x + t) dot v) / r0
|
||||
// mu0 = (x dot v + t dot v) / r0
|
||||
// mu0 = (r*mu + t) / r0
|
||||
mu0 = (r * mu + t) / r0;
|
||||
vec4 inScatterAboveX = texture4D(inscatterTexture, r, mu, muSun, nu);
|
||||
vec4 inScatterAboveXs = texture4D(inscatterTexture, r0, mu0, muSun0, nu);
|
||||
// Attention for the attenuation.r value applied to the S_Mie
|
||||
vec4 inScatterAbove = max(inScatterAboveX - attenuation.rgbr * inScatterAboveXs, 0.0f);
|
||||
|
||||
// Below Horizon
|
||||
mu = muHorizon + INTERPOLATION_EPS;
|
||||
r0 = sqrt(r2 + t2 + 2.0f * r * t * mu);
|
||||
mu0 = (r * mu + t) / r0;
|
||||
vec4 inScatterBelowX = texture4D(inscatterTexture, r, mu, muSun, nu);
|
||||
vec4 inScatterBelowXs = texture4D(inscatterTexture, r0, mu0, muSun0, nu);
|
||||
// Attention for the attenuation.r value applied to the S_Mie
|
||||
vec4 inScatterBelow = max(inScatterBelowX - attenuation.rgbr * inScatterBelowXs, 0.0);
|
||||
|
||||
// Interpolate between above and below inScattering radiance
|
||||
inscatterRadiance = mix(inScatterAbove, inScatterBelow, interpolationValue);
|
||||
}
|
||||
|
||||
// The w component of inscatterRadiance has stored the Cm,r value (Cm = Sm[L0])
|
||||
// So, we must reintroduce the Mie inscatter by the proximity rule as described in the
|
||||
// paper by Bruneton and Neyret in "Angular precision" paragraph:
|
||||
|
||||
// Hermite interpolation between two values
|
||||
// This step is done because imprecision problems happen when the Sun is slightly below
|
||||
// the horizon. When this happen, we avoid the Mie scattering contribution.
|
||||
inscatterRadiance.w *= smoothstep(0.0f, 0.02f, muSun);
|
||||
vec3 inscatterMie = inscatterRadiance.rgb * inscatterRadiance.a / max(inscatterRadiance.r, 1e-4) *
|
||||
(betaRayleigh.r / betaRayleigh);
|
||||
|
||||
radiance = max(inscatterRadiance.rgb * rayleighPhase + inscatterMie * miePhase, 0.0f);
|
||||
|
||||
// Finally we add the Lsun (all calculations are done with no Lsun so
|
||||
// we can change it on the fly with no precomputations)
|
||||
// return radiance * sunRadiance;
|
||||
vec3 finalScatteringRadiance = radiance * sunIntensity;
|
||||
if (groundHit) {
|
||||
return finalScatteringRadiance;
|
||||
} else {
|
||||
return ((r-Rg)/(Rt-Rg))*spaceColor.rgb * backgroundConstant + finalScatteringRadiance;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculates the light reflected in the view direction comming from other
|
||||
* light rays integrated over the hemispehre plus the direct light (L0) from Sun.
|
||||
* Following the paper: R[L]= R[L0]+R[L*]
|
||||
* The the ray is x + tv, v the view direction, s is the sun direction,
|
||||
* r and mu the position and zenith cosine angle as in the paper.
|
||||
* As for all calculations in the atmosphere, the center of the coordinate system
|
||||
* is the planet's center of coordiante system, i.e., the planet's position is (0,0,0).
|
||||
* Arguments:
|
||||
* x := camera position
|
||||
* t := ray displacement variable. Here, differently from the inScatter light calculation,
|
||||
* the position of the camera is already offset (on top of atmosphere) or inside
|
||||
* the atmosphere.
|
||||
* v := view direction (ray's direction) (normalized)
|
||||
* s := Sun direction (normalized)
|
||||
* r := ||x|| inside atmosphere (or top of atmosphere). r <= Rt here.
|
||||
* mu := cosine of the zenith view angle
|
||||
* attenuationXtoX0 := transmittance T(x,x0)
|
||||
*/
|
||||
vec3 groundColor(const vec3 x, const float t, const vec3 v, const vec3 s, const float r,
|
||||
const float mu, const vec3 attenuationXtoX0, const vec4 groundColor,
|
||||
const vec3 normal, const float irradianceFactor,
|
||||
const float waterReflectance, const float sunIntensity)
|
||||
{
|
||||
vec3 reflectedRadiance = vec3(0.0f);
|
||||
|
||||
// First we obtain the ray's end point on the surface
|
||||
vec3 x0 = x + t * v;
|
||||
float r0 = length(x0);
|
||||
// Normal of intersection point.
|
||||
vec3 n = normalize(normal);
|
||||
//vec4 groundReflectance = groundColor * vec4(.37);
|
||||
vec4 groundReflectance = groundColor *
|
||||
vec4(groundRadianceEmittion, groundRadianceEmittion, groundRadianceEmittion, 1.0f);
|
||||
|
||||
// L0 is not included in the irradiance texture.
|
||||
// We first calculate the light attenuation from the top of the atmosphere
|
||||
// to x0.
|
||||
float dotNS = dot(n, s);
|
||||
float muSun = max(dotNS, 0.0f);
|
||||
|
||||
// Is direct Sun light arriving at x0? If not, there is no direct light from Sun (shadowed)
|
||||
vec3 transmittanceL0 = muSun < -sqrt(1.0f - ((Rg * Rg) / (r0 * r0))) ?
|
||||
vec3(0.0f) : transmittanceLUT(r0, muSun);
|
||||
// E[L*] at x0
|
||||
vec3 irradianceReflected = irradiance(irradianceTexture, r0, muSun) * irradianceFactor;
|
||||
|
||||
// R[L0] + R[L*]
|
||||
// vec3 groundRadiance = (dotNS < -0.2f ? groundReflectance.rgb * 15 : groundReflectance.rgb) *
|
||||
// (muSun * transmittanceL0 + irradianceReflected) * sunIntensity / M_PI;
|
||||
|
||||
vec3 groundRadiance;
|
||||
vec3 RLStar = (muSun * transmittanceL0 + irradianceReflected) * sunIntensity / M_PI;
|
||||
if (dotNS < 0.05f) {
|
||||
groundRadiance = groundReflectance.rgb * mix(30.0f, 1.0f, smoothstep(-1.0f, 0.05f, dotNS)) * RLStar;
|
||||
} else {
|
||||
groundRadiance = groundReflectance.rgb * RLStar;
|
||||
}
|
||||
|
||||
//groundRadiance = groundReflectance.rgb * RLStar;
|
||||
|
||||
// Specular reflection from sun on oceans and rivers
|
||||
if ((waterReflectance > 0.1) && /*(dotNS > -0.2f)*/(muSun > 0.0)) {
|
||||
vec3 h = normalize(s - v);
|
||||
// Fresnell Schlick's approximation
|
||||
float fresnel = 0.02f + 0.98f * pow(1.0f - dot(-v, h), 5.0f);
|
||||
// Walter BRDF approximation
|
||||
float waterBrdf = fresnel * pow(max(dot(h, n), 0.0f), 150.0f);
|
||||
// Adding Fresnell and Water BRDFs approximation to the final surface color
|
||||
// (After adding the sunRadiance and the attenuation of the Sun through atmosphere)
|
||||
groundRadiance += waterReflectance * max(waterBrdf, 0.0) * transmittanceL0 * sunIntensity;
|
||||
}
|
||||
//return groundRadiance;
|
||||
// Finally, we attenuate the surface Radiance from the the point x0 to the camera location.
|
||||
reflectedRadiance = attenuationXtoX0 * groundRadiance;
|
||||
|
||||
// Returns reflectedRadiance = 0.0 if the ray doesn't hit the ground.
|
||||
return reflectedRadiance;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculates the Sun color.
|
||||
* The the ray is x + tv, v the view direction, s is the sun direction,
|
||||
* r and mu the position and zenith cosine angle as in the paper.
|
||||
* As for all calculations in the atmosphere, the center of the coordinate system
|
||||
* is the planet's center of coordiante system, i.e., the planet's position is (0,0,0).
|
||||
* Arguments:
|
||||
* x := camera position
|
||||
* t := ray displacement variable. Here, differently from the inScatter light calculation,
|
||||
* the position of the camera is already offset (on top of atmosphere) or inside
|
||||
* the atmosphere.
|
||||
* v := view direction (ray's direction) (normalized)
|
||||
* s := Sun direction (normalized)
|
||||
* r := ||x|| inside atmosphere (or top of atmosphere). r <= Rt here.
|
||||
* mu := cosine of the zenith view angle
|
||||
* attenuation := transmittance T(x,x0)
|
||||
*/
|
||||
vec3 sunColor(const vec3 x, const float t, const vec3 v, const vec3 s, const float r,
|
||||
const float mu, const float irradianceFactor) {
|
||||
vec3 transmittance = (r <= Rt) ? ( mu < -sqrt(1.0f - (Rg*Rg)/(r*r)) ?
|
||||
vec3(0.0f) : transmittanceLUT(r, mu)) : vec3(1.0f);
|
||||
// JCC: Change this function to a impostor texture with gaussian decay color weighted
|
||||
// by tge sunRadiance, transmittance and irradianceColor (11/03/2017)
|
||||
float sunFinalColor = step(cos(M_PI / 650.0), dot(v, s)) * sunRadiance * (1.0 - irradianceFactor);
|
||||
|
||||
return transmittance * sunFinalColor;
|
||||
}
|
||||
|
||||
void main() {
|
||||
if (cullAtmosphere == 0) {
|
||||
vec4 atmosphereFinalColor = vec4(0.0f);
|
||||
|
||||
// First we determine if the pixel is complex (different fragments on it)
|
||||
bool complex = false;
|
||||
vec4 oldColor, currentColor;
|
||||
//vec4 colorArray[16];
|
||||
//int colorIndexArray[16];
|
||||
|
||||
oldColor = texelFetch(mainColorTexture, ivec2(gl_FragCoord), 0);
|
||||
//colorArray[0] = oldColor;
|
||||
//colorIndexArray[0] = 0;
|
||||
for (int i = 1; i < nAaSamples; i++) {
|
||||
//vec4 normal = texelFetch(mainNormalTexture, ivec2(gl_FragCoord), i);
|
||||
vec4 currentColor = texelFetch(mainColorTexture, ivec2(gl_FragCoord), i);
|
||||
//colorArray[i] = currentColor;
|
||||
if (currentColor != oldColor) {
|
||||
complex = true;
|
||||
break;
|
||||
// for (int c = 0; c < nAaSamples; c++) {
|
||||
// if (currentColor == colorArray[c]) {
|
||||
// colorIndexArray[i] = c;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
//else {
|
||||
// for (int c = 0; c < nAaSamples; c++) {
|
||||
// if (currentColor == colorArray[c]) {
|
||||
// colorIndexArray[i] = c;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
oldColor = currentColor;
|
||||
}
|
||||
|
||||
int nSamples = 1;
|
||||
if (complex) {
|
||||
//nSamples = nAaSamples;
|
||||
nSamples = nAaSamples > 1 ? nAaSamples/2 : nAaSamples;
|
||||
}
|
||||
|
||||
for (int i = 0; i < nSamples; i++) {
|
||||
vec4 normal = texelFetch(mainNormalTexture, ivec2(gl_FragCoord), i);
|
||||
vec4 color = texelFetch(mainColorTexture, ivec2(gl_FragCoord), i);
|
||||
// Data in the mainPositionTexture are written in view space (view plus camera rig)
|
||||
vec4 position = texelFetch(mainPositionTexture, ivec2(gl_FragCoord), i);
|
||||
vec4 otherData = texelFetch(otherDataTexture, ivec2(gl_FragCoord), i);
|
||||
|
||||
// Ray in object space
|
||||
dRay ray;
|
||||
dvec4 planetPositionObjectCoords = dvec4(0.0);
|
||||
dvec4 cameraPositionInObject = dvec4(0.0);
|
||||
|
||||
// Get the ray from camera to atm in object space
|
||||
dCalculateRayRenderableGlobe(i * 3, ray, planetPositionObjectCoords,
|
||||
cameraPositionInObject);
|
||||
|
||||
bool insideATM = false;
|
||||
double offset = 0.0;
|
||||
double maxLength = 0.0;
|
||||
|
||||
bool intersectATM = false;
|
||||
|
||||
// Instead of ray-ellipsoid intersection lets transform the ray to a sphere:
|
||||
dRay transfRay;
|
||||
transfRay.origin = ray.origin;
|
||||
transfRay.direction = ray.direction;
|
||||
|
||||
// transfRay.origin.z *= 1000.0/ellipsoidRadii.x;
|
||||
// transfRay.direction.z *= 1000.0/ellipsoidRadii.x;
|
||||
// transfRay.origin.x *= 1000.0/ellipsoidRadii.y;
|
||||
// transfRay.direction.x *= 1000.0/ellipsoidRadii.y;
|
||||
// transfRay.origin.y *= 1000.0/ellipsoidRadii.z;
|
||||
// transfRay.direction.y *= 1000.0/ellipsoidRadii.z;
|
||||
// transfRay.direction.xyz = normalize(transfRay.direction.xyz);
|
||||
|
||||
intersectATM = dAtmosphereIntersection(planetPositionObjectCoords.xyz, transfRay,
|
||||
Rt - ATM_EPSILON/100.0, insideATM, offset, maxLength );
|
||||
|
||||
if ( intersectATM ) {
|
||||
// Now we check is if the atmosphere is occluded, i.e., if the distance to the pixel
|
||||
// in the depth buffer is less than the distance to the atmosphere then the atmosphere
|
||||
// is occluded
|
||||
// Fragments positions into G-Buffer are written in OS Eye Space (Camera Rig Coords)
|
||||
// when using their positions later, one must convert them to the planet's coords
|
||||
|
||||
// OS Eye to World coords
|
||||
dvec4 tmpRInvPos = dInverseCamRotTransform * dSgctEyeToOSEyeTranform * position;
|
||||
dvec4 fragWorldCoords = dvec4(dvec3(tmpRInvPos) + dCampos, 1.0);
|
||||
|
||||
// World to Object (Normal and Position in meters)
|
||||
dvec4 fragObjectCoords = dInverseModelTransformMatrix * fragWorldCoords;
|
||||
|
||||
// Distance of the pixel in the gBuffer to the observer
|
||||
// JCC (12/12/2017): AMD distance function is buggy.
|
||||
//double pixelDepth = distance(cameraPositionInObject.xyz, fragObjectCoords.xyz);
|
||||
double pixelDepth = length(cameraPositionInObject.xyz - fragObjectCoords.xyz);
|
||||
|
||||
// JCC (12/13/2017): TRick to remove floating error in texture.
|
||||
// We see a squared noise on planet's surface when seeing the planet
|
||||
// from far away.
|
||||
float dC = float(length(cameraPositionInObject.xyz));
|
||||
float x1 = 1e8;
|
||||
if (dC > x1) {
|
||||
pixelDepth += 1000.0;
|
||||
float alpha = 1000.0;
|
||||
float beta = 1000000.0;
|
||||
float x2 = 1e9;
|
||||
float diffGreek = beta - alpha;
|
||||
float diffDist = x2 - x1;
|
||||
float varA = diffGreek/diffDist;
|
||||
float varB = (alpha - varA * x1);
|
||||
pixelDepth += double(varA * dC + varB);
|
||||
}
|
||||
|
||||
// All calculations are done in Km:
|
||||
pixelDepth *= 0.001;
|
||||
fragObjectCoords.xyz *= 0.001;
|
||||
|
||||
if (position.xyz != vec3(0.0) && (pixelDepth < offset)) {
|
||||
atmosphereFinalColor += vec4(HDR(color.xyz * backgroundConstant, atmExposure), color.a);
|
||||
//discard;
|
||||
} else {
|
||||
// Following paper nomenclature
|
||||
double t = offset;
|
||||
vec3 attenuation;
|
||||
|
||||
// Moving observer from camera location to top atmosphere
|
||||
// If the observer is already inside the atm, offset = 0.0
|
||||
// and no changes at all.
|
||||
vec3 x = vec3(ray.origin.xyz + t*ray.direction.xyz);
|
||||
float r = 0.0;//length(x);
|
||||
vec3 v = vec3(ray.direction.xyz);
|
||||
float mu = 0.0;//dot(x, v) / r;
|
||||
vec3 s = vec3(sunDirectionObj);
|
||||
float tF = float(maxLength - t);
|
||||
|
||||
// Because we may move the camera origin to the top of atmosphere
|
||||
// we also need to adjust the pixelDepth for tdCalculateRayRenderableGlobehis offset so the
|
||||
// next comparison with the planet's ground make sense:
|
||||
pixelDepth -= offset;
|
||||
|
||||
dvec4 onATMPos = dModelTransformMatrix * dvec4(x*1000.0, 1.0);
|
||||
vec4 eclipseShadowATM = calcShadow(shadowDataArray, onATMPos.xyz, false);
|
||||
vec4 eclipseShadowPlanet = calcShadow(shadowDataArray, fragWorldCoords.xyz, true);
|
||||
|
||||
float sunIntensityInscatter = sunRadiance * eclipseShadowATM.x;
|
||||
float sunIntensityGround = sunRadiance * eclipseShadowPlanet.x;
|
||||
|
||||
float irradianceFactor = 0.0;
|
||||
|
||||
vec3 inscatterColor = inscatterRadiance(x, tF, irradianceFactor, v,
|
||||
s, r, mu, attenuation,
|
||||
vec3(fragObjectCoords.xyz),
|
||||
maxLength, pixelDepth,
|
||||
color, sunIntensityInscatter);
|
||||
vec3 groundColor = groundColor(x, tF, v, s, r, mu, attenuation,
|
||||
color, normal.xyz, irradianceFactor,
|
||||
otherData.r, sunIntensityGround);
|
||||
vec3 sunColor = sunColor(x, tF, v, s, r, mu, irradianceFactor);
|
||||
|
||||
// Final Color of ATM plus terrain:
|
||||
vec4 finalRadiance = vec4(HDR(inscatterColor + groundColor + sunColor, atmExposure), 1.0);
|
||||
|
||||
atmosphereFinalColor += finalRadiance;
|
||||
}
|
||||
}
|
||||
else { // no intersection
|
||||
//discard;
|
||||
atmosphereFinalColor += vec4(HDR(color.xyz * backgroundConstant, atmExposure), color.a);
|
||||
}
|
||||
}
|
||||
|
||||
renderTarget = atmosphereFinalColor / float(nSamples);
|
||||
}
|
||||
else { // culling
|
||||
if (firstPaint) {
|
||||
vec4 bColor = vec4(0.0f);
|
||||
for (int f = 0; f < nAaSamples; f++) {
|
||||
bColor += texelFetch(mainColorTexture, ivec2(gl_FragCoord), f);
|
||||
}
|
||||
bColor /= float(nAaSamples);
|
||||
renderTarget = vec4(HDR(bColor.xyz * backgroundConstant, atmExposure), bColor.a);
|
||||
}
|
||||
else {
|
||||
discard;
|
||||
}
|
||||
//renderTarget = vec4(1.0, 0.0, 0.0, 1.0);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
layout(location = 0) in vec4 in_position;
|
||||
|
||||
out vec3 interpolatedNDCPos;
|
||||
|
||||
void main()
|
||||
{
|
||||
interpolatedNDCPos = in_position.xyz;
|
||||
gl_Position = in_position;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
#version __CONTEXT__
|
||||
|
||||
#include "atmosphere_common.glsl"
|
||||
|
||||
out vec4 renderTableColor;
|
||||
|
||||
void main(void) {
|
||||
renderTableColor = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
layout(location = 0) in vec3 in_position;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(in_position, 1.0);
|
||||
}
|
||||
@@ -0,0 +1,209 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
#include "atmosphere_common.glsl"
|
||||
|
||||
out vec4 renderTarget1;
|
||||
|
||||
uniform float r;
|
||||
uniform vec4 dhdH;
|
||||
|
||||
uniform sampler2D deltaETexture;
|
||||
uniform sampler3D deltaSRTexture;
|
||||
uniform sampler3D deltaSMTexture;
|
||||
|
||||
uniform int firstIteraction;
|
||||
|
||||
// -- Spherical Coordinates Steps. phi e [0,2PI] and theta e [0, PI]
|
||||
const float stepPhi = (2.0f * M_PI) / float(INSCATTER_SPHERICAL_INTEGRAL_SAMPLES);
|
||||
const float stepTheta = M_PI / float(INSCATTER_SPHERICAL_INTEGRAL_SAMPLES);
|
||||
|
||||
void inscatter(float r, float mu, float muSun, float nu, inout vec3 radianceJ) {
|
||||
// Be sure to not get a cosine or height out of bounds
|
||||
r = clamp(r, Rg, Rt);
|
||||
mu = clamp(mu, -1.0f, 1.0f);
|
||||
muSun = clamp(muSun, -1.0f, 1.0f);
|
||||
|
||||
// s sigma | theta v
|
||||
// \ | /
|
||||
// \ | /
|
||||
// \ | /
|
||||
// \ | / theta + signam = ni
|
||||
// \ | / cos(theta) = mu
|
||||
// \ | / cos(sigma) = muSun
|
||||
// \|/ cos(ni) = nu
|
||||
float mu2 = mu * mu;
|
||||
float muSun2 = muSun * muSun;
|
||||
float sinThetaSinSigma = sqrt(1.0f - mu2) * sqrt(1.0f - muSun2);
|
||||
// cos(sigma + theta) = cos(theta)cos(sigma)-sin(theta)sin(sigma)
|
||||
// cos(ni) = nu = mu * muSun - sqrt(1.0f - mu*mu)*sqrt(1.0 - muSun*muSun) // sin(theta) = sqrt(1.0 - mu*mu)
|
||||
// Now we make sure the angle between vec(s) and vec(v) is in the right range:
|
||||
nu = clamp(nu, muSun * mu - sinThetaSinSigma, muSun * mu + sinThetaSinSigma);
|
||||
|
||||
// Lets calculate the consine of the angle to the horizon:
|
||||
// theta is the angle between vec(v) and x
|
||||
// cos(PI-theta) = d/r
|
||||
// -cos(theta) = sqrt(r*r-Rg*Rg)/r
|
||||
float Rg2 = Rg * Rg;
|
||||
float r2 = r * r;
|
||||
float cosHorizon = -sqrt(r2 - Rg2)/r;
|
||||
|
||||
// Now we get vec(v) and vec(s) from mu, muSun and nu:
|
||||
// Assuming:
|
||||
// z |theta
|
||||
// |\ vec(v) ||vec(v)|| = 1
|
||||
// | \
|
||||
// |__\_____x
|
||||
// sin(PI-theta) = x/||v|| => x = sin(theta) =? x = sqrt(1-mu*mu)
|
||||
// cos(PI-theta) = z/||v|| => z = cos(theta) = mu
|
||||
// v.y = 0 because ||v|| = 1
|
||||
vec3 v = vec3(sqrt(1.0 - mu2), 0.0, mu);
|
||||
|
||||
// To obtain vec(s), we use the following properties:
|
||||
// ||vec(s)|| = 1, ||vec(v)|| = 1
|
||||
// vec(s) dot vec(v) = cos(ni) = nu
|
||||
// Following the same idea for vec(v), we now that s.z = cos(sigma) = muSun
|
||||
// So, from vec(s) dot vec(v) = cos(ni) = nu we have,
|
||||
// s.x*v.x +s.y*v.y + s.z*v.z = nu
|
||||
// s.x = (nu - s.z*v.z)/v.x = (nu - mu*muSun)/v.x
|
||||
float sx = (v.x == 0.0) ? 0.0 : (nu - muSun * mu) / v.x;
|
||||
// Also, ||vec(s)|| = 1, so:
|
||||
// 1 = sqrt(s.x*s.x + s.y*s.y + s.z*s.z)
|
||||
// s.y = sqrt(1 - s.x*s.x - s.z*s.z) = sqrt(1 - s.x*s.x - muSun*muSun)
|
||||
vec3 s = vec3(sx, sqrt(max(0.0, 1.0 - sx * sx - muSun2)), muSun);
|
||||
|
||||
// In order to integrate over 4PI, we scan the sphere using the spherical coordinates
|
||||
// previously defined
|
||||
for ( int theta_i = 0; theta_i < INSCATTER_SPHERICAL_INTEGRAL_SAMPLES; ++theta_i ) {
|
||||
float theta = (float(theta_i) + 0.5f) * stepTheta;
|
||||
float cosineTheta = cos(theta);
|
||||
float cosineTheta2 = cosineTheta * cosineTheta;
|
||||
float distanceToGround = 0.0f;
|
||||
float groundReflectance = 0.0f;
|
||||
vec3 groundTransmittance = vec3(0.0f);
|
||||
|
||||
// If the ray w can see the ground we must compute the transmittance
|
||||
// effect from the starting point x to the ground point in direction -vec(v):
|
||||
if ( cosineTheta < cosHorizon ) { // ray hits ground
|
||||
// AverageGroundReflectance e [0,1]
|
||||
groundReflectance = AverageGroundReflectance / M_PI;
|
||||
// From cosine law: Rg*Rg = r*r + distanceToGround*distanceToGround - 2*r*distanceToGround*cos(PI-theta)
|
||||
distanceToGround = -r * cosineTheta - sqrt(r2 * (cosineTheta2 - 1.0f) + Rg2);
|
||||
// |
|
||||
// | theta
|
||||
// |
|
||||
// |\ distGround
|
||||
// r | \ alpha
|
||||
// | \/
|
||||
// | /
|
||||
// | / Rg
|
||||
// |/
|
||||
// So cos(alpha) = ((vec(x)+vec(dg)) dot -vec(distG))/(||(vec(x)+vec(distG))|| * ||vec(distG)||)
|
||||
// cos(alpha) = (-r*distG*cos(theta) - distG*distG)/(Rg*distG)
|
||||
// muGround = -(r*cos(theta) + distG)/Rg
|
||||
float muGround = -(r * cosineTheta + distanceToGround) / Rg;
|
||||
// We can use the same triangle in calculate the distanceToGround to calculate the cosine of the
|
||||
// angle between the ground touching point at height Rg and the zenith angle
|
||||
//float muGround = (r2 - distanceToGround*distanceToGround - Rg2)/(2*distanceToGround*Rg);
|
||||
// Acesss the Transmittance LUT in order to calculate the transmittance from the ground point Rg,
|
||||
// thorugh the atmosphere, at a distance: distanceToGround
|
||||
groundTransmittance = transmittance(Rg, muGround, distanceToGround);
|
||||
}
|
||||
//for ( int phi_i = 0; phi_i < 2*INSCATTER_SPHERICAL_INTEGRAL_SAMPLES; ++phi_i ) {
|
||||
for ( int phi_i = 0; phi_i < INSCATTER_SPHERICAL_INTEGRAL_SAMPLES; ++phi_i ) {
|
||||
float phi = (float(phi_i) + 0.5) * stepPhi;
|
||||
// spherical coordinates: dw = dtheta*dphi*sin(theta)*rho^2
|
||||
// rho = 1, we are integrating over a unit sphere
|
||||
float dw = stepTheta * stepPhi * sin(theta);
|
||||
// w = (rho*sin(theta)*cos(phi), rho*sin(theta)*sin(phi), rho*cos(theta))
|
||||
float sinPhi = sin(phi);
|
||||
float sinTheta = sin(theta);
|
||||
float cosPhi = cos(phi);
|
||||
vec3 w = vec3(sinTheta * cosPhi, sinTheta * sinPhi, cosineTheta);
|
||||
|
||||
// We calculate the Rayleigh and Mie phase function for the new scattering angle:
|
||||
// cos(angle between vec(v) and vec(w)), ||v|| = ||w|| = 1
|
||||
float nuWV = dot(v, w);
|
||||
float phaseRayleighWV = rayleighPhaseFunction(nuWV);
|
||||
float phaseMieWV = miePhaseFunction(nuWV);
|
||||
|
||||
vec3 groundNormal = (vec3(0.0, 0.0, r) + distanceToGround * w) / Rg;
|
||||
vec3 groundIrradiance = irradianceLUT(deltaETexture, dot(groundNormal, s), Rg);
|
||||
|
||||
// We finally calculate the radiance from the reflected ray from ground (0.0 if not reflected)
|
||||
vec3 radianceJ1 = groundTransmittance * groundReflectance * groundIrradiance;
|
||||
|
||||
// We calculate the Rayleigh and Mie phase function for the new scattering angle:
|
||||
// cos(angle between vec(s) and vec(w)), ||s|| = ||w|| = 1
|
||||
float nuSW = dot(s, w);
|
||||
// The first iteraction is different from the others, that's because in the first
|
||||
// iteraction all the light InScattered are coming from the initial pre-computed
|
||||
// single InScattered light. We stored these values in the deltaS textures (Ray and Mie),
|
||||
// and in order to avoid problems with the high angle dependency in the phase functions,
|
||||
// we don't include the phase functions on those tables (that's why we calculate them now).
|
||||
if ( firstIteraction == 1 ) {
|
||||
float phaseRaySW = rayleighPhaseFunction(nuSW);
|
||||
float phaseMieSW = miePhaseFunction(nuSW);
|
||||
// We can now access the values for the single InScattering in the textures deltaS textures.
|
||||
vec3 singleRay = texture4D(deltaSRTexture, r, w.z, muSun, nuSW).rgb;
|
||||
vec3 singleMie = texture4D(deltaSMTexture, r, w.z, muSun, nuSW).rgb;
|
||||
|
||||
// Initial InScattering including the phase functions
|
||||
radianceJ1 += singleRay * phaseRaySW + singleMie * phaseMieSW;
|
||||
} else {
|
||||
// On line 9 of the algorithm, the texture table deltaSR is updated, so when we are not in the first
|
||||
// iteraction, we are getting the updated result of deltaSR (not the single inscattered light but the
|
||||
// accumulated (higher order) inscattered light.
|
||||
// w.z is the cosine(theta) = mu for vec(w)
|
||||
radianceJ1 += texture4D(deltaSRTexture, r, w.z, muSun, nuSW).rgb;
|
||||
}
|
||||
|
||||
// Finally, we add the atmospheric scale height (See: Radiation Transfer on the Atmosphere and Ocean from
|
||||
// Thomas and Stamnes, pg 9-10.
|
||||
radianceJ += radianceJ1 * (betaRayleigh * exp(-(r - Rg) / HR) * phaseRayleighWV +
|
||||
betaMieScattering * exp(-(r - Rg) / HM) * phaseMieWV) * dw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
// cosine variables to access deltaS textures
|
||||
float mu, muSun, nu;
|
||||
// InScattering Radiance to be calculated at
|
||||
// different points in the ray path
|
||||
vec3 radianceJ = vec3(0.0f);
|
||||
|
||||
// Unmapping the variables from texture texels coordinates
|
||||
// to mapped coordinates
|
||||
unmappingMuMuSunNu(r, dhdH, mu, muSun, nu);
|
||||
|
||||
// Calculate the the light inScattered in direction
|
||||
// -vec(v) for the point at height r (vec(y) following Bruneton and Neyret's paper
|
||||
inscatter(r, mu, muSun, nu, radianceJ);
|
||||
|
||||
// Write to texture detaJ
|
||||
renderTarget1 = vec4(radianceJ, 1.0);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
uniform int layer;
|
||||
|
||||
layout (triangles) in;
|
||||
layout (triangle_strip, max_vertices = 3) out;
|
||||
|
||||
void main()
|
||||
{
|
||||
int n;
|
||||
for (n = 0; n < gl_in.length(); ++n) {
|
||||
gl_Position = gl_in[n].gl_Position;
|
||||
gl_Layer = layer;
|
||||
EmitVertex();
|
||||
}
|
||||
EndPrimitive();
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
layout(location = 0) in vec3 in_position;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(in_position, 1.0);
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
#include "atmosphere_common.glsl"
|
||||
|
||||
out vec4 renderTarget1;
|
||||
|
||||
uniform int layer;
|
||||
|
||||
uniform sampler3D deltaSRTexture;
|
||||
uniform sampler3D deltaSMTexture;
|
||||
|
||||
void main(void) {
|
||||
// First we convert the window's fragment coordinate to
|
||||
// texel coordinates
|
||||
vec3 rst = vec3(gl_FragCoord.xy, float(layer) + 0.5f) /
|
||||
vec3(ivec3(SAMPLES_MU_S * SAMPLES_NU, SAMPLES_MU, SAMPLES_R));
|
||||
|
||||
vec4 rayleighInscattering0 = texture(deltaSRTexture, rst);
|
||||
vec4 mieInscattering0 = texture(deltaSMTexture, rst);
|
||||
|
||||
// We are using only the red component of the Mie scattering
|
||||
// See the Precomputed Atmosphere Scattering paper for details about
|
||||
// the angular precision.
|
||||
renderTarget1 = vec4(rayleighInscattering0.rgb, mieInscattering0.r);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
uniform int layer;
|
||||
|
||||
layout (triangles) in;
|
||||
layout (triangle_strip, max_vertices = 3) out;
|
||||
|
||||
void main()
|
||||
{
|
||||
int n;
|
||||
for (n = 0; n < gl_in.length(); ++n) {
|
||||
gl_Position = gl_in[n].gl_Position;
|
||||
gl_Layer = layer;
|
||||
EmitVertex();
|
||||
}
|
||||
EndPrimitive();
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
layout(location = 0) in vec3 in_position;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(in_position, 1.0);
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
#include "atmosphere_common.glsl"
|
||||
|
||||
out vec4 renderTarget1;
|
||||
|
||||
uniform int layer;
|
||||
|
||||
uniform sampler3D deltaSTexture;
|
||||
|
||||
void main(void) {
|
||||
float x = gl_FragCoord.x - 0.5f;
|
||||
float y = gl_FragCoord.y - 0.5f;
|
||||
|
||||
float nu = -1.0f + floor(x / float(SAMPLES_MU_S)) / (float(SAMPLES_NU) - 1.0f) * 2.0f;
|
||||
vec3 uvw = vec3(gl_FragCoord.xy, float(layer) + 0.5f) / vec3(ivec3(SAMPLES_MU_S * SAMPLES_NU, SAMPLES_MU, SAMPLES_R));
|
||||
|
||||
// See Bruneton and Neyret paper, "Angular Precision" paragraph to understanding why we are
|
||||
// dividing the S[L*] by the Rayleigh phase function.
|
||||
renderTarget1 = vec4(texture(deltaSTexture, uvw).rgb / rayleighPhaseFunction(nu), 0.0f);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
uniform int layer;
|
||||
|
||||
layout (triangles) in;
|
||||
layout (triangle_strip, max_vertices = 3) out;
|
||||
|
||||
void main()
|
||||
{
|
||||
int n;
|
||||
for (n = 0; n < gl_in.length(); ++n) {
|
||||
gl_Position = gl_in[n].gl_Position;
|
||||
gl_Layer = layer;
|
||||
EmitVertex();
|
||||
}
|
||||
EndPrimitive();
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
layout(location = 0) in vec3 in_position;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(in_position, 1.0);
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
#version __CONTEXT__
|
||||
|
||||
#include "atmosphere_common.glsl"
|
||||
|
||||
layout(location = 0) out vec4 renderTarget1;
|
||||
layout(location = 1) out vec4 renderTarget2;
|
||||
|
||||
uniform float r;
|
||||
uniform vec4 dhdH;
|
||||
|
||||
//uniform sampler2D transmittanceTexture;
|
||||
|
||||
void integrand(const float r, const float mu, const float muSun, const float nu,
|
||||
const float y, out vec3 S_R, out vec3 S_M) {
|
||||
// The integral's integrand is the single inscattering radiance:
|
||||
// S[L0] = P_M*S_M[L0] + P_R*S_R[L0]
|
||||
// where S_M[L0] = T*(betaMScattering * exp(-h/H_M))*L0 and
|
||||
// S_R[L0] = T*(betaRScattering * exp(-h/H_R))*L0.
|
||||
// T = transmittance.
|
||||
// One must remember that because the occlusion on L0, the integrand
|
||||
// here will be equal to 0 in that cases.
|
||||
// Also it is important to remember that the phase function for the
|
||||
// Rayleigh and Mie scattering are added during the rendering time
|
||||
// to increase the angular precision
|
||||
S_R = vec3(0.0);
|
||||
S_M = vec3(0.0);
|
||||
|
||||
// cosine law
|
||||
float ri = max(sqrt(r * r + y * y + 2.0 * r * mu * y), Rg);
|
||||
|
||||
// Considering the Sun as a parallel light source,
|
||||
// thew vector s_i = s.
|
||||
// So muSun_i = (vec(y_i) dot vec(s))/r_i = ((vec(x) + vec(yi-x)) dot vec(s))/r_i
|
||||
// muSun_i = (vec(x) dot vec(s) + vec(yi-x) dot vec(s))/r_i = (r*muSun + yi*nu)/r_i
|
||||
float muSun_i = (nu * y + muSun * r) / ri;
|
||||
|
||||
// If the muSun_i is smaller than the angle to horizon (no sun radiance
|
||||
// hitting the point y), we return S_R = S_M = 0.0f.
|
||||
if (muSun_i >= -sqrt(1.0 - Rg * Rg / (ri * ri))) {
|
||||
// It's the transmittance from the point y (ri) to the top of atmosphere
|
||||
// in direction of the sun (muSun_i) and the transmittance from the observer
|
||||
// at x (r) to y (ri).
|
||||
vec3 transmittanceY = transmittance(r, mu, y) * transmittanceLUT(ri, muSun_i);
|
||||
// exp(-h/H)*T(x,v)
|
||||
if (ozoneLayerEnabled) {
|
||||
S_R = (exp(-(ri - Rg) / HO) + exp( -(ri - Rg) / HR )) * transmittanceY;
|
||||
S_M = exp( -(ri - Rg) / HM ) * transmittanceY;
|
||||
} else {
|
||||
S_R = exp( -(ri - Rg) / HR ) * transmittanceY;
|
||||
S_M = exp( -(ri - Rg) / HM ) * transmittanceY;
|
||||
}
|
||||
// The L0 (sun radiance) is added in real-time.
|
||||
}
|
||||
}
|
||||
|
||||
void inscatter(const float r, const float mu, const float muSun, const float nu,
|
||||
out vec3 S_R, out vec3 S_M) {
|
||||
// Let's calculate S_M and S_R by integration along the eye ray path inside
|
||||
// the atmosphere, given a position r, a view angle (cosine) mu, a sun
|
||||
// position angle (cosine) muSun, and the angle (cosine) between the sun position
|
||||
// and the view direction, nu.
|
||||
// Integrating using the Trapezoidal rule:
|
||||
// Integral(f(y)dy)(from a to b) = (b-a)/2n_steps*(Sum(f(y_i+1)+f(y_i)))
|
||||
S_R = vec3(0.0f);
|
||||
S_M = vec3(0.0f);
|
||||
float rayDist = rayDistance(r, mu);
|
||||
float dy = rayDist / float(INSCATTER_INTEGRAL_SAMPLES);
|
||||
float yi = 0.0f;
|
||||
vec3 S_Ri;
|
||||
vec3 S_Mi;
|
||||
integrand(r, mu, muSun, nu, 0.0, S_Ri, S_Mi);
|
||||
for (int i = 1; i <= INSCATTER_INTEGRAL_SAMPLES; ++i) {
|
||||
float yj = float(i) * dy;
|
||||
vec3 S_Rj;
|
||||
vec3 S_Mj;
|
||||
integrand(r, mu, muSun, nu, yj, S_Rj, S_Mj);
|
||||
S_R += (S_Ri + S_Rj);
|
||||
S_M += (S_Mi + S_Mj);
|
||||
yi = yj;
|
||||
S_Ri = S_Rj;
|
||||
S_Mi = S_Mj;
|
||||
}
|
||||
S_R *= betaRayleigh * (rayDist / (2.0f * float(INSCATTER_INTEGRAL_SAMPLES)));
|
||||
S_M *= betaMieScattering * (rayDist / (2.0f * float(INSCATTER_INTEGRAL_SAMPLES)));
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
vec3 S_R; // First Order Rayleigh InScattering
|
||||
vec3 S_M; // First Order Mie InScattering
|
||||
float mu, muSun, nu; // parametrization angles
|
||||
|
||||
// From the layer interpolation (see C++ code for layer to r)
|
||||
// and the textures parameters (uv), we unmapping mu, muSun and nu.
|
||||
unmappingMuMuSunNu(r, dhdH, mu, muSun, nu);
|
||||
|
||||
// Here we calculate the single inScattered light.
|
||||
// Because this is a single inscattering, the light
|
||||
// that arrives at a point y in the path from the
|
||||
// eye to the infinity (top of atmosphere or planet's
|
||||
// ground), comes only from the light source, i.e., the
|
||||
// sun. So, the there is no need to integrate over the
|
||||
// whole solid angle (4pi), we need only to consider
|
||||
// the Sun position (cosine of sun pos = muSun).
|
||||
// Then, following the paper notation:
|
||||
// S[L] = P_R*S_R[L0] + P_M*S_M[L0] + S[L*]
|
||||
// For single inscattering only:
|
||||
// S[L0] = P_R*S_R[L0] + P_M*S_M[L0]
|
||||
// In order to save memory, we just store the red component
|
||||
// of S_M[L0], and later we use the proportionality rule
|
||||
// to calcule the other components.
|
||||
inscatter(r, mu, muSun, nu, S_R, S_M);
|
||||
renderTarget1 = vec4(S_R, 1.0);
|
||||
renderTarget2 = vec4(S_M, 1.0);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
uniform int layer;
|
||||
|
||||
layout (triangles) in;
|
||||
layout (triangle_strip, max_vertices=3) out;
|
||||
|
||||
void main()
|
||||
{
|
||||
int n;
|
||||
for (n = 0; n < gl_in.length(); ++n) {
|
||||
gl_Position = gl_in[n].gl_Position;
|
||||
gl_Layer = layer;
|
||||
EmitVertex();
|
||||
}
|
||||
EndPrimitive();
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
layout(location = 0) in vec3 in_position;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(in_position, 1.0);
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
#include "atmosphere_common.glsl"
|
||||
|
||||
out vec4 renderTarget1;
|
||||
|
||||
uniform float r;
|
||||
uniform vec4 dhdH;
|
||||
|
||||
//uniform sampler2D transmittanceTexture;
|
||||
uniform sampler3D deltaJTexture;
|
||||
|
||||
// The integrand here is the f(y) of the trapezoidal rule:
|
||||
vec3 integrand(const float r, const float mu, const float muSun, const float nu, const float dist) {
|
||||
// We can calculate r_i by the cosine law: r_i^2=dist^2 + r^2 - 2*r*dist*cos(PI-theta)
|
||||
float r_i = sqrt(r * r + dist * dist + 2.0f * r * dist * mu);
|
||||
// r_i can be found using the dot product:
|
||||
// vec(y_i) dot vec(dist) = cos(theta_i) * ||vec(y_i)|| * ||vec(dist)||
|
||||
// But vec(y_i) = vec(x) + vec(dist), also: vec(x) dot vec(dist) = cos(theta) = mu
|
||||
// So, cos(theta_i) = mu_i = (r*dist**mu + dist*2)/(r_i*dist)
|
||||
float mu_i = (r * mu + dist) / r_i;
|
||||
// muSun_i can also be found by the dot product:
|
||||
// cos(sigma_i) = muSun_i = (vec(s) dot vec(y_i))/(||vec(y_i)|| * ||vec(s)||)
|
||||
// But vec(y_i) = vec(x) + vec(dist), and vec(x) dot vec(s) = muSun, cos(sigma_i + theta_i) = nu
|
||||
float muSun_i = (r * muSun + dist * nu) / r_i;
|
||||
// The irradiance attenuated from point r until y (y-x = dist)
|
||||
return transmittance(r, mu, dist) * texture4D(deltaJTexture, r_i, mu_i, muSun_i, nu).rgb;
|
||||
}
|
||||
|
||||
vec3 inscatter(float r, float mu, float muSun, float nu) {
|
||||
vec3 inScatteringRadiance = vec3(0.0f);
|
||||
float dy = rayDistance(r, mu) / float(INSCATTER_INTEGRAL_SAMPLES);
|
||||
vec3 inScatteringRadiance_i = integrand(r, mu, muSun, nu, 0.0);
|
||||
|
||||
// In order to solve the integral from equation (11) we use the trapezoidal
|
||||
// rule: Integral(f(y)dy)(from a to b) = ((b-a)/2n_steps)*(Sum(f(y_i+1)+f(y_i)))
|
||||
// where y_i+1 = y_j
|
||||
for (int i = 1; i <= INSCATTER_INTEGRAL_SAMPLES; ++i) {
|
||||
float y_j = float(i) * dy;
|
||||
vec3 inScatteringRadiance_j = integrand(r, mu, muSun, nu, y_j);
|
||||
inScatteringRadiance += (inScatteringRadiance_i + inScatteringRadiance_j) / 2.0 * dy;
|
||||
inScatteringRadiance_i = inScatteringRadiance_j;
|
||||
}
|
||||
return inScatteringRadiance;
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
float mu = 0.0f, muSunun = 0.0f, nu = 0.0f;
|
||||
// Unmapping the variables from texture texels coordinates
|
||||
// to mapped coordinates
|
||||
unmappingMuMuSunNu(r, dhdH, mu, muSunun, nu);
|
||||
|
||||
// Write to texture deltaSR
|
||||
renderTarget1 = vec4(inscatter(r, mu, muSunun, nu), 1.0);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
uniform int layer;
|
||||
|
||||
layout (triangles) in;
|
||||
layout (triangle_strip, max_vertices = 3) out;
|
||||
|
||||
void main()
|
||||
{
|
||||
int n;
|
||||
for (n = 0; n < gl_in.length(); ++n) {
|
||||
gl_Position = gl_in[n].gl_Position;
|
||||
gl_Layer = layer;
|
||||
EmitVertex();
|
||||
}
|
||||
EndPrimitive();
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
layout(location = 0) in vec3 in_position;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(in_position, 1.0);
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
#version __CONTEXT__
|
||||
|
||||
#include "atmosphere_common.glsl"
|
||||
|
||||
out vec4 renderTableColor;
|
||||
|
||||
//uniform sampler2D transmittanceTexture;
|
||||
|
||||
void main(void) {
|
||||
float muSun, r;
|
||||
unmappingRAndMuSun(r, muSun);
|
||||
// We are calculating the Irradiance for L0, i.e.,
|
||||
// only the radiance comming from sun direction is accounted:
|
||||
// E[L0](x,s) = L0*dot(w,n) or 0 (if v!=s or the sun is occluded).
|
||||
// Because we consider the Planet as a perfect sphere and we are
|
||||
// considering only single scattering here, the
|
||||
// dot product dot(w,n) is equal to dot(s,n) that is equal to
|
||||
// dot(s, r/||r||) = muSun.
|
||||
renderTableColor = vec4(transmittanceLUT(r, muSun) * max(muSun, 0.0), 0.0);
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
layout(location = 0) in vec3 in_position;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(in_position, 1.0);
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
#version __CONTEXT__
|
||||
|
||||
#include "atmosphere_common.glsl"
|
||||
|
||||
out vec4 renderTableColor;
|
||||
|
||||
uniform sampler2D deltaETexture;
|
||||
|
||||
void main(void) {
|
||||
vec2 uv = gl_FragCoord.xy / vec2(OTHER_TEXTURES_W, OTHER_TEXTURES_H);
|
||||
|
||||
// Update texture E with E plus deltaE textures.
|
||||
renderTableColor = texture(deltaETexture, uv);
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
layout(location = 0) in vec3 in_position;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(in_position, 1.0);
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
#include "atmosphere_common.glsl"
|
||||
|
||||
out vec4 renderTableColor;
|
||||
|
||||
uniform int firstIteraction;
|
||||
//uniform float firstIteraction;
|
||||
|
||||
// -- Spherical Coordinates Steps. phi e [0,2PI] and theta e [0, PI/2]
|
||||
const float stepPhi = (2.0f * M_PI) / float(IRRADIANCE_INTEGRAL_SAMPLES);
|
||||
const float stepTheta = M_PI / (2.0f * float(IRRADIANCE_INTEGRAL_SAMPLES));
|
||||
|
||||
//uniform sampler2D transmittanceTexture;
|
||||
uniform sampler3D deltaSRTexture;
|
||||
uniform sampler3D deltaSMTexture;
|
||||
|
||||
void main(void) {
|
||||
|
||||
float r = 0.0f;
|
||||
float muSun = 0.0f;
|
||||
// Unmapping the variables from texture texels coordinates
|
||||
// to mapped coordinates
|
||||
unmappingRAndMuSunIrradiance(r, muSun);
|
||||
|
||||
// We know that muSun = cos(sigma) = s.z/||s||
|
||||
// But, ||s|| = 1, so s.z = muSun. Also,
|
||||
// ||s|| = 1, so s.x = sin(sigma) = sqrt(1-muSun^2) and s.y = 0.0f
|
||||
vec3 s = vec3(max(sqrt(1.0f - muSun * muSun), 0.0f), 0.0f, muSun);
|
||||
|
||||
// In order to solve the integral from equation (15) we use the trapezoidal
|
||||
// rule: Integral(f(y)dy)(from a to b) = ((b-a)/2n_steps)*(Sum(f(y_i+1)+f(y_i)))
|
||||
vec3 irradianceE = vec3(0.0f);
|
||||
for (int iphi = 0; iphi < IRRADIANCE_INTEGRAL_SAMPLES; ++iphi) {
|
||||
float phi = (float(iphi) + 0.5f) * stepPhi;
|
||||
for (int itheta = 0; itheta < IRRADIANCE_INTEGRAL_SAMPLES; ++itheta) {
|
||||
float theta = (float(itheta) + 0.5f) * stepTheta;
|
||||
// spherical coordinates: dw = dtheta*dphi*sin(theta)*rho^2
|
||||
// rho = 1, we are integrating over a unit sphere
|
||||
float dw = stepTheta * stepPhi * sin(theta);
|
||||
// w = (cos(phi) * sin(theta) * rho, sin(phi) * sin(theta) * rho, cos(theta) * rho)
|
||||
vec3 w = vec3(cos(phi) * sin(theta), sin(phi) * sin(theta), cos(theta));
|
||||
float nu = dot(s, w);
|
||||
|
||||
// The first iteraction is different from the others, that's because in the first
|
||||
// iteraction all the light arriving are coming from the initial pre-computed
|
||||
// single scattered light. We stored these values in the deltaS textures (Ray and Mie),
|
||||
// and in order to avoid problems with the high angle dependency in the phase functions,
|
||||
// we don't include the phase functions on those tables (that's why we calculate them now).
|
||||
if (firstIteraction == 1) {
|
||||
float phaseRay = rayleighPhaseFunction(nu);
|
||||
float phaseMie = miePhaseFunction(nu);
|
||||
vec3 singleRay = texture4D(deltaSRTexture, r, w.z, muSun, nu).rgb;
|
||||
vec3 singleMie = texture4D(deltaSMTexture, r, w.z, muSun, nu).rgb;
|
||||
// w.z is the cosine(theta) = mu for vec(w) and also vec(w) dot vec(n(xo))
|
||||
irradianceE += (singleRay * phaseRay + singleMie * phaseMie) * w.z * dw;
|
||||
} else {
|
||||
// On line 10 of the algorithm, the texture table deltaE is updated, so when we are not in the first
|
||||
// iteraction, we are getting the updated result of deltaE (not the single irradiance light but the
|
||||
// accumulated (higher order) irradiance light.
|
||||
// w.z is the cosine(theta) = mu for vec(w) and also vec(w) dot vec(n(xo))
|
||||
irradianceE += texture4D(deltaSRTexture, r, w.z, muSun, nu).rgb * w.z * dw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Write the higher oder irradiance to texture deltaE
|
||||
renderTableColor = vec4(irradianceE, 0.0);
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
layout(location = 0) in vec3 in_position;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(in_position, 1.0);
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
#version __CONTEXT__
|
||||
|
||||
#include "atmosphere_common.glsl"
|
||||
|
||||
//layout(location = 1) out vec4 renderTableColor;
|
||||
out vec4 renderTableColor;
|
||||
|
||||
//-- Optical depth by integration, from ray starting at point vec(x), i.e,
|
||||
// height r and angle mu (cosine of vec(v)) until top of atmosphere
|
||||
// or planet's ground. --
|
||||
// r := height of starting point vect(x)
|
||||
// mu := cosine of the zeith angle of vec(v). Or mu = (vec(x) * vec(v))/r
|
||||
// H := Thickness of atmosphere if its density were uniform (can be used
|
||||
// for Rayleigh and Mie.
|
||||
float opticalDepth(const float r, const float mu, const float H) {
|
||||
float r2 = r*r;
|
||||
// Is ray below horizon? The transmittance table will have only
|
||||
// the values for transmittance starting at r (x) until the
|
||||
// light ray touches the atmosphere or the ground and only for
|
||||
// view angles v between 0 and pi/2 + eps. That's because we
|
||||
// can calculate the transmittance for angles bigger than pi/2
|
||||
// just inverting the ray direction and starting and ending points.
|
||||
|
||||
// cosine law for triangles: y_i^2 = a^2 + b^2 - 2abcos(alpha)
|
||||
float cosZenithHorizon = -sqrt( 1.0f - ( ( Rg * Rg ) / r2 ) );
|
||||
if (mu < cosZenithHorizon)
|
||||
return 1e9;
|
||||
|
||||
// Integrating using the Trapezoidal rule:
|
||||
// Integral(f(y)dy)(from a to b) = ((b-a)/2n_steps)*(Sum(f(y_i+1)+f(y_i)))
|
||||
float b_a = rayDistance(r, mu);
|
||||
float deltaStep = b_a / float(TRANSMITTANCE_STEPS);
|
||||
// cosine law
|
||||
float y_i = exp(-(r - Rg) / H);
|
||||
|
||||
float x_step = 0.0f;
|
||||
float accumulation = 0.0f;
|
||||
for (int i = 1; i <= TRANSMITTANCE_STEPS; ++i) {
|
||||
float x_i = float(i) * deltaStep;
|
||||
// cosine law for triangles: y_i^2 = a^2 + b^2 - 2abcos(alpha)
|
||||
// In this case, a = r, b = x_i and cos(alpha) = cos(PI-zenithView) = mu
|
||||
float y_ii = exp(-(sqrt(r2 + x_i * x_i + 2.0 * x_i * r * mu) - Rg) / H);
|
||||
accumulation += (y_ii + y_i);
|
||||
//x_step = x_i;
|
||||
y_i = y_ii;
|
||||
}
|
||||
return accumulation * ( b_a / ( 2 * TRANSMITTANCE_STEPS ) );
|
||||
}
|
||||
|
||||
|
||||
void main(void) {
|
||||
float r, muSun;
|
||||
|
||||
unmappingRAndMu(r, muSun);
|
||||
|
||||
vec3 opDepth = vec3(0.0);
|
||||
|
||||
if (ozoneLayerEnabled) {
|
||||
opDepth = betaOzoneExtinction * (0.0000006) * opticalDepth(r, muSun, HO) +
|
||||
betaMieExtinction * opticalDepth(r, muSun, HM) +
|
||||
betaRayleigh * opticalDepth(r, muSun, HR);
|
||||
} else {
|
||||
opDepth = betaMieExtinction * opticalDepth(r, muSun, HM) +
|
||||
betaRayleigh * opticalDepth(r, muSun, HR);
|
||||
}
|
||||
|
||||
renderTableColor = vec4( exp( -opDepth ), 0.0f );
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
layout(location = 0) in vec4 in_position;
|
||||
|
||||
void main() {
|
||||
gl_Position = in_position;
|
||||
}
|
||||
@@ -243,6 +243,9 @@ void RenderablePlane::render(const RenderData& data, RendererTasks&) {
|
||||
_shader->setUniform("modelViewProjectionTransform",
|
||||
data.camera.projectionMatrix() * glm::mat4(modelViewTransform));
|
||||
|
||||
_shader->setUniform("modelViewTransform",
|
||||
glm::mat4(data.camera.combinedViewMatrix() * glm::dmat4(modelViewTransform)));
|
||||
|
||||
ghoul::opengl::TextureUnit unit;
|
||||
unit.activate();
|
||||
_texture->bind();
|
||||
|
||||
@@ -84,6 +84,19 @@ namespace {
|
||||
"This value determines percentage of the sphere is visible before starting "
|
||||
"fading-out it."
|
||||
};
|
||||
|
||||
static const openspace::properties::Property::PropertyInfo FadeInThreshouldInfo = {
|
||||
"FadeInThreshould",
|
||||
"Fade-In Threshould",
|
||||
"Distance from center of MilkyWay from where the astronomical object starts to "
|
||||
"fade in."
|
||||
};
|
||||
|
||||
static const openspace::properties::Property::PropertyInfo DisableFadeInOuInfo = {
|
||||
"DisableFadeInOu",
|
||||
"Disable Fade-In/Fade-Out effects",
|
||||
"Enables/Disables the Fade-In/Out effects."
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
@@ -129,7 +142,19 @@ documentation::Documentation RenderableSphere::Documentation() {
|
||||
new DoubleInRangeVerifier(0.0, 1.0),
|
||||
Optional::Yes,
|
||||
FadeOutThreshouldInfo.description
|
||||
}
|
||||
},
|
||||
{
|
||||
FadeInThreshouldInfo.identifier,
|
||||
new DoubleVerifier,
|
||||
Optional::Yes,
|
||||
FadeInThreshouldInfo.description
|
||||
},
|
||||
{
|
||||
DisableFadeInOuInfo.identifier,
|
||||
new BoolVerifier,
|
||||
Optional::Yes,
|
||||
DisableFadeInOuInfo.description
|
||||
},
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -142,7 +167,9 @@ RenderableSphere::RenderableSphere(const ghoul::Dictionary& dictionary)
|
||||
, _size(SizeInfo, 1.f, 0.f, 1e35f)
|
||||
, _segments(SegmentsInfo, 8, 4, 1000)
|
||||
, _transparency(TransparencyInfo, 1.f, 0.f, 1.f)
|
||||
, _disableFadeInDistance(DisableFadeInOuInfo, true)
|
||||
, _fadeOutThreshold(-1.0)
|
||||
, _fadeInThreshold(0.0)
|
||||
, _shader(nullptr)
|
||||
, _texture(nullptr)
|
||||
, _sphere(nullptr)
|
||||
@@ -211,7 +238,19 @@ RenderableSphere::RenderableSphere(const ghoul::Dictionary& dictionary)
|
||||
if (dictionary.hasKey(FadeOutThreshouldInfo.identifier)) {
|
||||
_fadeOutThreshold = static_cast<float>(
|
||||
dictionary.value<double>(FadeOutThreshouldInfo.identifier)
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
if (dictionary.hasKey(FadeInThreshouldInfo.identifier)) {
|
||||
_fadeInThreshold = static_cast<float>(
|
||||
dictionary.value<double>(FadeInThreshouldInfo.identifier)
|
||||
);
|
||||
}
|
||||
|
||||
if (dictionary.hasKey(FadeOutThreshouldInfo.identifier) ||
|
||||
dictionary.hasKey(FadeInThreshouldInfo.identifier)) {
|
||||
_disableFadeInDistance.set(false);
|
||||
addProperty(_disableFadeInDistance);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -260,23 +299,35 @@ void RenderableSphere::render(const RenderData& data, RendererTasks&) {
|
||||
|
||||
setPscUniforms(*_shader.get(), data.camera, data.position);
|
||||
|
||||
float adjustedTransparency = _transparency;
|
||||
|
||||
if (_fadeInThreshold > 0.0) {
|
||||
float distCamera = glm::length(data.camera.positionVec3());
|
||||
float funcValue = static_cast<float>(
|
||||
(1.0 / double(_fadeInThreshold/1E24))*(distCamera / 1E24)
|
||||
);
|
||||
|
||||
adjustedTransparency *= funcValue > 1.0 ? 1.0 : funcValue;
|
||||
}
|
||||
|
||||
if (_fadeOutThreshold > -1.0) {
|
||||
double distCamera = glm::distance(
|
||||
float distCamera = glm::distance(
|
||||
data.camera.positionVec3(),
|
||||
data.position.dvec3()
|
||||
);
|
||||
double term = std::exp(
|
||||
(-distCamera + _size * _fadeOutThreshold) / (_size * _fadeOutThreshold)
|
||||
);
|
||||
|
||||
adjustedTransparency *= static_cast<float>(term / (term + 1.0));
|
||||
}
|
||||
|
||||
// Performance wise
|
||||
if (adjustedTransparency < 0.01) {
|
||||
return;
|
||||
}
|
||||
|
||||
_shader->setUniform(
|
||||
"alpha",
|
||||
_transparency * static_cast<float>(term / (term + 1.0))
|
||||
);
|
||||
}
|
||||
else {
|
||||
_shader->setUniform("alpha", _transparency);
|
||||
}
|
||||
_shader->setUniform("alpha", adjustedTransparency);
|
||||
|
||||
ghoul::opengl::TextureUnit unit;
|
||||
unit.activate();
|
||||
|
||||
@@ -70,7 +70,10 @@ private:
|
||||
|
||||
properties::FloatProperty _transparency;
|
||||
|
||||
properties::BoolProperty _disableFadeInDistance;
|
||||
|
||||
float _fadeOutThreshold;
|
||||
float _fadeInThreshold;
|
||||
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _shader;
|
||||
std::unique_ptr<ghoul::opengl::Texture> _texture;
|
||||
|
||||
@@ -250,7 +250,7 @@ void RenderableTrail::render(const RenderData& data, RendererTasks&) {
|
||||
glm::scale(glm::dmat4(1.0), glm::dvec3(data.modelTransform.scale));
|
||||
|
||||
_programObject->setUniform("projectionTransform", data.camera.projectionMatrix());
|
||||
|
||||
|
||||
_programObject->setUniform("color", _lineColor);
|
||||
_programObject->setUniform("useLineFade", _useLineFade);
|
||||
if (_useLineFade) {
|
||||
@@ -270,7 +270,7 @@ void RenderableTrail::render(const RenderData& data, RendererTasks&) {
|
||||
|
||||
if (usingFramebufferRenderer) {
|
||||
glDepthMask(false);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
//glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
}
|
||||
|
||||
bool renderLines =
|
||||
|
||||
@@ -26,12 +26,16 @@
|
||||
#include "PowerScaling/powerScaling_fs.hglsl"
|
||||
|
||||
in float vs_screenSpaceDepth;
|
||||
in vec4 vs_positionViewSpace;
|
||||
|
||||
uniform vec4 gridColor;
|
||||
|
||||
Fragment getFragment() {
|
||||
Fragment frag;
|
||||
frag.color = gridColor;
|
||||
frag.depth = vs_screenSpaceDepth;
|
||||
frag.color = gridColor;
|
||||
frag.depth = vs_screenSpaceDepth;
|
||||
frag.gPosition = vs_positionViewSpace;
|
||||
frag.gOtherData = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
frag.gNormal = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
return frag;
|
||||
}
|
||||
|
||||
@@ -29,14 +29,17 @@
|
||||
layout(location = 0) in vec3 in_position;
|
||||
|
||||
out float vs_screenSpaceDepth;
|
||||
out vec4 vs_positionViewSpace;
|
||||
|
||||
uniform mat4 modelViewTransform;
|
||||
uniform mat4 projectionTransform;
|
||||
|
||||
void main() {
|
||||
vec4 positionClipSpace = projectionTransform * modelViewTransform * vec4(in_position, 1.0);
|
||||
vec4 positionViewSpace = modelViewTransform * vec4(in_position, 1.0);
|
||||
vec4 positionClipSpace = projectionTransform * positionViewSpace;
|
||||
vec4 positionScreenSpace = z_normalization(positionClipSpace);
|
||||
vs_screenSpaceDepth = positionScreenSpace.w;
|
||||
|
||||
vs_screenSpaceDepth = positionScreenSpace.w;
|
||||
vs_positionViewSpace = positionViewSpace;
|
||||
|
||||
gl_Position = positionScreenSpace;
|
||||
}
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
|
||||
in float vs_screenSpaceDepth;
|
||||
in vec2 vs_st;
|
||||
in vec4 vs_gPosition;
|
||||
in vec3 vs_gNormal;
|
||||
|
||||
uniform sampler2D texture1;
|
||||
uniform bool additiveBlending;
|
||||
@@ -49,5 +51,11 @@ Fragment getFragment() {
|
||||
if (additiveBlending) {
|
||||
frag.blend = BLEND_MODE_ADDITIVE;
|
||||
}
|
||||
|
||||
// G-Buffer
|
||||
frag.gOtherData = vec4(frag.color.xyz, 1.0);
|
||||
frag.gPosition = vs_gPosition;
|
||||
frag.gNormal = vec4(vs_gNormal, 1.0);
|
||||
|
||||
return frag;
|
||||
}
|
||||
|
||||
@@ -32,9 +32,12 @@ layout(location = 1) in vec2 in_st;
|
||||
out vec2 vs_st;
|
||||
out float vs_screenSpaceDepth;
|
||||
out vec4 vs_positionScreenSpace;
|
||||
// G-Buffer
|
||||
out vec4 vs_gPosition;
|
||||
out vec3 vs_gNormal;
|
||||
|
||||
uniform mat4 modelViewProjectionTransform;
|
||||
|
||||
uniform mat4 modelViewTransform;
|
||||
|
||||
void main() {
|
||||
vec4 position = vec4(in_position.xyz * pow(10, in_position.w), 1);
|
||||
@@ -43,6 +46,10 @@ void main() {
|
||||
|
||||
gl_Position = positionScreenSpace;
|
||||
|
||||
// G-Buffer
|
||||
vs_gNormal = vec3(0.0);
|
||||
vs_gPosition = vec4(modelViewTransform * position); // Must be in SGCT eye space;
|
||||
|
||||
vs_st = in_st;
|
||||
vs_screenSpaceDepth = positionScreenSpace.w;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "fragment.glsl"
|
||||
|
||||
in vec4 vs_positionScreenSpace;
|
||||
in vec4 vs_gPosition;
|
||||
in float fade;
|
||||
|
||||
uniform vec3 color;
|
||||
@@ -50,5 +51,12 @@ Fragment getFragment() {
|
||||
frag.color.a *= 1.0 - smoothstep(1.0 - Delta, 1.0, dot(circCoord, circCoord));
|
||||
}
|
||||
|
||||
// G-Buffer
|
||||
frag.gOtherData = vec4(frag.color.xyz, 1.0);
|
||||
frag.gPosition = vs_gPosition;
|
||||
// There is no normal here
|
||||
// TODO: Add the correct normal if necessary (JCC)
|
||||
frag.gNormal = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
|
||||
return frag;
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
layout(location = 0) in vec3 in_point_position;
|
||||
|
||||
out vec4 vs_positionScreenSpace;
|
||||
out vec4 vs_gPosition;
|
||||
out float fade;
|
||||
|
||||
uniform dmat4 modelViewTransform;
|
||||
@@ -70,9 +71,8 @@ void main() {
|
||||
fade = 1.0;
|
||||
}
|
||||
|
||||
vs_positionScreenSpace = z_normalization(
|
||||
projectionTransform * vec4(modelViewTransform * dvec4(in_point_position, 1))
|
||||
);
|
||||
vs_gPosition = vec4(modelViewTransform * dvec4(in_point_position, 1));
|
||||
vs_positionScreenSpace = z_normalization(projectionTransform * vs_gPosition);
|
||||
|
||||
gl_PointSize = (stride == 1 || int(modId) % stride == 0) ? float(pointSize) : float(pointSize) / 2;
|
||||
gl_Position = vs_positionScreenSpace;
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
in vec2 vs_st;
|
||||
in vec4 vs_position;
|
||||
in vec4 vs_gPosition;
|
||||
|
||||
uniform float time;
|
||||
uniform sampler2D texture1;
|
||||
@@ -35,7 +36,6 @@ uniform float alpha;
|
||||
|
||||
Fragment getFragment() {
|
||||
vec4 position = vs_position;
|
||||
|
||||
vec2 texCoord = vs_st;
|
||||
// Why is this here? ---abock
|
||||
texCoord.s = 1 - texCoord.s;
|
||||
@@ -43,6 +43,14 @@ Fragment getFragment() {
|
||||
|
||||
Fragment frag;
|
||||
frag.color = texture(texture1, texCoord) * vec4(1.0, 1.0, 1.0, alpha);
|
||||
frag.depth = pscDepth(position);;
|
||||
frag.depth = pscDepth(position);
|
||||
|
||||
// G-Buffer
|
||||
frag.gOtherData = vec4(frag.color.xyz, 1.0);
|
||||
frag.gPosition = vs_gPosition;
|
||||
// There is no normal here
|
||||
// TODO: Add the correct normal (JCC)
|
||||
frag.gNormal = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
|
||||
return frag;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ layout(location = 1) in vec2 in_st;
|
||||
out vec2 vs_st;
|
||||
out vec4 vs_position;
|
||||
out float s;
|
||||
out vec4 vs_gPosition;
|
||||
|
||||
uniform mat4 ViewProjection;
|
||||
uniform mat4 ModelTransform;
|
||||
@@ -45,11 +46,13 @@ void main() {
|
||||
0.0, 0.0, -1.0, 0.0,
|
||||
0.0, 0.0, 0.0, 1.0) * ModelTransform;
|
||||
|
||||
vec4 position = pscTransform(tmp, mt);
|
||||
|
||||
vs_position = tmp;
|
||||
vs_st = in_st;
|
||||
|
||||
vec4 position = pscTransform(tmp, mt);
|
||||
vs_gPosition = position;
|
||||
|
||||
position = ViewProjection * position;
|
||||
gl_Position = z_normalization(position);
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2017 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
out vec4 renderTableColor;
|
||||
|
||||
void main() {
|
||||
renderTableColor = vec4(0.0);
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2017 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
layout(location = 0) in vec3 in_position;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(in_position, 1.0);
|
||||
}
|
||||
@@ -161,11 +161,47 @@ namespace {
|
||||
"astronomical objects."
|
||||
};
|
||||
|
||||
static const openspace::properties::Property::PropertyInfo TransformationMatrixInfo =
|
||||
{
|
||||
"TransformationMatrix",
|
||||
"Transformation Matrix",
|
||||
"Transformation matrix to be applied to each astronomical object."
|
||||
};
|
||||
|
||||
static const openspace::properties::Property::PropertyInfo RenderOptionInfo = {
|
||||
"RenderOptionInfo",
|
||||
"Render Option",
|
||||
"Debug option for rendering of billboards and texts."
|
||||
};
|
||||
|
||||
static const openspace::properties::Property::PropertyInfo FadeInDistancesInfo = {
|
||||
"FadeInDistances",
|
||||
"Fade-In Start and End Distances",
|
||||
"These values determine the initial and final distances from the center of "
|
||||
"our galaxy from which the astronomical object will start and end "
|
||||
"fading-in."
|
||||
};
|
||||
|
||||
static const openspace::properties::Property::PropertyInfo DisableFadeInInfo = {
|
||||
"DisableFadeIn",
|
||||
"Disable Fade-in effect",
|
||||
"Enables/Disables the Fade-in effect."
|
||||
};
|
||||
|
||||
static const openspace::properties::Property::PropertyInfo BillboardMaxSizeInfo = {
|
||||
"BillboardMaxSize",
|
||||
"Billboard Max Size in Pixels",
|
||||
"The max size (in pixels) for the billboard representing the astronomical "
|
||||
"object."
|
||||
};
|
||||
|
||||
static const openspace::properties::Property::PropertyInfo BillboardMinSizeInfo = {
|
||||
"BillboardMinSize",
|
||||
"Billboard Min Size in Pixels",
|
||||
"The min size (in pixels) for the billboard representing the astronomical "
|
||||
"object."
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
@@ -271,6 +307,36 @@ documentation::Documentation RenderableBillboardsCloud::Documentation() {
|
||||
new Vector2ListVerifier<float>,
|
||||
Optional::Yes,
|
||||
ColorRangeInfo.description
|
||||
},
|
||||
{
|
||||
TransformationMatrixInfo.identifier,
|
||||
new Matrix4x4Verifier<double>,
|
||||
Optional::Yes,
|
||||
TransformationMatrixInfo.description
|
||||
},
|
||||
{
|
||||
FadeInDistancesInfo.identifier,
|
||||
new Vector2Verifier<double>,
|
||||
Optional::Yes,
|
||||
FadeInDistancesInfo.description
|
||||
},
|
||||
{
|
||||
DisableFadeInInfo.identifier,
|
||||
new BoolVerifier,
|
||||
Optional::Yes,
|
||||
DisableFadeInInfo.description
|
||||
},
|
||||
{
|
||||
BillboardMaxSizeInfo.identifier,
|
||||
new DoubleVerifier,
|
||||
Optional::Yes,
|
||||
BillboardMaxSizeInfo.description
|
||||
},
|
||||
{
|
||||
BillboardMinSizeInfo.identifier,
|
||||
new DoubleVerifier,
|
||||
Optional::Yes,
|
||||
BillboardMinSizeInfo.description
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -306,6 +372,10 @@ RenderableBillboardsCloud::RenderableBillboardsCloud(const ghoul::Dictionary& di
|
||||
, _drawElements(DrawElementsInfo, true)
|
||||
, _drawLabels(DrawLabelInfo, false)
|
||||
, _colorOption(ColorOptionInfo, properties::OptionProperty::DisplayType::Dropdown)
|
||||
, _fadeInDistance(FadeInDistancesInfo, glm::vec2(0.0f), glm::vec2(0.0), glm::vec2(100.0))
|
||||
, _disableFadeInDistance(DisableFadeInInfo, true)
|
||||
, _billboardMaxSize(BillboardMaxSizeInfo, 400.0, 0.0, 1000.0)
|
||||
, _billboardMinSize(BillboardMinSizeInfo, 0.0, 0.0, 100.0)
|
||||
, _renderOption(RenderOptionInfo, properties::OptionProperty::DisplayType::Dropdown)
|
||||
, _polygonTexture(nullptr)
|
||||
, _spriteTexture(nullptr)
|
||||
@@ -317,6 +387,7 @@ RenderableBillboardsCloud::RenderableBillboardsCloud(const ghoul::Dictionary& di
|
||||
, _labelFile("")
|
||||
, _colorOptionString("")
|
||||
, _unit(Parsec)
|
||||
, _transformationMatrix(glm::dmat4(1.0))
|
||||
, _nValuesPerAstronomicalObject(0)
|
||||
, _vao(0)
|
||||
, _vbo(0)
|
||||
@@ -460,7 +531,7 @@ RenderableBillboardsCloud::RenderableBillboardsCloud(const ghoul::Dictionary& di
|
||||
|
||||
_labelFile = absPath(dictionary.value<std::string>(
|
||||
LabelFileInfo.identifier
|
||||
));
|
||||
));
|
||||
_hasLabel = true;
|
||||
|
||||
if (dictionary.hasKey(TextColorInfo.identifier)) {
|
||||
@@ -479,7 +550,7 @@ RenderableBillboardsCloud::RenderableBillboardsCloud(const ghoul::Dictionary& di
|
||||
|
||||
if (dictionary.hasKey(LabelMinSizeInfo.identifier)) {
|
||||
_textMinSize = static_cast<int>(dictionary.value<float>(LabelMinSizeInfo.identifier));
|
||||
}
|
||||
}
|
||||
addProperty(_textMinSize);
|
||||
|
||||
if (dictionary.hasKey(LabelMaxSizeInfo.identifier)) {
|
||||
@@ -487,6 +558,37 @@ RenderableBillboardsCloud::RenderableBillboardsCloud(const ghoul::Dictionary& di
|
||||
}
|
||||
addProperty(_textMaxSize);
|
||||
}
|
||||
|
||||
if (dictionary.hasKey(TransformationMatrixInfo.identifier)) {
|
||||
_transformationMatrix = dictionary.value<glm::dmat4>(
|
||||
TransformationMatrixInfo.identifier
|
||||
);
|
||||
}
|
||||
|
||||
if (dictionary.hasKey(FadeInDistancesInfo.identifier)) {
|
||||
glm::vec2 fadeInValue = dictionary.value<glm::vec2>(
|
||||
FadeInDistancesInfo.identifier
|
||||
);
|
||||
_fadeInDistance.set(fadeInValue);
|
||||
_disableFadeInDistance.set(false);
|
||||
addProperty(_fadeInDistance);
|
||||
addProperty(_disableFadeInDistance);
|
||||
}
|
||||
|
||||
if (dictionary.hasKey(BillboardMaxSizeInfo.identifier)) {
|
||||
_billboardMaxSize = static_cast<float>(
|
||||
dictionary.value<double>(BillboardMaxSizeInfo.identifier)
|
||||
);
|
||||
addProperty(_billboardMaxSize);
|
||||
}
|
||||
|
||||
if (dictionary.hasKey(BillboardMinSizeInfo.identifier)) {
|
||||
_billboardMinSize = static_cast<float>(
|
||||
dictionary.value<double>(BillboardMinSizeInfo.identifier)
|
||||
);
|
||||
addProperty(_billboardMinSize);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool RenderableBillboardsCloud::isReady() const {
|
||||
@@ -554,8 +656,13 @@ void RenderableBillboardsCloud::deinitializeGL() {
|
||||
}
|
||||
}
|
||||
|
||||
void RenderableBillboardsCloud::renderBillboards(const RenderData& data, const glm::dmat4& modelViewMatrix,
|
||||
const glm::dmat4& projectionMatrix, const glm::vec3& orthoRight, const glm::vec3& orthoUp) {
|
||||
void RenderableBillboardsCloud::renderBillboards(const RenderData& data,
|
||||
const glm::dmat4& modelViewMatrix,
|
||||
const glm::dmat4& worldToModelTransform,
|
||||
const glm::dvec3& orthoRight,
|
||||
const glm::dvec3& orthoUp,
|
||||
float fadeInVariable)
|
||||
{
|
||||
glDepthMask(false);
|
||||
|
||||
// Saving current OpenGL state
|
||||
@@ -583,18 +690,28 @@ void RenderableBillboardsCloud::renderBillboards(const RenderData& data, const g
|
||||
using IgnoreError = ghoul::opengl::ProgramObject::IgnoreError;
|
||||
_program->setIgnoreUniformLocationError(IgnoreError::Yes);
|
||||
|
||||
glm::dmat4 projMatrix = glm::dmat4(data.camera.projectionMatrix());
|
||||
_program->setUniform("screenSize", glm::vec2(OsEng.renderEngine().renderingResolution()));
|
||||
_program->setUniform("projection", projectionMatrix);
|
||||
_program->setUniform("projection", projMatrix);
|
||||
_program->setUniform("modelViewTransform", modelViewMatrix);
|
||||
_program->setUniform("modelViewProjectionTransform", glm::dmat4(projectionMatrix) * modelViewMatrix);
|
||||
_program->setUniform("modelViewProjectionTransform", projMatrix * modelViewMatrix);
|
||||
_program->setUniform("cameraPosition", glm::dvec3(worldToModelTransform *
|
||||
glm::dvec4(data.camera.positionVec3(), 1.0)));
|
||||
_program->setUniform("cameraLookUp", glm::dvec3(worldToModelTransform *
|
||||
glm::dvec4(data.camera.lookUpVectorWorldSpace(), 1.0)));
|
||||
|
||||
//_program->setUniform("cameraPosition", data.camera.positionVec3());
|
||||
//_program->setUniform("cameraLookUp", data.camera.lookUpVectorWorldSpace());
|
||||
|
||||
|
||||
_program->setUniform("cameraPosition", data.camera.positionVec3());
|
||||
_program->setUniform("cameraLookUp", data.camera.lookUpVectorWorldSpace());
|
||||
_program->setUniform("renderOption", _renderOption.value());
|
||||
glm::dvec4 centerScreenWorld = glm::inverse(data.camera.combinedViewMatrix()) * glm::dvec4(0.0, 0.0, 0.0, 1.0);
|
||||
glm::dvec4 centerScreenWorld = glm::inverse(data.camera.combinedViewMatrix()) *
|
||||
glm::dvec4(0.0, 0.0, 0.0, 1.0);
|
||||
|
||||
_program->setUniform("centerScreenInWorldPosition", centerScreenWorld);
|
||||
|
||||
_program->setUniform("minBillboardSize", 1.f); // in pixels
|
||||
_program->setUniform("minBillboardSize", _billboardMinSize); // in pixels
|
||||
_program->setUniform("maxBillboardSize", _billboardMaxSize); // in pixels
|
||||
_program->setUniform("color", _pointColor);
|
||||
_program->setUniform("sides", 4);
|
||||
_program->setUniform("alphaValue", _alphaValue);
|
||||
@@ -603,6 +720,13 @@ void RenderableBillboardsCloud::renderBillboards(const RenderData& data, const g
|
||||
_program->setUniform("up", orthoUp);
|
||||
_program->setUniform("right", orthoRight);
|
||||
|
||||
_program->setUniform("fadeInValue", fadeInVariable);
|
||||
|
||||
GLint viewport[4];
|
||||
glGetIntegerv(GL_VIEWPORT, viewport);
|
||||
_program->setUniform("screenSize", glm::vec2(viewport[2], viewport[3]));
|
||||
|
||||
|
||||
ghoul::opengl::TextureUnit spriteTextureUnit;
|
||||
if (_hasSpriteTexture) {
|
||||
spriteTextureUnit.activate();
|
||||
@@ -647,8 +771,12 @@ void RenderableBillboardsCloud::renderBillboards(const RenderData& data, const g
|
||||
|
||||
}
|
||||
|
||||
void RenderableBillboardsCloud::renderLabels(const RenderData& data, const glm::dmat4& modelViewProjectionMatrix,
|
||||
const glm::vec3& orthoRight, const glm::vec3& orthoUp) {
|
||||
void RenderableBillboardsCloud::renderLabels(const RenderData& data,
|
||||
const glm::dmat4& modelViewProjectionMatrix,
|
||||
const glm::dvec3& orthoRight,
|
||||
const glm::dvec3& orthoUp,
|
||||
float fadeInVariable)
|
||||
{
|
||||
RenderEngine& renderEngine = OsEng.renderEngine();
|
||||
|
||||
_fontRenderer->setFramebufferSize(renderEngine.renderingResolution());
|
||||
@@ -678,6 +806,8 @@ void RenderableBillboardsCloud::renderLabels(const RenderData& data, const glm::
|
||||
break;
|
||||
}
|
||||
|
||||
glm::vec4 textColor = _textColor;
|
||||
textColor.a *= fadeInVariable;
|
||||
for (const std::pair<glm::vec3, std::string>& pair : _labelData) {
|
||||
//glm::vec3 scaledPos(_transformationMatrix * glm::dvec4(pair.first, 1.0));
|
||||
glm::vec3 scaledPos(pair.first);
|
||||
@@ -685,7 +815,7 @@ void RenderableBillboardsCloud::renderLabels(const RenderData& data, const glm::
|
||||
_fontRenderer->render(
|
||||
*_font,
|
||||
scaledPos,
|
||||
_textColor,
|
||||
textColor,
|
||||
pow(10.0, _textSize.value()),
|
||||
_textMinSize,
|
||||
_textMaxSize,
|
||||
@@ -701,6 +831,58 @@ void RenderableBillboardsCloud::renderLabels(const RenderData& data, const glm::
|
||||
}
|
||||
|
||||
void RenderableBillboardsCloud::render(const RenderData& data, RendererTasks&) {
|
||||
|
||||
float scale = 0.0;
|
||||
switch (_unit) {
|
||||
case Meter:
|
||||
scale = 1.0;
|
||||
break;
|
||||
case Kilometer:
|
||||
scale = 1e3;
|
||||
break;
|
||||
case Parsec:
|
||||
scale = PARSEC;
|
||||
break;
|
||||
case Kiloparsec:
|
||||
scale = 1e3 * PARSEC;
|
||||
break;
|
||||
case Megaparsec:
|
||||
scale = 1e6 * PARSEC;
|
||||
break;
|
||||
case Gigaparsec:
|
||||
scale = 1e9 * PARSEC;
|
||||
break;
|
||||
case GigalightYears:
|
||||
scale = 306391534.73091 * PARSEC;
|
||||
break;
|
||||
}
|
||||
|
||||
float fadeInVariable = 1.0f;
|
||||
if (!_disableFadeInDistance) {
|
||||
float distCamera = glm::length(data.camera.positionVec3());
|
||||
|
||||
/*
|
||||
// Linear Fading
|
||||
float funcValue = static_cast<float>((1.0 / double(_fadeInDistance*scale))*(distCamera));
|
||||
fadeInVariable *= funcValue > 1.0 ? 1.0 : funcValue;
|
||||
|
||||
if (funcValue < 0.01) {
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
glm::vec2 fadeRange = _fadeInDistance;
|
||||
float a = 1.0f / ((fadeRange.y - fadeRange.x) * scale);
|
||||
float b = -(fadeRange.x / (fadeRange.y - fadeRange.x));
|
||||
float funcValue = a * distCamera + b;
|
||||
fadeInVariable *= funcValue > 1.0 ? 1.0 : funcValue;
|
||||
|
||||
if (funcValue < 0.01) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
glm::dmat4 modelMatrix =
|
||||
glm::translate(glm::dmat4(1.0), data.modelTransform.translation) * // Translation
|
||||
glm::dmat4(data.modelTransform.rotation) * // Spice rotation
|
||||
@@ -709,24 +891,59 @@ void RenderableBillboardsCloud::render(const RenderData& data, RendererTasks&) {
|
||||
glm::dmat4 modelViewMatrix = data.camera.combinedViewMatrix() * modelMatrix;
|
||||
glm::mat4 viewMatrix = data.camera.viewMatrix();
|
||||
glm::mat4 projectionMatrix = data.camera.projectionMatrix();
|
||||
glm::dmat4 modelViewProjectionMatrix = glm::dmat4(projectionMatrix) * modelViewMatrix;
|
||||
|
||||
glm::vec3 lookup = data.camera.lookUpVectorWorldSpace();
|
||||
glm::vec3 viewDirection = data.camera.viewDirectionWorldSpace();
|
||||
glm::dmat4 modelViewProjectionMatrix = glm::dmat4(projectionMatrix) *
|
||||
modelViewMatrix;
|
||||
|
||||
glm::dmat4 worldToModelTransform = glm::inverse(modelMatrix);
|
||||
|
||||
/*glm::dmat4 internalCameraMatrix = data.camera.viewRotationMatrix() *
|
||||
glm::inverse(glm::translate(glm::dmat4(1.0), data.camera.positionVec3()));
|
||||
glm::dmat4 invInternalCameraMatrix = glm::inverse(internalCameraMatrix);
|
||||
glm::vec3 lookup = worldToModelTransform * invInternalCameraMatrix * glm::dvec4(data.camera.lookUpVectorWorldSpace(), 0.0);
|
||||
glm::vec3 viewDirection = worldToModelTransform * invInternalCameraMatrix * glm::dvec4(data.camera.viewDirectionWorldSpace(), 0.0);
|
||||
|
||||
|
||||
glm::vec3 right = glm::cross(viewDirection, lookup);
|
||||
glm::vec3 up = glm::cross(right, viewDirection);
|
||||
|
||||
glm::dmat4 worldToModelTransform = glm::inverse(modelMatrix);
|
||||
glm::vec3 orthoRight = glm::normalize(glm::vec3(worldToModelTransform * glm::vec4(right, 0.0)));
|
||||
glm::vec3 orthoUp = glm::normalize(glm::vec3(worldToModelTransform * glm::vec4(up, 0.0)));
|
||||
|
||||
glm::vec3 orthoRight = glm::normalize(right);
|
||||
glm::vec3 orthoUp = glm::normalize(up);*/
|
||||
|
||||
/*
|
||||
glm::dmat4 internalCameraMatrix = data.camera.viewRotationMatrix() *
|
||||
glm::inverse(glm::translate(glm::dmat4(1.0), data.camera.positionVec3()));
|
||||
glm::dmat4 invInternalCameraMatrix = glm::inverse(internalCameraMatrix);
|
||||
glm::dvec4 lookup = worldToModelTransform * glm::dvec4(data.camera.lookUpVectorWorldSpace(), 0.0);
|
||||
glm::dvec4 viewDirection = worldToModelTransform * glm::dvec4(data.camera.viewDirectionWorldSpace(), 0.0);
|
||||
glm::vec3 right = glm::cross(glm::vec3(viewDirection), glm::vec3(lookup));
|
||||
glm::vec3 up = glm::cross(right, glm::vec3(viewDirection));
|
||||
|
||||
glm::vec3 orthoRight = glm::normalize(right);
|
||||
glm::vec3 orthoUp = glm::normalize(up);
|
||||
*/
|
||||
|
||||
|
||||
// Almost Working
|
||||
glm::dmat4 invMVPParts = worldToModelTransform * glm::inverse(data.camera.combinedViewMatrix()) *
|
||||
glm::inverse(glm::dmat4(projectionMatrix));
|
||||
glm::dvec3 orthoRight = glm::dvec3(glm::normalize(glm::dvec3(invMVPParts * glm::dvec4(1.0, 0.0, 0.0, 0.0))));
|
||||
glm::dvec3 orthoUp = glm::dvec3(glm::normalize(glm::dvec3(invMVPParts * glm::dvec4(0.0, 1.0, 0.0, 0.0))));
|
||||
|
||||
if (_hasSpeckFile) {
|
||||
renderBillboards(data, modelViewMatrix, projectionMatrix, orthoRight, orthoUp);
|
||||
renderBillboards(
|
||||
data,
|
||||
modelViewMatrix,
|
||||
worldToModelTransform,
|
||||
orthoRight,
|
||||
orthoUp,
|
||||
fadeInVariable
|
||||
);
|
||||
}
|
||||
|
||||
if (_drawLabels && _hasLabel) {
|
||||
renderLabels(data, modelViewProjectionMatrix, orthoRight, orthoUp);
|
||||
renderLabels(data, modelViewProjectionMatrix, orthoRight, orthoUp, fadeInVariable);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1119,12 +1336,18 @@ bool RenderableBillboardsCloud::readLabelFile() {
|
||||
dummy.clear();
|
||||
|
||||
while (str >> dummy) {
|
||||
if (dummy == "#") {
|
||||
break;
|
||||
}
|
||||
|
||||
label += " " + dummy;
|
||||
dummy.clear();
|
||||
}
|
||||
|
||||
_labelData.push_back(std::make_pair(position, label));
|
||||
|
||||
glm::vec3 transformedPos = glm::vec3(
|
||||
_transformationMatrix * glm::dvec4(position, 1.0)
|
||||
);
|
||||
_labelData.push_back(std::make_pair(transformedPos, label));
|
||||
} while (!file.eof());
|
||||
|
||||
return true;
|
||||
@@ -1247,13 +1470,20 @@ void RenderableBillboardsCloud::createDataSlice() {
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < _fullData.size(); i += _nValuesPerAstronomicalObject) {
|
||||
glm::dvec4 transformedPos = glm::dvec4(_fullData[i + 0], _fullData[i + 1], _fullData[i + 2], 1.0);
|
||||
float biggestCoord = -1.0f;
|
||||
for (size_t i = 0; i < _fullData.size(); i += _nValuesPerAstronomicalObject) {
|
||||
glm::dvec4 transformedPos = _transformationMatrix * glm::dvec4(
|
||||
_fullData[i + 0],
|
||||
_fullData[i + 1],
|
||||
_fullData[i + 2],
|
||||
1.0
|
||||
);
|
||||
glm::vec4 position(glm::vec3(transformedPos), static_cast<float>(_unit));
|
||||
|
||||
if (_hasColorMapFile) {
|
||||
for (auto j = 0; j < 4; ++j) {
|
||||
_slicedData.push_back(position[j]);
|
||||
biggestCoord = biggestCoord < position[j] ? position[j] : biggestCoord;
|
||||
}
|
||||
// Finds from which bin to get the color.
|
||||
// Note: the first color in the colormap file
|
||||
@@ -1279,6 +1509,7 @@ void RenderableBillboardsCloud::createDataSlice() {
|
||||
}
|
||||
}
|
||||
}
|
||||
_fadeInDistance.setMaxValue(glm::vec2(10.0f * biggestCoord));
|
||||
}
|
||||
|
||||
void RenderableBillboardsCloud::createPolygonTexture() {
|
||||
@@ -1363,7 +1594,8 @@ void RenderableBillboardsCloud::renderPolygonGeometry(GLuint vao) {
|
||||
ghoul::opengl::ProgramObject::Build("RenderableBillboardsCloud_Polygon",
|
||||
absPath("${MODULE_DIGITALUNIVERSE}/shaders/billboardpolygon_vs.glsl"),
|
||||
absPath("${MODULE_DIGITALUNIVERSE}/shaders/billboardpolygon_fs.glsl"),
|
||||
absPath("${MODULE_DIGITALUNIVERSE}/shaders/billboardpolygon_gs.glsl"));
|
||||
absPath("${MODULE_DIGITALUNIVERSE}/shaders/billboardpolygon_gs.glsl")
|
||||
);
|
||||
|
||||
program->activate();
|
||||
static const float black[] = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <openspace/properties/stringproperty.h>
|
||||
#include <openspace/properties/scalar/boolproperty.h>
|
||||
#include <openspace/properties/scalar/floatproperty.h>
|
||||
#include <openspace/properties/vector/vec2property.h>
|
||||
#include <openspace/properties/vector/vec3property.h>
|
||||
#include <openspace/properties/vector/vec4property.h>
|
||||
|
||||
@@ -90,9 +91,10 @@ private:
|
||||
void loadPolygonGeometryForRendering();
|
||||
void renderPolygonGeometry(GLuint vao);
|
||||
void renderBillboards(const RenderData& data, const glm::dmat4& modelViewMatrix,
|
||||
const glm::dmat4& projectionMatrix, const glm::vec3& orthoRight, const glm::vec3& orthoUp);
|
||||
const glm::dmat4& worldToModelTransform, const glm::dvec3& orthoRight,
|
||||
const glm::dvec3& orthoUp, float fadeInVariable);
|
||||
void renderLabels(const RenderData& data, const glm::dmat4& modelViewProjectionMatrix,
|
||||
const glm::vec3& orthoRight, const glm::vec3& orthoUp);
|
||||
const glm::dvec3& orthoRight, const glm::dvec3& orthoUp, float fadeInVariable);
|
||||
|
||||
bool loadData();
|
||||
bool readSpeckFile();
|
||||
@@ -126,6 +128,10 @@ private:
|
||||
properties::BoolProperty _drawElements;
|
||||
properties::BoolProperty _drawLabels;
|
||||
properties::OptionProperty _colorOption;
|
||||
properties::Vec2Property _fadeInDistance;
|
||||
properties::BoolProperty _disableFadeInDistance;
|
||||
properties::FloatProperty _billboardMaxSize;
|
||||
properties::FloatProperty _billboardMinSize;
|
||||
|
||||
// DEBUG:
|
||||
properties::OptionProperty _renderOption;
|
||||
@@ -152,9 +158,11 @@ private:
|
||||
std::unordered_map<std::string, int> _variableDataPositionMap;
|
||||
std::unordered_map<int, std::string> _optionConversionMap;
|
||||
std::vector<glm::vec2> _colorRangeData;
|
||||
|
||||
|
||||
int _nValuesPerAstronomicalObject;
|
||||
|
||||
glm::dmat4 _transformationMatrix;
|
||||
|
||||
GLuint _vao;
|
||||
GLuint _vbo;
|
||||
|
||||
|
||||
@@ -127,7 +127,8 @@ namespace {
|
||||
"Determines whether labels should be drawn or hidden."
|
||||
};
|
||||
|
||||
static const openspace::properties::Property::PropertyInfo TransformationMatrixInfo = {
|
||||
static const openspace::properties::Property::PropertyInfo TransformationMatrixInfo =
|
||||
{
|
||||
"TransformationMatrix",
|
||||
"Transformation Matrix",
|
||||
"Transformation matrix to be applied to each astronomical object."
|
||||
@@ -163,8 +164,8 @@ documentation::Documentation RenderableDUMeshes::Documentation() {
|
||||
KeyFile,
|
||||
new StringVerifier,
|
||||
Optional::No,
|
||||
"The path to the SPECK file that contains information about the astronomical "
|
||||
"object being rendered."
|
||||
"The path to the SPECK file that contains information about the "
|
||||
"astronomical object being rendered."
|
||||
},
|
||||
{
|
||||
keyColor,
|
||||
@@ -243,12 +244,9 @@ RenderableDUMeshes::RenderableDUMeshes(const ghoul::Dictionary& dictionary)
|
||||
, _dataIsDirty(true)
|
||||
, _textColorIsDirty(true)
|
||||
, _hasLabel(false)
|
||||
, _labelDataIsDirty(true)
|
||||
, _textMinSize(0)
|
||||
, _textMaxSize(200)
|
||||
, _labelDataIsDirty(true)
|
||||
, _alphaValue(TransparencyInfo, 1.f, 0.f, 1.f)
|
||||
, _scaleFactor(ScaleFactorInfo, 1.f, 0.f, 64.f)
|
||||
//, _pointColor(ColorInfo, glm::vec3(1.f, 0.4f, 0.2f), glm::vec3(0.f, 0.f, 0.f), glm::vec3(1.0f, 1.0f, 1.0f))
|
||||
, _textColor(
|
||||
TextColorInfo,
|
||||
glm::vec4(1.0f, 1.0, 1.0f, 1.f),
|
||||
@@ -258,6 +256,8 @@ RenderableDUMeshes::RenderableDUMeshes(const ghoul::Dictionary& dictionary)
|
||||
, _textSize(TextSizeInfo, 8.0, 0.5, 24.0)
|
||||
, _drawElements(DrawElementsInfo, true)
|
||||
, _drawLabels(DrawLabelInfo, false)
|
||||
, _textMinSize(LabelMinSizeInfo, 8.0, 0.5, 24.0)
|
||||
, _textMaxSize(LabelMaxSizeInfo, 500.0, 0.0, 1000.0)
|
||||
, _renderOption(RenderOptionInfo, properties::OptionProperty::DisplayType::Dropdown)
|
||||
, _program(nullptr)
|
||||
, _fontRenderer(nullptr)
|
||||
@@ -361,22 +361,30 @@ RenderableDUMeshes::RenderableDUMeshes(const ghoul::Dictionary& dictionary)
|
||||
addProperty(_textSize);
|
||||
|
||||
if (dictionary.hasKey(LabelMinSizeInfo.identifier)) {
|
||||
_textMinSize = static_cast<int>(dictionary.value<float>(LabelMinSizeInfo.identifier));
|
||||
_textMinSize = static_cast<int>(
|
||||
dictionary.value<float>(LabelMinSizeInfo.identifier)
|
||||
);
|
||||
}
|
||||
addProperty(_textMinSize);
|
||||
|
||||
if (dictionary.hasKey(LabelMaxSizeInfo.identifier)) {
|
||||
_textMaxSize = static_cast<int>(dictionary.value<float>(LabelMaxSizeInfo.identifier));
|
||||
_textMaxSize = static_cast<int>(
|
||||
dictionary.value<float>(LabelMaxSizeInfo.identifier)
|
||||
);
|
||||
}
|
||||
addProperty(_textMaxSize);
|
||||
}
|
||||
|
||||
if (dictionary.hasKey(TransformationMatrixInfo.identifier)) {
|
||||
_transformationMatrix = dictionary.value<glm::dmat4>(TransformationMatrixInfo.identifier);
|
||||
_transformationMatrix = dictionary.value<glm::dmat4>(
|
||||
TransformationMatrixInfo.identifier
|
||||
);
|
||||
}
|
||||
|
||||
if (dictionary.hasKey(MeshColorInfo.identifier)) {
|
||||
ghoul::Dictionary colorDic = dictionary.value<ghoul::Dictionary>(
|
||||
MeshColorInfo.identifier
|
||||
);
|
||||
);
|
||||
for (int i = 0; i < static_cast<int>(colorDic.size()); ++i) {
|
||||
_meshColorMap.insert({ i + 1,
|
||||
colorDic.value<glm::vec3>(std::to_string(i + 1)) });
|
||||
@@ -386,7 +394,8 @@ RenderableDUMeshes::RenderableDUMeshes(const ghoul::Dictionary& dictionary)
|
||||
}
|
||||
|
||||
bool RenderableDUMeshes::isReady() const {
|
||||
return (_program != nullptr) && (!_renderingMeshesMap.empty() || (!_labelData.empty()));
|
||||
return (_program != nullptr) &&
|
||||
(!_renderingMeshesMap.empty() || (!_labelData.empty()));
|
||||
}
|
||||
|
||||
void RenderableDUMeshes::initializeGL() {
|
||||
@@ -409,9 +418,13 @@ void RenderableDUMeshes::initializeGL() {
|
||||
_fontRenderer = std::unique_ptr<ghoul::fontrendering::FontRenderer>(
|
||||
ghoul::fontrendering::FontRenderer::createProjectionSubjectText());
|
||||
if (_font == nullptr) {
|
||||
size_t _fontSize = 30;
|
||||
_font = OsEng.fontManager().font("Mono", static_cast<float>(_fontSize),
|
||||
ghoul::fontrendering::FontManager::Outline::Yes, ghoul::fontrendering::FontManager::LoadGlyphs::No);
|
||||
size_t _fontSize = 50;
|
||||
_font = OsEng.fontManager().font(
|
||||
"Mono",
|
||||
static_cast<float>(_fontSize),
|
||||
ghoul::fontrendering::FontManager::Outline::Yes,
|
||||
ghoul::fontrendering::FontManager::LoadGlyphs::No
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -436,6 +449,9 @@ void RenderableDUMeshes::renderMeshes(const RenderData&,
|
||||
const glm::dmat4& projectionMatrix)
|
||||
{
|
||||
// Saving current OpenGL state
|
||||
GLfloat lineWidth = 1.0f;
|
||||
glGetFloatv(GL_LINE_WIDTH, &lineWidth);
|
||||
|
||||
GLboolean blendEnabled = glIsEnabled(GL_BLEND);
|
||||
GLenum blendEquationRGB;
|
||||
GLenum blendEquationAlpha;
|
||||
@@ -461,7 +477,8 @@ void RenderableDUMeshes::renderMeshes(const RenderData&,
|
||||
using IgnoreError = ghoul::opengl::ProgramObject::IgnoreError;
|
||||
_program->setIgnoreUniformLocationError(IgnoreError::Yes);
|
||||
|
||||
_program->setUniform("modelViewProjectionTransform", glm::dmat4(projectionMatrix) * modelViewMatrix);
|
||||
_program->setUniform("modelViewTransform", modelViewMatrix);
|
||||
_program->setUniform("projectionTransform", projectionMatrix);
|
||||
_program->setUniform("alphaValue", _alphaValue);
|
||||
_program->setUniform("scaleFactor", _scaleFactor);
|
||||
|
||||
@@ -474,7 +491,9 @@ void RenderableDUMeshes::renderMeshes(const RenderData&,
|
||||
case Solid:
|
||||
break;
|
||||
case Wire:
|
||||
glLineWidth(2.0);
|
||||
glDrawArrays(GL_LINE_STRIP, 0, pair.second.numV);
|
||||
glLineWidth(lineWidth);
|
||||
break;
|
||||
case Point:
|
||||
glDrawArrays(GL_POINTS, 0, pair.second.numV);
|
||||
@@ -502,8 +521,11 @@ void RenderableDUMeshes::renderMeshes(const RenderData&,
|
||||
}
|
||||
}
|
||||
|
||||
void RenderableDUMeshes::renderLabels(const RenderData& data, const glm::dmat4& modelViewProjectionMatrix,
|
||||
const glm::vec3& orthoRight, const glm::vec3& orthoUp) {
|
||||
void RenderableDUMeshes::renderLabels(const RenderData& data,
|
||||
const glm::dmat4& modelViewProjectionMatrix,
|
||||
const glm::vec3& orthoRight,
|
||||
const glm::vec3& orthoUp)
|
||||
{
|
||||
RenderEngine& renderEngine = OsEng.renderEngine();
|
||||
|
||||
_fontRenderer->setFramebufferSize(renderEngine.renderingResolution());
|
||||
@@ -562,8 +584,8 @@ void RenderableDUMeshes::render(const RenderData& data, RendererTasks&) {
|
||||
glm::scale(glm::dmat4(1.0), glm::dvec3(data.modelTransform.scale));
|
||||
|
||||
glm::dmat4 modelViewMatrix = data.camera.combinedViewMatrix() * modelMatrix;
|
||||
glm::mat4 projectionMatrix = data.camera.projectionMatrix();
|
||||
glm::dmat4 modelViewProjectionMatrix = glm::dmat4(projectionMatrix) * modelViewMatrix;
|
||||
glm::dmat4 projectionMatrix = data.camera.projectionMatrix();
|
||||
glm::dmat4 modelViewProjectionMatrix = projectionMatrix * modelViewMatrix;
|
||||
|
||||
glm::vec3 lookup = data.camera.lookUpVectorWorldSpace();
|
||||
glm::vec3 viewDirection = data.camera.viewDirectionWorldSpace();
|
||||
@@ -571,8 +593,12 @@ void RenderableDUMeshes::render(const RenderData& data, RendererTasks&) {
|
||||
glm::vec3 up = glm::cross(right, viewDirection);
|
||||
|
||||
glm::dmat4 worldToModelTransform = glm::inverse(modelMatrix);
|
||||
glm::vec3 orthoRight = glm::normalize(glm::vec3(worldToModelTransform * glm::vec4(right, 0.0)));
|
||||
glm::vec3 orthoUp = glm::normalize(glm::vec3(worldToModelTransform * glm::vec4(up, 0.0)));
|
||||
glm::vec3 orthoRight = glm::normalize(
|
||||
glm::vec3(worldToModelTransform * glm::vec4(right, 0.0))
|
||||
);
|
||||
glm::vec3 orthoUp = glm::normalize(
|
||||
glm::vec3(worldToModelTransform * glm::vec4(up, 0.0))
|
||||
);
|
||||
|
||||
if (_hasSpeckFile) {
|
||||
renderMeshes(data, modelViewMatrix, projectionMatrix);
|
||||
@@ -858,7 +884,9 @@ bool RenderableDUMeshes::readLabelFile() {
|
||||
dummy.clear();
|
||||
}
|
||||
|
||||
glm::vec3 transformedPos = glm::vec3(_transformationMatrix * glm::dvec4(position, 1.0));
|
||||
glm::vec3 transformedPos = glm::vec3(
|
||||
_transformationMatrix * glm::dvec4(position, 1.0)
|
||||
);
|
||||
_labelData.push_back(std::make_pair(transformedPos, label));
|
||||
|
||||
} while (!file.eof());
|
||||
@@ -880,7 +908,10 @@ bool RenderableDUMeshes::loadCachedFile(const std::string& file) {
|
||||
|
||||
int32_t nValues = 0;
|
||||
fileStream.read(reinterpret_cast<char*>(&nValues), sizeof(int32_t));
|
||||
fileStream.read(reinterpret_cast<char*>(&_nValuesPerAstronomicalObject), sizeof(int32_t));
|
||||
fileStream.read(
|
||||
reinterpret_cast<char*>(&_nValuesPerAstronomicalObject),
|
||||
sizeof(int32_t)
|
||||
);
|
||||
|
||||
_fullData.resize(nValues);
|
||||
fileStream.read(reinterpret_cast<char*>(&_fullData[0]),
|
||||
@@ -908,8 +939,13 @@ bool RenderableDUMeshes::saveCachedFile(const std::string& file) const {
|
||||
}
|
||||
fileStream.write(reinterpret_cast<const char*>(&nValues), sizeof(int32_t));
|
||||
|
||||
int32_t nValuesPerAstronomicalObject = static_cast<int32_t>(_nValuesPerAstronomicalObject);
|
||||
fileStream.write(reinterpret_cast<const char*>(&nValuesPerAstronomicalObject), sizeof(int32_t));
|
||||
int32_t nValuesPerAstronomicalObject = static_cast<int32_t>(
|
||||
_nValuesPerAstronomicalObject
|
||||
);
|
||||
fileStream.write(
|
||||
reinterpret_cast<const char*>(&nValuesPerAstronomicalObject),
|
||||
sizeof(int32_t)
|
||||
);
|
||||
|
||||
size_t nBytes = nValues * sizeof(_fullData[0]);
|
||||
fileStream.write(reinterpret_cast<const char*>(&_fullData[0]), nBytes);
|
||||
@@ -927,34 +963,34 @@ void RenderableDUMeshes::createMeshes() {
|
||||
if (_dataIsDirty && _hasSpeckFile) {
|
||||
LDEBUG("Creating planes");
|
||||
|
||||
|
||||
std::unordered_map<int, RenderingMesh>::iterator it = _renderingMeshesMap.begin();
|
||||
std::unordered_map<int, RenderingMesh>::iterator itEnd = _renderingMeshesMap.end();
|
||||
std::unordered_map<int, RenderingMesh>::iterator itEnd =
|
||||
_renderingMeshesMap.end();
|
||||
|
||||
for (; it != itEnd; ++it) {
|
||||
float scale = 0.0;
|
||||
switch (_unit) {
|
||||
case Meter:
|
||||
scale = 1.0;
|
||||
break;
|
||||
case Kilometer:
|
||||
scale = 1e3;
|
||||
break;
|
||||
case Parsec:
|
||||
scale = PARSEC;
|
||||
break;
|
||||
case Kiloparsec:
|
||||
scale = 1e3 * PARSEC;
|
||||
break;
|
||||
case Megaparsec:
|
||||
scale = 1e6 * PARSEC;
|
||||
break;
|
||||
case Gigaparsec:
|
||||
scale = 1e9 * PARSEC;
|
||||
break;
|
||||
case GigalightYears:
|
||||
scale = 306391534.73091 * PARSEC;
|
||||
break;
|
||||
case Meter:
|
||||
scale = 1.0;
|
||||
break;
|
||||
case Kilometer:
|
||||
scale = 1e3;
|
||||
break;
|
||||
case Parsec:
|
||||
scale = PARSEC;
|
||||
break;
|
||||
case Kiloparsec:
|
||||
scale = 1e3 * PARSEC;
|
||||
break;
|
||||
case Megaparsec:
|
||||
scale = 1e6 * PARSEC;
|
||||
break;
|
||||
case Gigaparsec:
|
||||
scale = 1e9 * PARSEC;
|
||||
break;
|
||||
case GigalightYears:
|
||||
scale = 306391534.73091 * PARSEC;
|
||||
break;
|
||||
}
|
||||
|
||||
for (int v = 0; v < static_cast<int>(it->second.vertices.size()); ++v) {
|
||||
@@ -971,12 +1007,17 @@ void RenderableDUMeshes::createMeshes() {
|
||||
glBindVertexArray(vao);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||
//glBufferData(GL_ARRAY_BUFFER, it->second.numV * sizeof(GLfloat),
|
||||
glBufferData(GL_ARRAY_BUFFER, it->second.vertices.size() * sizeof(GLfloat),
|
||||
&it->second.vertices[0], GL_STATIC_DRAW);
|
||||
glBufferData(
|
||||
GL_ARRAY_BUFFER,
|
||||
it->second.vertices.size() * sizeof(GLfloat),
|
||||
&it->second.vertices[0],
|
||||
GL_STATIC_DRAW
|
||||
);
|
||||
// in_position
|
||||
glEnableVertexAttribArray(0);
|
||||
// U and V may not be given by the user
|
||||
if (it->second.vertices.size() / (it->second.numU * it->second.numV) > 3) {
|
||||
if (it->second.vertices.size() / (it->second.numU * it->second.numV) > 3)
|
||||
{
|
||||
glVertexAttribPointer(
|
||||
0,
|
||||
3,
|
||||
@@ -994,7 +1035,9 @@ void RenderableDUMeshes::createMeshes() {
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
sizeof(GLfloat) * 7,
|
||||
reinterpret_cast<GLvoid*>(sizeof(GLfloat) * 3 * i * it->second.numV)
|
||||
reinterpret_cast<GLvoid*>(
|
||||
sizeof(GLfloat) * 3 * i * it->second.numV
|
||||
)
|
||||
);
|
||||
}
|
||||
else { // no U and V:
|
||||
@@ -1004,7 +1047,9 @@ void RenderableDUMeshes::createMeshes() {
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
0,
|
||||
reinterpret_cast<GLvoid*>(sizeof(GLfloat) * 3 * i * it->second.numV)
|
||||
reinterpret_cast<GLvoid*>(
|
||||
sizeof(GLfloat) * 3 * i * it->second.numV
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1020,12 +1065,18 @@ void RenderableDUMeshes::createMeshes() {
|
||||
|
||||
glBindVertexArray(cvao);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, cvbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, it->second.vertices.size() * sizeof(GLfloat),
|
||||
&it->second.vertices[0], GL_STATIC_DRAW);
|
||||
glBufferData(
|
||||
GL_ARRAY_BUFFER,
|
||||
it->second.vertices.size() * sizeof(GLfloat),
|
||||
&it->second.vertices[0],
|
||||
GL_STATIC_DRAW
|
||||
);
|
||||
// in_position
|
||||
glEnableVertexAttribArray(0);
|
||||
// U and V may not be given by the user
|
||||
if (it->second.vertices.size() / (it->second.numU * it->second.numV) > 3) {
|
||||
if (it->second.vertices.size() /
|
||||
(it->second.numU * it->second.numV) > 3)
|
||||
{
|
||||
glVertexAttribPointer(
|
||||
0,
|
||||
3,
|
||||
@@ -1067,7 +1118,7 @@ void RenderableDUMeshes::createMeshes() {
|
||||
|
||||
if (_hasLabel && _labelDataIsDirty) {
|
||||
_labelDataIsDirty = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -122,10 +122,7 @@ private:
|
||||
bool _textColorIsDirty;
|
||||
bool _hasLabel;
|
||||
bool _labelDataIsDirty;
|
||||
|
||||
int _textMinSize;
|
||||
int _textMaxSize;
|
||||
|
||||
|
||||
properties::FloatProperty _alphaValue;
|
||||
properties::FloatProperty _scaleFactor;
|
||||
//properties::Vec3Property _pointColor;
|
||||
@@ -134,6 +131,8 @@ private:
|
||||
properties::BoolProperty _drawElements;
|
||||
properties::BoolProperty _drawLabels;
|
||||
//properties::OptionProperty _blendMode;
|
||||
properties::FloatProperty _textMinSize;
|
||||
properties::FloatProperty _textMaxSize;
|
||||
|
||||
// DEBUG:
|
||||
properties::OptionProperty _renderOption;
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
#include <ghoul/font/fontrenderer.h>
|
||||
|
||||
#include <glm/gtx/string_cast.hpp>
|
||||
#include <glm/glm.hpp>
|
||||
#include <ghoul/glm.h>
|
||||
|
||||
#include <array>
|
||||
#include <fstream>
|
||||
@@ -121,7 +121,8 @@ namespace {
|
||||
"Enables/Disables the drawing of the astronomical objects."
|
||||
};
|
||||
|
||||
static const openspace::properties::Property::PropertyInfo TransformationMatrixInfo = {
|
||||
static const openspace::properties::Property::PropertyInfo TransformationMatrixInfo =
|
||||
{
|
||||
"TransformationMatrix",
|
||||
"Transformation Matrix",
|
||||
"Transformation matrix to be applied to each astronomical object."
|
||||
@@ -157,6 +158,26 @@ namespace {
|
||||
"Debug option for rendering of billboards and texts."
|
||||
};
|
||||
|
||||
static const openspace::properties::Property::PropertyInfo FadeInDistancesInfo = {
|
||||
"FadeInDistances",
|
||||
"Fade-In Start and End Distances",
|
||||
"These values determine the initial and final distances from the center of "
|
||||
"our galaxy from which the astronomical object will start and end "
|
||||
"fading-in."
|
||||
};
|
||||
|
||||
static const openspace::properties::Property::PropertyInfo DisableFadeInInfo = {
|
||||
"DisableFadeIn",
|
||||
"Disable Fade-in effect",
|
||||
"Enables/Disables the Fade-in effect."
|
||||
};
|
||||
|
||||
static const openspace::properties::Property::PropertyInfo PlaneMinSizeInfo = {
|
||||
"PlaneMinSize",
|
||||
"Plane Min Size in Pixels",
|
||||
"The min size (in pixels) for the plane representing the astronomical "
|
||||
"object."
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -177,8 +198,8 @@ documentation::Documentation RenderablePlanesCloud::Documentation() {
|
||||
KeyFile,
|
||||
new StringVerifier,
|
||||
Optional::Yes,
|
||||
"The path to the SPECK file that contains information about the astronomical "
|
||||
"object being rendered."
|
||||
"The path to the SPECK file that contains information about the "
|
||||
"astronomical object being rendered."
|
||||
},
|
||||
{
|
||||
TransparencyInfo.identifier,
|
||||
@@ -252,6 +273,24 @@ documentation::Documentation RenderablePlanesCloud::Documentation() {
|
||||
Optional::Yes,
|
||||
ScaleFactorInfo.description,
|
||||
},
|
||||
{
|
||||
FadeInDistancesInfo.identifier,
|
||||
new Vector2Verifier<float>,
|
||||
Optional::Yes,
|
||||
FadeInDistancesInfo.description
|
||||
},
|
||||
{
|
||||
DisableFadeInInfo.identifier,
|
||||
new BoolVerifier,
|
||||
Optional::Yes,
|
||||
DisableFadeInInfo.description
|
||||
},
|
||||
{
|
||||
PlaneMinSizeInfo.identifier,
|
||||
new DoubleVerifier,
|
||||
Optional::Yes,
|
||||
PlaneMinSizeInfo.description
|
||||
},
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -279,6 +318,14 @@ RenderablePlanesCloud::RenderablePlanesCloud(const ghoul::Dictionary& dictionary
|
||||
, _textSize(TextSizeInfo, 8.0, 0.5, 24.0)
|
||||
, _drawElements(DrawElementsInfo, true)
|
||||
, _blendMode(BlendModeInfo, properties::OptionProperty::DisplayType::Dropdown)
|
||||
, _fadeInDistance(
|
||||
FadeInDistancesInfo,
|
||||
glm::vec2(0.f),
|
||||
glm::vec2(0.f),
|
||||
glm::vec2(200000.f)
|
||||
)
|
||||
, _disableFadeInDistance(DisableFadeInInfo, true)
|
||||
, _planeMinSize(PlaneMinSizeInfo, 0.5, 0.0, 500.0)
|
||||
, _renderOption(RenderOptionInfo, properties::OptionProperty::DisplayType::Dropdown)
|
||||
, _program(nullptr)
|
||||
, _fontRenderer(nullptr)
|
||||
@@ -311,6 +358,7 @@ RenderablePlanesCloud::RenderablePlanesCloud(const ghoul::Dictionary& dictionary
|
||||
_renderOption.addOption(1, "Camera Position Normal");
|
||||
_renderOption.addOption(2, "Screen center Position Normal");
|
||||
addProperty(_renderOption);
|
||||
//_renderOption.set(1);
|
||||
|
||||
if (dictionary.hasKey(keyUnit)) {
|
||||
std::string unit = dictionary.value<std::string>(keyUnit);
|
||||
@@ -383,16 +431,22 @@ RenderablePlanesCloud::RenderablePlanesCloud(const ghoul::Dictionary& dictionary
|
||||
addProperty(_textSize);
|
||||
|
||||
if (dictionary.hasKey(LabelMinSizeInfo.identifier)) {
|
||||
_textMinSize = static_cast<int>(dictionary.value<float>(LabelMinSizeInfo.identifier));
|
||||
}
|
||||
_textMinSize = static_cast<int>(
|
||||
dictionary.value<float>(LabelMinSizeInfo.identifier)
|
||||
);
|
||||
}
|
||||
|
||||
if (dictionary.hasKey(LabelMaxSizeInfo.identifier)) {
|
||||
_textMaxSize = static_cast<int>(dictionary.value<float>(LabelMaxSizeInfo.identifier));
|
||||
_textMaxSize = static_cast<int>(
|
||||
dictionary.value<float>(LabelMaxSizeInfo.identifier)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (dictionary.hasKey(TransformationMatrixInfo.identifier)) {
|
||||
_transformationMatrix = dictionary.value<glm::dmat4>(TransformationMatrixInfo.identifier);
|
||||
_transformationMatrix = dictionary.value<glm::dmat4>(
|
||||
TransformationMatrixInfo.identifier
|
||||
);
|
||||
}
|
||||
|
||||
_blendMode.addOptions({
|
||||
@@ -429,7 +483,26 @@ RenderablePlanesCloud::RenderablePlanesCloud(const ghoul::Dictionary& dictionary
|
||||
}
|
||||
|
||||
if (dictionary.hasKey(ScaleLuminosityInfo.identifier)) {
|
||||
_sluminosity = static_cast<float>(dictionary.value<double>(ScaleLuminosityInfo.identifier));
|
||||
_sluminosity = static_cast<float>(
|
||||
dictionary.value<double>(ScaleLuminosityInfo.identifier)
|
||||
);
|
||||
}
|
||||
|
||||
if (dictionary.hasKey(FadeInDistancesInfo.identifier)) {
|
||||
glm::vec2 fadeInValue = dictionary.value<glm::vec2>(
|
||||
FadeInDistancesInfo.identifier
|
||||
);
|
||||
_fadeInDistance.set(fadeInValue);
|
||||
_disableFadeInDistance.set(false);
|
||||
addProperty(_fadeInDistance);
|
||||
addProperty(_disableFadeInDistance);
|
||||
}
|
||||
|
||||
if (dictionary.hasKey(PlaneMinSizeInfo.identifier)) {
|
||||
_planeMinSize = static_cast<float>(
|
||||
dictionary.value<double>(PlaneMinSizeInfo.identifier)
|
||||
);
|
||||
addProperty(_planeMinSize);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -463,17 +536,21 @@ void RenderablePlanesCloud::initializeGL() {
|
||||
ghoul::fontrendering::FontRenderer::createProjectionSubjectText());
|
||||
if (_font == nullptr) {
|
||||
size_t _fontSize = 30;
|
||||
_font = OsEng.fontManager().font("Mono", static_cast<float>(_fontSize),
|
||||
ghoul::fontrendering::FontManager::Outline::Yes, ghoul::fontrendering::FontManager::LoadGlyphs::No);
|
||||
_font = OsEng.fontManager().font(
|
||||
"Mono",
|
||||
static_cast<float>(_fontSize),
|
||||
ghoul::fontrendering::FontManager::Outline::Yes,
|
||||
ghoul::fontrendering::FontManager::LoadGlyphs::No
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RenderablePlanesCloud::deleteDataGPU() {
|
||||
for (auto pair : _renderingPlanesMap) {
|
||||
glDeleteVertexArrays(1, &pair.second.vao);
|
||||
glDeleteBuffers(1, &pair.second.vbo);
|
||||
for (auto renderingPlane : _renderingPlanesArray) {
|
||||
glDeleteVertexArrays(1, &renderingPlane.vao);
|
||||
glDeleteBuffers(1, &renderingPlane.vbo);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -489,7 +566,8 @@ void RenderablePlanesCloud::deinitializeGL() {
|
||||
|
||||
void RenderablePlanesCloud::renderPlanes(const RenderData&,
|
||||
const glm::dmat4& modelViewMatrix,
|
||||
const glm::dmat4& projectionMatrix)
|
||||
const glm::dmat4& projectionMatrix,
|
||||
const float fadeInVariable)
|
||||
{
|
||||
// Saving current OpenGL state
|
||||
GLboolean blendEnabled = glIsEnabled(GL_BLEND);
|
||||
@@ -517,34 +595,56 @@ void RenderablePlanesCloud::renderPlanes(const RenderData&,
|
||||
using IgnoreError = ghoul::opengl::ProgramObject::IgnoreError;
|
||||
_program->setIgnoreUniformLocationError(IgnoreError::Yes);
|
||||
|
||||
_program->setUniform("modelViewProjectionTransform", glm::dmat4(projectionMatrix) * modelViewMatrix);
|
||||
glm::dmat4 modelViewProjectionMatrix = glm::dmat4(projectionMatrix) * modelViewMatrix;
|
||||
_program->setUniform("modelViewProjectionTransform", modelViewProjectionMatrix);
|
||||
_program->setUniform("alphaValue", _alphaValue);
|
||||
_program->setUniform("scaleFactor", _scaleFactor);
|
||||
//_program->setUniform("minPlaneSize", 1.f); // in pixels
|
||||
_program->setUniform("fadeInValue", fadeInVariable);
|
||||
|
||||
//bool usingFramebufferRenderer =
|
||||
// OsEng.renderEngine().rendererImplementation() == RenderEngine::RendererImplementation::Framebuffer;
|
||||
|
||||
//bool usingABufferRenderer =
|
||||
// OsEng.renderEngine().rendererImplementation() == RenderEngine::RendererImplementation::ABuffer;
|
||||
|
||||
//if (usingABufferRenderer) {
|
||||
// _program->setUniform("additiveBlending", _blendMode == BlendModeAdditive);
|
||||
//}
|
||||
|
||||
//bool additiveBlending = _blendMode == BlendModeAdditive && usingFramebufferRenderer;
|
||||
//if (additiveBlending) {
|
||||
// //glDepthMask(false);
|
||||
// glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
//}
|
||||
GLint viewport[4];
|
||||
glGetIntegerv(GL_VIEWPORT, viewport);
|
||||
|
||||
for (auto pair : _renderingPlanesMap) {
|
||||
ghoul::opengl::TextureUnit unit;
|
||||
unit.activate();
|
||||
_textureMap[pair.second.planeIndex]->bind();
|
||||
_program->setUniform("galaxyTexture", unit);
|
||||
ghoul::opengl::TextureUnit unit;
|
||||
unit.activate();
|
||||
_program->setUniform("galaxyTexture", unit);
|
||||
int currentTextureIndex = -1;
|
||||
for (auto renderingPlane : _renderingPlanesArray) {
|
||||
// For planes with undefined textures references
|
||||
if (renderingPlane.planeIndex == -1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
glBindVertexArray(pair.second.vao);
|
||||
glm::dvec4 vertex0(renderingPlane.vertexData[0], renderingPlane.vertexData[1],
|
||||
renderingPlane.vertexData[2], renderingPlane.vertexData[3]);
|
||||
glm::dvec4 vertex1(renderingPlane.vertexData[6], renderingPlane.vertexData[7],
|
||||
renderingPlane.vertexData[8], renderingPlane.vertexData[9]);
|
||||
|
||||
vertex0 = modelViewProjectionMatrix * vertex0;
|
||||
vertex1 = modelViewProjectionMatrix * vertex1;
|
||||
|
||||
// Testing size:
|
||||
glm::vec4 topRight = vertex1 / vertex1.w;
|
||||
topRight = ((topRight + glm::vec4(1.0)) / glm::vec4(2.0)) *
|
||||
glm::vec4(viewport[2], viewport[3], 1.0, 1.0);
|
||||
glm::vec4 bottomLeft = vertex0 / vertex0.w;
|
||||
bottomLeft = ((bottomLeft + glm::vec4(1.0)) / glm::vec4(2.0)) *
|
||||
glm::vec4(viewport[2], viewport[3], 1.0, 1.0);
|
||||
|
||||
float lengthY = std::fabs(topRight.y - bottomLeft.y);
|
||||
float lengthX = std::fabs(topRight.x - bottomLeft.x);
|
||||
float lengthXY = glm::length(glm::vec2(topRight) - glm::vec2(bottomLeft));
|
||||
float biggestAxis =
|
||||
lengthY > lengthX ? (lengthY > lengthXY ? lengthY : lengthXY) :
|
||||
(lengthX > lengthXY ? lengthX : lengthXY);
|
||||
if (biggestAxis < _planeMinSize ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (currentTextureIndex != renderingPlane.planeIndex) {
|
||||
_textureMap[renderingPlane.planeIndex]->bind();
|
||||
currentTextureIndex = renderingPlane.planeIndex;
|
||||
}
|
||||
glBindVertexArray(renderingPlane.vao);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
}
|
||||
|
||||
@@ -570,37 +670,42 @@ void RenderablePlanesCloud::renderPlanes(const RenderData&,
|
||||
}
|
||||
}
|
||||
|
||||
void RenderablePlanesCloud::renderLabels(const RenderData& data, const glm::dmat4& modelViewProjectionMatrix,
|
||||
const glm::vec3& orthoRight, const glm::vec3& orthoUp) {
|
||||
void RenderablePlanesCloud::renderLabels(const RenderData& data,
|
||||
const glm::dmat4& modelViewProjectionMatrix,
|
||||
const glm::dvec3& orthoRight,
|
||||
const glm::dvec3& orthoUp, float fadeInVariable)
|
||||
{
|
||||
RenderEngine& renderEngine = OsEng.renderEngine();
|
||||
|
||||
_fontRenderer->setFramebufferSize(renderEngine.renderingResolution());
|
||||
|
||||
float scale = 0.0;
|
||||
switch (_unit) {
|
||||
case Meter:
|
||||
scale = 1.0;
|
||||
break;
|
||||
case Kilometer:
|
||||
scale = 1e3;
|
||||
break;
|
||||
case Parsec:
|
||||
scale = PARSEC;
|
||||
break;
|
||||
case Kiloparsec:
|
||||
scale = 1e3 * PARSEC;
|
||||
break;
|
||||
case Megaparsec:
|
||||
scale = 1e6 * PARSEC;
|
||||
break;
|
||||
case Gigaparsec:
|
||||
scale = 1e9 * PARSEC;
|
||||
break;
|
||||
case GigalightYears:
|
||||
scale = 306391534.73091 * PARSEC;
|
||||
break;
|
||||
case Meter:
|
||||
scale = 1.0;
|
||||
break;
|
||||
case Kilometer:
|
||||
scale = 1e3;
|
||||
break;
|
||||
case Parsec:
|
||||
scale = PARSEC;
|
||||
break;
|
||||
case Kiloparsec:
|
||||
scale = 1e3 * PARSEC;
|
||||
break;
|
||||
case Megaparsec:
|
||||
scale = 1e6 * PARSEC;
|
||||
break;
|
||||
case Gigaparsec:
|
||||
scale = 1e9 * PARSEC;
|
||||
break;
|
||||
case GigalightYears:
|
||||
scale = 306391534.73091 * PARSEC;
|
||||
break;
|
||||
}
|
||||
|
||||
glm::vec4 textColor = _textColor;
|
||||
textColor.a *= fadeInVariable;
|
||||
for (const std::pair<glm::vec3, std::string>& pair : _labelData) {
|
||||
//glm::vec3 scaledPos(_transformationMatrix * glm::dvec4(pair.first, 1.0));
|
||||
glm::vec3 scaledPos(pair.first);
|
||||
@@ -608,7 +713,8 @@ void RenderablePlanesCloud::renderLabels(const RenderData& data, const glm::dmat
|
||||
_fontRenderer->render(
|
||||
*_font,
|
||||
scaledPos,
|
||||
_textColor,
|
||||
//_textColor,
|
||||
textColor,
|
||||
pow(10.0, _textSize.value()),
|
||||
_textMinSize,
|
||||
_textMaxSize,
|
||||
@@ -625,6 +731,56 @@ void RenderablePlanesCloud::renderLabels(const RenderData& data, const glm::dmat
|
||||
}
|
||||
|
||||
void RenderablePlanesCloud::render(const RenderData& data, RendererTasks&) {
|
||||
double scale = 0.0;
|
||||
switch (_unit) {
|
||||
case Meter:
|
||||
scale = 1.0;
|
||||
break;
|
||||
case Kilometer:
|
||||
scale = 1e3;
|
||||
break;
|
||||
case Parsec:
|
||||
scale = PARSEC;
|
||||
break;
|
||||
case Kiloparsec:
|
||||
scale = 1e3 * PARSEC;
|
||||
break;
|
||||
case Megaparsec:
|
||||
scale = 1e6 * PARSEC;
|
||||
break;
|
||||
case Gigaparsec:
|
||||
scale = 1e9 * PARSEC;
|
||||
break;
|
||||
case GigalightYears:
|
||||
scale = 306391534.73091 * PARSEC;
|
||||
break;
|
||||
}
|
||||
|
||||
float fadeInVariable = 1.0f;
|
||||
if (!_disableFadeInDistance) {
|
||||
double distCamera = glm::length(data.camera.positionVec3());
|
||||
//float funcValue = static_cast<float>(
|
||||
//(1.0 / double(_fadeInDistance))*(distCamera / scale)
|
||||
//);
|
||||
//
|
||||
//// Let's not waste performance
|
||||
//if (funcValue < 0.01) {
|
||||
// return;
|
||||
//}
|
||||
|
||||
//fadeInVariable = funcValue > 1.0 ? 1.0 : funcValue;
|
||||
|
||||
glm::vec2 fadeRange = _fadeInDistance;
|
||||
float a = 1.0f / ((fadeRange.y - fadeRange.x) * scale);
|
||||
float b = -(fadeRange.x / (fadeRange.y - fadeRange.x));
|
||||
float funcValue = a * distCamera + b;
|
||||
fadeInVariable *= funcValue > 1.0 ? 1.0 : funcValue;
|
||||
|
||||
if (funcValue < 0.01) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
glm::dmat4 modelMatrix =
|
||||
glm::translate(glm::dmat4(1.0), data.modelTransform.translation) * // Translation
|
||||
glm::dmat4(data.modelTransform.rotation) * // Spice rotation
|
||||
@@ -634,22 +790,36 @@ void RenderablePlanesCloud::render(const RenderData& data, RendererTasks&) {
|
||||
glm::mat4 projectionMatrix = data.camera.projectionMatrix();
|
||||
glm::dmat4 modelViewProjectionMatrix = glm::dmat4(projectionMatrix) * modelViewMatrix;
|
||||
|
||||
glm::vec3 lookup = data.camera.lookUpVectorWorldSpace();
|
||||
glm::vec3 viewDirection = data.camera.viewDirectionWorldSpace();
|
||||
glm::vec3 right = glm::cross(viewDirection, lookup);
|
||||
glm::vec3 up = glm::cross(right, viewDirection);
|
||||
//glm::vec3 lookup = data.camera.lookUpVectorWorldSpace();
|
||||
//glm::vec3 viewDirection = data.camera.viewDirectionWorldSpace();
|
||||
//glm::vec3 right = glm::cross(viewDirection, lookup);
|
||||
//glm::vec3 up = glm::cross(right, viewDirection);
|
||||
|
||||
glm::dmat4 worldToModelTransform = glm::inverse(modelMatrix);
|
||||
glm::vec3 orthoRight = glm::normalize(glm::vec3(worldToModelTransform * glm::vec4(right, 0.0)));
|
||||
glm::vec3 orthoUp = glm::normalize(glm::vec3(worldToModelTransform * glm::vec4(up, 0.0)));
|
||||
//glm::dmat4 worldToModelTransform = glm::inverse(modelMatrix);
|
||||
//glm::vec3 orthoRight = glm::normalize(
|
||||
// glm::vec3(worldToModelTransform * glm::vec4(right, 0.0))
|
||||
//);
|
||||
//glm::vec3 orthoUp = glm::normalize(
|
||||
// glm::vec3(worldToModelTransform * glm::vec4(up, 0.0))
|
||||
//);
|
||||
|
||||
//glm::dmat4 invMVP = glm::inverse(modelViewProjectionMatrix);
|
||||
glm::dmat4 invMVPParts = glm::inverse(modelMatrix) *
|
||||
glm::inverse(data.camera.combinedViewMatrix()) *
|
||||
glm::inverse(glm::dmat4(projectionMatrix));
|
||||
glm::dvec3 orthoRight = glm::dvec3(
|
||||
glm::normalize(glm::dvec3(invMVPParts * glm::dvec4(1.0, 0.0, 0.0, 0.0)))
|
||||
);
|
||||
glm::dvec3 orthoUp = glm::dvec3(
|
||||
glm::normalize(glm::dvec3(invMVPParts * glm::dvec4(0.0, 1.0, 0.0, 0.0)))
|
||||
);
|
||||
|
||||
|
||||
if (_hasSpeckFile) {
|
||||
renderPlanes(data, modelViewMatrix, projectionMatrix);
|
||||
renderPlanes(data, modelViewMatrix, projectionMatrix, fadeInVariable);
|
||||
}
|
||||
|
||||
if (_hasLabel) {
|
||||
renderLabels(data, modelViewProjectionMatrix, orthoRight, orthoUp);
|
||||
renderLabels(data, modelViewProjectionMatrix, orthoRight, orthoUp, fadeInVariable);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -810,11 +980,13 @@ bool RenderablePlanesCloud::readSpeckFile() {
|
||||
// +3 because of the x, y and z at the begining of each line.
|
||||
_variableDataPositionMap.insert({ dummy, _nValuesPerAstronomicalObject + 3});
|
||||
|
||||
if (dummy == "orientation") { // 3d vectors u and v
|
||||
_nValuesPerAstronomicalObject += 6; // We want the number, but the index is 0 based
|
||||
if ((dummy == "orientation") || (dummy == "ori")) { // 3d vectors u and v
|
||||
// We want the number, but the index is 0 based
|
||||
_nValuesPerAstronomicalObject += 6;
|
||||
}
|
||||
else {
|
||||
_nValuesPerAstronomicalObject += 1; // We want the number, but the index is 0 based
|
||||
// We want the number, but the index is 0 based
|
||||
_nValuesPerAstronomicalObject += 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -841,10 +1013,18 @@ bool RenderablePlanesCloud::readSpeckFile() {
|
||||
if (line.substr(0, 8) == "texture ") {
|
||||
std::stringstream str(line);
|
||||
|
||||
std::size_t found = line.find("-");
|
||||
|
||||
int textureIndex = 0;
|
||||
|
||||
std::string dummy;
|
||||
str >> dummy; // command
|
||||
|
||||
if (found != std::string::npos) {
|
||||
std::string option; // Not being used right now.
|
||||
str >> option;
|
||||
}
|
||||
|
||||
str >> textureIndex;
|
||||
str >> dummy; // texture file name
|
||||
|
||||
@@ -879,7 +1059,7 @@ bool RenderablePlanesCloud::readSpeckFile() {
|
||||
for (int i = 0; i < _nValuesPerAstronomicalObject; ++i) {
|
||||
str >> values[i];
|
||||
if ((i >= _planeStartingIndexPos) &&
|
||||
(i <= _planeStartingIndexPos+6)) { // vectors u and v
|
||||
(i <= _planeStartingIndexPos + 6)) { // vectors u and v
|
||||
int index = i - _planeStartingIndexPos;
|
||||
switch (index) {
|
||||
case 0:
|
||||
@@ -993,7 +1173,9 @@ bool RenderablePlanesCloud::readLabelFile() {
|
||||
dummy.clear();
|
||||
}
|
||||
|
||||
glm::vec3 transformedPos = glm::vec3(_transformationMatrix * glm::dvec4(position, 1.0));
|
||||
glm::vec3 transformedPos = glm::vec3(
|
||||
_transformationMatrix * glm::dvec4(position, 1.0)
|
||||
);
|
||||
_labelData.push_back(std::make_pair(transformedPos, label));
|
||||
|
||||
} while (!file.eof());
|
||||
@@ -1015,7 +1197,10 @@ bool RenderablePlanesCloud::loadCachedFile(const std::string& file) {
|
||||
|
||||
int32_t nValues = 0;
|
||||
fileStream.read(reinterpret_cast<char*>(&nValues), sizeof(int32_t));
|
||||
fileStream.read(reinterpret_cast<char*>(&_nValuesPerAstronomicalObject), sizeof(int32_t));
|
||||
fileStream.read(reinterpret_cast<char*>(
|
||||
&_nValuesPerAstronomicalObject),
|
||||
sizeof(int32_t)
|
||||
);
|
||||
|
||||
_fullData.resize(nValues);
|
||||
fileStream.read(reinterpret_cast<char*>(&_fullData[0]),
|
||||
@@ -1043,8 +1228,13 @@ bool RenderablePlanesCloud::saveCachedFile(const std::string& file) const {
|
||||
}
|
||||
fileStream.write(reinterpret_cast<const char*>(&nValues), sizeof(int32_t));
|
||||
|
||||
int32_t nValuesPerAstronomicalObject = static_cast<int32_t>(_nValuesPerAstronomicalObject);
|
||||
fileStream.write(reinterpret_cast<const char*>(&nValuesPerAstronomicalObject), sizeof(int32_t));
|
||||
int32_t nValuesPerAstronomicalObject = static_cast<int32_t>(
|
||||
_nValuesPerAstronomicalObject
|
||||
);
|
||||
fileStream.write(reinterpret_cast<const char*>(
|
||||
&nValuesPerAstronomicalObject),
|
||||
sizeof(int32_t)
|
||||
);
|
||||
|
||||
size_t nBytes = nValues * sizeof(_fullData[0]);
|
||||
fileStream.write(reinterpret_cast<const char*>(&_fullData[0]), nBytes);
|
||||
@@ -1061,7 +1251,7 @@ bool RenderablePlanesCloud::saveCachedFile(const std::string& file) const {
|
||||
void RenderablePlanesCloud::createPlanes() {
|
||||
if (_dataIsDirty && _hasSpeckFile) {
|
||||
LDEBUG("Creating planes");
|
||||
|
||||
float maxSize = 0.0f;
|
||||
int planeNumber = 0;
|
||||
for (int p = 0; p < _fullData.size(); p += _nValuesPerAstronomicalObject) {
|
||||
glm::vec4 transformedPos = glm::vec4(_transformationMatrix *
|
||||
@@ -1086,7 +1276,8 @@ void RenderablePlanesCloud::createPlanes() {
|
||||
v.w = 0.0;
|
||||
|
||||
if (!_luminosityVar.empty()) {
|
||||
float lumS = _fullData[p + _variableDataPositionMap[_luminosityVar]] * _sluminosity;
|
||||
float lumS = _fullData[p + _variableDataPositionMap[_luminosityVar]] *
|
||||
_sluminosity;
|
||||
u *= lumS;
|
||||
v *= lumS;
|
||||
}
|
||||
@@ -1099,8 +1290,7 @@ void RenderablePlanesCloud::createPlanes() {
|
||||
|
||||
// JCC: Ask Abbott about these points refeering to a non-existing texture.
|
||||
if (plane.planeIndex == 30) {
|
||||
//std::cout << "--- Creating planes - index: " << plane.planeIndex << std::endl;
|
||||
plane.planeIndex = 0;
|
||||
plane.planeIndex = -1;
|
||||
}
|
||||
|
||||
glGenVertexArrays(1, &plane.vao);
|
||||
@@ -1136,11 +1326,18 @@ void RenderablePlanesCloud::createPlanes() {
|
||||
break;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
maxSize = maxSize > vertex0[i] ? maxSize : vertex0[i];
|
||||
maxSize = maxSize > vertex1[i] ? maxSize : vertex1[i];
|
||||
maxSize = maxSize > vertex2[i] ? maxSize : vertex2[i];
|
||||
maxSize = maxSize > vertex4[i] ? maxSize : vertex4[i];
|
||||
}
|
||||
|
||||
vertex0 *= static_cast<float>(scale);
|
||||
vertex1 *= static_cast<float>(scale);
|
||||
vertex2 *= static_cast<float>(scale);
|
||||
vertex4 *= static_cast<float>(scale);
|
||||
|
||||
vertex4 *= static_cast<float>(scale);
|
||||
|
||||
GLfloat vertexData[] = {
|
||||
// x y z w s t
|
||||
vertex0.x, vertex0.y, vertex0.z, 1.f, 0.f, 0.f,
|
||||
@@ -1155,7 +1352,12 @@ void RenderablePlanesCloud::createPlanes() {
|
||||
|
||||
glBindVertexArray(plane.vao);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, plane.vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(plane.vertexData), plane.vertexData, GL_STATIC_DRAW);
|
||||
glBufferData(
|
||||
GL_ARRAY_BUFFER,
|
||||
sizeof(plane.vertexData),
|
||||
plane.vertexData,
|
||||
GL_STATIC_DRAW
|
||||
);
|
||||
// in_position
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(
|
||||
@@ -1178,18 +1380,29 @@ void RenderablePlanesCloud::createPlanes() {
|
||||
reinterpret_cast<GLvoid*>(sizeof(GLfloat) * 4)
|
||||
);
|
||||
|
||||
_renderingPlanesMap.insert({planeNumber++, plane});
|
||||
_renderingPlanesArray.push_back(plane);
|
||||
}
|
||||
|
||||
glBindVertexArray(0);
|
||||
|
||||
_dataIsDirty = false;
|
||||
|
||||
_fadeInDistance.setMaxValue(glm::vec2(10.0f * maxSize));
|
||||
}
|
||||
|
||||
if (_hasLabel && _labelDataIsDirty) {
|
||||
|
||||
_labelDataIsDirty = false;
|
||||
}
|
||||
|
||||
// Sort planes by texture index
|
||||
if (!_renderingPlanesArray.empty()) {
|
||||
std::sort(_renderingPlanesArray.begin(), _renderingPlanesArray.end(),
|
||||
[](const RenderingPlane& planeA, const RenderingPlane& planeB) {
|
||||
return planeA.planeIndex < planeB.planeIndex;
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <openspace/properties/stringproperty.h>
|
||||
#include <openspace/properties/scalar/boolproperty.h>
|
||||
#include <openspace/properties/scalar/floatproperty.h>
|
||||
#include <openspace/properties/vector/vec2property.h>
|
||||
#include <openspace/properties/vector/vec3property.h>
|
||||
#include <openspace/properties/vector/vec4property.h>
|
||||
|
||||
@@ -93,9 +94,9 @@ namespace openspace {
|
||||
void deleteDataGPU();
|
||||
void createPlanes();
|
||||
void renderPlanes(const RenderData& data, const glm::dmat4& modelViewMatrix,
|
||||
const glm::dmat4& projectionMatrix);
|
||||
const glm::dmat4& projectionMatrix, float fadeInVariable);
|
||||
void renderLabels(const RenderData& data, const glm::dmat4& modelViewProjectionMatrix,
|
||||
const glm::vec3& orthoRight, const glm::vec3& orthoUp);
|
||||
const glm::dvec3& orthoRight, const glm::dvec3& orthoUp, float fadeInVarible);
|
||||
|
||||
bool loadData();
|
||||
bool loadTextures();
|
||||
@@ -121,6 +122,9 @@ namespace openspace {
|
||||
properties::FloatProperty _textSize;
|
||||
properties::BoolProperty _drawElements;
|
||||
properties::OptionProperty _blendMode;
|
||||
properties::Vec2Property _fadeInDistance;
|
||||
properties::BoolProperty _disableFadeInDistance;
|
||||
properties::FloatProperty _planeMinSize;
|
||||
|
||||
// DEBUG:
|
||||
properties::OptionProperty _renderOption;
|
||||
@@ -145,10 +149,10 @@ namespace openspace {
|
||||
int _nValuesPerAstronomicalObject;
|
||||
|
||||
float _sluminosity;
|
||||
|
||||
|
||||
glm::dmat4 _transformationMatrix;
|
||||
|
||||
std::unordered_map<int, RenderingPlane> _renderingPlanesMap;
|
||||
std::vector<RenderingPlane> _renderingPlanesArray;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
in vec4 gs_colorMap;
|
||||
in float vs_screenSpaceDepth;
|
||||
in vec2 texCoord;
|
||||
in float ta;
|
||||
|
||||
uniform float alphaValue;
|
||||
uniform vec3 color;
|
||||
@@ -34,6 +35,7 @@ uniform sampler2D spriteTexture;
|
||||
uniform sampler2D polygonTexture;
|
||||
uniform bool hasColorMap;
|
||||
uniform bool hasPolygon;
|
||||
uniform float fadeInValue;
|
||||
|
||||
Fragment getFragment() {
|
||||
|
||||
@@ -50,13 +52,19 @@ Fragment getFragment() {
|
||||
fullColor = vec4(color.rgb * textureColor.rgb, textureColor.a * alphaValue);
|
||||
}
|
||||
|
||||
fullColor.a *= fadeInValue * ta;
|
||||
|
||||
if (fullColor.a == 0.f) {
|
||||
discard;
|
||||
}
|
||||
|
||||
Fragment frag;
|
||||
frag.color = fullColor;
|
||||
frag.depth = vs_screenSpaceDepth;
|
||||
frag.color = fullColor;
|
||||
frag.depth = vs_screenSpaceDepth;
|
||||
frag.gPosition = vec4(1e32, 1e32, 1e32, 1.0);
|
||||
frag.gOtherData = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
frag.gNormal = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
|
||||
|
||||
return frag;
|
||||
}
|
||||
|
||||
@@ -32,19 +32,22 @@ layout(triangle_strip, max_vertices = 6) out;
|
||||
//uniform dmat4 transformMatrix;
|
||||
uniform dmat4 modelViewProjectionTransform;
|
||||
uniform float scaleFactor;
|
||||
uniform vec3 up;
|
||||
uniform vec3 right;
|
||||
uniform dvec3 up;
|
||||
uniform dvec3 right;
|
||||
uniform dvec3 cameraPosition;
|
||||
uniform dvec3 cameraLookUp;
|
||||
uniform dvec4 centerScreenInWorldPosition;
|
||||
uniform int renderOption;
|
||||
|
||||
uniform vec2 screenSize;
|
||||
uniform float maxBillboardSize;
|
||||
uniform float minBillboardSize;
|
||||
|
||||
in vec4 colorMap[];
|
||||
|
||||
out vec4 gs_colorMap;
|
||||
out vec2 texCoord;
|
||||
out float vs_screenSpaceDepth;
|
||||
out float ta;
|
||||
|
||||
const double PARSEC = 0.308567756e17LF;
|
||||
|
||||
@@ -57,27 +60,29 @@ const vec2 corners[4] = vec2[4](
|
||||
|
||||
|
||||
void main() {
|
||||
vec4 pos = gl_in[0].gl_Position;
|
||||
ta = 1.0f;
|
||||
vec4 pos = gl_in[0].gl_Position;
|
||||
gs_colorMap = colorMap[0];
|
||||
|
||||
double scaleMultiply = exp(scaleFactor/10);
|
||||
dvec3 scaledRight = dvec3(0.0);
|
||||
dvec3 scaledUp = dvec3(0.0);
|
||||
dvec3 scaledRight = dvec3(0.0);
|
||||
dvec3 scaledUp = dvec3(0.0);
|
||||
|
||||
if (renderOption == 0) {
|
||||
scaledRight = scaleMultiply * right/2.0f;
|
||||
scaledUp = scaleMultiply * up/2.0f;
|
||||
scaledUp = scaleMultiply * up/2.0f;
|
||||
} else if (renderOption == 1) {
|
||||
dvec3 normal = normalize(cameraPosition - dvec3(pos.xyz));
|
||||
dvec3 normal = normalize(cameraPosition - dvec3(pos.xyz));
|
||||
dvec3 newRight = normalize(cross(cameraLookUp, normal));
|
||||
dvec3 newUp = cross(normal, newRight);
|
||||
scaledRight = scaleMultiply * newRight/2.0f;
|
||||
scaledUp = scaleMultiply * newUp/2.0f;
|
||||
dvec3 newUp = cross(normal, newRight);
|
||||
scaledRight = scaleMultiply * newRight/2.0f;
|
||||
scaledUp = scaleMultiply * newUp/2.0f;
|
||||
} else if (renderOption == 2) {
|
||||
dvec3 normal = normalize(centerScreenInWorldPosition.xyz - dvec3(pos.xyz));
|
||||
dvec3 normal = normalize(centerScreenInWorldPosition.xyz - dvec3(pos.xyz));
|
||||
dvec3 newRight = normalize(cross(cameraLookUp, normal));
|
||||
dvec3 newUp = cross(normal, newRight);
|
||||
scaledRight = scaleMultiply * newRight/2.0f;
|
||||
scaledUp = scaleMultiply * newUp/2.0f;
|
||||
dvec3 newUp = cross(normal, newRight);
|
||||
scaledRight = scaleMultiply * newRight/2.0f;
|
||||
scaledUp = scaleMultiply * newUp/2.0f;
|
||||
}
|
||||
|
||||
double unit = PARSEC;
|
||||
@@ -100,32 +105,87 @@ void main() {
|
||||
//dvec4 dpos = transformMatrix * dvec4(dvec3(pos.xyz) * unit, 1.0);
|
||||
dvec4 dpos = dvec4(dvec3(pos.xyz) * unit, 1.0);
|
||||
|
||||
texCoord = corners[0];
|
||||
vec4 initialPosition = z_normalization(vec4(modelViewProjectionTransform * dvec4(dpos.xyz - scaledRight - scaledUp, dpos.w)));
|
||||
vs_screenSpaceDepth = initialPosition.w;
|
||||
// texCoord = corners[0];
|
||||
vec4 initialPosition = z_normalization(vec4(modelViewProjectionTransform *
|
||||
dvec4(dpos.xyz - scaledRight - scaledUp, dpos.w)));
|
||||
vs_screenSpaceDepth = initialPosition.w;
|
||||
|
||||
// texCoord = corners[1];
|
||||
vec4 secondPosition = z_normalization(vec4(modelViewProjectionTransform *
|
||||
dvec4(dpos.xyz + scaledRight - scaledUp, dpos.w)));
|
||||
|
||||
//texCoord = corners[2];
|
||||
vec4 crossCorner = z_normalization(vec4(modelViewProjectionTransform *
|
||||
dvec4(dpos.xyz + scaledUp + scaledRight, dpos.w)));
|
||||
|
||||
// texCoord = corners[3];
|
||||
vec4 thirdPosition = z_normalization(vec4(modelViewProjectionTransform *
|
||||
dvec4(dpos.xyz + scaledUp - scaledRight, dpos.w)));
|
||||
|
||||
// Testing size:
|
||||
vec4 topRight = secondPosition/secondPosition.w;
|
||||
topRight = ((topRight + vec4(1.0)) / vec4(2.0)) * vec4(screenSize.x, screenSize.y, 1.0, 1.0);
|
||||
vec4 bottomLeft = initialPosition/initialPosition.w;
|
||||
bottomLeft = ((bottomLeft + vec4(1.0)) / vec4(2.0)) * vec4(screenSize.x, screenSize.y, 1.0, 1.0);
|
||||
|
||||
float height = abs(topRight.y - bottomLeft.y);
|
||||
float width = abs(topRight.x - bottomLeft.x);
|
||||
float var = (height + width);
|
||||
|
||||
if ((height > maxBillboardSize) ||
|
||||
(width > maxBillboardSize)) {
|
||||
|
||||
// Set maximum size as Carter's instructions
|
||||
float correctionScale = height > maxBillboardSize ? maxBillboardSize / (topRight.y - bottomLeft.y) :
|
||||
maxBillboardSize / (topRight.x - bottomLeft.x);
|
||||
|
||||
scaledRight = correctionScale * scaleMultiply * right/2.0f;
|
||||
scaledUp = correctionScale * scaleMultiply * up/2.0f;
|
||||
initialPosition = z_normalization(vec4(modelViewProjectionTransform *
|
||||
dvec4(dpos.xyz - scaledRight - scaledUp, dpos.w)));
|
||||
vs_screenSpaceDepth = initialPosition.w;
|
||||
secondPosition = z_normalization(vec4(modelViewProjectionTransform *
|
||||
dvec4(dpos.xyz + scaledRight - scaledUp, dpos.w)));
|
||||
crossCorner = z_normalization(vec4(modelViewProjectionTransform *
|
||||
dvec4(dpos.xyz + scaledUp + scaledRight, dpos.w)));
|
||||
thirdPosition = z_normalization(vec4(modelViewProjectionTransform *
|
||||
dvec4(dpos.xyz + scaledUp - scaledRight, dpos.w)));
|
||||
|
||||
// Fade-out
|
||||
// float maxVar = 2.0f * maxBillboardSize;
|
||||
// float minVar = maxBillboardSize;
|
||||
// ta = 1.0f - ( (var - minVar)/(maxVar - minVar) );
|
||||
// if (ta == 0.0f)
|
||||
// return;
|
||||
}
|
||||
else if (width < 2.0f * minBillboardSize) {
|
||||
//return;
|
||||
float maxVar = 2.0f * minBillboardSize;
|
||||
float minVar = minBillboardSize;
|
||||
ta = ( (var - minVar)/(maxVar - minVar) );
|
||||
if (ta == 0.0f)
|
||||
return;
|
||||
}
|
||||
|
||||
// Build primitive
|
||||
texCoord = corners[0];
|
||||
gl_Position = initialPosition;
|
||||
EmitVertex();
|
||||
|
||||
texCoord = corners[1];
|
||||
gl_Position = z_normalization(vec4(modelViewProjectionTransform * dvec4(dpos.xyz + scaledRight - scaledUp, dpos.w)));
|
||||
texCoord = corners[1];
|
||||
gl_Position = secondPosition;
|
||||
EmitVertex();
|
||||
|
||||
texCoord = corners[2];
|
||||
vec4 crossCorner = z_normalization(vec4(modelViewProjectionTransform * dvec4(dpos.xyz + scaledUp + scaledRight, dpos.w)));
|
||||
texCoord = corners[2];
|
||||
gl_Position = crossCorner;
|
||||
EmitVertex();
|
||||
EndPrimitive(); // First Triangle
|
||||
|
||||
texCoord = corners[0];
|
||||
texCoord = corners[0];
|
||||
gl_Position = initialPosition;
|
||||
EmitVertex();
|
||||
|
||||
texCoord = corners[2];
|
||||
texCoord = corners[2];
|
||||
gl_Position = crossCorner;
|
||||
EmitVertex();
|
||||
|
||||
texCoord = corners[3];
|
||||
gl_Position = z_normalization(vec4(modelViewProjectionTransform * dvec4(dpos.xyz + scaledUp - scaledRight, dpos.w)));
|
||||
texCoord = corners[3];
|
||||
gl_Position = thirdPosition;
|
||||
EmitVertex();
|
||||
EndPrimitive(); // Second Triangle
|
||||
EndPrimitive(); // Second Triangle
|
||||
}
|
||||
|
||||
@@ -57,6 +57,9 @@ Fragment getFragment() {
|
||||
Fragment frag;
|
||||
frag.color = fullColor;
|
||||
frag.depth = gs_screenSpaceDepth;
|
||||
|
||||
frag.gPosition = vec4(1e27, 1e27, 1e27, 1.0);
|
||||
frag.gOtherData = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
frag.gNormal = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
|
||||
return frag;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "fragment.glsl"
|
||||
|
||||
in float vs_screenSpaceDepth;
|
||||
in vec4 vs_positionViewSpace;
|
||||
|
||||
uniform vec3 color;
|
||||
uniform float alphaValue;
|
||||
@@ -39,5 +40,10 @@ Fragment getFragment() {
|
||||
frag.color = vec4(color, alphaValue);
|
||||
frag.depth = vs_screenSpaceDepth;
|
||||
|
||||
// JCC: Need to change the position to camera space
|
||||
frag.gPosition = vs_positionViewSpace;
|
||||
frag.gOtherData = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
frag.gNormal = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
|
||||
return frag;
|
||||
}
|
||||
|
||||
@@ -28,16 +28,20 @@
|
||||
|
||||
in vec3 in_position;
|
||||
|
||||
uniform dmat4 modelViewProjectionTransform;
|
||||
uniform dmat4 modelViewTransform;
|
||||
uniform dmat4 projectionTransform;
|
||||
uniform float scaleFactor;
|
||||
|
||||
out float vs_screenSpaceDepth;
|
||||
out vec4 vs_positionViewSpace;
|
||||
|
||||
void main() {
|
||||
vec4 positionClipSpace = vec4(modelViewProjectionTransform * dvec4(in_position, 1.0));
|
||||
dvec4 positionViewSpace = modelViewTransform * dvec4(in_position, 1.0);
|
||||
vec4 positionClipSpace = vec4(projectionTransform * positionViewSpace);
|
||||
vec4 positionScreenSpace = vec4(z_normalization(positionClipSpace));
|
||||
|
||||
vs_screenSpaceDepth = positionScreenSpace.w;
|
||||
vs_screenSpaceDepth = positionScreenSpace.w;
|
||||
vs_positionViewSpace = vec4(positionViewSpace);
|
||||
|
||||
gl_Position = positionScreenSpace;
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ in vec2 vs_st;
|
||||
uniform sampler2D galaxyTexture;
|
||||
//uniform bool additiveBlending;
|
||||
uniform float alphaValue;
|
||||
uniform float fadeInValue;
|
||||
|
||||
|
||||
Fragment getFragment() {
|
||||
@@ -44,6 +45,8 @@ Fragment getFragment() {
|
||||
frag.color = texture(galaxyTexture, vs_st);
|
||||
frag.color *= alphaValue;
|
||||
|
||||
frag.color *= fadeInValue;
|
||||
|
||||
if (frag.color.a == 0.0) {
|
||||
discard;
|
||||
}
|
||||
@@ -52,8 +55,11 @@ Fragment getFragment() {
|
||||
// frag.blend = BLEND_MODE_ADDITIVE;
|
||||
// }
|
||||
|
||||
frag.color = texture(galaxyTexture, vs_st);
|
||||
//frag.color = texture(galaxyTexture, vs_st);
|
||||
frag.depth = vs_screenSpaceDepth;
|
||||
frag.gPosition = vec4(1e27, 1e27, 1e27, 1.0);
|
||||
frag.gOtherData = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
frag.gNormal = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
|
||||
return frag;
|
||||
}
|
||||
|
||||
@@ -47,6 +47,9 @@ Fragment getFragment() {
|
||||
|
||||
//frag.depth = gs_screenSpaceDepth;
|
||||
frag.depth = vs_screenSpaceDepth;
|
||||
frag.gPosition = vec4(1e27, 1e27, 1e27, 1.0);
|
||||
frag.gOtherData = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
frag.gNormal = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
|
||||
return frag;
|
||||
}
|
||||
|
||||
@@ -212,7 +212,7 @@ set(SHADER_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/pointglobe_fs.glsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/texturetilemapping.hglsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/tile.hglsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/tilefragcolor.hglsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/tilefragment.hglsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/tileheight.hglsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/tilevertexskirt.hglsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/globeshading.hglsl
|
||||
|
||||
@@ -166,4 +166,18 @@ glm::dvec3 Ellipsoid::cartesianPosition(const Geodetic3& geodetic3) const {
|
||||
return rSurface + geodetic3.height * normal;
|
||||
}
|
||||
|
||||
void Ellipsoid::setShadowConfigurationArray(
|
||||
const std::vector<Ellipsoid::ShadowConfiguration>& shadowConfArray)
|
||||
{
|
||||
_shadowConfArray = shadowConfArray;
|
||||
}
|
||||
|
||||
std::vector<Ellipsoid::ShadowConfiguration> Ellipsoid::shadowConfigurationArray() const {
|
||||
return _shadowConfArray;
|
||||
}
|
||||
|
||||
bool Ellipsoid::hasEclipseShadows() const {
|
||||
return !_shadowConfArray.empty();
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
|
||||
#include <ghoul/glm.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
/**
|
||||
@@ -43,6 +45,12 @@ namespace openspace::globebrowsing {
|
||||
*/
|
||||
class Ellipsoid {
|
||||
public:
|
||||
// Shadow configuration structure
|
||||
struct ShadowConfiguration {
|
||||
std::pair<std::string, double> source;
|
||||
std::pair<std::string, double> caster;
|
||||
};
|
||||
|
||||
/**
|
||||
* \param radii defines three radii for the Ellipsoid
|
||||
*/
|
||||
@@ -84,6 +92,12 @@ public:
|
||||
glm::dvec3 cartesianSurfacePosition(const Geodetic2& geodetic2) const;
|
||||
glm::dvec3 cartesianPosition(const Geodetic3& geodetic3) const;
|
||||
|
||||
void setShadowConfigurationArray(
|
||||
const std::vector<Ellipsoid::ShadowConfiguration>& shadowConfArray
|
||||
);
|
||||
std::vector<Ellipsoid::ShadowConfiguration> shadowConfigurationArray() const;
|
||||
bool hasEclipseShadows() const;
|
||||
|
||||
private:
|
||||
struct EllipsoidCache {
|
||||
glm::dvec3 _radiiSquared;
|
||||
@@ -97,6 +111,9 @@ private:
|
||||
void updateInternalCache();
|
||||
|
||||
glm::dvec3 _radii;
|
||||
|
||||
// Eclipse shadows conf
|
||||
std::vector<Ellipsoid::ShadowConfiguration> _shadowConfArray;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
@@ -29,11 +29,15 @@
|
||||
#include <modules/globebrowsing/globes/pointglobe.h>
|
||||
#include <modules/globebrowsing/rendering/layer/layermanager.h>
|
||||
|
||||
|
||||
namespace {
|
||||
const char* keyFrame = "Frame";
|
||||
const char* keyRadii = "Radii";
|
||||
const char* keySegmentsPerPatch = "SegmentsPerPatch";
|
||||
const char* keyLayers = "Layers";
|
||||
const char* keyShadowGroup = "ShadowGroup";
|
||||
const char* keyShadowSource = "Source";
|
||||
const char* keyShadowCaster = "Caster";
|
||||
|
||||
static const openspace::properties::Property::PropertyInfo SaveOrThrowInfo = {
|
||||
"SaveOrThrowCamera",
|
||||
@@ -131,6 +135,18 @@ namespace {
|
||||
"" // @TODO Missing documentation
|
||||
};
|
||||
|
||||
static const openspace::properties::Property::PropertyInfo EclipseInfo = {
|
||||
"Eclipse",
|
||||
"Eclipse",
|
||||
"Enables/Disable Eclipse shadows"
|
||||
};
|
||||
|
||||
static const openspace::properties::Property::PropertyInfo EclipseHardShadowsInfo = {
|
||||
"EclipseHardShadows",
|
||||
"Eclipse Hard Shadows",
|
||||
"Enables the rendering of eclipse shadows using hard shadows"
|
||||
};
|
||||
|
||||
static const openspace::properties::Property::PropertyInfo LodScaleFactorInfo = {
|
||||
"LodScaleFactor",
|
||||
"Level of Detail Scale Factor",
|
||||
@@ -175,6 +191,8 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary)
|
||||
BoolProperty(PerformShadingInfo, true),
|
||||
BoolProperty(AtmosphereInfo, false),
|
||||
BoolProperty(AccurateNormalsInfo, false),
|
||||
BoolProperty(EclipseInfo, false),
|
||||
BoolProperty(EclipseHardShadowsInfo, false),
|
||||
FloatProperty(LodScaleFactorInfo, 10.f, 1.f, 50.f),
|
||||
FloatProperty(CameraMinHeightInfo, 100.f, 0.f, 1000.f),
|
||||
FloatProperty(OrenNayarRoughnessInfo, 0.f, 0.f, 1.f)
|
||||
@@ -223,6 +241,8 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary)
|
||||
addProperty(_generalProperties.atmosphereEnabled);
|
||||
addProperty(_generalProperties.performShading);
|
||||
addProperty(_generalProperties.useAccurateNormals);
|
||||
addProperty(_generalProperties.eclipseShadowsEnabled);
|
||||
addProperty(_generalProperties.eclipseHardShadows);
|
||||
addProperty(_generalProperties.lodScaleFactor);
|
||||
addProperty(_generalProperties.cameraMinHeight);
|
||||
addProperty(_generalProperties.orenNayarRoughness);
|
||||
@@ -248,6 +268,8 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary)
|
||||
};
|
||||
_generalProperties.atmosphereEnabled.onChange(notifyShaderRecompilation);
|
||||
_generalProperties.useAccurateNormals.onChange(notifyShaderRecompilation);
|
||||
_generalProperties.eclipseShadowsEnabled.onChange(notifyShaderRecompilation);
|
||||
_generalProperties.eclipseHardShadows.onChange(notifyShaderRecompilation);
|
||||
_generalProperties.performShading.onChange(notifyShaderRecompilation);
|
||||
_debugProperties.showChunkEdges.onChange(notifyShaderRecompilation);
|
||||
_debugProperties.showHeightResolution.onChange(notifyShaderRecompilation);
|
||||
@@ -259,6 +281,78 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary)
|
||||
addPropertySubOwner(_layerManager.get());
|
||||
//addPropertySubOwner(_pointGlobe.get());
|
||||
|
||||
//================================================================
|
||||
//======== Reads Shadow (Eclipses) Entries in mod file ===========
|
||||
//================================================================
|
||||
ghoul::Dictionary shadowDictionary;
|
||||
bool success = dictionary.getValue(keyShadowGroup, shadowDictionary);
|
||||
bool disableShadows = false;
|
||||
if (success) {
|
||||
std::vector<std::pair<std::string, double>> sourceArray;
|
||||
unsigned int sourceCounter = 1;
|
||||
while (success) {
|
||||
std::string sourceName;
|
||||
success = shadowDictionary.getValue(keyShadowSource +
|
||||
std::to_string(sourceCounter) + ".Name", sourceName);
|
||||
if (success) {
|
||||
double sourceRadius;
|
||||
success = shadowDictionary.getValue(keyShadowSource +
|
||||
std::to_string(sourceCounter) + ".Radius", sourceRadius);
|
||||
if (success) {
|
||||
sourceArray.emplace_back(sourceName, sourceRadius);
|
||||
}
|
||||
else {
|
||||
//LWARNING("No Radius value expecified for Shadow Source Name "
|
||||
// << sourceName << " from " << name
|
||||
// << " planet.\nDisabling shadows for this planet.");
|
||||
disableShadows = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
sourceCounter++;
|
||||
}
|
||||
|
||||
if (!disableShadows && !sourceArray.empty()) {
|
||||
success = true;
|
||||
std::vector<std::pair<std::string, double>> casterArray;
|
||||
unsigned int casterCounter = 1;
|
||||
while (success) {
|
||||
std::string casterName;
|
||||
success = shadowDictionary.getValue(keyShadowCaster +
|
||||
std::to_string(casterCounter) + ".Name", casterName);
|
||||
if (success) {
|
||||
double casterRadius;
|
||||
success = shadowDictionary.getValue(keyShadowCaster +
|
||||
std::to_string(casterCounter) + ".Radius", casterRadius);
|
||||
if (success) {
|
||||
casterArray.emplace_back(casterName, casterRadius);
|
||||
}
|
||||
else {
|
||||
//LWARNING("No Radius value expecified for Shadow Caster Name "
|
||||
// << casterName << " from " << name
|
||||
// << " planet.\nDisabling shadows for this planet.");
|
||||
disableShadows = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
casterCounter++;
|
||||
}
|
||||
|
||||
std::vector<Ellipsoid::ShadowConfiguration> shadowConfArray;
|
||||
if (!disableShadows && (!sourceArray.empty() && !casterArray.empty())) {
|
||||
for (const auto & source : sourceArray) {
|
||||
for (const auto & caster : casterArray) {
|
||||
Ellipsoid::ShadowConfiguration sc;
|
||||
sc.source = source;
|
||||
sc.caster = caster;
|
||||
shadowConfArray.push_back(sc);
|
||||
}
|
||||
}
|
||||
_ellipsoid.setShadowConfigurationArray(shadowConfArray);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RenderableGlobe::initializeGL() {
|
||||
@@ -283,7 +377,7 @@ bool RenderableGlobe::isReady() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
void RenderableGlobe::render(const RenderData& data, RendererTasks& tasks) {
|
||||
void RenderableGlobe::render(const RenderData& data, RendererTasks& renderTask) {
|
||||
bool statsEnabled = _debugProperties.collectStats.value();
|
||||
_chunkedLodGlobe->stats.setEnabled(statsEnabled);
|
||||
|
||||
@@ -298,7 +392,7 @@ void RenderableGlobe::render(const RenderData& data, RendererTasks& tasks) {
|
||||
setSaveCamera(nullptr);
|
||||
}
|
||||
}
|
||||
_distanceSwitch.render(data, tasks);
|
||||
_distanceSwitch.render(data, renderTask);
|
||||
}
|
||||
if (_savedCamera != nullptr) {
|
||||
DebugRenderer::ref().renderCameraFrustum(data, *_savedCamera);
|
||||
|
||||
@@ -34,6 +34,12 @@
|
||||
#include <openspace/properties/scalar/intproperty.h>
|
||||
#include <openspace/properties/scalar/boolproperty.h>
|
||||
|
||||
#ifdef OPENSPACE_MODULE_ATMOSPHERE_ENABLED
|
||||
namespace openspace {
|
||||
class AtmosphereDeferredcaster;
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
class ChunkedLodGlobe;
|
||||
@@ -73,11 +79,24 @@ public:
|
||||
properties::BoolProperty performShading;
|
||||
properties::BoolProperty atmosphereEnabled;
|
||||
properties::BoolProperty useAccurateNormals;
|
||||
properties::BoolProperty eclipseShadowsEnabled;
|
||||
properties::BoolProperty eclipseHardShadows;
|
||||
properties::FloatProperty lodScaleFactor;
|
||||
properties::FloatProperty cameraMinHeight;
|
||||
properties::FloatProperty orenNayarRoughness;
|
||||
};
|
||||
|
||||
// Shadow structure
|
||||
struct ShadowRenderingStruct {
|
||||
double xu,
|
||||
xp;
|
||||
double rs,
|
||||
rc;
|
||||
glm::dvec3 sourceCasterVec;
|
||||
glm::dvec3 casterPositionVec;
|
||||
bool isShadowing;
|
||||
};
|
||||
|
||||
RenderableGlobe(const ghoul::Dictionary& dictionary);
|
||||
~RenderableGlobe() = default;
|
||||
|
||||
|
||||
@@ -32,6 +32,11 @@
|
||||
#include <modules/globebrowsing/rendering/layer/layergroup.h>
|
||||
#include <modules/globebrowsing/tile/rawtiledatareader/rawtiledatareader.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
#include <openspace/util/spicemanager.h>
|
||||
|
||||
namespace {
|
||||
const double KM_TO_M = 1000.0;
|
||||
}
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
@@ -111,6 +116,93 @@ ghoul::opengl::ProgramObject* ChunkRenderer::getActivatedProgramWithTileData(
|
||||
return programObject;
|
||||
}
|
||||
|
||||
void ChunkRenderer::calculateEclipseShadows(const Chunk& chunk, ghoul::opengl::ProgramObject* programObject,
|
||||
const RenderData& data) {
|
||||
// Shadow calculations..
|
||||
if (chunk.owner().ellipsoid().hasEclipseShadows()) {
|
||||
std::vector<RenderableGlobe::ShadowRenderingStruct> shadowDataArray;
|
||||
std::vector<Ellipsoid::ShadowConfiguration> shadowConfArray = chunk.owner().ellipsoid().shadowConfigurationArray();
|
||||
shadowDataArray.reserve(shadowConfArray.size());
|
||||
double lt;
|
||||
for (const auto & shadowConf : shadowConfArray) {
|
||||
// TO REMEMBER: all distances and lengths in world coordinates are in meters!!! We need to move this to view space...
|
||||
// Getting source and caster:
|
||||
glm::dvec3 sourcePos = SpiceManager::ref().targetPosition(shadowConf.source.first, "SUN", "GALACTIC", {},
|
||||
data.time.j2000Seconds(), lt);
|
||||
sourcePos *= KM_TO_M; // converting to meters
|
||||
glm::dvec3 casterPos = SpiceManager::ref().targetPosition(shadowConf.caster.first, "SUN", "GALACTIC", {},
|
||||
data.time.j2000Seconds(), lt);
|
||||
casterPos *= KM_TO_M; // converting to meters
|
||||
psc caster_pos = PowerScaledCoordinate::CreatePowerScaledCoordinate(casterPos.x, casterPos.y, casterPos.z);
|
||||
|
||||
|
||||
// First we determine if the caster is shadowing the current planet (all calculations in World Coordinates):
|
||||
glm::dvec3 planetCasterVec = casterPos - data.position.dvec3();
|
||||
glm::dvec3 sourceCasterVec = casterPos - sourcePos;
|
||||
double sc_length = glm::length(sourceCasterVec);
|
||||
glm::dvec3 planetCaster_proj = (glm::dot(planetCasterVec, sourceCasterVec) / (sc_length*sc_length)) * sourceCasterVec;
|
||||
double d_test = glm::length(planetCasterVec - planetCaster_proj);
|
||||
double xp_test = shadowConf.caster.second * sc_length / (shadowConf.source.second + shadowConf.caster.second);
|
||||
double rp_test = shadowConf.caster.second * (glm::length(planetCaster_proj) + xp_test) / xp_test;
|
||||
|
||||
glm::dvec3 sunPos = SpiceManager::ref().targetPosition("SUN", "SUN", "GALACTIC", {}, data.time.j2000Seconds(), lt);
|
||||
double casterDistSun = glm::length(casterPos - sunPos);
|
||||
double planetDistSun = glm::length(data.position.dvec3() - sunPos);
|
||||
|
||||
RenderableGlobe::ShadowRenderingStruct shadowData;
|
||||
shadowData.isShadowing = false;
|
||||
|
||||
// Eclipse shadows considers planets and moons as spheres
|
||||
if (((d_test - rp_test) < (chunk.owner().ellipsoid().radii().x * KM_TO_M)) &&
|
||||
(casterDistSun < planetDistSun)) {
|
||||
// The current caster is shadowing the current planet
|
||||
shadowData.isShadowing = true;
|
||||
shadowData.rs = shadowConf.source.second;
|
||||
shadowData.rc = shadowConf.caster.second;
|
||||
shadowData.sourceCasterVec = glm::normalize(sourceCasterVec);
|
||||
shadowData.xp = xp_test;
|
||||
shadowData.xu = shadowData.rc * sc_length / (shadowData.rs - shadowData.rc);
|
||||
shadowData.casterPositionVec = casterPos;
|
||||
}
|
||||
shadowDataArray.push_back(shadowData);
|
||||
}
|
||||
|
||||
const std::string uniformVarName("shadowDataArray[");
|
||||
unsigned int counter = 0;
|
||||
for (const auto & sd : shadowDataArray) {
|
||||
std::stringstream ss;
|
||||
ss << uniformVarName << counter << "].isShadowing";
|
||||
programObject->setUniform(ss.str(), sd.isShadowing);
|
||||
if (sd.isShadowing) {
|
||||
ss.str(std::string());
|
||||
ss << uniformVarName << counter << "].xp";
|
||||
programObject->setUniform(ss.str(), sd.xp);
|
||||
ss.str(std::string());
|
||||
ss << uniformVarName << counter << "].xu";
|
||||
programObject->setUniform(ss.str(), sd.xu);
|
||||
/*ss.str(std::string());
|
||||
ss << uniformVarName << counter << "].rs";
|
||||
programObject->setUniform(ss.str(), sd.rs);*/
|
||||
ss.str(std::string());
|
||||
ss << uniformVarName << counter << "].rc";
|
||||
programObject->setUniform(ss.str(), sd.rc);
|
||||
ss.str(std::string());
|
||||
ss << uniformVarName << counter << "].sourceCasterVec";
|
||||
programObject->setUniform(ss.str(), sd.sourceCasterVec);
|
||||
ss.str(std::string());
|
||||
ss << uniformVarName << counter << "].casterPositionVec";
|
||||
programObject->setUniform(ss.str(), sd.casterPositionVec);
|
||||
}
|
||||
counter++;
|
||||
}
|
||||
|
||||
programObject->setUniform("inverseViewTransform", glm::inverse(data.camera.combinedViewMatrix()));
|
||||
programObject->setUniform("modelTransform", chunk.owner().modelTransform());
|
||||
programObject->setUniform("hardShadows", chunk.owner().generalProperties().eclipseHardShadows);
|
||||
programObject->setUniform("calculateEclipseShadows", true);
|
||||
}
|
||||
}
|
||||
|
||||
void ChunkRenderer::setCommonUniforms(ghoul::opengl::ProgramObject& programObject,
|
||||
const Chunk& chunk, const RenderData& data)
|
||||
{
|
||||
@@ -177,6 +269,12 @@ void ChunkRenderer::setCommonUniforms(ghoul::opengl::ProgramObject& programObjec
|
||||
programObject.setUniform("deltaPhi0", glm::length(deltaPhi0));
|
||||
programObject.setUniform("deltaPhi1", glm::length(deltaPhi1));
|
||||
programObject.setUniform("tileDelta", tileDelta);
|
||||
|
||||
// This should not be needed once the light calculations for the atmosphere
|
||||
// is performed in view space..
|
||||
programObject.setUniform("invViewModelTransform",
|
||||
glm::inverse(glm::mat4(data.camera.combinedViewMatrix()) *
|
||||
glm::mat4(chunk.owner().modelTransform())));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,7 +288,7 @@ void ChunkRenderer::renderChunkGlobally(const Chunk& chunk, const RenderData& da
|
||||
}
|
||||
|
||||
const Ellipsoid& ellipsoid = chunk.owner().ellipsoid();
|
||||
|
||||
|
||||
if (_layerManager->hasAnyBlendingLayersEnabled()) {
|
||||
// Calculations are done in the reference frame of the globe. Hence, the
|
||||
// camera position needs to be transformed with the inverse model matrix
|
||||
@@ -220,6 +318,7 @@ void ChunkRenderer::renderChunkGlobally(const Chunk& chunk, const RenderData& da
|
||||
"modelViewProjectionTransform", modelViewProjectionTransform);
|
||||
programObject->setUniform("minLatLon", glm::vec2(swCorner.toLonLatVec2()));
|
||||
programObject->setUniform("lonLatScalingFactor", glm::vec2(patchSize.toLonLatVec2()));
|
||||
// Ellipsoid Radius (Model Space)
|
||||
programObject->setUniform("radiiSquared", glm::vec3(ellipsoid.radiiSquared()));
|
||||
|
||||
if (_layerManager->layerGroup(
|
||||
@@ -242,6 +341,10 @@ void ChunkRenderer::renderChunkGlobally(const Chunk& chunk, const RenderData& da
|
||||
|
||||
setCommonUniforms(*programObject, chunk, data);
|
||||
|
||||
if (chunk.owner().ellipsoid().hasEclipseShadows()) {
|
||||
calculateEclipseShadows(chunk, programObject, data);
|
||||
}
|
||||
|
||||
// OpenGL rendering settings
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_CULL_FACE);
|
||||
@@ -282,20 +385,24 @@ void ChunkRenderer::renderChunkLocally(const Chunk& chunk, const RenderData& dat
|
||||
}
|
||||
|
||||
// Calculate other uniform variables needed for rendering
|
||||
// Send the matrix inverse to the fragment for the global and local shader (JCC)
|
||||
dmat4 modelTransform = chunk.owner().modelTransform();
|
||||
dmat4 viewTransform = data.camera.combinedViewMatrix();
|
||||
dmat4 modelViewTransform = viewTransform * modelTransform;
|
||||
|
||||
std::vector<std::string> cornerNames = { "p01", "p11", "p00", "p10" };
|
||||
std::vector<glm::dvec3> cornersCameraSpace(4);
|
||||
std::vector<glm::dvec3> cornersModelSpace(4);
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
Quad q = static_cast<Quad>(i);
|
||||
Geodetic2 corner = chunk.surfacePatch().getCorner(q);
|
||||
glm::dvec3 cornerModelSpace = ellipsoid.cartesianSurfacePosition(corner);
|
||||
cornersModelSpace[i] = cornerModelSpace;
|
||||
glm::dvec3 cornerCameraSpace =
|
||||
glm::dvec3(modelViewTransform * glm::dvec4(cornerModelSpace, 1));
|
||||
cornersCameraSpace[i] = cornerCameraSpace;
|
||||
programObject->setUniform(cornerNames[i], vec3(cornerCameraSpace));
|
||||
|
||||
}
|
||||
|
||||
// TODO: Patch normal can be calculated for all corners and then linearly
|
||||
@@ -306,6 +413,15 @@ void ChunkRenderer::renderChunkLocally(const Chunk& chunk, const RenderData& dat
|
||||
cornersCameraSpace[Quad::NORTH_EAST] -
|
||||
cornersCameraSpace[Quad::SOUTH_WEST]));
|
||||
|
||||
// In order to improve performance, lets use the normal in object space (model space)
|
||||
// for deferred rendering.
|
||||
vec3 patchNormalModelSpace = normalize(
|
||||
cross(cornersModelSpace[Quad::SOUTH_EAST] -
|
||||
cornersModelSpace[Quad::SOUTH_WEST],
|
||||
cornersModelSpace[Quad::NORTH_EAST] -
|
||||
cornersModelSpace[Quad::SOUTH_WEST]));
|
||||
|
||||
programObject->setUniform("patchNormalModelSpace", patchNormalModelSpace);
|
||||
programObject->setUniform("patchNormalCameraSpace", patchNormalCameraSpace);
|
||||
programObject->setUniform(
|
||||
"projectionTransform",
|
||||
@@ -319,6 +435,10 @@ void ChunkRenderer::renderChunkLocally(const Chunk& chunk, const RenderData& dat
|
||||
}
|
||||
|
||||
setCommonUniforms(*programObject, chunk, data);
|
||||
|
||||
if (chunk.owner().ellipsoid().hasEclipseShadows()) {
|
||||
calculateEclipseShadows(chunk, programObject, data);
|
||||
}
|
||||
|
||||
// OpenGL rendering settings
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
@@ -83,6 +83,9 @@ private:
|
||||
std::shared_ptr<GPULayerManager> gpuLayerManager,
|
||||
const Chunk& chunk);
|
||||
|
||||
void calculateEclipseShadows(const Chunk& chunk, ghoul::opengl::ProgramObject* programObject,
|
||||
const RenderData& data);
|
||||
|
||||
void setCommonUniforms(ghoul::opengl::ProgramObject& programObject,
|
||||
const Chunk& chunk, const RenderData& data);
|
||||
|
||||
|
||||
@@ -112,6 +112,8 @@ LayerShaderManager::LayerShaderPreprocessingData
|
||||
);
|
||||
pairs.emplace_back("useAtmosphere", std::to_string(generalProps.atmosphereEnabled));
|
||||
pairs.emplace_back("performShading", std::to_string(generalProps.performShading));
|
||||
pairs.emplace_back("useEclipseShadows", std::to_string(generalProps.eclipseShadowsEnabled));
|
||||
pairs.emplace_back("useEclipseHardShadows", std::to_string(generalProps.eclipseHardShadows));
|
||||
pairs.emplace_back("showChunkEdges", std::to_string(debugProps.showChunkEdges));
|
||||
pairs.emplace_back("showHeightResolution",
|
||||
std::to_string(debugProps.showHeightResolution)
|
||||
@@ -234,6 +236,7 @@ void LayerShaderManager::recompileShaderProgram(
|
||||
ghoul_assert(_programObject != nullptr, "Failed to initialize programObject!");
|
||||
using IgnoreError = ghoul::opengl::ProgramObject::ProgramObject::IgnoreError;
|
||||
_programObject->setIgnoreSubroutineUniformLocationError(IgnoreError::Yes);
|
||||
_programObject->setIgnoreUniformLocationError(IgnoreError::Yes);
|
||||
_updatedOnLastCall = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,17 +22,16 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <${MODULE_GLOBEBROWSING}/shaders/tilefragcolor.hglsl>
|
||||
#include <${MODULE_GLOBEBROWSING}/shaders/tilefragment.hglsl>
|
||||
#include "fragment.glsl"
|
||||
|
||||
Fragment getFragment() {
|
||||
Fragment frag;
|
||||
frag.color = getTileFragColor();
|
||||
frag = getTileFragment();
|
||||
|
||||
#if SHOW_CHUNK_EDGES
|
||||
frag.color += patchBorderOverlay(fs_uv, vec3(0.0, 1.0, 0.0), 0.02);
|
||||
#endif // SHOW_CHUNK_EDGES
|
||||
|
||||
frag.depth = fs_position.w;
|
||||
|
||||
return frag;
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ layout(location = 1) in vec2 in_uv;
|
||||
|
||||
out vec2 fs_uv;
|
||||
out vec4 fs_position;
|
||||
out vec3 fs_normal;
|
||||
out vec3 ellipsoidNormalCameraSpace;
|
||||
out LevelWeights levelWeights;
|
||||
out vec3 positionCameraSpace;
|
||||
@@ -44,6 +45,11 @@ out vec3 ellipsoidTangentThetaCameraSpace;
|
||||
out vec3 ellipsoidTangentPhiCameraSpace;
|
||||
#endif //USE_ACCURATE_NORMALS
|
||||
|
||||
#if USE_ECLIPSE_SHADOWS
|
||||
out vec3 positionWorldSpace;
|
||||
uniform dmat4 modelTransform;
|
||||
#endif
|
||||
|
||||
uniform mat4 modelViewProjectionTransform;
|
||||
uniform mat4 modelViewTransform;
|
||||
uniform vec3 radiiSquared;
|
||||
@@ -109,12 +115,17 @@ void main() {
|
||||
// Add the height in the direction of the normal
|
||||
pair.position += pair.normal * height;
|
||||
vec4 positionClippingSpace =
|
||||
modelViewProjectionTransform * vec4(pair.position, 1);
|
||||
modelViewProjectionTransform * vec4(pair.position, 1.0);
|
||||
|
||||
// Write output
|
||||
fs_uv = in_uv;
|
||||
fs_position = z_normalization(positionClippingSpace);
|
||||
gl_Position = fs_position;
|
||||
ellipsoidNormalCameraSpace = mat3(modelViewTransform) * pair.normal;
|
||||
positionCameraSpace = vec3(modelViewTransform * vec4(pair.position, 1));
|
||||
fs_normal = pair.normal;
|
||||
positionCameraSpace = vec3(modelViewTransform * vec4(pair.position, 1.0));
|
||||
|
||||
#if USE_ECLIPSE_SHADOWS
|
||||
positionWorldSpace = vec3(modelTransform * dvec4(pair.position, 1.0));
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -22,17 +22,16 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <${MODULE_GLOBEBROWSING}/shaders/tilefragcolor.hglsl>
|
||||
#include <${MODULE_GLOBEBROWSING}/shaders/tilefragment.hglsl>
|
||||
#include "fragment.glsl"
|
||||
|
||||
Fragment getFragment() {
|
||||
Fragment frag;
|
||||
frag.color = getTileFragColor();
|
||||
frag = getTileFragment();
|
||||
|
||||
#if SHOW_CHUNK_EDGES
|
||||
frag.color += patchBorderOverlay(fs_uv, vec3(1,0,0), 0.005);
|
||||
#endif // SHOW_CHUNK_EDGES
|
||||
|
||||
frag.depth = fs_position.w;
|
||||
return frag;
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ layout(location = 1) in vec2 in_uv;
|
||||
|
||||
out vec2 fs_uv;
|
||||
out vec4 fs_position;
|
||||
out vec3 fs_normal;
|
||||
out vec3 ellipsoidNormalCameraSpace;
|
||||
out LevelWeights levelWeights;
|
||||
out vec3 positionCameraSpace;
|
||||
@@ -44,6 +45,11 @@ out vec3 ellipsoidTangentThetaCameraSpace;
|
||||
out vec3 ellipsoidTangentPhiCameraSpace;
|
||||
#endif // USE_ACCURATE_NORMALS
|
||||
|
||||
#if USE_ECLIPSE_SHADOWS
|
||||
out vec3 positionWorldSpace;
|
||||
uniform dmat4 inverseViewTransform;
|
||||
#endif
|
||||
|
||||
uniform mat4 projectionTransform;
|
||||
// Input points in camera space
|
||||
uniform vec3 p00;
|
||||
@@ -51,12 +57,12 @@ uniform vec3 p10;
|
||||
uniform vec3 p01;
|
||||
uniform vec3 p11;
|
||||
uniform vec3 patchNormalCameraSpace;
|
||||
uniform vec3 patchNormalModelSpace;
|
||||
uniform float chunkMinHeight;
|
||||
|
||||
uniform float distanceScaleFactor;
|
||||
uniform int chunkLevel;
|
||||
|
||||
|
||||
vec3 bilinearInterpolation(vec2 uv) {
|
||||
vec3 p0 = (1 - uv.x) * p00 + uv.x * p10;
|
||||
vec3 p1 = (1 - uv.x) * p01 + uv.x * p11;
|
||||
@@ -101,5 +107,10 @@ void main() {
|
||||
fs_position = z_normalization(positionClippingSpace);
|
||||
gl_Position = fs_position;
|
||||
ellipsoidNormalCameraSpace = patchNormalCameraSpace;
|
||||
fs_normal = patchNormalModelSpace;
|
||||
positionCameraSpace = p;
|
||||
|
||||
#if USE_ECLIPSE_SHADOWS
|
||||
positionWorldSpace = vec3(inverseViewTransform * dvec4(p, 1.0));
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -61,6 +61,8 @@
|
||||
#define USE_ATMOSPHERE #{useAtmosphere}
|
||||
#define USE_ACCURATE_NORMALS #{useAccurateNormals}
|
||||
#define PERFORM_SHADING #{performShading}
|
||||
#define USE_ECLIPSE_SHADOWS #{useEclipseShadows}
|
||||
#define USE_ECLIPSE_HARD_SHADOWS #{useEclipseHardShadows}
|
||||
#define SHOW_CHUNK_EDGES #{showChunkEdges}
|
||||
#define SHOW_HEIGHT_RESOLUTION #{showHeightResolution}
|
||||
#define SHOW_HEIGHT_INTENSITIES #{showHeightIntensities}
|
||||
@@ -321,7 +323,7 @@ vec4 calculateNight(vec4 currentColor, vec2 uv, LevelWeights levelWeights,
|
||||
|
||||
vec3 n = normalize(ellipsoidNormalCameraSpace);
|
||||
vec3 l = lightDirectionCameraSpace;
|
||||
float cosineFactor = clamp(dot(l, normalize(n + 0.15 * l)) * 3 , 0, 1);
|
||||
float cosineFactor = clamp(dot(l, normalize(n + 0.20 * l)) * 3 , 0, 1);
|
||||
|
||||
#for i in 0..#{lastLayerIndexNightLayers}
|
||||
{
|
||||
@@ -390,7 +392,8 @@ vec4 calculateOverlay(vec4 currentColor, vec2 uv, LevelWeights levelWeights,
|
||||
vec4 calculateWater(vec4 currentColor, vec2 uv, LevelWeights levelWeights,
|
||||
Layer WaterMasks[NUMLAYERS_WATERMASK],
|
||||
vec3 ellipsoidNormalCameraSpace,
|
||||
vec3 lightDirectionCameraSpace, vec3 positionCameraSpace)
|
||||
vec3 lightDirectionCameraSpace, vec3 positionCameraSpace,
|
||||
out float reflectance)
|
||||
{
|
||||
vec4 waterColor = vec4(0.0);
|
||||
|
||||
@@ -422,8 +425,10 @@ vec4 calculateWater(vec4 currentColor, vec2 uv, LevelWeights levelWeights,
|
||||
|
||||
vec3 specularTotal = specularColor * cosineFactor * specularIntensity * waterColor.a;
|
||||
|
||||
reflectance = waterColor.a;
|
||||
//return blendNormal(currentColor, waterColor);
|
||||
return currentColor + vec4(specularTotal, 1);
|
||||
//return currentColor + vec4(specularTotal, 1);
|
||||
return currentColor;
|
||||
}
|
||||
|
||||
#endif // TEXTURETILEMAPPING_HGLSL
|
||||
|
||||
+129
-28
@@ -29,6 +29,7 @@
|
||||
#include <${MODULE_GLOBEBROWSING}/shaders/texturetilemapping.hglsl>
|
||||
#include <${MODULE_GLOBEBROWSING}/shaders/tileheight.hglsl>
|
||||
#include "PowerScaling/powerScaling_fs.hglsl"
|
||||
#include "fragment.glsl"
|
||||
|
||||
// Below are all the tiles that are used for contributing the actual fragment color
|
||||
|
||||
@@ -46,6 +47,7 @@ uniform Layer Overlays[NUMLAYERS_OVERLAY];
|
||||
|
||||
#if USE_WATERMASK
|
||||
uniform Layer WaterMasks[NUMLAYERS_WATERMASK];
|
||||
float waterReflectance = 0.0;
|
||||
#endif // USE_WATERMASK
|
||||
|
||||
#if SHOW_HEIGHT_RESOLUTION
|
||||
@@ -64,7 +66,77 @@ uniform vec3 lightDirectionCameraSpace;
|
||||
uniform float orenNayarRoughness;
|
||||
#endif
|
||||
|
||||
#if USE_ECLIPSE_SHADOWS
|
||||
in vec3 positionWorldSpace;
|
||||
|
||||
/*******************************************************************************
|
||||
***** ALL CALCULATIONS FOR ECLIPSE ARE IN METERS AND IN WORLD SPACE SYSTEM ****
|
||||
*******************************************************************************/
|
||||
// JCC: Remove and use dictionary to
|
||||
// decides the number of shadows
|
||||
const uint numberOfShadows = 1;
|
||||
|
||||
struct ShadowRenderingStruct {
|
||||
double xu, xp;
|
||||
double rs, rc;
|
||||
dvec3 sourceCasterVec;
|
||||
dvec3 casterPositionVec;
|
||||
bool isShadowing;
|
||||
};
|
||||
|
||||
// Eclipse shadow data
|
||||
// JCC: Remove and use dictionary to
|
||||
// decides the number of shadows
|
||||
uniform ShadowRenderingStruct shadowDataArray[numberOfShadows];
|
||||
uniform int shadows;
|
||||
uniform bool hardShadows;
|
||||
|
||||
vec4 butterworthFunc(const float d, const float r, const float n) {
|
||||
return vec4(vec3(sqrt(r/(r + pow(d, 2*n)))), 1.0);
|
||||
}
|
||||
|
||||
vec4 calcShadow(const ShadowRenderingStruct shadowInfoArray[numberOfShadows], const dvec3 position,
|
||||
const bool ground) {
|
||||
if (shadowInfoArray[0].isShadowing) {
|
||||
dvec3 pc = shadowInfoArray[0].casterPositionVec - position;
|
||||
dvec3 sc_norm = shadowInfoArray[0].sourceCasterVec;
|
||||
dvec3 pc_proj = dot(pc, sc_norm) * sc_norm;
|
||||
dvec3 d = pc - pc_proj;
|
||||
|
||||
float length_d = float(length(d));
|
||||
double length_pc_proj = length(pc_proj);
|
||||
|
||||
float r_p_pi = float(shadowInfoArray[0].rc * (length_pc_proj + shadowInfoArray[0].xp) / shadowInfoArray[0].xp);
|
||||
float r_u_pi = float(shadowInfoArray[0].rc * (shadowInfoArray[0].xu - length_pc_proj) / shadowInfoArray[0].xu);
|
||||
|
||||
if ( length_d < r_u_pi ) { // umbra
|
||||
if (ground) {
|
||||
#if USE_ECLIPSE_HARD_SHADOWS
|
||||
return vec4(0.2, 0.2, 0.2, 1.0);
|
||||
#endif
|
||||
return butterworthFunc(length_d, r_u_pi, 4.0);
|
||||
}
|
||||
else {
|
||||
#if USE_ECLIPSE_HARD_SHADOWS
|
||||
return vec4(0.5, 0.5, 0.5, 1.0);
|
||||
#endif
|
||||
return vec4(vec3(length_d/r_p_pi), 1.0);
|
||||
}
|
||||
}
|
||||
else if ( length_d < r_p_pi ) {// penumbra
|
||||
#if USE_ECLIPSE_HARD_SHADOWS
|
||||
return vec4(0.5, 0.5, 0.5, 1.0);
|
||||
#endif
|
||||
return vec4(vec3(length_d/r_p_pi), 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
return vec4(1.0);
|
||||
}
|
||||
#endif
|
||||
|
||||
in vec4 fs_position;
|
||||
in vec3 fs_normal;
|
||||
in vec2 fs_uv;
|
||||
in vec3 ellipsoidNormalCameraSpace;
|
||||
in vec3 positionCameraSpace;
|
||||
@@ -72,6 +144,10 @@ in vec3 positionCameraSpace;
|
||||
#if USE_ACCURATE_NORMALS
|
||||
in vec3 ellipsoidTangentThetaCameraSpace;
|
||||
in vec3 ellipsoidTangentPhiCameraSpace;
|
||||
|
||||
// Once deferred light calculations are done in view space this can be removed
|
||||
// so that we only need one normal; in view space.
|
||||
uniform mat4 invViewModelTransform;
|
||||
#endif // USE_ACCURATE_NORMALS
|
||||
|
||||
// levelInterpolationParameter is used to interpolate between a tile and its parent tiles
|
||||
@@ -83,10 +159,12 @@ in LevelWeights levelWeights;
|
||||
* the local and global chunk rendering.
|
||||
*
|
||||
*/
|
||||
vec4 getTileFragColor() {
|
||||
vec4 color = vec4(0.3, 0.3, 0.3, 1.0);
|
||||
Fragment getTileFragment() {
|
||||
Fragment frag;
|
||||
frag.color = vec4(0.3, 0.3, 0.3, 1.0);
|
||||
|
||||
vec3 normal = normalize(ellipsoidNormalCameraSpace);
|
||||
vec3 normalModelSpace = normalize(fs_normal);
|
||||
#if USE_ACCURATE_NORMALS
|
||||
normal = getTileNormal(
|
||||
fs_uv,
|
||||
@@ -95,11 +173,14 @@ vec4 getTileFragColor() {
|
||||
normalize(ellipsoidTangentThetaCameraSpace),
|
||||
normalize(ellipsoidTangentPhiCameraSpace)
|
||||
);
|
||||
// Once deferred light calculations are done in view space this can be removed
|
||||
// so that we only need one normal; in view space.
|
||||
normalModelSpace = mat3(invViewModelTransform) * normal;
|
||||
#endif /// USE_ACCURATE_NORMALS
|
||||
|
||||
#if USE_COLORTEXTURE
|
||||
color = calculateColor(
|
||||
color,
|
||||
frag.color = calculateColor(
|
||||
frag.color,
|
||||
fs_uv,
|
||||
levelWeights,
|
||||
ColorLayers
|
||||
@@ -107,21 +188,22 @@ vec4 getTileFragColor() {
|
||||
#endif // USE_COLORTEXTURE
|
||||
|
||||
#if USE_WATERMASK
|
||||
color = calculateWater(
|
||||
color,
|
||||
frag.color = calculateWater(
|
||||
frag.color,
|
||||
fs_uv,
|
||||
levelWeights,
|
||||
WaterMasks,
|
||||
normal,
|
||||
lightDirectionCameraSpace, // Should already be normalized
|
||||
positionCameraSpace
|
||||
positionCameraSpace,
|
||||
waterReflectance
|
||||
);
|
||||
|
||||
#endif // USE_WATERMASK
|
||||
|
||||
#if USE_NIGHTTEXTURE
|
||||
color = calculateNight(
|
||||
color,
|
||||
frag.color = calculateNight(
|
||||
frag.color,
|
||||
fs_uv,
|
||||
levelWeights,
|
||||
NightLayers,
|
||||
@@ -132,8 +214,8 @@ vec4 getTileFragColor() {
|
||||
#endif // USE_NIGHTTEXTURE
|
||||
|
||||
#if PERFORM_SHADING
|
||||
color = calculateShadedColor(
|
||||
color,
|
||||
frag.color = calculateShadedColor(
|
||||
frag.color,
|
||||
normal,
|
||||
lightDirectionCameraSpace,
|
||||
normalize(positionCameraSpace),
|
||||
@@ -143,10 +225,10 @@ vec4 getTileFragColor() {
|
||||
|
||||
#if USE_ATMOSPHERE
|
||||
// Temporary until the real atmosphere code is here
|
||||
//color = color + vec4(0.5,0.5,1,0) * 0.3; // Just to see something for now
|
||||
vec3 n = normalize(ellipsoidNormalCameraSpace);
|
||||
vec3 l = lightDirectionCameraSpace;
|
||||
vec3 c = normalize(positionCameraSpace);
|
||||
//frag.color = frag.color + vec4(0.5,0.5,1,0) * 0.3; // Just to see something for now
|
||||
const vec3 n = normalize(ellipsoidNormalCameraSpace);
|
||||
const vec3 l = lightDirectionCameraSpace;
|
||||
const vec3 c = normalize(positionCameraSpace);
|
||||
float cosFactor = 1 - clamp(dot(-n * 0.9, c), 0, 1);
|
||||
cosFactor *= 1.1;
|
||||
cosFactor -= 0.1;
|
||||
@@ -159,13 +241,17 @@ vec4 getTileFragColor() {
|
||||
//float cosFactorLight = max(dot(-lightDirectionCameraSpace, normalize(ellipsoidNormalCameraSpace)), 0);
|
||||
//vec3 r = reflect(l, n);
|
||||
//float scatteredLight = pow(clamp(dot(-r,c), 0, 1), 20);
|
||||
vec3 atmosphereColor = vec3(0.5, 0.5, 1.0) * 2.0;
|
||||
color += vec4(atmosphereColor,0) * cosFactor * cosFactorLight * 0.5;
|
||||
const vec3 atmosphereColor = vec3(0.5, 0.5, 1.0) * 2.0;
|
||||
frag.color += vec4(atmosphereColor,0) * cosFactor * cosFactorLight * 0.5;
|
||||
#endif // USE_ATMOSPHERE
|
||||
|
||||
#if USE_ECLIPSE_SHADOWS
|
||||
frag.color *= calcShadow(shadowDataArray, dvec3(positionWorldSpace), true);
|
||||
#endif
|
||||
|
||||
#if USE_OVERLAY
|
||||
color = calculateOverlay(
|
||||
color,
|
||||
frag.color = calculateOverlay(
|
||||
frag.color,
|
||||
fs_uv,
|
||||
levelWeights,
|
||||
Overlays
|
||||
@@ -173,25 +259,40 @@ vec4 getTileFragColor() {
|
||||
#endif // USE_OVERLAY
|
||||
|
||||
#if SHOW_HEIGHT_INTENSITIES
|
||||
color.r *= 0.1;
|
||||
color.g *= 0.1;
|
||||
color.b *= 0.1;
|
||||
frag.color.r *= 0.1;
|
||||
frag.color.g *= 0.1;
|
||||
frag.color.b *= 0.1;
|
||||
|
||||
float untransformedHeight = getUntransformedTileVertexHeight(fs_uv, levelWeights);
|
||||
float contourLine = fract(10.0 * untransformedHeight) > 0.98 ? 1.0 : 0.0;
|
||||
color.r += untransformedHeight;
|
||||
color.b = contourLine;
|
||||
frag.color.r += untransformedHeight;
|
||||
frag.color.b = contourLine;
|
||||
#endif
|
||||
|
||||
#if SHOW_HEIGHT_RESOLUTION
|
||||
color += 0.0001*calculateDebugColor(fs_uv, fs_position, vertexResolution);
|
||||
frag.color += 0.0001*calculateDebugColor(fs_uv, fs_position, vertexResolution);
|
||||
#if USE_HEIGHTMAP
|
||||
color.r = min(color.r, 0.8);
|
||||
color.r += tileResolution(fs_uv, HeightLayers[0].pile.chunkTile0) > 0.9 ? 1 : 0;
|
||||
frag.color.r = min(frag.color.r, 0.8);
|
||||
frag.color.r += tileResolution(fs_uv, HeightLayers[0].pile.chunkTile0) > 0.9 ? 1 : 0;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return color;
|
||||
// Other data
|
||||
#if USE_WATERMASK
|
||||
// Water reflectance is added to the G-Buffer.
|
||||
frag.gOtherData = vec4(waterReflectance, waterReflectance, waterReflectance, 1.0);
|
||||
#else
|
||||
frag.gOtherData = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
#endif
|
||||
// Normal is written Object Space.
|
||||
// Right now the only renderable using this info is the atm and,
|
||||
// because all calculation for light interactions are done in Object
|
||||
// Space, we avoid a new computation saving the normals in Object Space.
|
||||
frag.gNormal = vec4(normalModelSpace, 1.0);
|
||||
frag.gPosition = vec4(positionCameraSpace, 1.0); // in Camera Rig Space
|
||||
|
||||
frag.depth = fs_position.w;
|
||||
return frag;
|
||||
}
|
||||
|
||||
#endif ///TILE_FRAG_COLOR_HGLSL
|
||||
@@ -97,7 +97,9 @@ vec3 getTileNormal(vec2 uv, LevelWeights levelWeights, vec3 ellipsoidNormalCamer
|
||||
vec3 ellipsoidTangentThetaCameraSpace,
|
||||
vec3 ellipsoidTangentPhiCameraSpace)
|
||||
{
|
||||
#if USE_ACCURATE_NORMALS && USE_HEIGHTMAP
|
||||
vec3 normal = ellipsoidNormalCameraSpace;
|
||||
|
||||
#if USE_ACCURATE_NORMALS
|
||||
float deltaPhi = mix(deltaPhi0, deltaPhi1, uv.x);
|
||||
float deltaTheta = mix(deltaTheta0, deltaTheta1, uv.y);
|
||||
|
||||
@@ -111,10 +113,9 @@ vec3 getTileNormal(vec2 uv, LevelWeights levelWeights, vec3 ellipsoidNormalCamer
|
||||
vec3 diffTheta = deltaThetaVec + ellipsoidNormalCameraSpace * (height10 - height00);
|
||||
vec3 diffPhi = deltaPhiVec + ellipsoidNormalCameraSpace * (height01 - height00);
|
||||
|
||||
return normalize(cross(diffTheta, diffPhi));
|
||||
#else // USE_ACCURATE_NORMALS && USE_HEIGHTMAP
|
||||
return ellipsoidNormalCameraSpace;
|
||||
#endif
|
||||
normal = normalize(cross(diffTheta, diffPhi));
|
||||
#endif // USE_ACCURATE_NORMALS
|
||||
return normal;
|
||||
}
|
||||
|
||||
#endif // TILE_HEIGHT_HGLSL
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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 <modules/imgui/include/guiorigincomponent.h>
|
||||
|
||||
#include <modules/imgui/include/imgui_include.h>
|
||||
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/interaction/navigationhandler.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/scene/scene.h>
|
||||
|
||||
#include <ghoul/misc/assert.h>
|
||||
|
||||
namespace openspace::gui {
|
||||
|
||||
GuiOriginComponent::GuiOriginComponent()
|
||||
: GuiComponent("Origin")
|
||||
{}
|
||||
|
||||
void GuiOriginComponent::render() {
|
||||
SceneGraphNode* currentFocus = OsEng.navigationHandler().focusNode();
|
||||
|
||||
std::vector<SceneGraphNode*> nodes =
|
||||
OsEng.renderEngine().scene()->allSceneGraphNodes();
|
||||
|
||||
std::sort(
|
||||
nodes.begin(),
|
||||
nodes.end(),
|
||||
[](SceneGraphNode* lhs, SceneGraphNode* rhs) {
|
||||
return lhs->name() < rhs->name();
|
||||
}
|
||||
);
|
||||
std::string nodeNames = "";
|
||||
for (SceneGraphNode* n : nodes) {
|
||||
nodeNames += n->name() + '\0';
|
||||
}
|
||||
|
||||
auto iCurrentFocus = std::find(nodes.begin(), nodes.end(), currentFocus);
|
||||
if (!nodes.empty()) {
|
||||
// Only check if we found the current focus node if we have any nodes at all
|
||||
// only then it would be a real error
|
||||
ghoul_assert(iCurrentFocus != nodes.end(), "Focus node not found");
|
||||
}
|
||||
int currentPosition = static_cast<int>(std::distance(nodes.begin(), iCurrentFocus));
|
||||
|
||||
bool hasChanged = ImGui::Combo("Origin", ¤tPosition, nodeNames.c_str());
|
||||
if (hasChanged) {
|
||||
OsEng.scriptEngine().queueScript(
|
||||
"openspace.setPropertyValue('NavigationHandler.Origin', '" +
|
||||
nodes[currentPosition]->name() + "');",
|
||||
scripting::ScriptEngine::RemoteScripting::Yes
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace openspace::gui
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <openspace/scripting/scriptengine.h>
|
||||
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <glm/ext.hpp>
|
||||
#include <ghoul/misc/misc.h>
|
||||
|
||||
#include <glm/gtx/component_wise.hpp>
|
||||
|
||||
@@ -27,13 +27,12 @@
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/documentation/verifier.h>
|
||||
|
||||
#include <openspace/engine/configurationmanager.h>
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <modules/space/rendering/planetgeometry.h>
|
||||
#include <openspace/util/time.h>
|
||||
#include <openspace/util/spicemanager.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/misc/assert.h>
|
||||
@@ -46,15 +45,17 @@
|
||||
#include <memory>
|
||||
#include <fstream>
|
||||
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <math.h>
|
||||
|
||||
namespace {
|
||||
constexpr const char* KeyGeometry = "Geometry";
|
||||
constexpr const char* KeyRadius = "Radius";
|
||||
constexpr const char* KeyGeometry = "Geometry";
|
||||
constexpr const char* KeyRadius = "Radius";
|
||||
constexpr const char* _loggerCat = "RenderablePlanet";
|
||||
|
||||
constexpr const char* _loggerCat = "RenderablePlanet";
|
||||
|
||||
constexpr const char* keyShadowGroup = "Shadow_Group";
|
||||
constexpr const char* keyShadowSource = "Source";
|
||||
constexpr const char* keyShadowCaster = "Caster";
|
||||
constexpr const char* keyShadowGroup = "Shadow_Group";
|
||||
constexpr const char* keyShadowSource = "Source";
|
||||
constexpr const char* keyShadowCaster = "Caster";
|
||||
|
||||
static const openspace::properties::Property::PropertyInfo ColorTextureInfo = {
|
||||
"ColorTexture",
|
||||
@@ -173,6 +174,7 @@ RenderablePlanet::RenderablePlanet(const ghoul::Dictionary& dictionary)
|
||||
, _hasNightTexture(false)
|
||||
, _hasHeightTexture(false)
|
||||
, _shadowEnabled(false)
|
||||
, _time(0.f)
|
||||
{
|
||||
ghoul_precondition(
|
||||
dictionary.hasKeyAndValue<std::string>(SceneGraphNode::KeyName),
|
||||
@@ -257,26 +259,25 @@ RenderablePlanet::RenderablePlanet(const ghoul::Dictionary& dictionary)
|
||||
}
|
||||
addProperty(_performShading);
|
||||
|
||||
// Shadow data:
|
||||
//================================================================
|
||||
//======== Reads Shadow (Eclipses) Entries in mod file ===========
|
||||
//================================================================
|
||||
ghoul::Dictionary shadowDictionary;
|
||||
bool success = dictionary.getValue(keyShadowGroup, shadowDictionary);
|
||||
bool disableShadows = false;
|
||||
if (success) {
|
||||
std::vector< std::pair<std::string, float > > sourceArray;
|
||||
std::vector<std::pair<std::string, float>> sourceArray;
|
||||
unsigned int sourceCounter = 1;
|
||||
while (success) {
|
||||
std::string sourceName;
|
||||
std::stringstream ss;
|
||||
ss << keyShadowSource << sourceCounter << ".Name";
|
||||
success = shadowDictionary.getValue(ss.str(), sourceName);
|
||||
success = shadowDictionary.getValue(keyShadowSource +
|
||||
std::to_string(sourceCounter) + ".Name", sourceName);
|
||||
if (success) {
|
||||
float sourceRadius;
|
||||
ss.str(std::string());
|
||||
ss << keyShadowSource << sourceCounter << ".Radius";
|
||||
success = shadowDictionary.getValue(ss.str(), sourceRadius);
|
||||
success = shadowDictionary.getValue(keyShadowSource +
|
||||
std::to_string(sourceCounter) + ".Radius", sourceRadius);
|
||||
if (success) {
|
||||
sourceArray.push_back(std::pair< std::string, float>(
|
||||
sourceName, sourceRadius));
|
||||
sourceArray.emplace_back(sourceName, sourceRadius);
|
||||
}
|
||||
else {
|
||||
LWARNING(
|
||||
@@ -297,17 +298,14 @@ RenderablePlanet::RenderablePlanet(const ghoul::Dictionary& dictionary)
|
||||
unsigned int casterCounter = 1;
|
||||
while (success) {
|
||||
std::string casterName;
|
||||
std::stringstream ss;
|
||||
ss << keyShadowCaster << casterCounter << ".Name";
|
||||
success = shadowDictionary.getValue(ss.str(), casterName);
|
||||
success = shadowDictionary.getValue(keyShadowCaster +
|
||||
std::to_string(casterCounter) + ".Name", casterName);
|
||||
if (success) {
|
||||
float casterRadius;
|
||||
ss.str(std::string());
|
||||
ss << keyShadowCaster << casterCounter << ".Radius";
|
||||
success = shadowDictionary.getValue(ss.str(), casterRadius);
|
||||
success = shadowDictionary.getValue(keyShadowCaster +
|
||||
std::to_string(casterCounter) + ".Radius", casterRadius);
|
||||
if (success) {
|
||||
casterArray.push_back(std::pair< std::string, float>(
|
||||
casterName, casterRadius));
|
||||
casterArray.emplace_back(casterName, casterRadius);
|
||||
}
|
||||
else {
|
||||
LWARNING("No Radius value expecified for Shadow Caster Name "
|
||||
@@ -322,13 +320,14 @@ RenderablePlanet::RenderablePlanet(const ghoul::Dictionary& dictionary)
|
||||
}
|
||||
|
||||
if (!disableShadows && (!sourceArray.empty() && !casterArray.empty())) {
|
||||
for (const auto & source : sourceArray)
|
||||
for (const auto & caster : casterArray) {
|
||||
ShadowConf sc;
|
||||
for (auto & source : sourceArray) {
|
||||
for (auto & caster : casterArray) {
|
||||
ShadowConfiguration sc;
|
||||
sc.source = source;
|
||||
sc.caster = caster;
|
||||
_shadowConfArray.push_back(sc);
|
||||
}
|
||||
}
|
||||
_shadowEnabled = true;
|
||||
}
|
||||
}
|
||||
@@ -370,12 +369,14 @@ void RenderablePlanet::initializeGL() {
|
||||
absPath("${MODULE_SPACE}/shaders/renderableplanet_fs.glsl")
|
||||
);
|
||||
}
|
||||
|
||||
using IgnoreError = ghoul::opengl::ProgramObject::IgnoreError;
|
||||
_programObject->setIgnoreSubroutineUniformLocationError(IgnoreError::Yes);
|
||||
_programObject->setIgnoreUniformLocationError(IgnoreError::Yes);
|
||||
|
||||
_geometry->initialize(this);
|
||||
|
||||
// Deactivate any previously activated shader program.
|
||||
_programObject->deactivate();
|
||||
|
||||
loadTexture();
|
||||
@@ -406,14 +407,12 @@ bool RenderablePlanet::isReady() const {
|
||||
return ready;
|
||||
}
|
||||
|
||||
void RenderablePlanet::render(const RenderData& data, RendererTasks&) {
|
||||
// activate shader
|
||||
_programObject->activate();
|
||||
|
||||
glm::dmat4 RenderablePlanet::computeModelTransformMatrix(const openspace::TransformData & transformData) {
|
||||
// scale the planet to appropriate size since the planet is a unit sphere
|
||||
glm::dmat4 modelTransform =
|
||||
glm::translate(glm::dmat4(1.0), data.modelTransform.translation) * // Translation
|
||||
glm::dmat4(data.modelTransform.rotation) * // Spice rotation
|
||||
glm::scale(glm::dmat4(1.0), glm::dvec3(data.modelTransform.scale));
|
||||
glm::translate(glm::dmat4(1.0), transformData.translation) * // Translation
|
||||
glm::dmat4(transformData.rotation) * // Spice rotation
|
||||
glm::dmat4(glm::scale(glm::dmat4(1.0), glm::dvec3(transformData.scale)));
|
||||
|
||||
// scale the planet to appropriate size since the planet is a unit sphere
|
||||
//glm::mat4 transform = glm::mat4(1);
|
||||
@@ -433,14 +432,22 @@ void RenderablePlanet::render(const RenderData& data, RendererTasks&) {
|
||||
// glm::dmat4(1.0),
|
||||
// glm::radians(static_cast<double>(_rotation)), glm::dvec3(0, 1, 0)
|
||||
//);
|
||||
modelTransform = modelTransform * rot * roty /** rotProp*/;
|
||||
|
||||
return modelTransform = modelTransform * rot * roty /** rotProp*/;
|
||||
}
|
||||
|
||||
void RenderablePlanet::render(const RenderData& data, RendererTasks& renderTask) {
|
||||
// activate shader
|
||||
_programObject->activate();
|
||||
|
||||
glm::dmat4 modelTransform = computeModelTransformMatrix(data.modelTransform);
|
||||
|
||||
glm::dmat4 modelViewTransform = data.camera.combinedViewMatrix() * modelTransform;
|
||||
|
||||
|
||||
_programObject->setUniform("transparency", _alpha);
|
||||
_programObject->setUniform(
|
||||
"modelViewProjectionTransform",
|
||||
data.camera.projectionMatrix() * glm::mat4(modelViewTransform)
|
||||
_programObject->setUniform("modelViewTransform", modelViewTransform);
|
||||
_programObject->setUniform("modelViewProjectionTransform",
|
||||
data.camera.sgctInternal.projectionMatrix() * glm::mat4(modelViewTransform)
|
||||
);
|
||||
_programObject->setUniform("ModelTransform", glm::mat4(modelTransform));
|
||||
|
||||
@@ -459,7 +466,6 @@ void RenderablePlanet::render(const RenderData& data, RendererTasks&) {
|
||||
setPscUniforms(*_programObject.get(), data.camera, data.position);
|
||||
|
||||
_programObject->setUniform("_performShading", _performShading);
|
||||
|
||||
_programObject->setUniform("_hasHeightMap", _hasHeightTexture);
|
||||
_programObject->setUniform("_heightExaggeration", _heightExaggeration);
|
||||
|
||||
@@ -488,10 +494,11 @@ void RenderablePlanet::render(const RenderData& data, RendererTasks&) {
|
||||
glEnable(GL_CULL_FACE);
|
||||
glCullFace(GL_BACK);
|
||||
|
||||
// TODO: Move Calculations to VIEW SPACE (precision problems avoidance...)
|
||||
|
||||
//=============================================================================
|
||||
//============= Eclipse Shadow Calculations and Uniforms Loading ==============
|
||||
//=============================================================================
|
||||
// TODO: Move Calculations to VIEW SPACE (let's avoid precision problems...)
|
||||
double lt;
|
||||
// Shadow calculations..
|
||||
if (!_shadowConfArray.empty()) {
|
||||
std::vector<ShadowRenderingStruct> shadowDataArray;
|
||||
shadowDataArray.reserve(_shadowConfArray.size());
|
||||
@@ -546,8 +553,8 @@ void RenderablePlanet::render(const RenderData& data, RendererTasks&) {
|
||||
ShadowRenderingStruct shadowData;
|
||||
shadowData.isShadowing = false;
|
||||
|
||||
if (((d_test - rp_test) < _planetRadius) &&
|
||||
(casterDistSun < planetDistSun) ) {
|
||||
if ( ((d_test - rp_test) < _planetRadius) &&
|
||||
(casterDistSun < planetDistSun) ) {
|
||||
// The current caster is shadowing the current planet
|
||||
shadowData.isShadowing = true;
|
||||
shadowData.rs = shadowConf.source.second;
|
||||
@@ -602,12 +609,10 @@ void RenderablePlanet::render(const RenderData& data, RendererTasks&) {
|
||||
void RenderablePlanet::update(const UpdateData& data) {
|
||||
// set spice-orientation in accordance to timestamp
|
||||
_stateMatrix = data.modelTransform.rotation;
|
||||
//_stateMatrix = SpiceManager::ref().positionTransformMatrix(
|
||||
// _frame,
|
||||
// "GALACTIC",
|
||||
// data.time
|
||||
//);
|
||||
_time = data.time.j2000Seconds();
|
||||
|
||||
if (_programObject && _programObject->isDirty())
|
||||
_programObject->rebuildFromFile();
|
||||
}
|
||||
|
||||
void RenderablePlanet::loadTexture() {
|
||||
|
||||
@@ -46,26 +46,33 @@ namespace ghoul::opengl {
|
||||
|
||||
namespace openspace {
|
||||
|
||||
struct TransformData;
|
||||
|
||||
namespace planetgeometry {
|
||||
class PlanetGeometry;
|
||||
}
|
||||
|
||||
namespace documentation { struct Documentation; }
|
||||
namespace planetgeometry { class PlanetGeometry; }
|
||||
|
||||
class RenderablePlanet : public Renderable {
|
||||
public:
|
||||
// Shadow structure
|
||||
typedef struct {
|
||||
struct ShadowConfiguration {
|
||||
std::pair<std::string, float> source;
|
||||
std::pair<std::string, float> caster;
|
||||
} ShadowConf;
|
||||
};
|
||||
|
||||
struct ShadowRenderingStruct {
|
||||
float xu, xp;
|
||||
float rs, rc;
|
||||
float xu,
|
||||
xp;
|
||||
float rs,
|
||||
rc;
|
||||
glm::vec3 sourceCasterVec;
|
||||
glm::vec3 casterPositionVec;
|
||||
bool isShadowing;
|
||||
};
|
||||
|
||||
public:
|
||||
RenderablePlanet(const ghoul::Dictionary& dictionary);
|
||||
|
||||
void initializeGL() override;
|
||||
@@ -80,7 +87,9 @@ public:
|
||||
protected:
|
||||
void loadTexture();
|
||||
|
||||
private:
|
||||
private:
|
||||
glm::dmat4 computeModelTransformMatrix(const openspace::TransformData & transformData);
|
||||
|
||||
properties::StringProperty _colorTexturePath;
|
||||
properties::StringProperty _nightTexturePath;
|
||||
properties::StringProperty _heightMapTexturePath;
|
||||
@@ -95,15 +104,17 @@ private:
|
||||
|
||||
std::unique_ptr<planetgeometry::PlanetGeometry> _geometry;
|
||||
properties::BoolProperty _performShading;
|
||||
float _alpha;
|
||||
std::vector< ShadowConf > _shadowConfArray;
|
||||
float _planetRadius;
|
||||
|
||||
glm::dmat3 _stateMatrix;
|
||||
float _alpha;
|
||||
float _planetRadius;
|
||||
bool _hasNightTexture;
|
||||
bool _hasHeightTexture;
|
||||
bool _shadowEnabled;
|
||||
double _time;
|
||||
|
||||
glm::dmat3 _stateMatrix;
|
||||
|
||||
std::vector<ShadowConfiguration> _shadowConfArray;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -645,8 +645,17 @@ bool RenderableStars::readSpeckFile() {
|
||||
for (int i = 0; i < _nValuesPerStar; ++i) {
|
||||
str >> values[i];
|
||||
}
|
||||
|
||||
_fullData.insert(_fullData.end(), values.begin(), values.end());
|
||||
bool nullArray = true;
|
||||
for (int i = 0; i < values.size(); ++i) {
|
||||
if (values[i] != 0.0) {
|
||||
nullArray = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!nullArray) {
|
||||
_fullData.insert(_fullData.end(), values.begin(), values.end());
|
||||
}
|
||||
|
||||
} while (!file.eof());
|
||||
|
||||
return true;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*****************************************************************************************
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
|
||||
@@ -29,6 +29,8 @@ in vec2 vs_st;
|
||||
in vec2 vs_nightTex;
|
||||
in vec4 vs_normal;
|
||||
in vec4 vs_position;
|
||||
in vec4 vs_gPosition;
|
||||
in vec3 vs_gNormal;
|
||||
|
||||
uniform vec4 objpos;
|
||||
|
||||
@@ -67,6 +69,10 @@ Fragment getFragment() {
|
||||
frag.color = vec4(diffuse.rgb, transparency);
|
||||
frag.depth = vs_position.w;
|
||||
|
||||
frag.gOtherData = vec4(diffuse.xyz, 1.0);
|
||||
frag.gPosition = vs_gPosition;
|
||||
frag.gNormal = vec4(vs_gNormal, 1.0);
|
||||
|
||||
return frag;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,8 +33,11 @@ layout(location = 2) in vec3 in_normal;
|
||||
out vec2 vs_st;
|
||||
out vec4 vs_normal;
|
||||
out vec4 vs_position;
|
||||
out vec4 vs_gPosition;
|
||||
out vec3 vs_gNormal;
|
||||
|
||||
uniform mat4 ModelTransform;
|
||||
uniform dmat4 modelViewTransform;
|
||||
uniform mat4 modelViewProjectionTransform;
|
||||
|
||||
uniform sampler2D heightTex;
|
||||
@@ -44,14 +47,16 @@ uniform float _heightExaggeration;
|
||||
void main() {
|
||||
// set variables
|
||||
vs_st = in_st;
|
||||
vec4 tmp = in_position;
|
||||
|
||||
|
||||
// this is wrong for the normal. The normal transform is the transposed inverse of the model transform
|
||||
vs_normal = normalize(ModelTransform * vec4(in_normal,0));
|
||||
// vs_normal = vec4(in_normal, 0.0);
|
||||
|
||||
vec4 position = vec4(tmp.xyz * pow(10, tmp. w), 1.0);
|
||||
|
||||
// G-Buffer
|
||||
vs_gNormal = in_normal;
|
||||
|
||||
vec4 position = vec4(in_position.xyz * pow(10, in_position.w), 1.0);
|
||||
|
||||
if (_hasHeightMap) {
|
||||
float height = texture(heightTex, in_st).r;
|
||||
vec3 displacementDirection = abs(normalize(in_normal.xyz));
|
||||
@@ -59,6 +64,9 @@ void main() {
|
||||
position.xyz = position.xyz + displacementDirection * displacementFactor;
|
||||
}
|
||||
|
||||
// G-Buffer
|
||||
vs_gPosition = vec4(modelViewTransform * position); // Must be in SGCT eye space
|
||||
|
||||
position = modelViewProjectionTransform * position;
|
||||
vs_position = z_normalization(position);
|
||||
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
in vec2 vs_st;
|
||||
in vec4 vs_normal;
|
||||
in vec4 vs_position;
|
||||
in vec4 vs_gPosition;
|
||||
in vec3 vs_gNormal;
|
||||
|
||||
uniform vec4 objpos;
|
||||
uniform vec3 sun_pos;
|
||||
@@ -35,7 +37,6 @@ uniform bool _performShading = true;
|
||||
uniform float transparency;
|
||||
uniform sampler2D texture1;
|
||||
|
||||
|
||||
Fragment getFragment() {
|
||||
vec4 diffuse = texture(texture1, vs_st);
|
||||
|
||||
@@ -52,5 +53,9 @@ Fragment getFragment() {
|
||||
frag.color = vec4(diffuse.rgb, transparency);
|
||||
frag.depth = vs_position.w;
|
||||
|
||||
frag.gOtherData = vec4(diffuse.xyz, 1.0);
|
||||
frag.gPosition = vs_gPosition;
|
||||
frag.gNormal = vec4(vs_gNormal, 1.0);
|
||||
|
||||
return frag;
|
||||
}
|
||||
|
||||
@@ -33,20 +33,29 @@ layout(location = 2) in vec3 in_normal;
|
||||
out vec2 vs_st;
|
||||
out vec4 vs_normal;
|
||||
out vec4 vs_position;
|
||||
out vec4 vs_gPosition;
|
||||
out vec3 vs_gNormal;
|
||||
|
||||
uniform mat4 ModelTransform;
|
||||
uniform dmat4 modelViewTransform;
|
||||
uniform mat4 modelViewProjectionTransform;
|
||||
|
||||
|
||||
void main() {
|
||||
vs_st = in_st;
|
||||
vec4 tmp = in_position;
|
||||
|
||||
// G-Buffer
|
||||
vs_gNormal = in_normal;
|
||||
|
||||
// this is wrong for the normal. The normal transform is the transposed inverse of the model transform
|
||||
vs_normal = normalize(ModelTransform * vec4(in_normal,0));
|
||||
// vs_normal = vec4(in_normal, 0.0);
|
||||
|
||||
vec4 position = vec4(tmp.xyz * pow(10, tmp.w), 1.0);
|
||||
vec4 position = vec4(in_position.xyz * pow(10, in_position.w), 1.0);
|
||||
|
||||
// G-Buffer
|
||||
vs_gPosition = vec4(modelViewTransform * position); // Must be in SGCT eye space;
|
||||
|
||||
position = modelViewProjectionTransform * position;
|
||||
|
||||
vs_position = z_normalization(position);
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
|
||||
in vec2 vs_st;
|
||||
in vec4 vs_position;
|
||||
//in vec4 vs_gPosition;
|
||||
//in vec3 vs_gNormal;
|
||||
|
||||
uniform sampler1D texture1;
|
||||
uniform vec2 textureOffset;
|
||||
@@ -86,5 +88,10 @@ Fragment getFragment() {
|
||||
Fragment frag;
|
||||
frag.color = diffuse;
|
||||
frag.depth = vs_position.w;
|
||||
|
||||
//frag.gOtherData = diffuse;
|
||||
//frag.gPosition = vs_gPosition;
|
||||
//frag.gNormal = vs_gNormal;
|
||||
|
||||
return frag;
|
||||
}
|
||||
|
||||
@@ -31,6 +31,8 @@ layout(location = 1) in vec2 in_st;
|
||||
|
||||
out vec2 vs_st;
|
||||
out vec4 vs_position;
|
||||
//out vec4 vs_gPosition;
|
||||
//out vec3 vs_gNormal;
|
||||
|
||||
uniform mat4 modelViewProjectionTransform;
|
||||
|
||||
|
||||
@@ -29,6 +29,8 @@ in vec2 vs_st;
|
||||
in vec4 vs_normal;
|
||||
in vec4 vs_position;
|
||||
in vec4 vs_posWorld;
|
||||
in vec4 vs_gPosition;
|
||||
in vec3 vs_gNormal;
|
||||
|
||||
const uint numberOfShadows = 1;
|
||||
|
||||
@@ -51,8 +53,7 @@ uniform float transparency;
|
||||
|
||||
uniform sampler2D texture1;
|
||||
|
||||
|
||||
vec4 butterworthFunc(float d, float r, float n) {
|
||||
vec4 butterworthFunc(const float d, const float r, const float n) {
|
||||
return vec4(vec3(sqrt(r / (r + pow(d, 2 * n)))), 1.0);
|
||||
}
|
||||
|
||||
@@ -109,6 +110,10 @@ Fragment getFragment() {
|
||||
|
||||
frag.color = vec4(diffuse.rgb, transparency);
|
||||
frag.depth = depth;
|
||||
|
||||
|
||||
frag.gOtherData = vec4(diffuse.xyz, 1.0);
|
||||
frag.gPosition = vs_gPosition;
|
||||
frag.gNormal = vec4(vs_gNormal, 1.0);
|
||||
|
||||
return frag;
|
||||
}
|
||||
|
||||
@@ -30,6 +30,8 @@ in vec2 vs_nightTex;
|
||||
in vec4 vs_normal;
|
||||
in vec4 vs_position;
|
||||
in vec4 vs_posWorld;
|
||||
in vec4 vs_gPosition;
|
||||
in vec3 vs_gNormal;
|
||||
|
||||
const uint numberOfShadows = 1;
|
||||
|
||||
@@ -56,8 +58,7 @@ uniform float time;
|
||||
uniform sampler2D texture1;
|
||||
uniform sampler2D nightTex;
|
||||
|
||||
|
||||
vec4 butterworthFunc(float d, float r, float n) {
|
||||
vec4 butterworthFunc(const float d, const float r, const float n) {
|
||||
return vec4(vec3(sqrt(r/(r + pow(d, 2*n)))), 1.0);
|
||||
}
|
||||
|
||||
@@ -117,5 +118,9 @@ Fragment getFragment() {
|
||||
frag.color = vec4(diffuse.rgb, transparency);
|
||||
frag.depth = depth;
|
||||
|
||||
frag.gOtherData = vec4(diffuse.xyz, 1.0);
|
||||
frag.gPosition = vs_gPosition;
|
||||
frag.gNormal = vec4(vs_gNormal, 1.0);
|
||||
|
||||
return frag;
|
||||
}
|
||||
|
||||
@@ -34,6 +34,8 @@ out vec2 vs_st;
|
||||
out vec4 vs_normal;
|
||||
out vec4 vs_position;
|
||||
out vec4 vs_posWorld;
|
||||
out vec4 vs_gPosition;
|
||||
out vec3 vs_gNormal;
|
||||
|
||||
uniform mat4 ViewProjection;
|
||||
uniform mat4 ModelTransform;
|
||||
@@ -47,10 +49,18 @@ void main() {
|
||||
// this is wrong for the normal. The normal transform is the transposed inverse of the model transform
|
||||
vs_normal = normalize(ModelTransform * vec4(in_normal,0));
|
||||
|
||||
// The things is not in world coordinates, they are in
|
||||
// regular view/eye coordinates.
|
||||
// G-Buffer
|
||||
vs_gNormal = in_normal;
|
||||
|
||||
// The tmp is now in the OS eye space (camera rig space)
|
||||
// and wrtitten using PSC coords.
|
||||
// position is in the same space, i.e., OS eye space but
|
||||
// in meters (no PSC coords).
|
||||
vec4 position = pscTransform(tmp, ModelTransform);
|
||||
|
||||
// G-Buffer
|
||||
vs_gPosition = position;
|
||||
|
||||
vec3 local_vertex_pos = mat3(ModelTransform) * in_position.xyz;
|
||||
vec4 vP = psc_addition(vec4(local_vertex_pos, in_position.w), objpos);
|
||||
vs_posWorld = vec4(vP.xyz * pow(10, vP.w), 1.0);
|
||||
|
||||
@@ -30,15 +30,19 @@ layout(location = 0) in vec4 in_position;
|
||||
layout(location = 1) in vec2 in_st;
|
||||
layout(location = 2) in vec3 in_normal;
|
||||
|
||||
uniform mat4 ViewProjection;
|
||||
uniform mat4 ModelTransform;
|
||||
uniform bool _hasHeightMap;
|
||||
uniform float _heightExaggeration;
|
||||
uniform sampler2D heightTex;
|
||||
|
||||
out vec2 vs_st;
|
||||
out vec4 vs_normal;
|
||||
out vec4 vs_position;
|
||||
out vec4 vs_posWorld;
|
||||
out float s;
|
||||
|
||||
uniform mat4 ViewProjection;
|
||||
uniform mat4 ModelTransform;
|
||||
|
||||
out vec4 vs_gPosition;
|
||||
out vec3 vs_gNormal;
|
||||
|
||||
void main() {
|
||||
// set variables
|
||||
@@ -49,15 +53,31 @@ void main() {
|
||||
// this is wrong for the normal. The normal transform is the transposed inverse of the model transform
|
||||
vs_normal = normalize(ModelTransform * vec4(in_normal,0));
|
||||
|
||||
// The things is not in world coordinates, they are in
|
||||
// regular view/eye coordinates.
|
||||
// We are using the normal in Object (model) space in G-Buffer (because of atm).
|
||||
vs_gNormal = in_normal;
|
||||
|
||||
// The tmp is now in the OS eye space (camera rig space)
|
||||
// and wrtitten using PSC coords.
|
||||
// position is in the same space, i.e., OS eye space but
|
||||
// in meters (no PSC coords).
|
||||
vec4 position = pscTransform(tmp, ModelTransform);
|
||||
|
||||
// G-Buffer
|
||||
vs_gPosition = position;
|
||||
|
||||
vec3 local_vertex_pos = mat3(ModelTransform) * in_position.xyz;
|
||||
vec4 vP = psc_addition(vec4(local_vertex_pos,in_position.w),objpos);
|
||||
vs_posWorld = vec4(vP.xyz * pow(10,vP.w), 1.0);
|
||||
|
||||
vs_position = tmp;
|
||||
|
||||
if (_hasHeightMap) {
|
||||
float height = texture(heightTex, in_st).r;
|
||||
vec3 displacementDirection = abs(normalize(in_normal.xyz));
|
||||
float displacementFactor = height * _heightExaggeration;
|
||||
position.xyz = position.xyz + displacementDirection * displacementFactor;
|
||||
}
|
||||
|
||||
// Now is transforming from view position to SGCT projection
|
||||
// coordinates.
|
||||
position = ViewProjection * position;
|
||||
|
||||
@@ -25,14 +25,6 @@
|
||||
#include "fragment.glsl"
|
||||
#include "PowerScaling/powerScaling_fs.hglsl"
|
||||
|
||||
in vec4 vs_position;
|
||||
in vec3 ge_brightness;
|
||||
in vec3 ge_velocity;
|
||||
in float ge_speed;
|
||||
in vec2 texCoord;
|
||||
in float billboardSize;
|
||||
|
||||
|
||||
// keep in sync with renderablestars.h:ColorOption enum
|
||||
const int COLOROPTION_COLOR = 0;
|
||||
const int COLOROPTION_VELOCITY = 1;
|
||||
@@ -45,6 +37,17 @@ uniform float minBillboardSize;
|
||||
uniform float alphaValue;
|
||||
uniform int colorOption;
|
||||
|
||||
in vec4 vs_position;
|
||||
in vec4 ge_gPosition;
|
||||
in vec3 ge_brightness;
|
||||
in vec3 ge_velocity;
|
||||
in float ge_speed;
|
||||
in vec2 texCoord;
|
||||
in float billboardSize;
|
||||
|
||||
#include "fragment.glsl"
|
||||
//#include "PowerScaling/powerScaling_fs.hglsl"
|
||||
|
||||
uniform vec2 magnitudeClamp;
|
||||
|
||||
|
||||
@@ -84,6 +87,12 @@ Fragment getFragment() {
|
||||
frag.color = fullColor;
|
||||
frag.depth = pscDepth(position);
|
||||
|
||||
// G-Buffer
|
||||
frag.gOtherData = vec4(fullColor.xyz, 1.0);
|
||||
frag.gPosition = ge_gPosition;
|
||||
// There is no normal here
|
||||
frag.gNormal = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
|
||||
if (fullColor.a == 0) {
|
||||
discard;
|
||||
}
|
||||
|
||||
@@ -30,11 +30,14 @@ layout(points) in;
|
||||
in vec4 psc_position[];
|
||||
in vec3 vs_brightness[];
|
||||
in vec3 vs_velocity[];
|
||||
in vec4 vs_gPosition[];
|
||||
in float vs_speed[];
|
||||
in vec4 cam_position[];
|
||||
|
||||
layout(triangle_strip, max_vertices = 4) out;
|
||||
|
||||
out vec4 vs_position;
|
||||
out vec4 ge_gPosition;
|
||||
out vec3 ge_brightness;
|
||||
out vec3 ge_velocity;
|
||||
out float ge_speed;
|
||||
@@ -56,12 +59,13 @@ const vec2 corners[4] = vec2[4](
|
||||
|
||||
|
||||
void main() {
|
||||
if ((psc_position[0].x == 0.0) &&
|
||||
(psc_position[0].y == 0.0) &&
|
||||
(psc_position[0].z == 0.0))
|
||||
{
|
||||
return;
|
||||
}
|
||||
// JCC: We want to display the Sun.
|
||||
// if ((psc_position[0].x == 0.0) &&
|
||||
// (psc_position[0].y == 0.0) &&
|
||||
// (psc_position[0].z == 0.0))
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
|
||||
ge_brightness = vs_brightness[0];
|
||||
ge_velocity = vs_velocity[0];
|
||||
@@ -92,9 +96,13 @@ void main() {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
vs_position = gl_in[0].gl_Position;
|
||||
gl_Position = projPos[i];
|
||||
texCoord = corners[i];
|
||||
texCoord = corners[i];
|
||||
|
||||
// G-Buffer
|
||||
ge_gPosition = vs_gPosition[0];
|
||||
billboardSize = sizeInPixels;
|
||||
EmitVertex();
|
||||
EmitVertex();
|
||||
}
|
||||
|
||||
EndPrimitive();
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ out vec4 psc_position;
|
||||
out vec3 vs_brightness;
|
||||
out vec3 vs_velocity;
|
||||
out float vs_speed;
|
||||
out vec4 cam_position;
|
||||
out vec4 vs_gPosition;
|
||||
|
||||
uniform mat4 model;
|
||||
uniform mat4 view;
|
||||
@@ -48,8 +48,14 @@ void main() {
|
||||
vs_brightness = in_brightness;
|
||||
vs_velocity = in_velocity;
|
||||
vs_speed = in_speed;
|
||||
cam_position = campos;
|
||||
|
||||
vec4 tmp = p;
|
||||
gl_Position = view * pscTransform(tmp, mat4(1.0));
|
||||
}
|
||||
vec4 position = pscTransform(tmp, mat4(1.0));
|
||||
|
||||
// G-Buffer
|
||||
vs_gPosition = position;
|
||||
|
||||
position = view * position;
|
||||
|
||||
gl_Position = position;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user