mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-04-24 04:58:59 -05:00
Added lunar eclipses back.
This commit is contained in:
@@ -60,7 +60,17 @@ return {
|
||||
Settings = { Multiplier = 0.5 },
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
ShadowGroup = {
|
||||
Source1 = {
|
||||
Name = "Sun",
|
||||
Radius = 696.3E6,
|
||||
},
|
||||
Caster1 = {
|
||||
Name = "Earth",
|
||||
Radius = 6.371E6,
|
||||
},
|
||||
},
|
||||
},
|
||||
GuiPath = "/Solar System/Planets/Earth/Moon"
|
||||
},
|
||||
|
||||
@@ -308,9 +308,8 @@ void AtmosphereDeferredcaster::preRaycast(const RenderData& renderData, const De
|
||||
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", {}, _time, lt);
|
||||
double casterDistSun = glm::length(casterPos - sunPos);
|
||||
double planetDistSun = glm::length(renderData.position.dvec3() - sunPos);
|
||||
double casterDistSun = glm::length(casterPos - sunPosWorld);
|
||||
double planetDistSun = glm::length(renderData.position.dvec3() - sunPosWorld);
|
||||
|
||||
ShadowRenderingStruct shadowData;
|
||||
shadowData.isShadowing = false;
|
||||
|
||||
@@ -318,7 +318,7 @@ namespace openspace {
|
||||
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, double>> sourceArray;
|
||||
unsigned int sourceCounter = 1;
|
||||
while (success) {
|
||||
std::string sourceName;
|
||||
@@ -344,7 +344,7 @@ namespace openspace {
|
||||
|
||||
if (!disableShadows && !sourceArray.empty()) {
|
||||
success = true;
|
||||
std::vector<std::pair<std::string, float>> casterArray;
|
||||
std::vector<std::pair<std::string, double>> casterArray;
|
||||
unsigned int casterCounter = 1;
|
||||
while (success) {
|
||||
std::string casterName;
|
||||
|
||||
@@ -98,7 +98,7 @@ uniform dvec3 sunDirectionObj;
|
||||
uniform dvec3 ellipsoidRadii;
|
||||
|
||||
/*******************************************************************************
|
||||
**** ALL CALCULATIONS FOR ECLIPSE ARE IN METERS AND IN OBJECT SPACE SYSTEM ****
|
||||
***** ALL CALCULATIONS FOR ECLIPSE ARE IN METERS AND IN WORLD SPACE SYSTEM ****
|
||||
*******************************************************************************/
|
||||
// JCC: Remove and use dictionary to
|
||||
// decides the number of shadows
|
||||
|
||||
@@ -165,4 +165,17 @@ 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
|
||||
*/
|
||||
@@ -83,6 +91,10 @@ 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;
|
||||
@@ -96,6 +108,9 @@ private:
|
||||
void updateInternalCache();
|
||||
|
||||
glm::dvec3 _radii;
|
||||
|
||||
// Eclipse shadows conf
|
||||
std::vector<Ellipsoid::ShadowConfiguration> _shadowConfArray;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*****************************************************************************************
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
@@ -29,12 +29,13 @@
|
||||
#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 = "Shadow_Group";
|
||||
const char* keyShadowGroup = "ShadowGroup";
|
||||
const char* keyShadowSource = "Source";
|
||||
const char* keyShadowCaster = "Caster";
|
||||
|
||||
@@ -134,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",
|
||||
@@ -178,12 +191,13 @@ 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)
|
||||
})
|
||||
, _debugPropertyOwner({ "Debug" })
|
||||
, _shadowEnabled(false)
|
||||
{
|
||||
setName("RenderableGlobe");
|
||||
|
||||
@@ -227,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);
|
||||
@@ -252,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);
|
||||
@@ -263,27 +281,30 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary)
|
||||
addPropertySubOwner(_layerManager.get());
|
||||
//addPropertySubOwner(_pointGlobe.get());
|
||||
|
||||
//================================================================
|
||||
//======== Reads Shadow (Eclipses) Entries in mod file ===========
|
||||
//================================================================
|
||||
ghoul::Dictionary shadowDictionary;
|
||||
bool dicSuccess = dictionary.getValue(keyShadowGroup, shadowDictionary);
|
||||
bool success = dictionary.getValue(keyShadowGroup, shadowDictionary);
|
||||
bool disableShadows = false;
|
||||
if (dicSuccess) {
|
||||
std::vector< std::pair<std::string, float > > sourceArray;
|
||||
if (success) {
|
||||
std::vector<std::pair<std::string, double>> sourceArray;
|
||||
unsigned int sourceCounter = 1;
|
||||
while (dicSuccess) {
|
||||
while (success) {
|
||||
std::string sourceName;
|
||||
dicSuccess = shadowDictionary.getValue(keyShadowSource +
|
||||
success = shadowDictionary.getValue(keyShadowSource +
|
||||
std::to_string(sourceCounter) + ".Name", sourceName);
|
||||
if (dicSuccess) {
|
||||
float sourceRadius;
|
||||
dicSuccess = shadowDictionary.getValue(keyShadowSource +
|
||||
if (success) {
|
||||
double sourceRadius;
|
||||
success = shadowDictionary.getValue(keyShadowSource +
|
||||
std::to_string(sourceCounter) + ".Radius", sourceRadius);
|
||||
if (dicSuccess) {
|
||||
sourceArray.emplace_back(sourceName, 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.");*/
|
||||
//LWARNING("No Radius value expecified for Shadow Source Name "
|
||||
// << sourceName << " from " << name
|
||||
// << " planet.\nDisabling shadows for this planet.");
|
||||
disableShadows = true;
|
||||
break;
|
||||
}
|
||||
@@ -292,24 +313,24 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary)
|
||||
}
|
||||
|
||||
if (!disableShadows && !sourceArray.empty()) {
|
||||
dicSuccess = true;
|
||||
std::vector< std::pair<std::string, float > > casterArray;
|
||||
success = true;
|
||||
std::vector<std::pair<std::string, double>> casterArray;
|
||||
unsigned int casterCounter = 1;
|
||||
while (dicSuccess) {
|
||||
while (success) {
|
||||
std::string casterName;
|
||||
dicSuccess = shadowDictionary.getValue(keyShadowCaster +
|
||||
success = shadowDictionary.getValue(keyShadowCaster +
|
||||
std::to_string(casterCounter) + ".Name", casterName);
|
||||
if (dicSuccess) {
|
||||
float casterRadius;
|
||||
dicSuccess = shadowDictionary.getValue(keyShadowCaster +
|
||||
if (success) {
|
||||
double casterRadius;
|
||||
success = shadowDictionary.getValue(keyShadowCaster +
|
||||
std::to_string(casterCounter) + ".Radius", casterRadius);
|
||||
if (dicSuccess) {
|
||||
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.");*/
|
||||
//LWARNING("No Radius value expecified for Shadow Caster Name "
|
||||
// << casterName << " from " << name
|
||||
// << " planet.\nDisabling shadows for this planet.");
|
||||
disableShadows = true;
|
||||
break;
|
||||
}
|
||||
@@ -318,19 +339,20 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary)
|
||||
casterCounter++;
|
||||
}
|
||||
|
||||
std::vector<Ellipsoid::ShadowConfiguration> shadowConfArray;
|
||||
if (!disableShadows && (!sourceArray.empty() && !casterArray.empty())) {
|
||||
for (auto source : sourceArray)
|
||||
for (auto caster : casterArray) {
|
||||
ShadowConfiguration sc;
|
||||
for (const auto & source : sourceArray) {
|
||||
for (const auto & caster : casterArray) {
|
||||
Ellipsoid::ShadowConfiguration sc;
|
||||
sc.source = source;
|
||||
sc.caster = caster;
|
||||
_shadowConfArray.push_back(sc);
|
||||
shadowConfArray.push_back(sc);
|
||||
}
|
||||
_shadowEnabled = true;
|
||||
}
|
||||
_ellipsoid.setShadowConfigurationArray(shadowConfArray);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// Recompile the shaders directly so that it is not done the first time the render
|
||||
// function is called.
|
||||
_chunkedLodGlobe->recompileShaders();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*****************************************************************************************
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
@@ -79,24 +79,21 @@ 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 ShadowConfiguration {
|
||||
std::pair<std::string, float> source;
|
||||
std::pair<std::string, float> caster;
|
||||
};
|
||||
|
||||
struct ShadowRenderingStruct {
|
||||
float xu,
|
||||
xp;
|
||||
float rs,
|
||||
rc;
|
||||
glm::vec3 sourceCasterVec;
|
||||
glm::vec3 casterPositionVec;
|
||||
double xu,
|
||||
xp;
|
||||
double rs,
|
||||
rc;
|
||||
glm::dvec3 sourceCasterVec;
|
||||
glm::dvec3 casterPositionVec;
|
||||
bool isShadowing;
|
||||
};
|
||||
|
||||
@@ -153,9 +150,6 @@ private:
|
||||
GeneralProperties _generalProperties;
|
||||
properties::PropertyOwner _debugPropertyOwner;
|
||||
|
||||
// Shadow
|
||||
bool _shadowEnabled;
|
||||
std::vector<ShadowConfiguration> _shadowConfArray;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*****************************************************************************************
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
@@ -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)
|
||||
{
|
||||
@@ -250,6 +342,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);
|
||||
@@ -341,7 +437,9 @@ 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);
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*****************************************************************************************
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
@@ -107,6 +107,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)
|
||||
|
||||
@@ -45,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;
|
||||
@@ -119,4 +124,8 @@ void main() {
|
||||
ellipsoidNormalCameraSpace = mat3(modelViewTransform) * pair.normal;
|
||||
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
|
||||
}
|
||||
|
||||
@@ -45,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;
|
||||
@@ -104,4 +109,8 @@ void main() {
|
||||
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}
|
||||
|
||||
@@ -66,6 +66,75 @@ 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;
|
||||
@@ -176,6 +245,10 @@ Fragment getTileFragment() {
|
||||
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
|
||||
frag.color = calculateOverlay(
|
||||
frag.color,
|
||||
|
||||
Reference in New Issue
Block a user