Compare commits

...

8 Commits

13 changed files with 412 additions and 154 deletions

View File

@ -658,6 +658,9 @@ class Repositories(QObject):
.text() .text()
.strip() .strip()
) )
supports_qt6 = pluginNodes.item(i).firstChildElement(
"supports_qt6"
).text().strip().upper() in ["TRUE", "YES"]
if not qgisMaximumVersion: if not qgisMaximumVersion:
if qgisMinimumVersion[0] == "3" and supports_qt6: if qgisMinimumVersion[0] == "3" and supports_qt6:
qgisMaximumVersion = "4.99" qgisMaximumVersion = "4.99"

View File

@ -90,6 +90,7 @@ set(QGIS_3D_SRCS
framegraph/qgsforwardrenderview.cpp framegraph/qgsforwardrenderview.cpp
framegraph/qgspostprocessingentity.cpp framegraph/qgspostprocessingentity.cpp
framegraph/qgsrenderpassquad.cpp framegraph/qgsrenderpassquad.cpp
framegraph/qgspostprocessingrenderview.cpp
framegraph/qgsshadowrenderview.cpp framegraph/qgsshadowrenderview.cpp
framegraph/qgsframegraph.cpp framegraph/qgsframegraph.cpp
framegraph/qgsframegraphutils.cpp framegraph/qgsframegraphutils.cpp
@ -207,6 +208,7 @@ set(QGIS_3D_HDRS
framegraph/qgsframegraphutils.h framegraph/qgsframegraphutils.h
framegraph/qgspostprocessingentity.h framegraph/qgspostprocessingentity.h
framegraph/qgsrenderpassquad.h framegraph/qgsrenderpassquad.h
framegraph/qgspostprocessingrenderview.h
framegraph/qgsshadowrenderview.h framegraph/qgsshadowrenderview.h
symbols/qgsbillboardgeometry.h symbols/qgsbillboardgeometry.h

View File

@ -67,6 +67,9 @@ class QgsForwardRenderView : public QgsAbstractRenderView
//! Sets whether debug overlay is enabled //! Sets whether debug overlay is enabled
void setDebugOverlayEnabled( bool enabled ); void setDebugOverlayEnabled( bool enabled );
//! Returns main camera
Qt3DRender::QCamera *mainCamera() const { return mMainCamera; }
//! Returns current render target selector //! Returns current render target selector
Qt3DRender::QRenderTargetSelector *renderTargetSelector() { return mRenderTargetSelector; } Qt3DRender::QRenderTargetSelector *renderTargetSelector() { return mRenderTargetSelector; }

View File

@ -58,6 +58,7 @@ typedef Qt3DCore::QGeometry Qt3DQGeometry;
#include "qgsdebugtexturerenderview.h" #include "qgsdebugtexturerenderview.h"
#include "qgsdebugtextureentity.h" #include "qgsdebugtextureentity.h"
#include "qgsambientocclusionrenderview.h" #include "qgsambientocclusionrenderview.h"
#include "qgspostprocessingrenderview.h"
const QString QgsFrameGraph::FORWARD_RENDERVIEW = "forward"; const QString QgsFrameGraph::FORWARD_RENDERVIEW = "forward";
const QString QgsFrameGraph::SHADOW_RENDERVIEW = "shadow"; const QString QgsFrameGraph::SHADOW_RENDERVIEW = "shadow";
@ -65,6 +66,7 @@ const QString QgsFrameGraph::AXIS3D_RENDERVIEW = "3daxis";
const QString QgsFrameGraph::DEPTH_RENDERVIEW = "depth"; const QString QgsFrameGraph::DEPTH_RENDERVIEW = "depth";
const QString QgsFrameGraph::DEBUG_RENDERVIEW = "debug_texture"; const QString QgsFrameGraph::DEBUG_RENDERVIEW = "debug_texture";
const QString QgsFrameGraph::AMBIENT_OCCLUSION_RENDERVIEW = "ambient_occlusion"; const QString QgsFrameGraph::AMBIENT_OCCLUSION_RENDERVIEW = "ambient_occlusion";
const QString QgsFrameGraph::POSTPROC_RENDERVIEW = "post_processing";
void QgsFrameGraph::constructForwardRenderPass() void QgsFrameGraph::constructForwardRenderPass()
{ {
@ -81,85 +83,24 @@ void QgsFrameGraph::constructDebugTexturePass( Qt3DRender::QFrameGraphNode *topN
registerRenderView( std::make_unique<QgsDebugTextureRenderView>( DEBUG_RENDERVIEW ), DEBUG_RENDERVIEW, topNode ); registerRenderView( std::make_unique<QgsDebugTextureRenderView>( DEBUG_RENDERVIEW ), DEBUG_RENDERVIEW, topNode );
} }
Qt3DRender::QFrameGraphNode *QgsFrameGraph::constructSubPostPassForProcessing() void QgsFrameGraph::constructPostprocessingPass()
{ {
Qt3DRender::QCameraSelector *cameraSelector = new Qt3DRender::QCameraSelector; // create post processing render view and register it
cameraSelector->setObjectName( "Sub pass Postprocessing" ); QgsPostprocessingRenderView *pprv = new QgsPostprocessingRenderView( POSTPROC_RENDERVIEW, //
cameraSelector->setCamera( shadowRenderView().lightCamera() ); shadowRenderView(), //
forwardRenderView(), //
ambientOcclusionRenderView(), //
mSize, //
mRootEntity );
registerRenderView( std::unique_ptr<QgsPostprocessingRenderView>( pprv ), POSTPROC_RENDERVIEW );
Qt3DRender::QLayerFilter *layerFilter = new Qt3DRender::QLayerFilter( cameraSelector ); // create debug texture render view and register it (will be detach from main framegraph and attach to postprocessing renderview)
constructDebugTexturePass();
// could be the first of this branch // add debug texture render view to post processing subpasses (before the render capture one)
new Qt3DRender::QClearBuffers( layerFilter ); QVector<Qt3DRender::QFrameGraphNode *> subPasses = pprv->subPasses();
subPasses.insert( subPasses.length() - 1, renderView( DEBUG_RENDERVIEW )->topGraphNode() );
Qt3DRender::QLayer *postProcessingLayer = new Qt3DRender::QLayer(); pprv->setSubPasses( subPasses );
mPostprocessingEntity = new QgsPostprocessingEntity( this, postProcessingLayer, mRootEntity );
layerFilter->addLayer( postProcessingLayer );
mPostprocessingEntity->setObjectName( "PostProcessingPassEntity" );
return cameraSelector;
}
Qt3DRender::QFrameGraphNode *QgsFrameGraph::constructSubPostPassForRenderCapture()
{
Qt3DRender::QFrameGraphNode *top = new Qt3DRender::QNoDraw;
top->setObjectName( "Sub pass RenderCapture" );
mRenderCapture = new Qt3DRender::QRenderCapture( top );
return top;
}
Qt3DRender::QFrameGraphNode *QgsFrameGraph::constructPostprocessingPass()
{
mRenderCaptureTargetSelector = new Qt3DRender::QRenderTargetSelector;
mRenderCaptureTargetSelector->setObjectName( "Postprocessing render pass" );
mRenderCaptureTargetSelector->setEnabled( mRenderCaptureEnabled );
Qt3DRender::QRenderTarget *renderTarget = new Qt3DRender::QRenderTarget( mRenderCaptureTargetSelector );
// The lifetime of the objects created here is managed
// automatically, as they become children of this object.
// Create a render target output for rendering color.
Qt3DRender::QRenderTargetOutput *colorOutput = new Qt3DRender::QRenderTargetOutput( renderTarget );
colorOutput->setAttachmentPoint( Qt3DRender::QRenderTargetOutput::Color0 );
// Create a texture to render into.
mRenderCaptureColorTexture = new Qt3DRender::QTexture2D( colorOutput );
mRenderCaptureColorTexture->setSize( mSize.width(), mSize.height() );
mRenderCaptureColorTexture->setFormat( Qt3DRender::QAbstractTexture::RGB8_UNorm );
mRenderCaptureColorTexture->setMinificationFilter( Qt3DRender::QAbstractTexture::Linear );
mRenderCaptureColorTexture->setMagnificationFilter( Qt3DRender::QAbstractTexture::Linear );
mRenderCaptureColorTexture->setObjectName( "PostProcessingPass::ColorTarget" );
// Hook the texture up to our output, and the output up to this object.
colorOutput->setTexture( mRenderCaptureColorTexture );
renderTarget->addOutput( colorOutput );
Qt3DRender::QRenderTargetOutput *depthOutput = new Qt3DRender::QRenderTargetOutput( renderTarget );
depthOutput->setAttachmentPoint( Qt3DRender::QRenderTargetOutput::Depth );
mRenderCaptureDepthTexture = new Qt3DRender::QTexture2D( depthOutput );
mRenderCaptureDepthTexture->setSize( mSize.width(), mSize.height() );
mRenderCaptureDepthTexture->setFormat( Qt3DRender::QAbstractTexture::DepthFormat );
mRenderCaptureDepthTexture->setMinificationFilter( Qt3DRender::QAbstractTexture::Linear );
mRenderCaptureDepthTexture->setMagnificationFilter( Qt3DRender::QAbstractTexture::Linear );
mRenderCaptureDepthTexture->setComparisonFunction( Qt3DRender::QAbstractTexture::CompareLessEqual );
mRenderCaptureDepthTexture->setComparisonMode( Qt3DRender::QAbstractTexture::CompareRefToTexture );
mRenderCaptureDepthTexture->setObjectName( "PostProcessingPass::DepthTarget" );
depthOutput->setTexture( mRenderCaptureDepthTexture );
renderTarget->addOutput( depthOutput );
mRenderCaptureTargetSelector->setTarget( renderTarget );
// sub passes:
constructSubPostPassForProcessing()->setParent( mRenderCaptureTargetSelector );
constructDebugTexturePass( mRenderCaptureTargetSelector );
constructSubPostPassForRenderCapture()->setParent( mRenderCaptureTargetSelector );
return mRenderCaptureTargetSelector;
} }
void QgsFrameGraph::constructAmbientOcclusionRenderPass() void QgsFrameGraph::constructAmbientOcclusionRenderPass()
@ -202,7 +143,6 @@ Qt3DRender::QFrameGraphNode *QgsFrameGraph::constructRubberBandsPass()
return mRubberBandsCameraSelector; return mRubberBandsCameraSelector;
} }
void QgsFrameGraph::constructDepthRenderPass() void QgsFrameGraph::constructDepthRenderPass()
{ {
// entity used to draw the depth texture and convert it to rgb image // entity used to draw the depth texture and convert it to rgb image
@ -284,9 +224,7 @@ QgsFrameGraph::QgsFrameGraph( QSurface *surface, QSize s, Qt3DRender::QCamera *m
constructAmbientOcclusionRenderPass(); constructAmbientOcclusionRenderPass();
// post process // post process
Qt3DRender::QFrameGraphNode *postprocessingPass = constructPostprocessingPass(); constructPostprocessingPass();
postprocessingPass->setParent( mMainViewPort );
postprocessingPass->setObjectName( "PostProcessingPass" );
mRubberBandsRootEntity = new Qt3DCore::QEntity( mRootEntity ); mRubberBandsRootEntity = new Qt3DCore::QEntity( mRootEntity );
mRubberBandsRootEntity->setObjectName( "mRubberBandsRootEntity" ); mRubberBandsRootEntity->setObjectName( "mRubberBandsRootEntity" );
@ -349,14 +287,13 @@ void QgsFrameGraph::updateAmbientOcclusionSettings( const QgsAmbientOcclusionSet
aoRenderView.setThreshold( settings.threshold() ); aoRenderView.setThreshold( settings.threshold() );
aoRenderView.setEnabled( settings.isEnabled() ); aoRenderView.setEnabled( settings.isEnabled() );
mPostprocessingEntity->setAmbientOcclusionEnabled( settings.isEnabled() ); postprocessingRenderView().entity()->setAmbientOcclusionEnabled( settings.isEnabled() );
} }
void QgsFrameGraph::updateEyeDomeSettings( const Qgs3DMapSettings &settings ) void QgsFrameGraph::updateEyeDomeSettings( const Qgs3DMapSettings &settings )
{ {
mPostprocessingEntity->setEyeDomeLightingEnabled( settings.eyeDomeLightingEnabled() ); postprocessingRenderView().entity()->setEyeDomeLightingEnabled( settings.eyeDomeLightingEnabled() );
mPostprocessingEntity->setEyeDomeLightingStrength( settings.eyeDomeLightingStrength() ); postprocessingRenderView().entity()->updateEyeDomeSettings( settings );
mPostprocessingEntity->setEyeDomeLightingDistance( settings.eyeDomeLightingDistance() );
} }
void QgsFrameGraph::updateShadowSettings( const QgsShadowSettings &shadowSettings, const QList<QgsLightSource *> &lightSources ) void QgsFrameGraph::updateShadowSettings( const QgsShadowSettings &shadowSettings, const QList<QgsLightSource *> &lightSources )
@ -379,15 +316,14 @@ void QgsFrameGraph::updateShadowSettings( const QgsShadowSettings &shadowSetting
{ {
shadowRenderView().setMapSize( shadowSettings.shadowMapResolution(), shadowSettings.shadowMapResolution() ); shadowRenderView().setMapSize( shadowSettings.shadowMapResolution(), shadowSettings.shadowMapResolution() );
shadowRenderView().setEnabled( true ); shadowRenderView().setEnabled( true );
mPostprocessingEntity->setShadowRenderingEnabled( true ); postprocessingRenderView().entity()->setShadowRenderingEnabled( true );
mPostprocessingEntity->setShadowBias( static_cast<float>( shadowSettings.shadowBias() ) ); postprocessingRenderView().entity()->updateShadowSettings( shadowSettings, *light );
mPostprocessingEntity->updateShadowSettings( *light, static_cast<float>( shadowSettings.maximumShadowRenderingDistance() ) );
} }
} }
else else
{ {
shadowRenderView().setEnabled( false ); shadowRenderView().setEnabled( false );
mPostprocessingEntity->setShadowRenderingEnabled( false ); postprocessingRenderView().entity()->setShadowRenderingEnabled( false );
} }
} }
@ -477,22 +413,17 @@ void QgsFrameGraph::setSize( QSize s )
rv->updateWindowResize( mSize.width(), mSize.height() ); rv->updateWindowResize( mSize.width(), mSize.height() );
} }
mRenderCaptureColorTexture->setSize( mSize.width(), mSize.height() );
mRenderCaptureDepthTexture->setSize( mSize.width(), mSize.height() );
mRenderSurfaceSelector->setExternalRenderTargetSize( mSize ); mRenderSurfaceSelector->setExternalRenderTargetSize( mSize );
} }
Qt3DRender::QRenderCapture *QgsFrameGraph::renderCapture() Qt3DRender::QRenderCapture *QgsFrameGraph::renderCapture()
{ {
return mRenderCapture; return postprocessingRenderView().renderCapture();
} }
void QgsFrameGraph::setRenderCaptureEnabled( bool enabled ) void QgsFrameGraph::setRenderCaptureEnabled( bool enabled )
{ {
if ( enabled == mRenderCaptureEnabled ) postprocessingRenderView().setOffScreenRenderCaptureEnabled( enabled );
return;
mRenderCaptureEnabled = enabled;
mRenderCaptureTargetSelector->setEnabled( mRenderCaptureEnabled );
} }
void QgsFrameGraph::setDebugOverlayEnabled( bool enabled ) void QgsFrameGraph::setDebugOverlayEnabled( bool enabled )
@ -533,3 +464,9 @@ QgsAmbientOcclusionRenderView &QgsFrameGraph::ambientOcclusionRenderView()
QgsAbstractRenderView *rv = mRenderViewMap[QgsFrameGraph::AMBIENT_OCCLUSION_RENDERVIEW].get(); QgsAbstractRenderView *rv = mRenderViewMap[QgsFrameGraph::AMBIENT_OCCLUSION_RENDERVIEW].get();
return *( dynamic_cast<QgsAmbientOcclusionRenderView *>( rv ) ); return *( dynamic_cast<QgsAmbientOcclusionRenderView *>( rv ) );
} }
QgsPostprocessingRenderView &QgsFrameGraph::postprocessingRenderView()
{
QgsAbstractRenderView *rv = mRenderViewMap[QgsFrameGraph::POSTPROC_RENDERVIEW].get();
return *( dynamic_cast<QgsPostprocessingRenderView *>( rv ) );
}

View File

@ -42,7 +42,6 @@
class QgsDirectionalLightSettings; class QgsDirectionalLightSettings;
class QgsCameraController; class QgsCameraController;
class QgsRectangle; class QgsRectangle;
class QgsPostprocessingEntity;
class QgsAbstractRenderView; class QgsAbstractRenderView;
class QgsForwardRenderView; class QgsForwardRenderView;
class QgsShadowRenderView; class QgsShadowRenderView;
@ -51,6 +50,8 @@ class QgsShadowSettings;
class QgsDebugTextureEntity; class QgsDebugTextureEntity;
class QgsAmbientOcclusionRenderView; class QgsAmbientOcclusionRenderView;
class QgsAmbientOcclusionSettings; class QgsAmbientOcclusionSettings;
class QgsPostprocessingEntity;
class QgsPostprocessingRenderView;
#define SIP_NO_FILE #define SIP_NO_FILE
@ -78,9 +79,6 @@ class QgsFrameGraph : public Qt3DCore::QEntity
//! Returns the main camera //! Returns the main camera
Qt3DRender::QCamera *mainCamera() { return mMainCamera; } Qt3DRender::QCamera *mainCamera() { return mMainCamera; }
//! Returns the postprocessing entity
QgsPostprocessingEntity *postprocessingEntity() { return mPostprocessingEntity; }
//! Returns entity for all rubber bands (to show them always on top) //! Returns entity for all rubber bands (to show them always on top)
Qt3DCore::QEntity *rubberBandsRootEntity() { return mRubberBandsRootEntity; } Qt3DCore::QEntity *rubberBandsRootEntity() { return mRubberBandsRootEntity; }
@ -191,6 +189,12 @@ class QgsFrameGraph : public Qt3DCore::QEntity
*/ */
QgsAmbientOcclusionRenderView &ambientOcclusionRenderView(); QgsAmbientOcclusionRenderView &ambientOcclusionRenderView();
/**
* Returns post processing renderview
* \since QGIS 3.44
*/
QgsPostprocessingRenderView &postprocessingRenderView();
/** /**
* Updates shadow bias, light and texture size according to \a shadowSettings and \a lightSources * Updates shadow bias, light and texture size according to \a shadowSettings and \a lightSources
* \since QGIS 3.44 * \since QGIS 3.44
@ -228,6 +232,8 @@ class QgsFrameGraph : public Qt3DCore::QEntity
static const QString DEBUG_RENDERVIEW; static const QString DEBUG_RENDERVIEW;
//! Ambient occlusion render view name //! Ambient occlusion render view name
static const QString AMBIENT_OCCLUSION_RENDERVIEW; static const QString AMBIENT_OCCLUSION_RENDERVIEW;
//! Postprocessing render view name
static const QString POSTPROC_RENDERVIEW;
private: private:
Qt3DRender::QRenderSurfaceSelector *mRenderSurfaceSelector = nullptr; Qt3DRender::QRenderSurfaceSelector *mRenderSurfaceSelector = nullptr;
@ -235,13 +241,6 @@ class QgsFrameGraph : public Qt3DCore::QEntity
Qt3DRender::QCamera *mMainCamera = nullptr; Qt3DRender::QCamera *mMainCamera = nullptr;
// Post processing pass branch nodes:
Qt3DRender::QRenderTargetSelector *mRenderCaptureTargetSelector = nullptr;
Qt3DRender::QRenderCapture *mRenderCapture = nullptr;
// Post processing pass texture related objects:
Qt3DRender::QTexture2D *mRenderCaptureColorTexture = nullptr;
Qt3DRender::QTexture2D *mRenderCaptureDepthTexture = nullptr;
// Rubber bands pass // Rubber bands pass
Qt3DRender::QCameraSelector *mRubberBandsCameraSelector = nullptr; Qt3DRender::QCameraSelector *mRubberBandsCameraSelector = nullptr;
Qt3DRender::QLayerFilter *mRubberBandsLayerFilter = nullptr; Qt3DRender::QLayerFilter *mRubberBandsLayerFilter = nullptr;
@ -256,8 +255,6 @@ class QgsFrameGraph : public Qt3DCore::QEntity
Qt3DRender::QLayer *mRubberBandsLayer = nullptr; Qt3DRender::QLayer *mRubberBandsLayer = nullptr;
QgsPostprocessingEntity *mPostprocessingEntity = nullptr;
Qt3DCore::QEntity *mRubberBandsRootEntity = nullptr; Qt3DCore::QEntity *mRubberBandsRootEntity = nullptr;
//! shadow texture debugging //! shadow texture debugging
@ -268,16 +265,11 @@ class QgsFrameGraph : public Qt3DCore::QEntity
void constructShadowRenderPass(); void constructShadowRenderPass();
void constructForwardRenderPass(); void constructForwardRenderPass();
void constructDebugTexturePass( Qt3DRender::QFrameGraphNode *topNode = nullptr ); void constructDebugTexturePass( Qt3DRender::QFrameGraphNode *topNode = nullptr );
Qt3DRender::QFrameGraphNode *constructPostprocessingPass(); void constructPostprocessingPass();
void constructDepthRenderPass(); void constructDepthRenderPass();
void constructAmbientOcclusionRenderPass(); void constructAmbientOcclusionRenderPass();
Qt3DRender::QFrameGraphNode *constructRubberBandsPass(); Qt3DRender::QFrameGraphNode *constructRubberBandsPass();
Qt3DRender::QFrameGraphNode *constructSubPostPassForProcessing();
Qt3DRender::QFrameGraphNode *constructSubPostPassForRenderCapture();
bool mRenderCaptureEnabled = false;
// holds renderviews according to their name // holds renderviews according to their name
std::map<QString, std::unique_ptr<QgsAbstractRenderView>> mRenderViewMap; std::map<QString, std::unique_ptr<QgsAbstractRenderView>> mRenderViewMap;

View File

@ -43,28 +43,30 @@ typedef Qt3DCore::QGeometry Qt3DQGeometry;
#include "qgs3dutils.h" #include "qgs3dutils.h"
#include "qgsdirectionallightsettings.h" #include "qgsdirectionallightsettings.h"
#include "qgsshadowsettings.h"
#include "qgsframegraph.h" #include "qgsframegraph.h"
#include "qgsshadowrenderview.h" #include "qgsshadowrenderview.h"
#include "qgsforwardrenderview.h" #include "qgsforwardrenderview.h"
#include "qgsambientocclusionrenderview.h" #include "qgsambientocclusionrenderview.h"
QgsPostprocessingEntity::QgsPostprocessingEntity( QgsFrameGraph *frameGraph, Qt3DRender::QLayer *layer, QNode *parent ) QgsPostprocessingEntity::QgsPostprocessingEntity( const QgsShadowRenderView &shadowRenderView, //
const QgsForwardRenderView &forwardRenderView, //
const QgsAmbientOcclusionRenderView &aoRenderView, //
Qt3DRender::QLayer *layer, //
QNode *parent )
: QgsRenderPassQuad( layer, parent ) : QgsRenderPassQuad( layer, parent )
{ {
QgsShadowRenderView &shadowRenderView = frameGraph->shadowRenderView();
QgsForwardRenderView &forwardRenderView = frameGraph->forwardRenderView();
QgsAmbientOcclusionRenderView &aoRenderView = frameGraph->ambientOcclusionRenderView();
mColorTextureParameter = new Qt3DRender::QParameter( QStringLiteral( "colorTexture" ), forwardRenderView.colorTexture() ); mColorTextureParameter = new Qt3DRender::QParameter( QStringLiteral( "colorTexture" ), forwardRenderView.colorTexture() );
mDepthTextureParameter = new Qt3DRender::QParameter( QStringLiteral( "depthTexture" ), forwardRenderView.depthTexture() ); mDepthTextureParameter = new Qt3DRender::QParameter( QStringLiteral( "depthTexture" ), forwardRenderView.depthTexture() );
mShadowMapParameter = new Qt3DRender::QParameter( QStringLiteral( "shadowTexture" ), shadowRenderView.mapTexture() ); mShadowMapParameter = new Qt3DRender::QParameter( QStringLiteral( "shadowTexture" ), shadowRenderView.mapTexture() );
mAmbientOcclusionTextureParameter = new Qt3DRender::QParameter( QStringLiteral( "ssaoTexture" ), aoRenderView.blurredFactorMapTexture() ); mAmbientOcclusionTextureParameter = new Qt3DRender::QParameter( QStringLiteral( "ssaoTexture" ), aoRenderView.blurredFactorMapTexture() );
mMaterial->addParameter( mColorTextureParameter ); mMaterial->addParameter( mColorTextureParameter );
mMaterial->addParameter( mDepthTextureParameter ); mMaterial->addParameter( mDepthTextureParameter );
mMaterial->addParameter( mShadowMapParameter ); mMaterial->addParameter( mShadowMapParameter );
mMaterial->addParameter( mAmbientOcclusionTextureParameter ); mMaterial->addParameter( mAmbientOcclusionTextureParameter );
mMainCamera = frameGraph->mainCamera(); mMainCamera = forwardRenderView.mainCamera();
mLightCamera = shadowRenderView.lightCamera(); mLightCamera = shadowRenderView.lightCamera();
mFarPlaneParameter = new Qt3DRender::QParameter( QStringLiteral( "farPlane" ), mMainCamera->farPlane() ); mFarPlaneParameter = new Qt3DRender::QParameter( QStringLiteral( "farPlane" ), mMainCamera->farPlane() );
@ -151,14 +153,15 @@ void QgsPostprocessingEntity::setupDirectionalLight( QVector3D position, QVector
mLightDirection->setValue( QVariant::fromValue( direction.normalized() ) ); mLightDirection->setValue( QVariant::fromValue( direction.normalized() ) );
} }
void QgsPostprocessingEntity::updateShadowSettings( const QgsDirectionalLightSettings &light, float maximumShadowRenderingDistance ) void QgsPostprocessingEntity::updateShadowSettings( const QgsShadowSettings &shadowSettings, const QgsDirectionalLightSettings &light )
{ {
float minX, maxX, minY, maxY, minZ, maxZ; float minX, maxX, minY, maxY, minZ, maxZ;
QVector3D lookingAt = mMainCamera->viewCenter(); QVector3D lookingAt = mMainCamera->viewCenter();
const float d = 2 * ( mMainCamera->position() - mMainCamera->viewCenter() ).length(); const float d = 2 * ( mMainCamera->position() - mMainCamera->viewCenter() ).length();
const QVector3D lightDirection = light.direction().toVector3D().normalized(); const QVector3D lightDirection = light.direction().toVector3D().normalized();
Qgs3DUtils::calculateViewExtent( mMainCamera, maximumShadowRenderingDistance, lookingAt.z(), minX, maxX, minY, maxY, minZ, maxZ ); Qgs3DUtils::calculateViewExtent( mMainCamera, static_cast<float>( shadowSettings.maximumShadowRenderingDistance() ), //
lookingAt.z(), minX, maxX, minY, maxY, minZ, maxZ );
lookingAt = QVector3D( 0.5f * ( minX + maxX ), 0.5f * ( minY + maxY ), mMainCamera->viewCenter().z() ); lookingAt = QVector3D( 0.5f * ( minX + maxX ), 0.5f * ( minY + maxY ), mMainCamera->viewCenter().z() );
const QVector3D lightPosition = lookingAt + QVector3D( 0.0f, 0.0f, d ); const QVector3D lightPosition = lookingAt + QVector3D( 0.0f, 0.0f, d );
@ -176,6 +179,7 @@ void QgsPostprocessingEntity::updateShadowSettings( const QgsDirectionalLightSet
setupShadowRenderingExtent( minX, maxX, minY, maxY ); setupShadowRenderingExtent( minX, maxX, minY, maxY );
setupDirectionalLight( lightPosition, lightDirection ); setupDirectionalLight( lightPosition, lightDirection );
setShadowBias( shadowSettings.shadowBias() );
} }
void QgsPostprocessingEntity::setShadowRenderingEnabled( bool enabled ) void QgsPostprocessingEntity::setShadowRenderingEnabled( bool enabled )
@ -183,11 +187,17 @@ void QgsPostprocessingEntity::setShadowRenderingEnabled( bool enabled )
mRenderShadowsParameter->setValue( QVariant::fromValue( enabled ? 1 : 0 ) ); mRenderShadowsParameter->setValue( QVariant::fromValue( enabled ? 1 : 0 ) );
} }
void QgsPostprocessingEntity::setShadowBias( float shadowBias ) void QgsPostprocessingEntity::setShadowBias( double shadowBias )
{ {
mShadowBiasParameter->setValue( QVariant::fromValue( shadowBias ) ); mShadowBiasParameter->setValue( QVariant::fromValue( shadowBias ) );
} }
void QgsPostprocessingEntity::updateEyeDomeSettings( const Qgs3DMapSettings &settings )
{
setEyeDomeLightingStrength( settings.eyeDomeLightingStrength() );
setEyeDomeLightingDistance( settings.eyeDomeLightingDistance() );
}
void QgsPostprocessingEntity::setEyeDomeLightingEnabled( bool enabled ) void QgsPostprocessingEntity::setEyeDomeLightingEnabled( bool enabled )
{ {
mEyeDomeLightingEnabledParameter->setValue( QVariant::fromValue( enabled ? 1 : 0 ) ); mEyeDomeLightingEnabledParameter->setValue( QVariant::fromValue( enabled ? 1 : 0 ) );

View File

@ -18,9 +18,12 @@
#include "qgsrenderpassquad.h" #include "qgsrenderpassquad.h"
class QgsFrameGraph;
class QgsShadowRenderView;
class QgsDirectionalLightSettings; class QgsDirectionalLightSettings;
class QgsShadowRenderView;
class QgsForwardRenderView;
class QgsAmbientOcclusionRenderView;
class QgsShadowSettings;
class Qgs3DMapSettings;
#define SIP_NO_FILE #define SIP_NO_FILE
@ -38,7 +41,11 @@ class QgsPostprocessingEntity : public QgsRenderPassQuad
public: public:
//! Constructor //! Constructor
QgsPostprocessingEntity( QgsFrameGraph *frameGraph, Qt3DRender::QLayer *layer, QNode *parent = nullptr ); QgsPostprocessingEntity( const QgsShadowRenderView &shadowRenderView, //
const QgsForwardRenderView &forwardRenderView, //
const QgsAmbientOcclusionRenderView &aoRenderView, //
Qt3DRender::QLayer *layer, //
QNode *parent = nullptr );
//! Sets the parts of the scene where objects cast shadows //! Sets the parts of the scene where objects cast shadows
void setupShadowRenderingExtent( float minX, float maxX, float minY, float maxY ); void setupShadowRenderingExtent( float minX, float maxX, float minY, float maxY );
//! Sets up a directional light that is used to render shadows //! Sets up a directional light that is used to render shadows
@ -46,7 +53,19 @@ class QgsPostprocessingEntity : public QgsRenderPassQuad
//! Sets whether shadow rendering is enabled //! Sets whether shadow rendering is enabled
void setShadowRenderingEnabled( bool enabled ); void setShadowRenderingEnabled( bool enabled );
//! Sets the shadow bias value //! Sets the shadow bias value
void setShadowBias( float shadowBias ); void setShadowBias( double shadowBias );
/**
* Sets shadow rendering to use a directional light
* \since QGIS 3.44
*/
void updateShadowSettings( const QgsShadowSettings &shadowSettings, const QgsDirectionalLightSettings &light );
/**
* Updates eye dome lighting settings from \a settings
* \since QGIS 3.44
*/
void updateEyeDomeSettings( const Qgs3DMapSettings &settings );
//! Sets whether eye dome lighting is enabled //! Sets whether eye dome lighting is enabled
void setEyeDomeLightingEnabled( bool enabled ); void setEyeDomeLightingEnabled( bool enabled );
//! Sets the eye dome lighting strength //! Sets the eye dome lighting strength
@ -54,12 +73,6 @@ class QgsPostprocessingEntity : public QgsRenderPassQuad
//! Sets the eye dome lighting distance (contributes to the contrast of the image) //! Sets the eye dome lighting distance (contributes to the contrast of the image)
void setEyeDomeLightingDistance( int distance ); void setEyeDomeLightingDistance( int distance );
/**
* Sets shadow rendering to use a directional light
* \since QGIS 3.44
*/
void updateShadowSettings( const QgsDirectionalLightSettings &light, float maximumShadowRenderingDistance );
/** /**
* Sets whether screen space ambient occlusion is enabled * Sets whether screen space ambient occlusion is enabled
* \since QGIS 3.28 * \since QGIS 3.28

View File

@ -0,0 +1,196 @@
/***************************************************************************
qgspostprocessingrenderview.cpp
--------------------------------------
Date : May 2025
Copyright : (C) 2025 by Benoit De Mezzo and (C) 2020 by Belgacem Nedjima
Email : benoit dot de dot mezzo at oslandia dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgspostprocessingrenderview.h"
#include <Qt3DRender/QRenderTargetSelector>
#include <Qt3DRender/QTexture>
#include <Qt3DRender/qsubtreeenabler.h>
#include <Qt3DRender/QRenderCapture>
#include <Qt3DRender/QRenderTarget>
#include <Qt3DRender/QRenderTargetOutput>
#include <Qt3DRender/QCameraSelector>
#include <Qt3DRender/QLayerFilter>
#include <Qt3DRender/QClearBuffers>
#include <Qt3DRender/QNoDraw>
#include <QNode>
#include "qgspostprocessingentity.h"
#include "qgsforwardrenderview.h"
#include "qgsshadowrenderview.h"
QgsPostprocessingRenderView::QgsPostprocessingRenderView( const QString &viewName, //
QgsShadowRenderView &shadowRenderView, //
QgsForwardRenderView &forwardRenderView, //
QgsAmbientOcclusionRenderView &aoRenderView, //
QSize mSize, //
Qt3DCore::QEntity *rootSceneEntity )
: QgsAbstractRenderView( viewName )
{
// postprocessing main rendering pass
constructPostprocessingMainPass( mSize );
// sub passes:
QVector<Qt3DRender::QFrameGraphNode *> subpasses;
// 1. postprocessing real render view
subpasses << constructSubPostPassForProcessing( shadowRenderView, forwardRenderView, aoRenderView, rootSceneEntity );
// 2. render capture render view
subpasses << constructSubPostPassForRenderCapture();
setSubPasses( subpasses );
}
QVector<Qt3DRender::QFrameGraphNode *> QgsPostprocessingRenderView::subPasses() const
{
QVector<Qt3DRender::QFrameGraphNode *> out;
Qt3DCore::QNodeVector children = mSubPassesNode->childNodes();
for ( Qt3DCore::QNode *child : children )
if ( dynamic_cast<Qt3DRender::QFrameGraphNode *>( child ) && child->parent() == mSubPassesNode )
out << dynamic_cast<Qt3DRender::QFrameGraphNode *>( child );
return out;
}
void QgsPostprocessingRenderView::setSubPasses( QVector<Qt3DRender::QFrameGraphNode *> topNodes )
{
// detach all subpasses
Qt3DCore::QNodeVector children = mSubPassesNode->childNodes();
for ( Qt3DCore::QNode *child : children )
if ( dynamic_cast<Qt3DRender::QFrameGraphNode *>( child ) && child->parent() == mSubPassesNode )
child->setParent( ( Qt3DCore::QNode * ) nullptr );
// attach new subpasses
for ( Qt3DRender::QFrameGraphNode *child : topNodes )
child->setParent( mSubPassesNode );
}
void QgsPostprocessingRenderView::updateWindowResize( int width, int height )
{
QgsAbstractRenderView::updateWindowResize( width, height );
mRenderCaptureColorTexture->setSize( width, height );
mRenderCaptureDepthTexture->setSize( width, height );
}
void QgsPostprocessingRenderView::setOffScreenRenderCaptureEnabled( bool enabled )
{
if ( !isEnabled() || mRenderCaptureTargetSelector->isEnabled() == enabled )
return;
mRenderCaptureTargetSelector->setEnabled( enabled );
mRenderCapture->parentNode()->setEnabled( enabled ); // for NoDraw node
}
Qt3DRender::QRenderTarget *QgsPostprocessingRenderView::buildRenderCaptureTextures( QSize mSize )
{
// =============== v NEEDED ONLY DURING UNIT TEST v
Qt3DRender::QRenderTarget *renderTarget = new Qt3DRender::QRenderTarget( mRenderCaptureTargetSelector );
// Create a render target output for rendering color.
Qt3DRender::QRenderTargetOutput *colorOutput = new Qt3DRender::QRenderTargetOutput( renderTarget );
colorOutput->setAttachmentPoint( Qt3DRender::QRenderTargetOutput::Color0 );
// Create a texture to render into.
mRenderCaptureColorTexture = new Qt3DRender::QTexture2D( colorOutput );
mRenderCaptureColorTexture->setSize( mSize.width(), mSize.height() );
mRenderCaptureColorTexture->setFormat( Qt3DRender::QAbstractTexture::RGB8_UNorm );
mRenderCaptureColorTexture->setMinificationFilter( Qt3DRender::QAbstractTexture::Linear );
mRenderCaptureColorTexture->setMagnificationFilter( Qt3DRender::QAbstractTexture::Linear );
mRenderCaptureColorTexture->setObjectName( mViewName + "::ColorTarget" );
// Hook the texture up to our output, and the output up to this object.
colorOutput->setTexture( mRenderCaptureColorTexture );
renderTarget->addOutput( colorOutput );
Qt3DRender::QRenderTargetOutput *depthOutput = new Qt3DRender::QRenderTargetOutput( renderTarget );
depthOutput->setAttachmentPoint( Qt3DRender::QRenderTargetOutput::Depth );
mRenderCaptureDepthTexture = new Qt3DRender::QTexture2D( depthOutput );
mRenderCaptureDepthTexture->setSize( mSize.width(), mSize.height() );
mRenderCaptureDepthTexture->setFormat( Qt3DRender::QAbstractTexture::DepthFormat );
mRenderCaptureDepthTexture->setMinificationFilter( Qt3DRender::QAbstractTexture::Linear );
mRenderCaptureDepthTexture->setMagnificationFilter( Qt3DRender::QAbstractTexture::Linear );
mRenderCaptureDepthTexture->setComparisonFunction( Qt3DRender::QAbstractTexture::CompareLessEqual );
mRenderCaptureDepthTexture->setComparisonMode( Qt3DRender::QAbstractTexture::CompareRefToTexture );
mRenderCaptureDepthTexture->setObjectName( mViewName + "::DepthTarget" );
depthOutput->setTexture( mRenderCaptureDepthTexture );
renderTarget->addOutput( depthOutput );
return renderTarget;
// =============== ^ NEEDED ONLY DURING UNIT TEST ^
}
Qt3DRender::QFrameGraphNode *QgsPostprocessingRenderView::constructPostprocessingMainPass( QSize mSize )
{
// Due to a bug in Qt5 (fixed in Qt6 - https://codereview.qt-project.org/c/qt/qt3d/+/462575) we need to move the render target selector at the top
// of this branch. Doing so this allows Qt3d to have a FBO format matching the one need to do the capture
mRenderCaptureTargetSelector = new Qt3DRender::QRenderTargetSelector( mRendererEnabler );
mRenderCaptureTargetSelector->setObjectName( mViewName + "::RenderTargetSelector" );
mRenderCaptureTargetSelector->setEnabled( false );
// build texture part
Qt3DRender::QRenderTarget *renderTarget = buildRenderCaptureTextures( mSize );
mRenderCaptureTargetSelector->setTarget( renderTarget );
// add node for sub passes
mSubPassesNode = new Qt3DRender::QFrameGraphNode( mRenderCaptureTargetSelector );
mSubPassesNode->setObjectName( mViewName + "::Sub passes top node" );
return mRenderCaptureTargetSelector;
}
Qt3DRender::QFrameGraphNode *QgsPostprocessingRenderView::constructSubPostPassForProcessing( QgsShadowRenderView &shadowRenderView, //
QgsForwardRenderView &forwardRenderView, //
QgsAmbientOcclusionRenderView &aoRenderView, //
Qt3DCore::QEntity *rootSceneEntity )
{
Qt3DRender::QLayerFilter *layerFilter = new Qt3DRender::QLayerFilter;
layerFilter->setObjectName( mViewName + "::Sub pass::Postprocessing" );
Qt3DRender::QLayer *postProcessingLayer = new Qt3DRender::QLayer();
postProcessingLayer->setRecursive( true );
layerFilter->addLayer( postProcessingLayer );
// end of this branch
new Qt3DRender::QClearBuffers( layerFilter );
mPostprocessingEntity = new QgsPostprocessingEntity( shadowRenderView, //
forwardRenderView, //
aoRenderView, //
postProcessingLayer, //
rootSceneEntity );
mPostprocessingEntity->setObjectName( "PostProcessingPassEntity" );
return layerFilter;
}
Qt3DRender::QFrameGraphNode *QgsPostprocessingRenderView::constructSubPostPassForRenderCapture()
{
Qt3DRender::QFrameGraphNode *top = new Qt3DRender::QNoDraw;
top->setObjectName( mViewName + "::Sub pass::RenderCapture" );
mRenderCapture = new Qt3DRender::QRenderCapture( top );
return top;
}
Qt3DRender::QRenderCapture *QgsPostprocessingRenderView::renderCapture() const
{
return mRenderCapture;
}
QgsPostprocessingEntity *QgsPostprocessingRenderView::entity() const
{
return mPostprocessingEntity;
}

View File

@ -0,0 +1,98 @@
/***************************************************************************
qgspostprocessingrenderview.h
--------------------------------------
Date : May 2025
Copyright : (C) 2025 by Benoit De Mezzo and (C) 2020 by Belgacem Nedjima
Email : benoit dot de dot mezzo at oslandia dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSPOSTPROCESSINGRENDERVIEW_H
#define QGSPOSTPROCESSINGRENDERVIEW_H
#include "qgsabstractrenderview.h"
namespace Qt3DRender
{
class QTexture2D;
class QRenderTargetSelector;
class QClearBuffers;
class QRenderStateSet;
class QRenderCapture;
class QRenderTarget;
} //namespace Qt3DRender
class QgsPostprocessingEntity;
#define SIP_NO_FILE
/**
* \ingroup qgis_3d
* \brief Container class that holds different objects related to postprocessing rendering
*
* \note Not available in Python bindings
*
* The postprocessing pass apply post-processing effects (shadows, EDL, SSAO).
*
* \since QGIS 3.44
*/
class QgsPostprocessingRenderView : public QgsAbstractRenderView
{
public:
//! Default constructor
QgsPostprocessingRenderView( const QString &viewName, //
QgsShadowRenderView &shadowRenderView, //
QgsForwardRenderView &forwardRenderView, //
QgsAmbientOcclusionRenderView &aoRenderView, //
QSize mSize, //
Qt3DCore::QEntity *rootSceneEntity );
virtual void updateWindowResize( int width, int height ) override;
//! Returns the render capture object used to take an image of the postprocessing buffer of the scene
Qt3DRender::QRenderCapture *renderCapture() const;
//! Returns the QT3D entity used to do the rendering
QgsPostprocessingEntity *entity() const;
/**
* Sets whether it will be possible to render to an image
*/
void setOffScreenRenderCaptureEnabled( bool enabled );
//! Returns the top node of all subpasses
QVector<Qt3DRender::QFrameGraphNode *> subPasses() const;
/**
* Updates the subpasses with the new \a topNodes
*/
void setSubPasses( QVector<Qt3DRender::QFrameGraphNode *> topNodes );
private:
Qt3DRender::QRenderTarget *buildRenderCaptureTextures( QSize mSize );
Qt3DRender::QFrameGraphNode *constructPostprocessingMainPass( QSize mSize );
Qt3DRender::QFrameGraphNode *constructSubPostPassForProcessing( QgsShadowRenderView &shadowRenderView, //
QgsForwardRenderView &forwardRenderView, //
QgsAmbientOcclusionRenderView &aoRenderView, //
Qt3DCore::QEntity *rootSceneEntity );
Qt3DRender::QFrameGraphNode *constructSubPostPassForRenderCapture();
Qt3DRender::QRenderTargetSelector *mRenderCaptureTargetSelector = nullptr;
Qt3DRender::QRenderCapture *mRenderCapture = nullptr;
QgsPostprocessingEntity *mPostprocessingEntity = nullptr;
// Post processing pass texture related objects:
Qt3DRender::QTexture2D *mRenderCaptureColorTexture = nullptr;
Qt3DRender::QTexture2D *mRenderCaptureDepthTexture = nullptr;
Qt3DRender::QFrameGraphNode *mSubPassesNode = nullptr;
};
#endif // QGSPOSTPROCESSINGRENDERVIEW_H

View File

@ -74,7 +74,7 @@ class QgsShadowRenderView : public QgsAbstractRenderView
virtual void setEnabled( bool enable ) override; virtual void setEnabled( bool enable ) override;
//! Returns the light camera //! Returns the light camera
Qt3DRender::QCamera *lightCamera() { return mLightCamera; } Qt3DRender::QCamera *lightCamera() const { return mLightCamera; }
//! Returns shadow depth texture //! Returns shadow depth texture
Qt3DRender::QTexture2D *mapTexture() const; Qt3DRender::QTexture2D *mapTexture() const;

View File

@ -39,13 +39,15 @@
(Qt3DRender::QRenderStateSet{121/<no_name>}) [ (QDepthTest:Always), (QCullFace:NoCulling) ] (Qt3DRender::QRenderStateSet{121/<no_name>}) [ (QDepthTest:Always), (QCullFace:NoCulling) ]
(Qt3DRender::QLayerFilter{124/<no_name>}) [ (AcceptAnyMatchingLayers:[ {90/ambient_occlusion::Layer(Blur)} ]) ] (Qt3DRender::QLayerFilter{124/<no_name>}) [ (AcceptAnyMatchingLayers:[ {90/ambient_occlusion::Layer(Blur)} ]) ]
(Qt3DRender::QRenderTargetSelector{128/ambient_occlusion::RenderTargetSelector(Blur)}) [ (outputs:[ (Color0:{126[R32F]/ambient_occlusion::ColorTarget(blur)) ]) ] (Qt3DRender::QRenderTargetSelector{128/ambient_occlusion::RenderTargetSelector(Blur)}) [ (outputs:[ (Color0:{126[R32F]/ambient_occlusion::ColorTarget(blur)) ]) ]
(Qt3DRender::QRenderTargetSelector{141/PostProcessingPass}) [D] [ (outputs:[ (Color0:{144[RGB8_UNorm]/PostProcessingPass::ColorTarget), (Depth:{146[DepthFormat]/PostProcessingPass::DepthTarget) ]) ] (Qt3DRender::QNoDraw{141/post_processing::NoDraw}) [D]
(Qt3DRender::QCameraSelector{147/Sub pass Postprocessing}) [ (Qt3DRender::QCamera:{51/shadow::LightCamera}) ] (Qt3DRender::QSubtreeEnabler{142/post_processing::SubtreeEnabler})
(Qt3DRender::QLayerFilter{148/<no_name>}) [ (AcceptAnyMatchingLayers:[ {150/<no_name>} ]) ] (Qt3DRender::QRenderTargetSelector{143/post_processing::RenderTargetSelector}) [D] [ (outputs:[ (Color0:{146[RGB8_UNorm]/post_processing::ColorTarget), (Depth:{148[DepthFormat]/post_processing::DepthTarget) ]) ]
(Qt3DRender::QClearBuffers{149/<no_name>}) (Qt3DRender::QFrameGraphNode{149/post_processing::Sub passes top node})
(Qt3DRender::QNoDraw{184/debug_texture::NoDraw}) (Qt3DRender::QLayerFilter{150/post_processing::Sub pass::Postprocessing}) [ (AcceptAnyMatchingLayers:[ {151/<no_name>} ]) ]
(Qt3DRender::QSubtreeEnabler{185/debug_texture::SubtreeEnabler}) [D] (Qt3DRender::QClearBuffers{152/<no_name>})
(Qt3DRender::QLayerFilter{187/<no_name>}) [ (AcceptAnyMatchingLayers:[ {186/debug_texture::Layer} ]) ] (Qt3DRender::QNoDraw{188/debug_texture::NoDraw})
(Qt3DRender::QRenderStateSet{188/<no_name>}) [ (QDepthTest:Always), (QCullFace:NoCulling) ] (Qt3DRender::QSubtreeEnabler{189/debug_texture::SubtreeEnabler}) [D]
(Qt3DRender::QNoDraw{191/Sub pass RenderCapture}) (Qt3DRender::QLayerFilter{191/<no_name>}) [ (AcceptAnyMatchingLayers:[ {190/debug_texture::Layer} ]) ]
(Qt3DRender::QRenderCapture{192/<no_name>}) (Qt3DRender::QRenderStateSet{192/<no_name>}) [ (QDepthTest:Always), (QCullFace:NoCulling) ]
(Qt3DRender::QNoDraw{186/post_processing::Sub pass::RenderCapture}) [D]
(Qt3DRender::QRenderCapture{187/<no_name>})

View File

@ -39,13 +39,15 @@
(Qt3DRender::QRenderStateSet{121/<no_name>}) [ (QDepthTest:Always), (QCullFace:NoCulling) ] (Qt3DRender::QRenderStateSet{121/<no_name>}) [ (QDepthTest:Always), (QCullFace:NoCulling) ]
(Qt3DRender::QLayerFilter{124/<no_name>}) [ (AcceptAnyMatchingLayers:[ {90/ambient_occlusion::Layer(Blur)} ]) ] (Qt3DRender::QLayerFilter{124/<no_name>}) [ (AcceptAnyMatchingLayers:[ {90/ambient_occlusion::Layer(Blur)} ]) ]
(Qt3DRender::QRenderTargetSelector{128/ambient_occlusion::RenderTargetSelector(Blur)}) [ (outputs:[ (Color0:{126[R32F]/ambient_occlusion::ColorTarget(blur)) ]) ] (Qt3DRender::QRenderTargetSelector{128/ambient_occlusion::RenderTargetSelector(Blur)}) [ (outputs:[ (Color0:{126[R32F]/ambient_occlusion::ColorTarget(blur)) ]) ]
(Qt3DRender::QRenderTargetSelector{141/PostProcessingPass}) [D] [ (outputs:[ (Color0:{144[RGB8_UNorm]/PostProcessingPass::ColorTarget), (Depth:{146[DepthFormat]/PostProcessingPass::DepthTarget) ]) ] (Qt3DRender::QNoDraw{141/post_processing::NoDraw}) [D]
(Qt3DRender::QCameraSelector{147/Sub pass Postprocessing}) [ (Qt3DRender::QCamera:{51/shadow::LightCamera}) ] (Qt3DRender::QSubtreeEnabler{142/post_processing::SubtreeEnabler})
(Qt3DRender::QLayerFilter{148/<no_name>}) [ (AcceptAnyMatchingLayers:[ {150/<no_name>} ]) ] (Qt3DRender::QRenderTargetSelector{143/post_processing::RenderTargetSelector}) [D] [ (outputs:[ (Color0:{146[RGB8_UNorm]/post_processing::ColorTarget), (Depth:{148[DepthFormat]/post_processing::DepthTarget) ]) ]
(Qt3DRender::QClearBuffers{149/<no_name>}) (Qt3DRender::QFrameGraphNode{149/post_processing::Sub passes top node})
(Qt3DRender::QNoDraw{184/debug_texture::NoDraw}) (Qt3DRender::QLayerFilter{150/post_processing::Sub pass::Postprocessing}) [ (AcceptAnyMatchingLayers:[ {151/<no_name>} ]) ]
(Qt3DRender::QSubtreeEnabler{185/debug_texture::SubtreeEnabler}) [D] (Qt3DRender::QClearBuffers{152/<no_name>})
(Qt3DRender::QLayerFilter{187/<no_name>}) [ (AcceptAnyMatchingLayers:[ {186/debug_texture::Layer} ]) ] (Qt3DRender::QNoDraw{188/debug_texture::NoDraw})
(Qt3DRender::QRenderStateSet{188/<no_name>}) [ (QDepthTest:Always), (QCullFace:NoCulling) ] (Qt3DRender::QSubtreeEnabler{189/debug_texture::SubtreeEnabler}) [D]
(Qt3DRender::QNoDraw{191/Sub pass RenderCapture}) (Qt3DRender::QLayerFilter{191/<no_name>}) [ (AcceptAnyMatchingLayers:[ {190/debug_texture::Layer} ]) ]
(Qt3DRender::QRenderCapture{192/<no_name>}) (Qt3DRender::QRenderStateSet{192/<no_name>}) [ (QDepthTest:Always), (QCullFace:NoCulling) ]
(Qt3DRender::QNoDraw{186/post_processing::Sub pass::RenderCapture}) [D]
(Qt3DRender::QRenderCapture{187/<no_name>})

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB