Skip to content
Permalink
Browse files

Initial EDL implementation

  • Loading branch information
NEDJIMAbelgacem authored and wonder-sk committed Nov 6, 2020
1 parent f6e6149 commit 618807ed2fbf5c7762bb862c45bc23d789076093
@@ -413,6 +413,24 @@ Sets whether to display labels on terrain tiles
bool showLabels() const;
%Docstring
Returns whether to display labels on terrain tiles
%End

void setEyeDomeLightingEnabled( bool enabled );
%Docstring
Sets whether eye dome lighting will be used
%End
bool eyeDomeLightingEnabled() const;
%Docstring
Returns whether eye dome lighting is used
%End

void setEyeDomeLightingStrength( double strength );
%Docstring
Sets the eye dome lighting strength value
%End
double eyeDomeLightingStrength() const;
%Docstring
Returns the eye dome lighting strength value
%End

QList<QgsPointLightSettings> pointLights() const;
@@ -599,6 +617,20 @@ Emitted when the flag whether light source origins are shown has changed.
void showLabelsChanged();
%Docstring
Emitted when the flag whether labels are displayed on terrain tiles has changed
%End

void eyeDomeLightingEnabledChanged();
%Docstring
Emitted when the flag whether eye dome lighting is used has changed

.. versionadded:: 3.18
%End

void eyeDomeLightingStrengthChanged();
%Docstring
Emitted when the eye dome lighting stength has changed

.. versionadded:: 3.18
%End

void pointLightsChanged();
@@ -131,6 +131,8 @@ Qgs3DMapScene::Qgs3DMapScene( const Qgs3DMapSettings &map, QgsAbstract3DEngine *
connect( &map, &Qgs3DMapSettings::renderersChanged, this, &Qgs3DMapScene::onRenderersChanged );
connect( &map, &Qgs3DMapSettings::skyboxSettingsChanged, this, &Qgs3DMapScene::onSkyboxSettingsChanged );
connect( &map, &Qgs3DMapSettings::shadowSettingsChanged, this, &Qgs3DMapScene::onShadowSettingsChanged );
connect( &map, &Qgs3DMapSettings::eyeDomeLightingEnabled, this, &Qgs3DMapScene::onEyeDomeShadingSettingsChanged );
connect( &map, &Qgs3DMapSettings::eyeDomeLightingStrengthChanged, this, &Qgs3DMapScene::onEyeDomeShadingSettingsChanged );

connect( QgsApplication::instance()->sourceCache(), &QgsSourceCache::remoteSourceFetched, this, [ = ]( const QString & url )
{
@@ -962,6 +964,19 @@ void Qgs3DMapScene::onShadowSettingsChanged()
shadowRenderingFrameGraph->setShadowRenderingEnabled( false );
}

void Qgs3DMapScene::onEyeDomeShadingSettingsChanged()
{
qDebug() << __FUNCTION__;
QgsWindow3DEngine *windowEngine = dynamic_cast<QgsWindow3DEngine *>( mEngine );
if ( windowEngine == nullptr )
return;
QgsShadowRenderingFrameGraph *shadowRenderingFrameGraph = windowEngine->shadowRenderingFrameGraph();

bool edlEnabled = mMap.eyeDomeLightingEnabled();
double edlStrength = mMap.eyeDomeLightingStrength();
shadowRenderingFrameGraph->setupEyeDomeLighting( edlEnabled, edlStrength );
}

void Qgs3DMapScene::exportScene( const Qgs3DMapExportSettings &exportSettings )
{
QVector<QString> notParsedLayers;
@@ -144,6 +144,7 @@ class _3D_EXPORT Qgs3DMapScene : public Qt3DCore::QEntity
void onRenderersChanged();
void onSkyboxSettingsChanged();
void onShadowSettingsChanged();
void onEyeDomeShadingSettingsChanged();

private:
void addLayerEntity( QgsMapLayer *layer );
@@ -237,6 +237,10 @@ void Qgs3DMapSettings::readXml( const QDomElement &elem, const QgsReadWriteConte
QDomElement elemShadows = elem.firstChildElement( QStringLiteral( "shadow-rendering" ) );
mShadowSettings.readXml( elemShadows, context );

QDomElement elemEyeDomeLighting = elem.firstChildElement( QStringLiteral( "eye-dome-lighting" ) );
mEyeDomeLightingEnabled = elemEyeDomeLighting.attribute( "enabled", QStringLiteral( "0" ) ).toInt();
mEyeDomeLightingStrength = elemEyeDomeLighting.attribute( "eye-dome-lighting-strength", QStringLiteral( "1000.0" ) ).toDouble();

QDomElement elemDebug = elem.firstChildElement( QStringLiteral( "debug" ) );
mShowTerrainBoundingBoxes = elemDebug.attribute( QStringLiteral( "bounding-boxes" ), QStringLiteral( "0" ) ).toInt();
mShowTerrainTileInfo = elemDebug.attribute( QStringLiteral( "terrain-tile-info" ), QStringLiteral( "0" ) ).toInt();
@@ -350,6 +354,11 @@ QDomElement Qgs3DMapSettings::writeXml( QDomDocument &doc, const QgsReadWriteCon
elemDebug.setAttribute( QStringLiteral( "show-light-sources" ), mShowLightSources ? 1 : 0 );
elem.appendChild( elemDebug );

QDomElement elemEyeDomeLighting = doc.createElement( QStringLiteral( "eye-dome-lighting" ) );
elemEyeDomeLighting.setAttribute( "enabled", mEyeDomeLightingEnabled ? 1 : 0 );
elemEyeDomeLighting.setAttribute( "eye-dome-lighting-strength", mEyeDomeLightingStrength );
elem.appendChild( elemEyeDomeLighting );

QDomElement elemTemporalRange = doc.createElement( QStringLiteral( "temporal-range" ) );
elemTemporalRange.setAttribute( QStringLiteral( "start" ), temporalRange().begin().toString( Qt::ISODate ) );
elemTemporalRange.setAttribute( QStringLiteral( "end" ), temporalRange().end().toString( Qt::ISODate ) );
@@ -631,6 +640,23 @@ void Qgs3DMapSettings::setShowLabels( bool enabled )
emit showLabelsChanged();
}

void Qgs3DMapSettings::setEyeDomeLightingEnabled( bool enabled )
{
if ( mEyeDomeLightingEnabled == enabled )
return;
mEyeDomeLightingEnabled = enabled;
emit eyeDomeLightingEnabledChanged();
}

void Qgs3DMapSettings::setEyeDomeLightingStrength( double strength )
{
if ( mEyeDomeLightingStrength == strength )
return;
qDebug() << "Qgs3DMapSettings::setEyeDomeLightingStrength";
mEyeDomeLightingStrength = strength;
emit eyeDomeLightingStrengthChanged();
}

void Qgs3DMapSettings::setPointLights( const QList<QgsPointLightSettings> &pointLights )
{
if ( mPointLights == pointLights )
@@ -362,6 +362,16 @@ class _3D_EXPORT Qgs3DMapSettings : public QObject, public QgsTemporalRangeObjec
//! Returns whether to display labels on terrain tiles
bool showLabels() const { return mShowLabels; }

//! Sets whether eye dome lighting will be used
void setEyeDomeLightingEnabled( bool enabled );
//! Returns whether eye dome lighting is used
bool eyeDomeLightingEnabled() const { return mEyeDomeLightingEnabled; }

//! Sets the eye dome lighting strength value
void setEyeDomeLightingStrength( double strength );
//! Returns the eye dome lighting strength value
double eyeDomeLightingStrength() const { return mEyeDomeLightingStrength; }

/**
* Returns list of point lights defined in the scene
* \since QGIS 3.6
@@ -526,6 +536,18 @@ class _3D_EXPORT Qgs3DMapSettings : public QObject, public QgsTemporalRangeObjec
//! Emitted when the flag whether labels are displayed on terrain tiles has changed
void showLabelsChanged();

/**
* Emitted when the flag whether eye dome lighting is used has changed
* \since QGIS 3.18
*/
void eyeDomeLightingEnabledChanged();

/**
* Emitted when the eye dome lighting stength has changed
* \since QGIS 3.18
*/
void eyeDomeLightingStrengthChanged();

/**
* Emitted when the list of point lights changes
* \since QGIS 3.6
@@ -595,6 +617,9 @@ class _3D_EXPORT Qgs3DMapSettings : public QObject, public QgsTemporalRangeObjec
bool mIsSkyboxEnabled = false; //!< Whether the skybox is enabled
QgsSkyboxSettings mSkyboxSettings; //!< Skybox related configuration
QgsShadowSettings mShadowSettings; //!< Shadow rendering related settings

bool mEyeDomeLightingEnabled = false;
double mEyeDomeLightingStrength = 1000.0f;
};


@@ -124,6 +124,11 @@ QgsPostprocessingEntity::QgsPostprocessingEntity( QgsShadowRenderingFrameGraph *
mShadowBiasParameter = new Qt3DRender::QParameter( "shadowBias", QVariant::fromValue( 0.00001f ) );
mMaterial->addParameter( mShadowBiasParameter );

mEyeDomeShadingEnabledParameter = new Qt3DRender::QParameter( "edlEnabled", QVariant::fromValue( 0 ) );
mEyeDomeShadingStrengthParameter = new Qt3DRender::QParameter( "edlStrength", QVariant::fromValue( 1000.0f ) );
mMaterial->addParameter( mEyeDomeShadingEnabledParameter );
mMaterial->addParameter( mEyeDomeShadingStrengthParameter );

mLightPosition = new Qt3DRender::QParameter( "lightPosition", QVariant::fromValue( QVector3D() ) );
mLightDirection = new Qt3DRender::QParameter( "lightDirection", QVariant::fromValue( QVector3D() ) );
mMaterial->addParameter( mLightPosition );
@@ -182,3 +187,13 @@ void QgsPostprocessingEntity::setShadowBias( float shadowBias )
{
mShadowBiasParameter->setValue( QVariant::fromValue( shadowBias ) );
}

void QgsPostprocessingEntity::setEyeDomeLightingEnabled( bool enabled )
{
mEyeDomeShadingEnabledParameter->setValue( QVariant::fromValue( enabled ? 1 : 0 ) );
}

void QgsPostprocessingEntity::setEyeDomeLightingStrength( double strength )
{
mEyeDomeShadingStrengthParameter->setValue( QVariant::fromValue( strength ) );
}
@@ -48,6 +48,10 @@ class QgsPostprocessingEntity : public Qt3DCore::QEntity
void setShadowRenderingEnabled( bool enabled );
//! Sets the shadow bias value
void setShadowBias( float shadowBias );
//! Sets whether eye dome lighting is enabled
void setEyeDomeLightingEnabled( bool enabled );
//! Sets the eye dome lighting strength
void setEyeDomeLightingStrength( double strength );
private:
Qt3DRender::QMaterial *mMaterial = nullptr;
Qt3DRender::QEffect *mEffect = nullptr;
@@ -74,6 +78,8 @@ class QgsPostprocessingEntity : public Qt3DCore::QEntity

Qt3DRender::QParameter *mRenderShadowsParameter = nullptr;
Qt3DRender::QParameter *mShadowBiasParameter = nullptr;
Qt3DRender::QParameter *mEyeDomeShadingEnabledParameter = nullptr;
Qt3DRender::QParameter *mEyeDomeShadingStrengthParameter = nullptr;
};

#endif // QGSPOSTPROCESSINGENTITY_H
@@ -342,3 +342,11 @@ void QgsShadowRenderingFrameGraph::setFrustumCullingEnabled( bool enabled )
else
mFrustumCulling->setParent( ( Qt3DCore::QNode * )nullptr );
}

void QgsShadowRenderingFrameGraph::setupEyeDomeLighting( bool enabled, double strength )
{
mEyeDomeLightingEnabled = enabled;
mEyeDomeLightingStrength = strength;
mPostprocessingEntity->setEyeDomeLightingEnabled( enabled );
mPostprocessingEntity->setEyeDomeLightingStrength( strength );
}
@@ -116,6 +116,8 @@ class QgsShadowRenderingFrameGraph : public Qt3DCore::QEntity
void addTexturePreviewOverlay( Qt3DRender::QTexture2D *texture, const QPointF &centerNDC, const QSizeF &size, QVector<Qt3DRender::QParameter *> additionalShaderParameters = QVector<Qt3DRender::QParameter *>() );
//! Sets shadow rendering to use a directional light
void setupDirectionalLight( const QgsDirectionalLightSettings &light, float maximumShadowRenderingDistance );
//! Sets eye dome lighting shading related settings
void setupEyeDomeLighting( bool enabled, double strength );
private:
Qt3DRender::QRenderSurfaceSelector *mRenderSurfaceSelector = nullptr;
Qt3DRender::QViewport *mMainViewPort = nullptr;
@@ -153,6 +155,9 @@ class QgsShadowRenderingFrameGraph : public Qt3DCore::QEntity
float mShadowBias = 0.00001f;
int mShadowMapResolution = 2048;

bool mEyeDomeLightingEnabled = false;
double mEyeDomeLightingStrength = 1000.0f;

Qt3DRender::QLayerFilter *mShadowSceneEntitiesFilter = nullptr;
Qt3DRender::QRenderStateSet *mShadowRenderStateSet = nullptr;
Qt3DRender::QCullFace *mShadowCullFace = nullptr;
@@ -28,6 +28,9 @@ uniform float nearPlane;
uniform int renderShadows;
uniform float shadowBias;

uniform int edlEnabled;
uniform float edlStrength;

in vec2 texCoord;

out vec4 fragColor;
@@ -69,6 +72,26 @@ float CalcShadowFactor(vec4 LightSpacePos)
return shadow / (2 * k + 1) / (2 * k + 1);
}

float edlFactor(vec2 coords)
{
vec2 texelSize = 2.0 / textureSize(shadowTexture, 0);
vec2 neighbours[4] = vec2[4](vec2(-1.0f, 0.0f), vec2(1.0f, 0.0f), vec2(0.0f, -1.0f), vec2(0.0f, 1.0f));
float factor = 0.0f;
float centerDepth = texture(depthTexture, coords).r;
for (int i = 0; i < 4; i++)
{
vec2 neighbourCoords = coords + texelSize * neighbours[i];
float neighbourDepth = texture(depthTexture, neighbourCoords).r;
neighbourDepth = (neighbourDepth == 1.0) ? 0.0 : neighbourDepth;
if (neighbourDepth != 0.0f)
{
if (centerDepth == 0.0f) factor += 100.0f;
else factor += max(0, centerDepth - neighbourDepth);
}
}
return factor / 4.0f;
}

void main()
{
vec3 worldPosition = WorldPosFromDepth(texture(depthTexture, texCoord).r);
@@ -82,4 +105,9 @@ void main()
float visibilityFactor = CalcShadowFactor(positionInLightSpace);
fragColor = vec4(visibilityFactor * color, 1.0f);
}
if (edlEnabled != 0)
{
float shade = exp(-edlFactor(texCoord) * 300.0 * edlStrength);
fragColor = vec4(fragColor.rgb * shade, fragColor.a);
}
}
@@ -161,6 +161,10 @@ Qgs3DMapConfigWidget::Qgs3DMapConfigWidget( Qgs3DMapSettings *map, QgsMapCanvas
connect( widgetLights, &QgsLightsWidget::lightsRemoved, this, &Qgs3DMapConfigWidget::validate );

groupShadowRendering->setChecked( map->shadowSettings().renderShadows() );

edlGroupBox->setChecked( map->eyeDomeLightingEnabled() );
edlStrengthSpinBox->setValue( map->eyeDomeLightingStrength() );
connect( edlStrengthSpinBox, qgis::overload<double>::of( &QDoubleSpinBox::valueChanged ), mMap, &Qgs3DMapSettings::setEyeDomeLightingStrength );
}

Qgs3DMapConfigWidget::~Qgs3DMapConfigWidget()
@@ -286,6 +290,9 @@ void Qgs3DMapConfigWidget::apply()
QgsShadowSettings shadowSettings = mShadowSetiingsWidget->toShadowSettings();
shadowSettings.setRenderShadows( groupShadowRendering->isChecked() );
mMap->setShadowSettings( shadowSettings );

mMap->setEyeDomeLightingEnabled( edlGroupBox->isChecked() );
mMap->setEyeDomeLightingStrength( edlStrengthSpinBox->value() );
}

void Qgs3DMapConfigWidget::onTerrainTypeChanged()

0 comments on commit 618807e

Please sign in to comment.
You can’t perform that action at this time.