QGIS API Documentation 3.43.0-Master (b60ef06885e)
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#include "moc_qgspostprocessingentity.cpp"
18
19#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
20#include <Qt3DRender/QAttribute>
21#include <Qt3DRender/QBuffer>
22#include <Qt3DRender/QGeometry>
23
24typedef Qt3DRender::QAttribute Qt3DQAttribute;
25typedef Qt3DRender::QBuffer Qt3DQBuffer;
26typedef Qt3DRender::QGeometry Qt3DQGeometry;
27#else
28#include <Qt3DCore/QAttribute>
29#include <Qt3DCore/QBuffer>
30#include <Qt3DCore/QGeometry>
31
32typedef Qt3DCore::QAttribute Qt3DQAttribute;
33typedef Qt3DCore::QBuffer Qt3DQBuffer;
34typedef Qt3DCore::QGeometry Qt3DQGeometry;
35#endif
36
37#include <Qt3DRender/QGeometryRenderer>
38#include <Qt3DRender/QParameter>
39#include <Qt3DRender/QTechnique>
40#include <Qt3DRender/QGraphicsApiFilter>
41#include <Qt3DRender/QDepthTest>
42#include <QUrl>
43
44#include "qgs3dutils.h"
46#include "qgsframegraph.h"
47#include "qgsshadowrenderview.h"
49
50QgsPostprocessingEntity::QgsPostprocessingEntity( QgsFrameGraph *frameGraph, Qt3DRender::QLayer *layer, QNode *parent )
51 : QgsRenderPassQuad( layer, parent )
52{
53 QgsShadowRenderView &shadowRenderView = frameGraph->shadowRenderView();
54 QgsForwardRenderView &forwardRenderView = frameGraph->forwardRenderView();
55 mColorTextureParameter = new Qt3DRender::QParameter( QStringLiteral( "colorTexture" ), forwardRenderView.colorTexture() );
56 mDepthTextureParameter = new Qt3DRender::QParameter( QStringLiteral( "depthTexture" ), forwardRenderView.depthTexture() );
57 mShadowMapParameter = new Qt3DRender::QParameter( QStringLiteral( "shadowTexture" ), shadowRenderView.mapTexture() );
58 mAmbientOcclusionTextureParameter = new Qt3DRender::QParameter( QStringLiteral( "ssaoTexture" ), frameGraph->blurredAmbientOcclusionFactorMap() );
59 mMaterial->addParameter( mColorTextureParameter );
60 mMaterial->addParameter( mDepthTextureParameter );
61 mMaterial->addParameter( mShadowMapParameter );
62 mMaterial->addParameter( mAmbientOcclusionTextureParameter );
63
64 mMainCamera = frameGraph->mainCamera();
65 mLightCamera = shadowRenderView.lightCamera();
66
67 mFarPlaneParameter = new Qt3DRender::QParameter( QStringLiteral( "farPlane" ), mMainCamera->farPlane() );
68 mMaterial->addParameter( mFarPlaneParameter );
69 connect( mMainCamera, &Qt3DRender::QCamera::farPlaneChanged, mFarPlaneParameter, [&]( float farPlane ) {
70 mFarPlaneParameter->setValue( farPlane );
71 } );
72 mNearPlaneParameter = new Qt3DRender::QParameter( QStringLiteral( "nearPlane" ), mMainCamera->nearPlane() );
73 mMaterial->addParameter( mNearPlaneParameter );
74 connect( mMainCamera, &Qt3DRender::QCamera::nearPlaneChanged, mNearPlaneParameter, [&]( float nearPlane ) {
75 mNearPlaneParameter->setValue( nearPlane );
76 } );
77
78 mLightFarPlaneParameter = new Qt3DRender::QParameter( QStringLiteral( "lightFarPlane" ), mLightCamera->farPlane() );
79 mMaterial->addParameter( mLightFarPlaneParameter );
80 connect( mLightCamera, &Qt3DRender::QCamera::farPlaneChanged, mLightFarPlaneParameter, [&]( float farPlane ) {
81 mLightFarPlaneParameter->setValue( farPlane );
82 } );
83 mLightNearPlaneParameter = new Qt3DRender::QParameter( QStringLiteral( "lightNearPlane" ), mLightCamera->nearPlane() );
84 mMaterial->addParameter( mLightNearPlaneParameter );
85 connect( mLightCamera, &Qt3DRender::QCamera::nearPlaneChanged, mLightNearPlaneParameter, [&]( float nearPlane ) {
86 mLightNearPlaneParameter->setValue( nearPlane );
87 } );
88
89 mMainCameraInvViewMatrixParameter = new Qt3DRender::QParameter( QStringLiteral( "invertedCameraView" ), mMainCamera->viewMatrix().inverted() );
90 mMaterial->addParameter( mMainCameraInvViewMatrixParameter );
91 mMainCameraInvProjMatrixParameter = new Qt3DRender::QParameter( QStringLiteral( "invertedCameraProj" ), mMainCamera->projectionMatrix().inverted() );
92 mMaterial->addParameter( mMainCameraInvProjMatrixParameter );
93 connect( mMainCamera, &Qt3DRender::QCamera::projectionMatrixChanged, mMainCameraInvProjMatrixParameter, [&]( const QMatrix4x4 &projectionMatrix ) {
94 mMainCameraInvProjMatrixParameter->setValue( projectionMatrix.inverted() );
95 } );
96 connect( mMainCamera, &Qt3DRender::QCamera::viewMatrixChanged, mMainCameraInvViewMatrixParameter, [&]() {
97 mMainCameraInvViewMatrixParameter->setValue( mMainCamera->viewMatrix().inverted() );
98 } );
99
100 mShadowMinX = new Qt3DRender::QParameter( QStringLiteral( "shadowMinX" ), QVariant::fromValue( 0.0f ) );
101 mShadowMaxX = new Qt3DRender::QParameter( QStringLiteral( "shadowMaxX" ), QVariant::fromValue( 0.0f ) );
102 mShadowMinY = new Qt3DRender::QParameter( QStringLiteral( "shadowMinY" ), QVariant::fromValue( 0.0f ) );
103 mShadowMaxY = new Qt3DRender::QParameter( QStringLiteral( "shadowMaxY" ), QVariant::fromValue( 0.0f ) );
104 mMaterial->addParameter( mShadowMinX );
105 mMaterial->addParameter( mShadowMaxX );
106 mMaterial->addParameter( mShadowMinY );
107 mMaterial->addParameter( mShadowMaxY );
108
109 mRenderShadowsParameter = new Qt3DRender::QParameter( QStringLiteral( "renderShadows" ), QVariant::fromValue( 0 ) );
110 mMaterial->addParameter( mRenderShadowsParameter );
111
112 mShadowBiasParameter = new Qt3DRender::QParameter( QStringLiteral( "shadowBias" ), QVariant::fromValue( 0.00001f ) );
113 mMaterial->addParameter( mShadowBiasParameter );
114
115 mEyeDomeLightingEnabledParameter = new Qt3DRender::QParameter( QStringLiteral( "edlEnabled" ), QVariant::fromValue( 0 ) );
116 mEyeDomeLightingStrengthParameter = new Qt3DRender::QParameter( QStringLiteral( "edlStrength" ), QVariant::fromValue( 1000.0f ) );
117 mEyeDomeLightingDistanceParameter = new Qt3DRender::QParameter( QStringLiteral( "edlDistance" ), QVariant::fromValue( 2.0f ) );
118 mMaterial->addParameter( mEyeDomeLightingEnabledParameter );
119 mMaterial->addParameter( mEyeDomeLightingStrengthParameter );
120 mMaterial->addParameter( mEyeDomeLightingDistanceParameter );
121
122 mAmbientOcclusionEnabledParameter = new Qt3DRender::QParameter( QStringLiteral( "ssaoEnabled" ), QVariant::fromValue( 0 ) );
123 mMaterial->addParameter( mAmbientOcclusionEnabledParameter );
124
125 mLightPosition = new Qt3DRender::QParameter( QStringLiteral( "lightPosition" ), QVariant::fromValue( QVector3D() ) );
126 mLightDirection = new Qt3DRender::QParameter( QStringLiteral( "lightDirection" ), QVariant::fromValue( QVector3D() ) );
127 mMaterial->addParameter( mLightPosition );
128 mMaterial->addParameter( mLightDirection );
129
130 const QString vertexShaderPath = QStringLiteral( "qrc:/shaders/postprocess.vert" );
131 const QString fragmentShaderPath = QStringLiteral( "qrc:/shaders/postprocess.frag" );
132
133 mShader->setVertexShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( vertexShaderPath ) ) );
134 mShader->setFragmentShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( fragmentShaderPath ) ) );
135}
136
137void QgsPostprocessingEntity::setupShadowRenderingExtent( float minX, float maxX, float minY, float maxY )
138{
139 mShadowMinX->setValue( minX );
140 mShadowMaxX->setValue( maxX );
141 mShadowMinY->setValue( minY );
142 mShadowMaxY->setValue( maxY );
143}
144
145void QgsPostprocessingEntity::setupDirectionalLight( QVector3D position, QVector3D direction )
146{
147 mLightPosition->setValue( QVariant::fromValue( position ) );
148 mLightDirection->setValue( QVariant::fromValue( direction.normalized() ) );
149}
150
151void QgsPostprocessingEntity::updateShadowSettings( const QgsDirectionalLightSettings &light, float maximumShadowRenderingDistance )
152{
153 float minX, maxX, minY, maxY, minZ, maxZ;
154 QVector3D lookingAt = mMainCamera->viewCenter();
155 const float d = 2 * ( mMainCamera->position() - mMainCamera->viewCenter() ).length();
156
157 const QVector3D lightDirection = light.direction().toVector3D().normalized();
158 Qgs3DUtils::calculateViewExtent( mMainCamera, maximumShadowRenderingDistance, lookingAt.z(), minX, maxX, minY, maxY, minZ, maxZ );
159
160 lookingAt = QVector3D( 0.5f * ( minX + maxX ), 0.5f * ( minY + maxY ), mMainCamera->viewCenter().z() );
161 const QVector3D lightPosition = lookingAt + QVector3D( 0.0f, 0.0f, d );
162 mLightCamera->setPosition( lightPosition );
163 mLightCamera->setViewCenter( lookingAt );
164 mLightCamera->setUpVector( QVector3D( 0.0f, 1.0f, 0.0f ) );
165 mLightCamera->rotateAboutViewCenter( QQuaternion::rotationTo( QVector3D( 0.0f, 0.0f, -1.0f ), lightDirection ) );
166
167 mLightCamera->setProjectionType( Qt3DRender::QCameraLens::ProjectionType::OrthographicProjection );
168 mLightCamera->lens()->setOrthographicProjection(
169 -0.7f * ( maxX - minX ), 0.7f * ( maxX - minX ),
170 -0.7f * ( maxY - minY ), 0.7f * ( maxY - minY ),
171 1.0f, 2 * ( lookingAt - lightPosition ).length()
172 );
173
174 setupShadowRenderingExtent( minX, maxX, minY, maxY );
175 setupDirectionalLight( lightPosition, lightDirection );
176}
177
179{
180 mRenderShadowsParameter->setValue( QVariant::fromValue( enabled ? 1 : 0 ) );
181}
182
184{
185 mShadowBiasParameter->setValue( QVariant::fromValue( shadowBias ) );
186}
187
189{
190 mEyeDomeLightingEnabledParameter->setValue( QVariant::fromValue( enabled ? 1 : 0 ) );
191}
192
194{
195 mEyeDomeLightingStrengthParameter->setValue( QVariant::fromValue( strength ) );
196}
197
199{
200 mEyeDomeLightingDistanceParameter->setValue( QVariant::fromValue( distance ) );
201}
202
204{
205 mAmbientOcclusionEnabledParameter->setValue( enabled );
206}
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.
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.
QgsForwardRenderView & forwardRenderView()
Returns forward renderview.
Qt3DRender::QTexture2D * blurredAmbientOcclusionFactorMap()
Returns blurred ambient occlusion factor values texture.
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.
An entity that is responsible for rendering a screen quad for a specific rendering pass.
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.
Qt3DCore::QAttribute Qt3DQAttribute
Qt3DCore::QBuffer Qt3DQBuffer
Qt3DCore::QGeometry Qt3DQGeometry