mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-05 19:19:39 -06:00
Added more control over shadow generation. Added documentation. Merged Master.
This commit is contained in:
@@ -62,6 +62,8 @@ uniform float orenNayarRoughness;
|
||||
#if SHADOW_MAPPING_ENABLED
|
||||
in vec4 shadowCoords;
|
||||
uniform sampler2DShadow shadowMapTexture;
|
||||
uniform int nShadowSamples;
|
||||
uniform float zFightingPercentage;
|
||||
#endif
|
||||
|
||||
#if USE_ECLIPSE_SHADOWS
|
||||
@@ -267,26 +269,23 @@ Fragment getFragment() {
|
||||
float shadow = 1.0;
|
||||
if ( shadowCoords.w > 1 ) {
|
||||
vec4 normalizedShadowCoords = shadowCoords;
|
||||
normalizedShadowCoords.z = normalizeFloat(normalizedShadowCoords.w - 0.005 * normalizedShadowCoords.w);
|
||||
normalizedShadowCoords.xy = normalizedShadowCoords.xy / normalizedShadowCoords.w;
|
||||
normalizedShadowCoords.w = 1.0;
|
||||
normalizedShadowCoords.z = normalizeFloat(zFightingPercentage * normalizedShadowCoords.w);
|
||||
normalizedShadowCoords.xy = normalizedShadowCoords.xy / normalizedShadowCoords.w;
|
||||
normalizedShadowCoords.w = 1.0;
|
||||
|
||||
//shadow = textureProj(shadowMapTexture, normalizedShadowCoords);
|
||||
|
||||
float sum = 0;
|
||||
int fStep = 5;
|
||||
for (int i = 0; i < fStep; ++i) {
|
||||
sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-fStep + i, -fStep + i));
|
||||
sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-fStep + i, 0));
|
||||
sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-fStep + i, fStep - i));
|
||||
sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0, -fStep + i));
|
||||
sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0, fStep - i));
|
||||
sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( fStep - i, -fStep + i));
|
||||
sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( fStep - i, 0));
|
||||
sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( fStep - i, fStep - i));
|
||||
float sum = 0;
|
||||
for (int i = 0; i < nShadowSamples; ++i) {
|
||||
sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-nShadowSamples + i, -nShadowSamples + i));
|
||||
sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-nShadowSamples + i, 0));
|
||||
sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-nShadowSamples + i, nShadowSamples - i));
|
||||
sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0 , -nShadowSamples + i));
|
||||
sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0 , nShadowSamples - i));
|
||||
sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( nShadowSamples - i, -nShadowSamples + i));
|
||||
sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( nShadowSamples - i, 0));
|
||||
sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( nShadowSamples - i, nShadowSamples - i));
|
||||
}
|
||||
sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0, 0));
|
||||
shadow = sum / (8.f * fStep + 1.f);
|
||||
sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(0, 0));
|
||||
shadow = sum / (8.f * nShadowSamples + 1.f);
|
||||
}
|
||||
frag.color.xyz *= shadow < 0.99 ? clamp(shadow + 0.5, 0.0, 1.0) : shadow;
|
||||
#endif
|
||||
|
||||
@@ -37,6 +37,8 @@ uniform float transparency;
|
||||
uniform bool hasSunPosition;
|
||||
uniform vec3 sunPosition;
|
||||
uniform float _nightFactor;
|
||||
uniform int nShadowSamples;
|
||||
uniform float zFightingPercentage;
|
||||
|
||||
// temp
|
||||
in vec4 fragPosInLightSpace;
|
||||
@@ -73,24 +75,23 @@ Fragment getFragment() {
|
||||
float shadow = 1.0;
|
||||
if ( shadowCoords.z >= 0 ) {
|
||||
vec4 normalizedShadowCoords = shadowCoords;
|
||||
normalizedShadowCoords.z = normalizeFloat(normalizedShadowCoords.w - 0.005 * normalizedShadowCoords.w);
|
||||
normalizedShadowCoords.xy = normalizedShadowCoords.xy / normalizedShadowCoords.w;
|
||||
normalizedShadowCoords.w = 1.0;
|
||||
|
||||
//shadow = textureProj(shadowMapTexture, normalizedShadowCoords);
|
||||
normalizedShadowCoords.z = normalizeFloat(zFightingPercentage * normalizedShadowCoords.w);
|
||||
normalizedShadowCoords.xy = normalizedShadowCoords.xy / normalizedShadowCoords.w;
|
||||
normalizedShadowCoords.w = 1.0;
|
||||
|
||||
float sum = 0;
|
||||
int fStep = 2;
|
||||
sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-fStep, -fStep));
|
||||
sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-fStep, 0));
|
||||
sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-fStep, fStep));
|
||||
sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0, -fStep));
|
||||
sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0, 0));
|
||||
sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0, fStep));
|
||||
sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( fStep, -fStep));
|
||||
sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( fStep, 0));
|
||||
sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( fStep, fStep));
|
||||
shadow = sum / 9.f;
|
||||
for (int i = 0; i < nShadowSamples; ++i) {
|
||||
sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-nShadowSamples + i, -nShadowSamples + i));
|
||||
sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-nShadowSamples + i, 0));
|
||||
sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-nShadowSamples + i, nShadowSamples - i));
|
||||
sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0 , -nShadowSamples + i));
|
||||
sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0 , nShadowSamples - i));
|
||||
sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( nShadowSamples - i, -nShadowSamples + i));
|
||||
sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( nShadowSamples - i, 0));
|
||||
sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( nShadowSamples - i, nShadowSamples - i));
|
||||
}
|
||||
sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(0, 0));
|
||||
shadow = sum / (8.f * nShadowSamples + 1.f);
|
||||
}
|
||||
|
||||
// The normal for the one plane depends on whether we are dealing
|
||||
|
||||
@@ -190,6 +190,20 @@ namespace {
|
||||
"Enables shadow mapping algorithm. Used by renderable rings too."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo ZFightingPercentageInfo = {
|
||||
"ZFightingPercentage",
|
||||
"Z-Fighting Percentage",
|
||||
"The percentage of the correct distance to the surface being shadowed. "
|
||||
"Possible values: [0.0, 1.0]"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo NumberShadowSamplesInfo = {
|
||||
"NumberShadowSamples",
|
||||
"Number of Shadow Samples",
|
||||
"The number of samples used during shadow mapping calculation "
|
||||
"(Percentage Closer Filtering)."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo TargetLodScaleFactorInfo = {
|
||||
"TargetLodScaleFactor",
|
||||
"Target Level of Detail Scale Factor",
|
||||
@@ -502,12 +516,15 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary)
|
||||
BoolProperty(EclipseInfo, false),
|
||||
BoolProperty(EclipseHardShadowsInfo, false),
|
||||
BoolProperty(ShadowMappingInfo, false),
|
||||
FloatProperty(ZFightingPercentageInfo, 0.995f, 0.000001f, 1.f),
|
||||
IntProperty(NumberShadowSamplesInfo, 5, 1, 20),
|
||||
FloatProperty(TargetLodScaleFactorInfo, 15.f, 1.f, 50.f),
|
||||
FloatProperty(CurrentLodScaleFactorInfo, 15.f, 1.f, 50.f),
|
||||
FloatProperty(CameraMinHeightInfo, 100.f, 0.f, 1000.f),
|
||||
FloatProperty(OrenNayarRoughnessInfo, 0.f, 0.f, 1.f),
|
||||
IntProperty(NActiveLayersInfo, 0, 0, OpenGLCap.maxTextureUnits() / 3)
|
||||
})
|
||||
, _shadowMappingPropertyOwner({ "Shadow Mapping" })
|
||||
, _debugPropertyOwner({ "Debug" })
|
||||
, _grid(DefaultSkirtedGridSegments, DefaultSkirtedGridSegments)
|
||||
, _leftRoot(Chunk(LeftHemisphereIndex))
|
||||
@@ -544,7 +561,12 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary)
|
||||
addProperty(_generalProperties.useAccurateNormals);
|
||||
addProperty(_generalProperties.eclipseShadowsEnabled);
|
||||
addProperty(_generalProperties.eclipseHardShadows);
|
||||
addProperty(_generalProperties.shadowMapping);
|
||||
|
||||
_shadowMappingPropertyOwner.addProperty(_generalProperties.shadowMapping);
|
||||
_shadowMappingPropertyOwner.addProperty(_generalProperties.zFightingPercentage);
|
||||
_shadowMappingPropertyOwner.addProperty(_generalProperties.nShadowSamples);
|
||||
addPropertySubOwner(_shadowMappingPropertyOwner);
|
||||
|
||||
_generalProperties.targetLodScaleFactor.onChange([this]() {
|
||||
float sf = _generalProperties.targetLodScaleFactor;
|
||||
_generalProperties.currentLodScaleFactor = sf;
|
||||
@@ -1296,6 +1318,8 @@ void RenderableGlobe::renderChunkGlobally(const Chunk& chunk, const RenderData&
|
||||
glBindTexture(GL_TEXTURE_2D, shadowData.shadowDepthTexture);
|
||||
|
||||
program.setUniform("shadowMapTexture", shadowMapUnit);
|
||||
program.setUniform("nShadowSamples", _generalProperties.nShadowSamples);
|
||||
program.setUniform("zFightingPercentage", _generalProperties.zFightingPercentage);
|
||||
}
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
@@ -1420,6 +1444,8 @@ void RenderableGlobe::renderChunkLocally(const Chunk& chunk, const RenderData& d
|
||||
glBindTexture(GL_TEXTURE_2D, shadowData.shadowDepthTexture);
|
||||
|
||||
program.setUniform("shadowMapTexture", shadowMapUnit);
|
||||
program.setUniform("nShadowSamples", _generalProperties.nShadowSamples);
|
||||
program.setUniform("zFightingPercentage", _generalProperties.zFightingPercentage);
|
||||
}
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
@@ -129,25 +129,29 @@ private:
|
||||
properties::BoolProperty showHeightIntensities;
|
||||
properties::BoolProperty levelByProjectedAreaElseDistance;
|
||||
properties::BoolProperty resetTileProviders;
|
||||
properties::IntProperty modelSpaceRenderingCutoffLevel;
|
||||
properties::IntProperty dynamicLodIterationCount;
|
||||
properties::IntProperty modelSpaceRenderingCutoffLevel;
|
||||
properties::IntProperty dynamicLodIterationCount;
|
||||
} _debugProperties;
|
||||
|
||||
struct {
|
||||
properties::BoolProperty performShading;
|
||||
properties::BoolProperty useAccurateNormals;
|
||||
properties::BoolProperty eclipseShadowsEnabled;
|
||||
properties::BoolProperty eclipseHardShadows;
|
||||
properties::BoolProperty shadowMapping;
|
||||
properties::BoolProperty performShading;
|
||||
properties::BoolProperty useAccurateNormals;
|
||||
properties::BoolProperty eclipseShadowsEnabled;
|
||||
properties::BoolProperty eclipseHardShadows;
|
||||
properties::BoolProperty shadowMapping;
|
||||
properties::FloatProperty zFightingPercentage;
|
||||
properties::IntProperty nShadowSamples;
|
||||
properties::FloatProperty targetLodScaleFactor;
|
||||
properties::FloatProperty currentLodScaleFactor;
|
||||
properties::FloatProperty cameraMinHeight;
|
||||
properties::FloatProperty orenNayarRoughness;
|
||||
properties::IntProperty nActiveLayers;
|
||||
properties::IntProperty nActiveLayers;
|
||||
} _generalProperties;
|
||||
|
||||
properties::PropertyOwner _debugPropertyOwner;
|
||||
|
||||
properties::PropertyOwner _shadowMappingPropertyOwner;
|
||||
|
||||
/**
|
||||
* Test if a specific chunk can safely be culled without affecting the rendered
|
||||
* image.
|
||||
|
||||
@@ -56,9 +56,10 @@
|
||||
#include <locale>
|
||||
|
||||
namespace {
|
||||
constexpr const std::array<const char*, 8> UniformNames = {
|
||||
constexpr const std::array<const char*, 10> UniformNames = {
|
||||
"modelViewProjectionMatrix", "textureOffset", "transparency", "_nightFactor",
|
||||
"sunPosition", "ringTexture", "shadowMatrix", "shadowMapTexture"
|
||||
"sunPosition", "ringTexture", "shadowMatrix", "shadowMapTexture",
|
||||
"nShadowSamples", "zFightingPercentage"
|
||||
};
|
||||
|
||||
constexpr const std::array<const char*, 3> GeomUniformNames = {
|
||||
@@ -101,6 +102,20 @@ namespace {
|
||||
"This value determines the transparency of part of the rings depending on the "
|
||||
"color values. For this value v, the transparency is equal to length(color) / v."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo ZFightingPercentageInfo = {
|
||||
"ZFightingPercentage",
|
||||
"Z-Fighting Percentage",
|
||||
"The percentage of the correct distance to the surface being shadowed. "
|
||||
"Possible values: [0.0, 1.0]"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo NumberShadowSamplesInfo = {
|
||||
"NumberShadowSamples",
|
||||
"Number of Shadow Samples",
|
||||
"The number of samples used during shadow mapping calculation "
|
||||
"(Percentage Closer Filtering)."
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
@@ -140,6 +155,18 @@ namespace openspace {
|
||||
new DoubleVerifier,
|
||||
Optional::Yes,
|
||||
TransparencyInfo.description
|
||||
},
|
||||
{
|
||||
ZFightingPercentageInfo.identifier,
|
||||
new DoubleVerifier,
|
||||
Optional::Yes,
|
||||
ZFightingPercentageInfo.description
|
||||
},
|
||||
{
|
||||
NumberShadowSamplesInfo.identifier,
|
||||
new IntVerifier,
|
||||
Optional::Yes,
|
||||
NumberShadowSamplesInfo.description
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -153,6 +180,8 @@ namespace openspace {
|
||||
, _nightFactor(NightFactorInfo, 0.33f, 0.f, 1.f)
|
||||
, _transparency(TransparencyInfo, 0.15f, 0.f, 1.f)
|
||||
, _enabled({ "Enabled", "Enabled", "Enable/Disable Rings" }, true)
|
||||
, _zFightingPercentage(ZFightingPercentageInfo, 0.995f, 0.000001f, 1.f)
|
||||
, _nShadowSamples(NumberShadowSamplesInfo, 2, 1, 20)
|
||||
, _ringsDictionary(dictionary)
|
||||
{
|
||||
using ghoul::filesystem::File;
|
||||
@@ -204,6 +233,22 @@ namespace openspace {
|
||||
_ringsDictionary.value<double>(TransparencyInfo.identifier)
|
||||
);
|
||||
}
|
||||
|
||||
// Shadow Mapping Quality Controls
|
||||
if (_ringsDictionary.hasKey(ZFightingPercentageInfo.identifier)) {
|
||||
_zFightingPercentage = _ringsDictionary.value<float>(
|
||||
ZFightingPercentageInfo.identifier
|
||||
);
|
||||
}
|
||||
addProperty(_zFightingPercentage);
|
||||
|
||||
if (_ringsDictionary.hasKey(NumberShadowSamplesInfo.identifier)) {
|
||||
_nShadowSamples = _ringsDictionary.value<int>(
|
||||
NumberShadowSamplesInfo.identifier
|
||||
);
|
||||
}
|
||||
addProperty(_nShadowSamples);
|
||||
|
||||
addProperty(_transparency);
|
||||
}
|
||||
|
||||
@@ -287,6 +332,8 @@ namespace openspace {
|
||||
_shader->setUniform(_uniformCache.transparency, _transparency);
|
||||
_shader->setUniform(_uniformCache.nightFactor, _nightFactor);
|
||||
_shader->setUniform(_uniformCache.sunPosition, _sunPosition);
|
||||
_shader->setUniform(_uniformCache.nShadowSamples, _nShadowSamples);
|
||||
_shader->setUniform(_uniformCache.zFightingPercentage, _zFightingPercentage);
|
||||
|
||||
ringTextureUnit.activate();
|
||||
_texture->bind();
|
||||
|
||||
@@ -92,11 +92,14 @@ namespace openspace {
|
||||
properties::FloatProperty _nightFactor;
|
||||
properties::FloatProperty _transparency;
|
||||
properties::BoolProperty _enabled;
|
||||
properties::FloatProperty _zFightingPercentage;
|
||||
properties::IntProperty _nShadowSamples;
|
||||
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _shader;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _geometryOnlyShader;
|
||||
UniformCache(modelViewProjectionMatrix, textureOffset, transparency, nightFactor,
|
||||
sunPosition, ringTexture, shadowMatrix, shadowMapTexture
|
||||
sunPosition, ringTexture, shadowMatrix, shadowMapTexture,
|
||||
nShadowSamples, zFightingPercentage
|
||||
) _uniformCache;
|
||||
UniformCache(modelViewProjectionMatrix, textureOffset, ringTexture)
|
||||
_geomUniformCache;
|
||||
|
||||
@@ -163,13 +163,19 @@ namespace openspace {
|
||||
new DoubleVerifier,
|
||||
Optional::Yes,
|
||||
DistanceFractionInfo.description
|
||||
},
|
||||
{
|
||||
DepthMapSizeInfo.identifier,
|
||||
new Vector2ListVerifier<float>,
|
||||
Optional::Yes,
|
||||
DepthMapSizeInfo.description
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
ShadowComponent::ShadowComponent(const ghoul::Dictionary& dictionary)
|
||||
: properties::PropertyOwner({ "Shadows" })
|
||||
: properties::PropertyOwner({ "Shadows Component" })
|
||||
, _saveDepthTexture(SaveDepthTextureInfo)
|
||||
, _distanceFraction(DistanceFractionInfo, 20, 1, 10000)
|
||||
, _enabled({ "Enabled", "Enabled", "Enable/Disable Shadows" }, true)
|
||||
@@ -222,6 +228,10 @@ namespace openspace {
|
||||
_dynamicDepthTextureRes = true;
|
||||
}
|
||||
|
||||
_saveDepthTexture.onChange([&]() {
|
||||
_executeDepthTextureSave = true;
|
||||
});
|
||||
|
||||
_viewDepthMap = false;
|
||||
|
||||
addProperty(_enabled);
|
||||
|
||||
Reference in New Issue
Block a user