Added lunar eclipses back.

This commit is contained in:
Jonathas Costa
2017-10-19 11:41:36 -04:00
parent 6fdb587cca
commit a925d0646a
15 changed files with 308 additions and 59 deletions
+11 -1
View File
@@ -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();
+9 -15
View File
@@ -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,