QGIS API Documentation 4.1.0-Master (64dc32379c2)
Loading...
Searching...
No Matches
qgspostprocessingentity.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgspostprocessingentity.cpp
3 --------------------------------------
4 Date : August 2020
5 Copyright : (C) 2020 by Belgacem Nedjima
6 Email : gb underscore nedjima at esi dot dz
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
17
18#include "qgs3dutils.h"
22#include "qgsframegraph.h"
23#include "qgsshadowrenderview.h"
24
25#include <QString>
26#include <QUrl>
27#include <Qt3DCore/QAttribute>
28#include <Qt3DCore/QBuffer>
29#include <Qt3DCore/QGeometry>
30#include <Qt3DRender/QDepthTest>
31#include <Qt3DRender/QGeometryRenderer>
32#include <Qt3DRender/QGraphicsApiFilter>
33#include <Qt3DRender/QMaterial>
34#include <Qt3DRender/QParameter>
35#include <Qt3DRender/QTechnique>
36
37#include "moc_qgspostprocessingentity.cpp"
38
39using namespace Qt::StringLiterals;
40
41QgsPostprocessingEntity::QgsPostprocessingEntity( QgsFrameGraph *frameGraph, Qt3DRender::QLayer *layer, QNode *parent )
42 : QgsRenderPassQuad( layer, parent )
43{
44 QgsShadowRenderView &shadowRenderView = frameGraph->shadowRenderView();
45 QgsForwardRenderView &forwardRenderView = frameGraph->forwardRenderView();
47
48 mColorTextureParameter = new Qt3DRender::QParameter( u"colorTexture"_s, forwardRenderView.colorTexture() );
49 mDepthTextureParameter = new Qt3DRender::QParameter( u"depthTexture"_s, forwardRenderView.depthTexture() );
50 mShadowMapParameter = new Qt3DRender::QParameter( u"shadowTexture"_s, shadowRenderView.mapTexture() );
51 mAmbientOcclusionTextureParameter = new Qt3DRender::QParameter( u"ssaoTexture"_s, aoRenderView.blurredFactorMapTexture() );
52 mMaterial->addParameter( mColorTextureParameter );
53 mMaterial->addParameter( mDepthTextureParameter );
54 mMaterial->addParameter( mShadowMapParameter );
55 mMaterial->addParameter( mAmbientOcclusionTextureParameter );
56
57 mMainCamera = frameGraph->mainCamera();
58 mLightCamera = shadowRenderView.lightCamera();
59
60 mFarPlaneParameter = new Qt3DRender::QParameter( u"farPlane"_s, mMainCamera->farPlane() );
61 mMaterial->addParameter( mFarPlaneParameter );
62 connect( mMainCamera, &Qt3DRender::QCamera::farPlaneChanged, mFarPlaneParameter, [&]( float farPlane ) { mFarPlaneParameter->setValue( farPlane ); } );
63 mNearPlaneParameter = new Qt3DRender::QParameter( u"nearPlane"_s, mMainCamera->nearPlane() );
64 mMaterial->addParameter( mNearPlaneParameter );
65 connect( mMainCamera, &Qt3DRender::QCamera::nearPlaneChanged, mNearPlaneParameter, [&]( float nearPlane ) { mNearPlaneParameter->setValue( nearPlane ); } );
66
67 mLightFarPlaneParameter = new Qt3DRender::QParameter( u"lightFarPlane"_s, mLightCamera->farPlane() );
68 mMaterial->addParameter( mLightFarPlaneParameter );
69 connect( mLightCamera, &Qt3DRender::QCamera::farPlaneChanged, mLightFarPlaneParameter, [&]( float farPlane ) { mLightFarPlaneParameter->setValue( farPlane ); } );
70 mLightNearPlaneParameter = new Qt3DRender::QParameter( u"lightNearPlane"_s, mLightCamera->nearPlane() );
71 mMaterial->addParameter( mLightNearPlaneParameter );
72 connect( mLightCamera, &Qt3DRender::QCamera::nearPlaneChanged, mLightNearPlaneParameter, [&]( float nearPlane ) { mLightNearPlaneParameter->setValue( nearPlane ); } );
73
74 mMainCameraInvViewMatrixParameter = new Qt3DRender::QParameter( u"invertedCameraView"_s, mMainCamera->viewMatrix().inverted() );
75 mMaterial->addParameter( mMainCameraInvViewMatrixParameter );
76 mMainCameraInvProjMatrixParameter = new Qt3DRender::QParameter( u"invertedCameraProj"_s, mMainCamera->projectionMatrix().inverted() );
77 mMaterial->addParameter( mMainCameraInvProjMatrixParameter );
78 connect( mMainCamera, &Qt3DRender::QCamera::projectionMatrixChanged, mMainCameraInvProjMatrixParameter, [&]( const QMatrix4x4 &projectionMatrix ) {
79 mMainCameraInvProjMatrixParameter->setValue( projectionMatrix.inverted() );
80 } );
81 connect( mMainCamera, &Qt3DRender::QCamera::viewMatrixChanged, mMainCameraInvViewMatrixParameter, [&]() { mMainCameraInvViewMatrixParameter->setValue( mMainCamera->viewMatrix().inverted() ); } );
82
83 mShadowMinX = new Qt3DRender::QParameter( u"shadowMinX"_s, QVariant::fromValue( 0.0f ) );
84 mShadowMaxX = new Qt3DRender::QParameter( u"shadowMaxX"_s, QVariant::fromValue( 0.0f ) );
85 mShadowMinY = new Qt3DRender::QParameter( u"shadowMinY"_s, QVariant::fromValue( 0.0f ) );
86 mShadowMaxY = new Qt3DRender::QParameter( u"shadowMaxY"_s, QVariant::fromValue( 0.0f ) );
87 mMaterial->addParameter( mShadowMinX );
88 mMaterial->addParameter( mShadowMaxX );
89 mMaterial->addParameter( mShadowMinY );
90 mMaterial->addParameter( mShadowMaxY );
91
92 mRenderShadowsParameter = new Qt3DRender::QParameter( u"renderShadows"_s, QVariant::fromValue( 0 ) );
93 mMaterial->addParameter( mRenderShadowsParameter );
94
95 mShadowBiasParameter = new Qt3DRender::QParameter( u"shadowBias"_s, QVariant::fromValue( 0.00001f ) );
96 mMaterial->addParameter( mShadowBiasParameter );
97
98 mEyeDomeLightingEnabledParameter = new Qt3DRender::QParameter( u"edlEnabled"_s, QVariant::fromValue( 0 ) );
99 mEyeDomeLightingStrengthParameter = new Qt3DRender::QParameter( u"edlStrength"_s, QVariant::fromValue( 1000.0f ) );
100 mEyeDomeLightingDistanceParameter = new Qt3DRender::QParameter( u"edlDistance"_s, QVariant::fromValue( 2.0f ) );
101 mMaterial->addParameter( mEyeDomeLightingEnabledParameter );
102 mMaterial->addParameter( mEyeDomeLightingStrengthParameter );
103 mMaterial->addParameter( mEyeDomeLightingDistanceParameter );
104
105 mAmbientOcclusionEnabledParameter = new Qt3DRender::QParameter( u"ssaoEnabled"_s, QVariant::fromValue( 0 ) );
106 mMaterial->addParameter( mAmbientOcclusionEnabledParameter );
107
108 mLightPosition = new Qt3DRender::QParameter( u"lightPosition"_s, QVariant::fromValue( QVector3D() ) );
109 mLightDirection = new Qt3DRender::QParameter( u"lightDirection"_s, QVariant::fromValue( QVector3D() ) );
110 mMaterial->addParameter( mLightPosition );
111 mMaterial->addParameter( mLightDirection );
112
113 const QString vertexShaderPath = u"qrc:/shaders/postprocess.vert"_s;
114 const QString fragmentShaderPath = u"qrc:/shaders/postprocess.frag"_s;
115
116 mShader->setVertexShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( vertexShaderPath ) ) );
117
118 const QByteArray fragmentShaderCode = Qt3DRender::QShaderProgram::loadSource( QUrl( fragmentShaderPath ) );
119 const QByteArray finalFragmentShaderCode = Qgs3DUtils::addDefinesToShaderCode( fragmentShaderCode, QStringList( { "ENABLE_EFFECTS" } ) );
120 mShader->setFragmentShaderCode( finalFragmentShaderCode );
121}
122
123void QgsPostprocessingEntity::setupShadowRenderingExtent( float minX, float maxX, float minY, float maxY )
124{
125 mShadowMinX->setValue( minX );
126 mShadowMaxX->setValue( maxX );
127 mShadowMinY->setValue( minY );
128 mShadowMaxY->setValue( maxY );
129}
130
131void QgsPostprocessingEntity::setupDirectionalLight( QVector3D position, QVector3D direction )
132{
133 mLightPosition->setValue( QVariant::fromValue( position ) );
134 mLightDirection->setValue( QVariant::fromValue( direction.normalized() ) );
135}
136
137void QgsPostprocessingEntity::updateShadowSettings( const QgsDirectionalLightSettings &light, float maximumShadowRenderingDistance )
138{
139 float minX, maxX, minY, maxY, minZ, maxZ;
140 QVector3D lookingAt = mMainCamera->viewCenter();
141 const float d = 2 * ( mMainCamera->position() - mMainCamera->viewCenter() ).length();
142
143 const QVector3D lightDirection = light.direction().toVector3D().normalized();
144 Qgs3DUtils::calculateViewExtent( mMainCamera, maximumShadowRenderingDistance, lookingAt.z(), minX, maxX, minY, maxY, minZ, maxZ );
145
146 lookingAt = QVector3D( 0.5f * ( minX + maxX ), 0.5f * ( minY + maxY ), mMainCamera->viewCenter().z() );
147 const QVector3D lightPosition = lookingAt + QVector3D( 0.0f, 0.0f, d );
148 mLightCamera->setPosition( lightPosition );
149 mLightCamera->setViewCenter( lookingAt );
150 mLightCamera->setUpVector( QVector3D( 0.0f, 1.0f, 0.0f ) );
151 mLightCamera->rotateAboutViewCenter( QQuaternion::rotationTo( QVector3D( 0.0f, 0.0f, -1.0f ), lightDirection ) );
152
153 mLightCamera->setProjectionType( Qt3DRender::QCameraLens::ProjectionType::OrthographicProjection );
154 // clang-format off
155 mLightCamera->lens()->setOrthographicProjection(
156 -0.7f * ( maxX - minX ), 0.7f * ( maxX - minX ),
157 -0.7f * ( maxY - minY ), 0.7f * ( maxY - minY ),
158 1.0f, 2 * ( lookingAt - lightPosition ).length()
159 );
160 // clang-format on
161
162 setupShadowRenderingExtent( minX, maxX, minY, maxY );
163 setupDirectionalLight( lightPosition, lightDirection );
164}
165
167{
168 mRenderShadowsParameter->setValue( QVariant::fromValue( enabled ? 1 : 0 ) );
169}
170
172{
173 mShadowBiasParameter->setValue( QVariant::fromValue( shadowBias ) );
174}
175
177{
178 mEyeDomeLightingEnabledParameter->setValue( QVariant::fromValue( enabled ? 1 : 0 ) );
179}
180
182{
183 mEyeDomeLightingStrengthParameter->setValue( QVariant::fromValue( strength ) );
184}
185
187{
188 mEyeDomeLightingDistanceParameter->setValue( QVariant::fromValue( distance ) );
189}
190
192{
193 mAmbientOcclusionEnabledParameter->setValue( enabled );
194}
static QByteArray addDefinesToShaderCode(const QByteArray &shaderCode, const QStringList &defines)
Inserts some define macros into a shader source code.
static void calculateViewExtent(const Qt3DRender::QCamera *camera, float maxRenderingDistance, float z, float &minX, float &maxX, float &minY, float &maxY, float &minZ, float &maxZ)
Computes the portion of the Y=y plane the camera is looking at.
Container class that holds different objects related to ambient occlusion rendering.
Qt3DRender::QTexture2D * blurredFactorMapTexture() const
Returns blur pass texture.
Definition of a directional light in a 3D map scene.
QgsVector3D direction() const
Returns the direction of the light in degrees.
Container class that holds different objects related to forward rendering.
Qt3DRender::QTexture2D * colorTexture() const
Returns forward color texture.
Qt3DRender::QTexture2D * depthTexture() const
Returns forward depth texture.
Container class that holds different objects related to frame graphs of 3D scenes.
QgsAmbientOcclusionRenderView & ambientOcclusionRenderView()
Returns ambient occlusion renderview.
QgsForwardRenderView & forwardRenderView()
Returns forward renderview.
QgsShadowRenderView & shadowRenderView()
Returns shadow renderview.
Qt3DRender::QCamera * mainCamera()
Returns the main camera.
void setupShadowRenderingExtent(float minX, float maxX, float minY, float maxY)
Sets the parts of the scene where objects cast shadows.
void setAmbientOcclusionEnabled(bool enabled)
Sets whether screen space ambient occlusion is enabled.
void setShadowRenderingEnabled(bool enabled)
Sets whether shadow rendering is enabled.
void updateShadowSettings(const QgsDirectionalLightSettings &light, float maximumShadowRenderingDistance)
Sets shadow rendering to use a directional light.
void setEyeDomeLightingDistance(int distance)
Sets the eye dome lighting distance (contributes to the contrast of the image).
void setShadowBias(float shadowBias)
Sets the shadow bias value.
void setEyeDomeLightingStrength(double strength)
Sets the eye dome lighting strength.
void setupDirectionalLight(QVector3D position, QVector3D direction)
Sets up a directional light that is used to render shadows.
void setEyeDomeLightingEnabled(bool enabled)
Sets whether eye dome lighting is enabled.
QgsPostprocessingEntity(QgsFrameGraph *frameGraph, Qt3DRender::QLayer *layer, QNode *parent=nullptr)
Constructor.
QgsRenderPassQuad(Qt3DRender::QLayer *layer, QNode *parent=nullptr)
Constructor.
Qt3DRender::QShaderProgram * mShader
Qt3DRender::QMaterial * mMaterial
Container class that holds different objects related to shadow rendering.
Qt3DRender::QCamera * lightCamera()
Returns the light camera.
Qt3DRender::QTexture2D * mapTexture() const
Returns shadow depth texture.
QVector3D toVector3D() const
Converts the current object to QVector3D.