34#include <Qt3DCore/QAttribute>
35#include <Qt3DCore/QBuffer>
36#include <Qt3DCore/QGeometry>
37#include <Qt3DRender/QAbstractTexture>
38#include <Qt3DRender/QBlendEquation>
39#include <Qt3DRender/QBlendEquationArguments>
40#include <Qt3DRender/QBlitFramebuffer>
41#include <Qt3DRender/QColorMask>
42#include <Qt3DRender/QGeometryRenderer>
43#include <Qt3DRender/QGraphicsApiFilter>
44#include <Qt3DRender/QNoDepthMask>
45#include <Qt3DRender/QNoDraw>
46#include <Qt3DRender/QSortPolicy>
47#include <Qt3DRender/QTechnique>
50#include "tracy/Tracy.hpp"
53#include "moc_qgsframegraph.cpp"
65void QgsFrameGraph::constructForwardRenderPass()
70void QgsFrameGraph::constructHighlightsPass()
75void QgsFrameGraph::constructShadowRenderPass()
80void QgsFrameGraph::constructOverlayTexturePass( Qt3DRender::QFrameGraphNode *topNode )
85void QgsFrameGraph::constructPostprocessingPass( Qt3DRender::QFrameGraphNode *topNode )
88 QgsPostprocessingRenderView *pprv =
new QgsPostprocessingRenderView(
sPostprocRenderView,
this, mSize, mRootEntity );
92void QgsFrameGraph::updateThumbnailTextureSize()
96 const int width = ( mSize.width() / 10 ) & ~3;
97 const int height = ( mSize.height() / 10 ) & ~3;
98 mThumbnailTexture->setSize( width, height );
101void QgsFrameGraph::constructThumbnailCapturePass()
109 mThumbnailTexture =
new Qt3DRender::QTexture2D(
this );
110 mThumbnailTexture->setFormat( Qt3DRender::QAbstractTexture::RGBA8_UNorm );
111 updateThumbnailTextureSize();
113 Qt3DRender::QRenderTargetOutput *renderTargetOutput =
new Qt3DRender::QRenderTargetOutput(
this );
114 renderTargetOutput->setTexture( mThumbnailTexture );
116 Qt3DRender::QRenderTarget *renderTarget =
new Qt3DRender::QRenderTarget(
this );
117 renderTarget->addOutput( renderTargetOutput );
120 Qt3DRender::QBlitFramebuffer *blit =
new Qt3DRender::QBlitFramebuffer( mMainViewPort );
121 blit->setObjectName(
"Framebuffer copy for thumbnail" );
123 blit->setDestination( renderTarget );
124 blit->setSourceRect( QRectF( 0, 0, 1, 1 ) );
125 blit->setDestinationRect( QRectF( 0, 0, 1, 1 ) );
126 blit->setInterpolationMethod( Qt3DRender::QBlitFramebuffer::Linear );
128 Qt3DRender::QRenderTargetSelector *targetSelector =
new Qt3DRender::QRenderTargetSelector( mMainViewPort );
129 targetSelector->setObjectName(
"Thumbnail capture target selector" );
130 targetSelector->setTarget( renderTarget );
132 mThumbnailCapture =
new Qt3DRender::QRenderCapture( targetSelector );
133 mThumbnailCapture->setObjectName(
"Thumbnail capture" );
138 Qt3DRender::QRenderCaptureReply *reply1 = mThumbnailCapture->requestCapture();
139 Qt3DRender::QRenderCaptureReply *reply2 = mThumbnailCapture->requestCapture();
140 for ( Qt3DRender::QRenderCaptureReply *reply : { reply1, reply2 } )
141 connect( reply, &Qt3DRender::QRenderCaptureReply::completed,
this, [
this, reply]() { onThumbnailCaptureCompleted( reply ); } );
144void QgsFrameGraph::onThumbnailCaptureCompleted( Qt3DRender::QRenderCaptureReply *reply )
146 reply->deleteLater();
150 QImage rgbaImage = reply->image().convertToFormat( QImage::Format_RGBA8888 );
154 rgbaImage.constBits(),
155 static_cast<uint16_t
>( rgbaImage.width() ),
156 static_cast<uint16_t
>( rgbaImage.height() ),
163 Qt3DRender::QRenderCaptureReply *nextReply = mThumbnailCapture->requestCapture();
164 connect( nextReply, &Qt3DRender::QRenderCaptureReply::completed,
this, [
this, nextReply]() { onThumbnailCaptureCompleted( nextReply ); } );
167void QgsFrameGraph::constructAmbientOcclusionRenderPass()
171 QgsAmbientOcclusionRenderView *aorv =
new QgsAmbientOcclusionRenderView(
sAmbientOcclusionRenderView, mMainCamera, mSize, forwardDepthTexture, mRootEntity );
175void QgsFrameGraph::constructBloomRenderPass()
179 QgsBloomRenderView *rv =
new QgsBloomRenderView(
sBloomRenderView, forwardColorTexture, mSize, mRootEntity );
183Qt3DRender::QFrameGraphNode *QgsFrameGraph::constructRubberBandsPass()
185 mRubberBandsCameraSelector =
new Qt3DRender::QCameraSelector;
186 mRubberBandsCameraSelector->setObjectName(
"RubberBands Pass CameraSelector" );
187 mRubberBandsCameraSelector->setCamera( mMainCamera );
189 mRubberBandsLayerFilter =
new Qt3DRender::QLayerFilter( mRubberBandsCameraSelector );
190 mRubberBandsLayerFilter->addLayer( mRubberBandsLayer );
192 Qt3DRender::QBlendEquationArguments *blendState =
new Qt3DRender::QBlendEquationArguments;
193 blendState->setSourceRgb( Qt3DRender::QBlendEquationArguments::SourceAlpha );
194 blendState->setDestinationRgb( Qt3DRender::QBlendEquationArguments::OneMinusSourceAlpha );
196 Qt3DRender::QBlendEquation *blendEquation =
new Qt3DRender::QBlendEquation;
197 blendEquation->setBlendFunction( Qt3DRender::QBlendEquation::Add );
199 mRubberBandsStateSet =
new Qt3DRender::QRenderStateSet( mRubberBandsLayerFilter );
200 Qt3DRender::QDepthTest *depthTest =
new Qt3DRender::QDepthTest;
201 depthTest->setDepthFunction( Qt3DRender::QDepthTest::Always );
202 mRubberBandsStateSet->addRenderState( depthTest );
203 mRubberBandsStateSet->addRenderState( blendState );
204 mRubberBandsStateSet->addRenderState( blendEquation );
209 mRubberBandsRenderTargetSelector =
new Qt3DRender::QRenderTargetSelector( mRubberBandsStateSet );
210 mRubberBandsRenderTargetSelector->setTarget(
forwardRenderView().renderTargetSelector()->target() );
212 return mRubberBandsCameraSelector;
215void QgsFrameGraph::constructDepthRenderPass()
219 QgsDepthRenderView *rv =
new QgsDepthRenderView(
sDepthRenderView, mSize, forwardDepthTexture, mRootEntity );
230 for ( Qt3DRender::QParameter *param : parameters )
232 mGlobalParamsStorage->addParameter( param );
278 mRubberBandsLayer =
new Qt3DRender::QLayer;
279 mRubberBandsLayer->setObjectName(
"mRubberBandsLayer" );
280 mRubberBandsLayer->setRecursive(
true );
282 mRenderSurfaceSelector =
new Qt3DRender::QRenderSurfaceSelector;
284 QObject *surfaceObj =
dynamic_cast<QObject *
>( surface );
285 Q_ASSERT( surfaceObj );
287 mRenderSurfaceSelector->setSurface( surfaceObj );
288 mRenderSurfaceSelector->setExternalRenderTargetSize( mSize );
290 mMainViewPort =
new Qt3DRender::QViewport( mRenderSurfaceSelector );
291 mMainViewPort->setNormalizedRect( QRectF( 0.0f, 0.0f, 1.0f, 1.0f ) );
293 mGlobalParamsStorage =
new Qt3DRender::QRenderPassFilter( mMainViewPort );
294 mGlobalParamsStorage->setObjectName(
"GlobalParametersStore" );
298 constructShadowRenderPass();
301 constructForwardRenderPass();
304 constructHighlightsPass();
307 Qt3DRender::QFrameGraphNode *rubberBandsPass = constructRubberBandsPass();
308 rubberBandsPass->setObjectName(
"rubberBandsPass" );
309 rubberBandsPass->setParent( mGlobalParamsStorage );
311 mMsaaBlitNode =
new Qt3DRender::QBlitFramebuffer( mGlobalParamsStorage );
312 mMsaaBlitNode->setObjectName(
"MsaaBlitFramebuffer" );
313 mMsaaBlitNode->setEnabled(
false );
315 mMsaaDepthBlitNode =
new Qt3DRender::QBlitFramebuffer( mGlobalParamsStorage );
316 mMsaaDepthBlitNode->setObjectName(
"MsaaDepthBlitFramebuffer" );
317 mMsaaDepthBlitNode->setEnabled(
false );
320 constructDepthRenderPass();
323 constructAmbientOcclusionRenderPass();
325 constructBloomRenderPass();
328 constructPostprocessingPass( mGlobalParamsStorage );
331 constructThumbnailCapturePass();
334 mRubberBandsRootEntity =
new Qt3DCore::QEntity( mRootEntity );
335 mRubberBandsRootEntity->setObjectName(
"mRubberBandsRootEntity" );
336 mRubberBandsRootEntity->addComponent( mRubberBandsLayer );
341 if ( mRenderViewMap.find( name ) != mRenderViewMap.end() )
343 mRenderViewMap[name]->topGraphNode()->setParent( ( QNode * )
nullptr );
344 mRenderViewMap.erase( name );
351 if ( mRenderViewMap.find( name ) == mRenderViewMap.end() )
353 mRenderViewMap[name] = std::move(
renderView );
354 mRenderViewMap[name]->topGraphNode()->setParent( topNode ? topNode : mGlobalParamsStorage );
355 mRenderViewMap[name]->updateWindowResize( mSize.width(), mSize.height() );
366 if ( mRenderViewMap[name] )
368 mRenderViewMap[name]->setEnabled( enable );
374 if ( mRenderViewMap.find( name ) != mRenderViewMap.end() )
376 return mRenderViewMap[name].get();
383 return mRenderViewMap[name] !=
nullptr && mRenderViewMap[name]->
isEnabled();
423 const QList<QgsLightSource *> lightSources = mapSettings.
lightSources();
426 const QString lightSourceId = shadowSettings.
lightSource();
428 int globalLightIndex = 0;
431 int backupLightSourceIndex = 0;
432 for (
int i = 0; !light && i < lightSources.size(); i++ )
434 if ( !backupLightSource )
438 backupLightSource = directionalLight;
439 backupLightSourceIndex = i;
443 backupLightSource = sunLight;
444 backupLightSourceIndex = i;
448 if ( lightSources[i]->
id() == lightSourceId )
450 light = lightSources[i];
451 globalLightIndex = i;
459 light = backupLightSource;
460 globalLightIndex = backupLightSourceIndex;
468 lightDirection = directionalLight->direction();
472 lightDirection = sunLight->direction( mapSettings );
502 if ( mDepthTextureDebugging )
509 delete mDepthTextureDebugging;
510 mDepthTextureDebugging =
nullptr;
517 QObject *top = mRenderSurfaceSelector;
518 while ( top->parent() &&
dynamic_cast<Qt3DRender::QFrameGraphNode *
>( top->parent() ) )
522 context.
lowestId = mMainCamera->id().id();
525 return strList.join(
"\n" ) + QString(
"\n" );
531 return strList.join(
"\n" ) + QString(
"\n" );
547 for (
auto it = mRenderViewMap.begin(); it != mRenderViewMap.end(); ++it )
553 mRenderSurfaceSelector->setExternalRenderTargetSize( mSize );
555 mMsaaBlitNode->setSourceRect( QRect( 0, 0, mSize.width(), mSize.height() ) );
556 mMsaaBlitNode->setDestinationRect( QRect( 0, 0, mSize.width(), mSize.height() ) );
557 mMsaaDepthBlitNode->setSourceRect( QRect( 0, 0, mSize.width(), mSize.height() ) );
558 mMsaaDepthBlitNode->setDestinationRect( QRect( 0, 0, mSize.width(), mSize.height() ) );
560 if ( mThumbnailTexture )
561 updateThumbnailTextureSize();
581 mMsaaEnabled = enabled;
583 if ( !enabled && mMsaaBlitConfigured )
585 mMsaaBlitNode->setSource(
nullptr );
586 mMsaaBlitNode->setDestination(
nullptr );
587 mMsaaDepthBlitNode->setSource(
nullptr );
588 mMsaaDepthBlitNode->setDestination(
nullptr );
589 mMsaaBlitConfigured =
false;
594 if ( enabled && !mMsaaBlitConfigured )
596 mMsaaBlitConfigured =
true;
599 mMsaaBlitNode->setSourceRect( QRect( 0, 0, mSize.width(), mSize.height() ) );
600 mMsaaBlitNode->setDestinationRect( QRect( 0, 0, mSize.width(), mSize.height() ) );
601 mMsaaBlitNode->setSourceAttachmentPoint( Qt3DRender::QRenderTargetOutput::Color0 );
602 mMsaaBlitNode->setDestinationAttachmentPoint( Qt3DRender::QRenderTargetOutput::Color0 );
603 mMsaaBlitNode->setInterpolationMethod( Qt3DRender::QBlitFramebuffer::Nearest );
607 mMsaaDepthBlitNode->setSourceRect( QRect( 0, 0, mSize.width(), mSize.height() ) );
608 mMsaaDepthBlitNode->setDestinationRect( QRect( 0, 0, mSize.width(), mSize.height() ) );
609 mMsaaDepthBlitNode->setSourceAttachmentPoint( Qt3DRender::QRenderTargetOutput::DepthStencil );
610 mMsaaDepthBlitNode->setDestinationAttachmentPoint( Qt3DRender::QRenderTargetOutput::DepthStencil );
611 mMsaaDepthBlitNode->setInterpolationMethod( Qt3DRender::QBlitFramebuffer::Nearest );
616 mRubberBandsRenderTargetSelector->setTarget( target );
617 mMsaaBlitNode->setEnabled( enabled );
618 mMsaaDepthBlitNode->setEnabled( enabled );
Qt::Corner debugDepthMapCorner() const
Returns the corner where the shadow map preview is displayed.
bool debugDepthMapEnabled() const
Returns whether the shadow map debugging is enabled.
QgsShadowSettings shadowSettings() const
Returns the current configuration of shadows.
QList< QgsLightSource * > lightSources() const
Returns list of directional light sources defined in the scene.
double debugDepthMapSize() const
Returns the size of the shadow map preview.
bool is2DMapOverlayEnabled() const
Returns whether 2D map overlay is enabled.
bool eyeDomeLightingEnabled() const
Returns whether eye dome lighting is used.
Base class for 3D render view.
virtual void setEnabled(bool enable)
Enable or disable via enable the render view sub tree.
virtual bool isEnabled() const
Returns true if render view is enabled.
virtual void updateWindowResize(int width, int height)
Called when 3D window is resized.
Container class that holds different objects related to ambient occlusion rendering.
void setRadius(float radius)
Delegates to QgsAmbientOcclusionRenderEntity::setRadius.
void setEnabled(bool enable) override
Enable or disable via enable the render view sub tree.
void setIntensity(float intensity)
Delegates to QgsAmbientOcclusionRenderEntity::setIntensity.
void setThreshold(float threshold)
Delegates to QgsAmbientOcclusionRenderEntity::setThreshold.
Contains the configuration of ambient occlusion rendering.
float radius() const
Returns the radius parameter of the ambient occlusion effect.
bool isEnabled() const
Returns whether ambient occlusion effect is enabled.
float intensity() const
Returns the shading factor of the ambient occlusion effect.
float threshold() const
Returns at what amount of occlusion the effect will kick in.
Container class that holds different objects related to bloom rendering.
Contains the configuration of the lighting "bloom" effect.
double radius() const
Returns the filter radius for the bloom.
bool isEnabled() const
Returns whether the bloom effect is enabled.
Contains the configuration of the scene's color grading settings, such as exposure and tone mapping.
Container class that holds different objects related to depth rendering.
Qt3DRender::QRenderCapture * renderCapture()
Returns the render capture object used to take an image of the depth buffer of the scene.
Definition of a directional light in a 3D map scene.
Container class that holds different objects related to forward rendering.
void setClearColor(const QColor &clearColor)
Sets the clear color of the scene (background color).
Qt3DRender::QTexture2D * colorTexture() const
Returns forward color texture.
void setDebugOverlayEnabled(bool enabled)
Sets whether debug overlay is enabled.
void setMsaaEnabled(bool enabled)
Sets whether multisample anti-aliasing (MSAA) is enabled.
void setFrustumCullingEnabled(bool enabled)
Sets whether frustum culling is enabled.
Qt3DRender::QTexture2D * depthTexture() const
Returns forward depth texture.
void addClipPlanes(int nrClipPlanes)
Setups nrClipPlanes clip planes in the forward pass to enable OpenGL clipping.
void removeClipPlanes()
Disables OpenGL clipping.
Qt3DRender::QRenderTarget * msaaRenderTarget() const
Returns the multisampled render target used as blit source when MSAA is enabled.
Qt3DRender::QRenderTarget * regularRenderTarget() const
Returns the regular (single-sample) render target used as blit destination and postprocessing input.
static QStringList dumpFrameGraph(const Qt3DCore::QNode *node, FgDumpContext context)
Returns a tree view of the frame graph starting from node. The object ids will be given relatively to...
static QStringList dumpSceneGraph(const Qt3DCore::QNode *node, FgDumpContext context)
Returns a tree view of the scene graph starting from node. The object ids will be given relatively to...
void addGlobalParameters(const QList< Qt3DRender::QParameter * > ¶meters)
Adds additional global parameters to the graph.
void setMsaaEnabled(bool enabled)
Sets whether multisample anti-aliasing (MSAA) is enabled.
void updateAmbientOcclusionSettings(const QgsAmbientOcclusionSettings &settings)
Updates settings for ambient occlusion.
void updateEyeDomeSettings(const Qgs3DMapSettings &settings)
Updates settings for eye dome lighting.
void updateBloomSettings(const QgsBloomSettings &settings)
Updates settings for the bloom lighting effect.
bool isRenderViewEnabled(const QString &name)
Returns true if the render view named name is found and enabled.
void setRenderViewEnabled(const QString &name, bool enable)
Enables or disables the render view named name according to enable.
void addClipPlanes(int nrClipPlanes)
Setups nrClipPlanes clip planes in the forward pass to enable OpenGL clipping.
void updateColorGradingSettings(const QgsColorGradingSettings &settings)
Updates settings for color grading.
static const QString sPostprocRenderView
Postprocessing render view name.
void unregisterRenderView(const QString &name)
Unregisters the render view named name, if any.
bool registerRenderView(std::unique_ptr< QgsAbstractRenderView > renderView, const QString &name, Qt3DRender::QFrameGraphNode *topNode=nullptr)
Registers a new the render view renderView with name name.
QString dumpFrameGraph() const
Dumps frame graph as string.
QgsPostprocessingRenderView & postprocessingRenderView()
Returns post processing renderview.
void setRenderCaptureEnabled(bool enabled)
Sets whether it will be possible to render to an image.
QgsAmbientOcclusionRenderView & ambientOcclusionRenderView()
Returns ambient occlusion renderview.
Qt3DRender::QRenderCapture * depthRenderCapture()
Returns the render capture object used to take an image of the depth buffer of the scene.
QgsAbstractRenderView * renderView(const QString &name)
Returns the render view named name, if any.
void removeClipPlanes()
Disables OpenGL clipping.
static const QString sOverlayRenderView
QgsDepthRenderView & depthRenderView()
Returns depth renderview.
void setClearColor(const QColor &clearColor)
Sets the clear color of the scene (background color).
static const QString sDepthRenderView
static const QString sForwardRenderView
static const QString sBloomRenderView
static const QString sShadowRenderView
void setFrustumCullingEnabled(bool enabled)
Sets whether frustum culling is enabled.
void updateShadowSettings(const Qgs3DMapSettings &mapSettings)
Updates shadow bias, light and texture size according to shadowSettings and lightSources.
void setDebugOverlayEnabled(bool enabled)
Sets whether debug overlay is enabled.
QgsHighlightsRenderView & highlightsRenderView()
Returns the highlights renderview, used for rendering highlight overlays of identified features.
static const QString sAxiS3DRenderView
void updateDebugDepthMapSettings(const Qgs3DMapSettings &settings)
Updates settings for depth debug map.
QgsForwardRenderView & forwardRenderView()
Returns forward renderview.
static const QString sAmbientOcclusionRenderView
Ambient occlusion render view name.
QgsOverlayTextureRenderView & overlayTextureRenderView()
Returns overlay texture renderview.
QString dumpSceneGraph() const
Dumps scene graph as string.
QgsShadowRenderView & shadowRenderView()
Returns shadow renderview.
void setSize(QSize s)
Sets the size of the buffers used for rendering.
QgsBloomRenderView & bloomRenderView()
Returns the bloom render view.
static const QString sHighlightsRenderView
Qt3DRender::QCamera * mainCamera()
Returns the main camera.
QgsFrameGraph(QSurface *surface, QSize s, Qt3DRender::QCamera *mainCamera, Qt3DCore::QEntity *root)
Constructor.
Qt3DRender::QRenderCapture * renderCapture()
Returns the render capture object used to take an image of the scene.
Container class that holds different objects related to highlighting identified features.
void setRenderTarget(Qt3DRender::QRenderTarget *target)
Switches the render target (called when toggling MSAA on/off).
Base class for light sources in 3d scenes.
An entity responsible for rendering an overlay texture in 3D view.
Simple render view to preview overlay textures in 3D view.
Qt3DRender::QLayer * overlayLayer() const
Returns layer in which entities must be added in the in order to be processed by this renderview.
void updateShadowSettings(const QgsShadowSettings &shadowSettings, const QgsVector3D &lightDir, int size, int globalLightIndex)
Sets shadow rendering to use a directional light.
void setAmbientOcclusionEnabled(bool enabled)
Sets whether screen space ambient occlusion is enabled.
void setShadowRenderingEnabled(bool enabled)
Sets whether shadow rendering is enabled.
void setBloomEnabled(bool enabled)
Sets whether physically based bloom is enabled.
void updateEyeDomeSettings(const Qgs3DMapSettings &settings)
Updates eye dome lighting settings from settings.
void updateBloomSettings(const QgsBloomSettings &settings)
Sets bloom rendering to use a directional light.
void setEyeDomeLightingEnabled(bool enabled)
Sets whether eye dome lighting is enabled.
void updateColorGradingSettings(const QgsColorGradingSettings &settings)
Updates settings for color grading.
Container class that holds different objects related to postprocessing rendering.
Qt3DRender::QRenderCapture * renderCapture() const
Returns the render capture object used to take an image of the postprocessing buffer of the scene.
QgsPostprocessingEntity * entity() const
Returns the QT3D entity used to do the rendering.
void setOffScreenRenderCaptureEnabled(bool enabled)
Sets whether it will be possible to render to an image.
QgsOverlayTextureRenderView * overlayTextureRenderView() const
Returns overlay texture render view.
Container class that holds different objects related to shadow rendering.
void setMapSize(int width, int height)
Update shadow depth texture size.
void setEnabled(bool enable) override
Enable or disable via enable the renderview sub tree.
Contains configuration for rendering shadows.
bool renderShadows() const
Returns whether shadow rendering is enabled.
static int qualityToMapResolution(Qgis::ShadowQuality quality)
Returns the shadow map resolution corresponding to the specified shadow quality.
QString lightSource() const
Returns the ID of the light source casting shadows.
Qgis::ShadowQuality shadowQuality() const
Returns the quality of the shadow map texture used to generate the shadows.
Definition of a sun light in a 3D map scene.
A 3D vector (similar to QVector3D) with the difference that it uses double precision instead of singl...