Skip to content

Commit

Permalink
add EDL distance
Browse files Browse the repository at this point in the history
  • Loading branch information
NEDJIMAbelgacem authored and wonder-sk committed Nov 6, 2020
1 parent 618807e commit d1d347d
Show file tree
Hide file tree
Showing 11 changed files with 104 additions and 22 deletions.
16 changes: 16 additions & 0 deletions python/3d/auto_generated/qgs3dmapsettings.sip.in
Expand Up @@ -431,6 +431,15 @@ Sets the eye dome lighting strength value
double eyeDomeLightingStrength() const;
%Docstring
Returns the eye dome lighting strength value
%End

void setEyeDomeLightingDistance( int distance );
%Docstring
Sets the eye dome lighting distance value (contributes to the contrast of the image)
%End
int eyeDomeLightingDistance() const;
%Docstring
Returns the eye dome lighting distance value (contributes to the contrast of the image)
%End

QList<QgsPointLightSettings> pointLights() const;
Expand Down Expand Up @@ -630,6 +639,13 @@ Emitted when the flag whether eye dome lighting is used has changed
%Docstring
Emitted when the eye dome lighting stength has changed

.. versionadded:: 3.18
%End

void eyeDomeLightingDistanceChanged();
%Docstring
Emitted when the eye dome lighting distance has changed

.. versionadded:: 3.18
%End

Expand Down
9 changes: 6 additions & 3 deletions src/3d/qgs3dmapscene.cpp
Expand Up @@ -131,8 +131,9 @@ 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::eyeDomeLightingEnabledChanged, this, &Qgs3DMapScene::onEyeDomeShadingSettingsChanged );
connect( &map, &Qgs3DMapSettings::eyeDomeLightingStrengthChanged, this, &Qgs3DMapScene::onEyeDomeShadingSettingsChanged );
connect( &map, &Qgs3DMapSettings::eyeDomeLightingDistanceChanged, this, &Qgs3DMapScene::onEyeDomeShadingSettingsChanged );

connect( QgsApplication::instance()->sourceCache(), &QgsSourceCache::remoteSourceFetched, this, [ = ]( const QString & url )
{
Expand Down Expand Up @@ -216,6 +217,8 @@ Qgs3DMapScene::Qgs3DMapScene( const Qgs3DMapSettings &map, QgsAbstract3DEngine *

// force initial update of chunked entities
onCameraChanged();
// force initial update of eye dome shadng
onEyeDomeShadingSettingsChanged();
}

void Qgs3DMapScene::viewZoomFull()
Expand Down Expand Up @@ -966,15 +969,15 @@ void Qgs3DMapScene::onShadowSettingsChanged()

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 );
double edlDistance = mMap.eyeDomeLightingDistance();
shadowRenderingFrameGraph->setupEyeDomeLighting( edlEnabled, edlStrength, edlDistance );
}

void Qgs3DMapScene::exportScene( const Qgs3DMapExportSettings &exportSettings )
Expand Down
11 changes: 10 additions & 1 deletion src/3d/qgs3dmapsettings.cpp
Expand Up @@ -240,6 +240,7 @@ void Qgs3DMapSettings::readXml( const QDomElement &elem, const QgsReadWriteConte
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();
mEyeDomeLightingDistance = elemEyeDomeLighting.attribute( "eye-dome-lighting-distance", QStringLiteral( "1" ) ).toInt();

QDomElement elemDebug = elem.firstChildElement( QStringLiteral( "debug" ) );
mShowTerrainBoundingBoxes = elemDebug.attribute( QStringLiteral( "bounding-boxes" ), QStringLiteral( "0" ) ).toInt();
Expand Down Expand Up @@ -357,6 +358,7 @@ QDomElement Qgs3DMapSettings::writeXml( QDomDocument &doc, const QgsReadWriteCon
QDomElement elemEyeDomeLighting = doc.createElement( QStringLiteral( "eye-dome-lighting" ) );
elemEyeDomeLighting.setAttribute( "enabled", mEyeDomeLightingEnabled ? 1 : 0 );
elemEyeDomeLighting.setAttribute( "eye-dome-lighting-strength", mEyeDomeLightingStrength );
elemEyeDomeLighting.setAttribute( "eye-dome-lighting-distance", mEyeDomeLightingDistance );
elem.appendChild( elemEyeDomeLighting );

QDomElement elemTemporalRange = doc.createElement( QStringLiteral( "temporal-range" ) );
Expand Down Expand Up @@ -652,11 +654,18 @@ void Qgs3DMapSettings::setEyeDomeLightingStrength( double strength )
{
if ( mEyeDomeLightingStrength == strength )
return;
qDebug() << "Qgs3DMapSettings::setEyeDomeLightingStrength";
mEyeDomeLightingStrength = strength;
emit eyeDomeLightingStrengthChanged();
}

void Qgs3DMapSettings::setEyeDomeLightingDistance( int distance )
{
if ( mEyeDomeLightingDistance == distance )
return;
mEyeDomeLightingDistance = distance;
emit eyeDomeLightingDistanceChanged();
}

void Qgs3DMapSettings::setPointLights( const QList<QgsPointLightSettings> &pointLights )
{
if ( mPointLights == pointLights )
Expand Down
12 changes: 12 additions & 0 deletions src/3d/qgs3dmapsettings.h
Expand Up @@ -372,6 +372,11 @@ class _3D_EXPORT Qgs3DMapSettings : public QObject, public QgsTemporalRangeObjec
//! Returns the eye dome lighting strength value
double eyeDomeLightingStrength() const { return mEyeDomeLightingStrength; }

//! Sets the eye dome lighting distance value (contributes to the contrast of the image)
void setEyeDomeLightingDistance( int distance );
//! Returns the eye dome lighting distance value (contributes to the contrast of the image)
int eyeDomeLightingDistance() const { return mEyeDomeLightingDistance; }

/**
* Returns list of point lights defined in the scene
* \since QGIS 3.6
Expand Down Expand Up @@ -548,6 +553,12 @@ class _3D_EXPORT Qgs3DMapSettings : public QObject, public QgsTemporalRangeObjec
*/
void eyeDomeLightingStrengthChanged();

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

/**
* Emitted when the list of point lights changes
* \since QGIS 3.6
Expand Down Expand Up @@ -620,6 +631,7 @@ class _3D_EXPORT Qgs3DMapSettings : public QObject, public QgsTemporalRangeObjec

bool mEyeDomeLightingEnabled = false;
double mEyeDomeLightingStrength = 1000.0f;
int mEyeDomeLightingDistance = 1;
};


Expand Down
19 changes: 13 additions & 6 deletions src/3d/qgspostprocessingentity.cpp
Expand Up @@ -124,10 +124,12 @@ 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 );
mEyeDomeLightingEnabledParameter = new Qt3DRender::QParameter( "edlEnabled", QVariant::fromValue( 0 ) );
mEyeDomeLightingStrengthParameter = new Qt3DRender::QParameter( "edlStrength", QVariant::fromValue( 1000.0f ) );
mEyeDomeLightingDistanceParameter = new Qt3DRender::QParameter( "edlDistance", QVariant::fromValue( 2.0f ) );
mMaterial->addParameter( mEyeDomeLightingEnabledParameter );
mMaterial->addParameter( mEyeDomeLightingStrengthParameter );
mMaterial->addParameter( mEyeDomeLightingDistanceParameter );

mLightPosition = new Qt3DRender::QParameter( "lightPosition", QVariant::fromValue( QVector3D() ) );
mLightDirection = new Qt3DRender::QParameter( "lightDirection", QVariant::fromValue( QVector3D() ) );
Expand Down Expand Up @@ -190,10 +192,15 @@ void QgsPostprocessingEntity::setShadowBias( float shadowBias )

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

void QgsPostprocessingEntity::setEyeDomeLightingStrength( double strength )
{
mEyeDomeShadingStrengthParameter->setValue( QVariant::fromValue( strength ) );
mEyeDomeLightingStrengthParameter->setValue( QVariant::fromValue( strength ) );
}

void QgsPostprocessingEntity::setEyeDomeLightingDistance( double distance )
{
mEyeDomeLightingDistanceParameter->setValue( QVariant::fromValue( distance ) );
}
7 changes: 5 additions & 2 deletions src/3d/qgspostprocessingentity.h
Expand Up @@ -52,6 +52,8 @@ class QgsPostprocessingEntity : public Qt3DCore::QEntity
void setEyeDomeLightingEnabled( bool enabled );
//! Sets the eye dome lighting strength
void setEyeDomeLightingStrength( double strength );
//! Sets the eye dome lighting distance (contributes to the contrast of the image)
void setEyeDomeLightingDistance( double distance );
private:
Qt3DRender::QMaterial *mMaterial = nullptr;
Qt3DRender::QEffect *mEffect = nullptr;
Expand All @@ -78,8 +80,9 @@ class QgsPostprocessingEntity : public Qt3DCore::QEntity

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

#endif // QGSPOSTPROCESSINGENTITY_H
4 changes: 3 additions & 1 deletion src/3d/qgsshadowrenderingframegraph.cpp
Expand Up @@ -343,10 +343,12 @@ void QgsShadowRenderingFrameGraph::setFrustumCullingEnabled( bool enabled )
mFrustumCulling->setParent( ( Qt3DCore::QNode * )nullptr );
}

void QgsShadowRenderingFrameGraph::setupEyeDomeLighting( bool enabled, double strength )
void QgsShadowRenderingFrameGraph::setupEyeDomeLighting( bool enabled, double strength, double distance )
{
mEyeDomeLightingEnabled = enabled;
mEyeDomeLightingStrength = strength;
mEyeDomeLightingDistance = distance;
mPostprocessingEntity->setEyeDomeLightingEnabled( enabled );
mPostprocessingEntity->setEyeDomeLightingStrength( strength );
mPostprocessingEntity->setEyeDomeLightingDistance( distance );
}
3 changes: 2 additions & 1 deletion src/3d/qgsshadowrenderingframegraph.h
Expand Up @@ -117,7 +117,7 @@ class QgsShadowRenderingFrameGraph : public Qt3DCore::QEntity
//! 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 );
void setupEyeDomeLighting( bool enabled, double strength, double distance );
private:
Qt3DRender::QRenderSurfaceSelector *mRenderSurfaceSelector = nullptr;
Qt3DRender::QViewport *mMainViewPort = nullptr;
Expand Down Expand Up @@ -157,6 +157,7 @@ class QgsShadowRenderingFrameGraph : public Qt3DCore::QEntity

bool mEyeDomeLightingEnabled = false;
double mEyeDomeLightingStrength = 1000.0f;
double mEyeDomeLightingDistance = 1.0f;

Qt3DRender::QLayerFilter *mShadowSceneEntitiesFilter = nullptr;
Qt3DRender::QRenderStateSet *mShadowRenderStateSet = nullptr;
Expand Down
19 changes: 14 additions & 5 deletions src/3d/shaders/postprocess.frag
Expand Up @@ -30,6 +30,7 @@ uniform float shadowBias;

uniform int edlEnabled;
uniform float edlStrength;
uniform float edlDistance;

in vec2 texCoord;

Expand All @@ -48,6 +49,14 @@ vec3 WorldPosFromDepth(float depth) {
return worldSpacePosition.xyz;
}

vec4 EyeCoordsFromDepth(vec2 textureCoord, float depth) {
float z = depth * 2.0 - 1.0;

vec4 clipSpacePosition = vec4(textureCoord * 2.0 - 1.0, z, 1.0);
vec4 viewSpacePosition = invertedCameraProj * clipSpacePosition;
return viewSpacePosition;
}

float CalcShadowFactor(vec4 LightSpacePos)
{
vec2 texelSize = 1.0 / textureSize(shadowTexture, 0);
Expand Down Expand Up @@ -75,17 +84,17 @@ float CalcShadowFactor(vec4 LightSpacePos)
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));
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;
vec2 neighbourCoords = coords + edlDistance * texelSize * neighbours[i];
float neighbourDepth = texture2D(depthTexture, neighbourCoords).r;
neighbourDepth = (neighbourDepth == 1.0) ? 0.0 : neighbourDepth;
if (neighbourDepth != 0.0f)
{
if (centerDepth == 0.0f) factor += 100.0f;
if (centerDepth == 0.0f) factor += 1.0f;
else factor += max(0, centerDepth - neighbourDepth);
}
}
Expand All @@ -107,7 +116,7 @@ void main()
}
if (edlEnabled != 0)
{
float shade = exp(-edlFactor(texCoord) * 300.0 * edlStrength);
float shade = exp(-edlFactor(texCoord) * edlStrength);
fragColor = vec4(fragColor.rgb * shade, fragColor.a);
}
}
3 changes: 3 additions & 0 deletions src/app/3d/qgs3dmapconfigwidget.cpp
Expand Up @@ -164,7 +164,9 @@ Qgs3DMapConfigWidget::Qgs3DMapConfigWidget( Qgs3DMapSettings *map, QgsMapCanvas

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

Qgs3DMapConfigWidget::~Qgs3DMapConfigWidget()
Expand Down Expand Up @@ -293,6 +295,7 @@ void Qgs3DMapConfigWidget::apply()

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

void Qgs3DMapConfigWidget::onTerrainTypeChanged()
Expand Down
23 changes: 20 additions & 3 deletions src/ui/3d/map3dconfigwidget.ui
Expand Up @@ -393,7 +393,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>77</width>
<width>98</width>
<height>43</height>
</rect>
</property>
Expand Down Expand Up @@ -477,8 +477,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>699</width>
<height>604</height>
<width>133</width>
<height>43</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayoutShadow">
Expand Down Expand Up @@ -832,6 +832,23 @@
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Eye dome lighting distance</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="edlDistanceSpinBox">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>20</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
Expand Down

0 comments on commit d1d347d

Please sign in to comment.