From 44bcf90aa6736aa5fce4ddce9f693e26e9ff354d Mon Sep 17 00:00:00 2001 From: bdm-oslandia Date: Tue, 2 Aug 2022 12:23:41 +0200 Subject: [PATCH] feat(3d/renderView): extract shadow renderview to dedicated renderview class --- src/3d/CMakeLists.txt | 2 + src/3d/framegraph/qgsframegraph.cpp | 201 ++++-------------- src/3d/framegraph/qgsframegraph.h | 47 +--- src/3d/framegraph/qgspostprocessingentity.cpp | 13 +- src/3d/framegraph/qgspostprocessingentity.h | 3 +- src/3d/framegraph/qgsshadowrenderview.cpp | 182 ++++++++++++++++ src/3d/framegraph/qgsshadowrenderview.h | 110 ++++++++++ src/3d/qgs3dmapscene.cpp | 25 ++- src/3d/qgsoffscreen3dengine.cpp | 6 +- src/3d/qgswindow3dengine.cpp | 15 +- src/3d/qgswindow3dengine.h | 6 - .../expected_framegraph.txt | 90 ++++---- .../expected_framegraph.txt | 90 ++++---- 13 files changed, 469 insertions(+), 321 deletions(-) create mode 100644 src/3d/framegraph/qgsshadowrenderview.cpp create mode 100644 src/3d/framegraph/qgsshadowrenderview.h diff --git a/src/3d/CMakeLists.txt b/src/3d/CMakeLists.txt index 2be63d48d4862..2947bc0775179 100644 --- a/src/3d/CMakeLists.txt +++ b/src/3d/CMakeLists.txt @@ -81,6 +81,7 @@ set(QGIS_3D_SRCS framegraph/qgspostprocessingentity.cpp framegraph/qgspreviewquad.cpp framegraph/qgsrenderpassquad.cpp + framegraph/qgsshadowrenderview.cpp framegraph/qgsframegraph.cpp framegraph/qgsfgutils.cpp @@ -179,6 +180,7 @@ set(QGIS_3D_HDRS framegraph/qgspostprocessingentity.h framegraph/qgspreviewquad.h framegraph/qgsrenderpassquad.h + framegraph/qgsshadowrenderview.h symbols/qgsbillboardgeometry.h symbols/qgsline3dsymbol.h diff --git a/src/3d/framegraph/qgsframegraph.cpp b/src/3d/framegraph/qgsframegraph.cpp index f95a46338a669..179c17d9df55b 100644 --- a/src/3d/framegraph/qgsframegraph.cpp +++ b/src/3d/framegraph/qgsframegraph.cpp @@ -19,6 +19,8 @@ #include "qgspreviewquad.h" #include "qgs3dutils.h" #include "qgsfgutils.h" +#include "qgsabstractrenderview.h" + #include "qgsambientocclusionrenderentity.h" #include "qgsambientocclusionblurentity.h" @@ -53,8 +55,9 @@ typedef Qt3DCore::QGeometry Qt3DQGeometry; #include #include #include -#include "qgsabstractrenderview.h" +#include "qgsshadowrenderview.h" +const QString QgsFrameGraph::SHADOW_RENDERVIEW = "shadow"; const QString QgsFrameGraph::AXIS3D_RENDERVIEW = "3daxis"; Qt3DRender::QFrameGraphNode *QgsFrameGraph::constructForwardRenderPass() @@ -216,54 +219,27 @@ Qt3DRender::QFrameGraphNode *QgsFrameGraph::constructForwardRenderPass() return mMainCameraSelector; } -Qt3DRender::QFrameGraphNode *QgsFrameGraph::constructShadowRenderPass() + +void QgsFrameGraph::constructShadowRenderPass() { - mLightCameraSelectorShadowPass = new Qt3DRender::QCameraSelector; - mLightCameraSelectorShadowPass->setObjectName( "Shadow render pass CameraSelector" ); - mLightCameraSelectorShadowPass->setCamera( mLightCamera ); - - mShadowSceneEntitiesFilter = new Qt3DRender::QLayerFilter( mLightCameraSelectorShadowPass ); - mShadowSceneEntitiesFilter->addLayer( mCastShadowsLayer ); - - mShadowMapTexture = new Qt3DRender::QTexture2D; - mShadowMapTexture->setWidth( mShadowMapResolution ); - mShadowMapTexture->setHeight( mShadowMapResolution ); - mShadowMapTexture->setFormat( Qt3DRender::QTexture2D::TextureFormat::DepthFormat ); - mShadowMapTexture->setGenerateMipMaps( false ); - mShadowMapTexture->setMagnificationFilter( Qt3DRender::QTexture2D::Linear ); - mShadowMapTexture->setMinificationFilter( Qt3DRender::QTexture2D::Linear ); - mShadowMapTexture->wrapMode()->setX( Qt3DRender::QTextureWrapMode::ClampToEdge ); - mShadowMapTexture->wrapMode()->setY( Qt3DRender::QTextureWrapMode::ClampToEdge ); - - Qt3DRender::QRenderTarget *shadowRenderTarget = new Qt3DRender::QRenderTarget; - Qt3DRender::QRenderTargetOutput *shadowRenderTargetOutput = new Qt3DRender::QRenderTargetOutput; - shadowRenderTargetOutput->setAttachmentPoint( Qt3DRender::QRenderTargetOutput::Depth ); - shadowRenderTargetOutput->setTexture( mShadowMapTexture ); - shadowRenderTarget->addOutput( shadowRenderTargetOutput ); - - mShadowRenderTargetSelector = new Qt3DRender::QRenderTargetSelector( mShadowSceneEntitiesFilter ); - mShadowRenderTargetSelector->setTarget( shadowRenderTarget ); - - mShadowClearBuffers = new Qt3DRender::QClearBuffers( mShadowRenderTargetSelector ); - mShadowClearBuffers->setBuffers( Qt3DRender::QClearBuffers::BufferType::ColorDepthBuffer ); - mShadowClearBuffers->setClearColor( QColor::fromRgbF( 0.0f, 1.0f, 0.0f ) ); - - mShadowRenderStateSet = new Qt3DRender::QRenderStateSet( mShadowClearBuffers ); - - Qt3DRender::QDepthTest *shadowDepthTest = new Qt3DRender::QDepthTest; - shadowDepthTest->setDepthFunction( Qt3DRender::QDepthTest::Less ); - mShadowRenderStateSet->addRenderState( shadowDepthTest ); - - Qt3DRender::QCullFace *shadowCullFace = new Qt3DRender::QCullFace; - shadowCullFace->setMode( Qt3DRender::QCullFace::CullingMode::Front ); - mShadowRenderStateSet->addRenderState( shadowCullFace ); - - Qt3DRender::QPolygonOffset *polygonOffset = new Qt3DRender::QPolygonOffset; - polygonOffset->setDepthSteps( 4.0 ); - polygonOffset->setScaleFactor( 1.1 ); - mShadowRenderStateSet->addRenderState( polygonOffset ); - - return mLightCameraSelectorShadowPass; + Qt3DRender::QTexture2D *shadowMapTexture = new Qt3DRender::QTexture2D; + shadowMapTexture->setWidth( QgsFrameGraph::mDefaultShadowMapResolution ); + shadowMapTexture->setHeight( QgsFrameGraph::mDefaultShadowMapResolution ); + shadowMapTexture->setFormat( Qt3DRender::QTexture2D::TextureFormat::DepthFormat ); + shadowMapTexture->setGenerateMipMaps( false ); + shadowMapTexture->setMagnificationFilter( Qt3DRender::QTexture2D::Linear ); + shadowMapTexture->setMinificationFilter( Qt3DRender::QTexture2D::Linear ); + shadowMapTexture->wrapMode()->setX( Qt3DRender::QTextureWrapMode::ClampToEdge ); + shadowMapTexture->wrapMode()->setY( Qt3DRender::QTextureWrapMode::ClampToEdge ); + shadowMapTexture->setObjectName( "QgsShadowRenderView::DepthTarget" ); + + mShadowRenderTargetOutput = new Qt3DRender::QRenderTargetOutput; + mShadowRenderTargetOutput->setAttachmentPoint( Qt3DRender::QRenderTargetOutput::Depth ); + mShadowRenderTargetOutput->setTexture( shadowMapTexture ); + + QgsShadowRenderView *shadowRenderView = new QgsShadowRenderView( this ); + shadowRenderView->setTargetOutputs( { mShadowRenderTargetOutput } ); + registerRenderView( shadowRenderView, SHADOW_RENDERVIEW ); } Qt3DRender::QFrameGraphNode *QgsFrameGraph::constructSubPostPassForTexturesPreview() @@ -287,7 +263,7 @@ Qt3DRender::QFrameGraphNode *QgsFrameGraph::constructSubPostPassForProcessing() { Qt3DRender::QCameraSelector *cameraSelector = new Qt3DRender::QCameraSelector; cameraSelector->setObjectName( "Sub pass Postprocessing" ); - cameraSelector->setCamera( mLightCamera ); + cameraSelector->setCamera( dynamic_cast( renderView( QgsFrameGraph::SHADOW_RENDERVIEW ) )->lightCamera() ); Qt3DRender::QLayerFilter *layerFilter = new Qt3DRender::QLayerFilter( cameraSelector ); @@ -654,10 +630,8 @@ QgsFrameGraph::QgsFrameGraph( QSurface *surface, QSize s, Qt3DRender::QCamera *m mRootEntity = root; mMainCamera = mainCamera; - mLightCamera = new Qt3DRender::QCamera; mPreviewLayer = new Qt3DRender::QLayer; - mCastShadowsLayer = new Qt3DRender::QLayer; mForwardRenderLayer = new Qt3DRender::QLayer; mDepthRenderPassLayer = new Qt3DRender::QLayer; mTransparentObjectsPassLayer = new Qt3DRender::QLayer; @@ -666,7 +640,6 @@ QgsFrameGraph::QgsFrameGraph( QSurface *surface, QSize s, Qt3DRender::QCamera *m mRubberBandsLayer->setObjectName( "mRubberBandsLayer" ); mPreviewLayer->setRecursive( true ); - mCastShadowsLayer->setRecursive( true ); mForwardRenderLayer->setRecursive( true ); mDepthRenderPassLayer->setRecursive( true ); mTransparentObjectsPassLayer->setRecursive( true ); @@ -693,8 +666,7 @@ QgsFrameGraph::QgsFrameGraph( QSurface *surface, QSize s, Qt3DRender::QCamera *m rubberBandsPass->setParent( mMainViewPort ); // shadow rendering pass - Qt3DRender::QFrameGraphNode *shadowRenderPass = constructShadowRenderPass(); - shadowRenderPass->setParent( mMainViewPort ); + constructShadowRenderPass(); // depth buffer processing Qt3DRender::QFrameGraphNode *depthBufferProcessingPass = constructDepthRenderPass(); @@ -720,7 +692,11 @@ QgsFrameGraph::QgsFrameGraph( QSurface *surface, QSize s, Qt3DRender::QCamera *m Qt3DRender::QParameter *shadowMapIsDepthParam = new Qt3DRender::QParameter( "isDepth", true ); mDebugDepthMapPreviewQuad = this->addTexturePreviewOverlay( mForwardDepthTexture, QPointF( 0.9f, 0.9f ), QSizeF( 0.1, 0.1 ), QVector { depthMapIsDepthParam } ); - mDebugShadowMapPreviewQuad = this->addTexturePreviewOverlay( mShadowMapTexture, QPointF( 0.9f, 0.9f ), QSizeF( 0.1, 0.1 ), QVector { shadowMapIsDepthParam } ); + + QgsAbstractRenderView *shadowRenderView = renderView( QgsFrameGraph::SHADOW_RENDERVIEW ); + Qt3DRender::QTexture2D *shadowDepthTexture = shadowRenderView->outputTexture( Qt3DRender::QRenderTargetOutput::Depth ); + mDebugShadowMapPreviewQuad = this->addTexturePreviewOverlay( shadowDepthTexture, QPointF( 0.9f, 0.9f ), QSizeF( 0.1, 0.1 ), QVector { shadowMapIsDepthParam } ); + mDebugDepthMapPreviewQuad->setEnabled( false ); mDebugShadowMapPreviewQuad->setEnabled( false ); @@ -756,7 +732,7 @@ bool QgsFrameGraph::registerRenderView( QgsAbstractRenderView *renderView, const void QgsFrameGraph::setEnableRenderView( const QString &name, bool enable ) { - if ( mRenderViewMap [name] != nullptr ) + if ( mRenderViewMap [name] ) { mRenderViewMap [name]->enableSubTree( enable ); } @@ -767,6 +743,10 @@ QgsAbstractRenderView *QgsFrameGraph::renderView( const QString &name ) return mRenderViewMap [name]; } +bool QgsFrameGraph::isRenderViewEnabled( const QString &name ) +{ + return mRenderViewMap [name] != nullptr && mRenderViewMap [name]->isSubTreeEnabled(); +} QgsPreviewQuad *QgsFrameGraph::addTexturePreviewOverlay( Qt3DRender::QTexture2D *texture, const QPointF ¢erTexCoords, const QSizeF &sizeTexCoords, QVector additionalShaderParameters ) { @@ -777,92 +757,6 @@ QgsPreviewQuad *QgsFrameGraph::addTexturePreviewOverlay( Qt3DRender::QTexture2D return previewQuad; } -// computes the portion of the Y=y plane the camera is looking at -void calculateViewExtent( Qt3DRender::QCamera *camera, float shadowRenderingDistance, float y, float &minX, float &maxX, float &minY, float &maxY, float &minZ, float &maxZ ) -{ - const QVector3D cameraPos = camera->position(); - const QMatrix4x4 projectionMatrix = camera->projectionMatrix(); - const QMatrix4x4 viewMatrix = camera->viewMatrix(); - float depth = 1.0f; - QVector4D viewCenter = viewMatrix * QVector4D( camera->viewCenter(), 1.0f ); - viewCenter /= viewCenter.w(); - viewCenter = projectionMatrix * viewCenter; - viewCenter /= viewCenter.w(); - depth = viewCenter.z(); - QVector viewFrustumPoints = - { - QVector3D( 0.0f, 0.0f, depth ), - QVector3D( 0.0f, 1.0f, depth ), - QVector3D( 1.0f, 0.0f, depth ), - QVector3D( 1.0f, 1.0f, depth ), - QVector3D( 0.0f, 0.0f, 0 ), - QVector3D( 0.0f, 1.0f, 0 ), - QVector3D( 1.0f, 0.0f, 0 ), - QVector3D( 1.0f, 1.0f, 0 ) - }; - maxX = std::numeric_limits::lowest(); - maxY = std::numeric_limits::lowest(); - maxZ = std::numeric_limits::lowest(); - minX = std::numeric_limits::max(); - minY = std::numeric_limits::max(); - minZ = std::numeric_limits::max(); - for ( int i = 0; i < viewFrustumPoints.size(); ++i ) - { - // convert from view port space to world space - viewFrustumPoints[i] = viewFrustumPoints[i].unproject( viewMatrix, projectionMatrix, QRect( 0, 0, 1, 1 ) ); - minX = std::min( minX, viewFrustumPoints[i].x() ); - maxX = std::max( maxX, viewFrustumPoints[i].x() ); - minY = std::min( minY, viewFrustumPoints[i].y() ); - maxY = std::max( maxY, viewFrustumPoints[i].y() ); - minZ = std::min( minZ, viewFrustumPoints[i].z() ); - maxZ = std::max( maxZ, viewFrustumPoints[i].z() ); - // find the intersection between the line going from cameraPos to the frustum quad point - // and the horizontal plane Y=y - // if the intersection is on the back side of the viewing panel we get a point that is - // shadowRenderingDistance units in front of the camera - const QVector3D pt = cameraPos; - const QVector3D vect = ( viewFrustumPoints[i] - pt ).normalized(); - float t = ( y - pt.y() ) / vect.y(); - if ( t < 0 ) - t = shadowRenderingDistance; - else - t = std::min( t, shadowRenderingDistance ); - viewFrustumPoints[i] = pt + t * vect; - minX = std::min( minX, viewFrustumPoints[i].x() ); - maxX = std::max( maxX, viewFrustumPoints[i].x() ); - minY = std::min( minY, viewFrustumPoints[i].y() ); - maxY = std::max( maxY, viewFrustumPoints[i].y() ); - minZ = std::min( minZ, viewFrustumPoints[i].z() ); - maxZ = std::max( maxZ, viewFrustumPoints[i].z() ); - } -} - -void QgsFrameGraph::setupDirectionalLight( const QgsDirectionalLightSettings &light, float maximumShadowRenderingDistance ) -{ - float minX, maxX, minY, maxY, minZ, maxZ; - QVector3D lookingAt = mMainCamera->viewCenter(); - const float d = 2 * ( mMainCamera->position() - mMainCamera->viewCenter() ).length(); - - const QVector3D vertical = QVector3D( 0.0f, d, 0.0f ); - const QVector3D lightDirection = QVector3D( light.direction().x(), light.direction().y(), light.direction().z() ).normalized(); - calculateViewExtent( mMainCamera, maximumShadowRenderingDistance, lookingAt.y(), minX, maxX, minY, maxY, minZ, maxZ ); - - lookingAt = QVector3D( 0.5 * ( minX + maxX ), mMainCamera->viewCenter().y(), 0.5 * ( minZ + maxZ ) ); - const QVector3D lightPosition = lookingAt + vertical; - mLightCamera->setPosition( lightPosition ); - mLightCamera->setViewCenter( lookingAt ); - mLightCamera->setUpVector( QVector3D( 0.0f, 1.0f, 0.0f ) ); - mLightCamera->rotateAboutViewCenter( QQuaternion::rotationTo( vertical.normalized(), -lightDirection.normalized() ) ); - - mLightCamera->setProjectionType( Qt3DRender::QCameraLens::ProjectionType::OrthographicProjection ); - mLightCamera->lens()->setOrthographicProjection( - - 0.7 * ( maxX - minX ), 0.7 * ( maxX - minX ), - - 0.7 * ( maxZ - minZ ), 0.7 * ( maxZ - minZ ), - 1.0f, 2 * ( lookingAt - lightPosition ).length() ); - - mPostprocessingEntity->setupShadowRenderingExtent( minX, maxX, minZ, maxZ ); - mPostprocessingEntity->setupDirectionalLight( lightPosition, lightDirection ); -} QString QgsFrameGraph::dumpFrameGraph() const { @@ -888,29 +782,6 @@ void QgsFrameGraph::setClearColor( const QColor &clearColor ) mForwardClearBuffers->setClearColor( clearColor ); } -void QgsFrameGraph::setShadowRenderingEnabled( bool enabled ) -{ - mShadowRenderingEnabled = enabled; - mPostprocessingEntity->setShadowRenderingEnabled( mShadowRenderingEnabled ); - if ( mShadowRenderingEnabled ) - mShadowSceneEntitiesFilter->setEnabled( true ); - else - mShadowSceneEntitiesFilter->setEnabled( false ); -} - -void QgsFrameGraph::setShadowBias( float shadowBias ) -{ - mShadowBias = shadowBias; - mPostprocessingEntity->setShadowBias( mShadowBias ); -} - -void QgsFrameGraph::setShadowMapResolution( int resolution ) -{ - mShadowMapResolution = resolution; - mShadowMapTexture->setWidth( mShadowMapResolution ); - mShadowMapTexture->setHeight( mShadowMapResolution ); -} - void QgsFrameGraph::setAmbientOcclusionEnabled( bool enabled ) { mAmbientOcclusionEnabled = enabled; diff --git a/src/3d/framegraph/qgsframegraph.h b/src/3d/framegraph/qgsframegraph.h index 6eb77738652af..6fed7f2947dc0 100644 --- a/src/3d/framegraph/qgsframegraph.h +++ b/src/3d/framegraph/qgsframegraph.h @@ -74,8 +74,6 @@ class QgsFrameGraph : public Qt3DCore::QEntity Qt3DRender::QTexture2D *forwardRenderColorTexture() { return mForwardColorTexture; } //! Returns the depth texture of the forward rendering pass Qt3DRender::QTexture2D *forwardRenderDepthTexture() { return mForwardDepthTexture; } - //! Returns the shadow map (a depth texture for the shadow rendering pass) - Qt3DRender::QTexture2D *shadowMapTexture() { return mShadowMapTexture; } /** * Returns blurred ambient occlusion factor values texture @@ -85,8 +83,6 @@ class QgsFrameGraph : public Qt3DCore::QEntity //! Returns a layer object used to indicate that an entity is to be rendered during the preview textures rendering pass Qt3DRender::QLayer *previewLayer() { return mPreviewLayer; } - //! Returns a layer object used to indicate that an entity will cast shadows - Qt3DRender::QLayer *castShadowsLayer() { return mCastShadowsLayer; } //! Returns a layer object used to indicate that an entity will be rendered during the forward rendering pass Qt3DRender::QLayer *forwardRenderLayer() { return mForwardRenderLayer; } @@ -98,8 +94,6 @@ class QgsFrameGraph : public Qt3DCore::QEntity //! Returns the main camera Qt3DRender::QCamera *mainCamera() { return mMainCamera; } - //! Returns the light camera - Qt3DRender::QCamera *lightCamera() { return mLightCamera; } //! Returns the postprocessing entity QgsPostprocessingEntity *postprocessingEntity() { return mPostprocessingEntity; } //! Returns the root entity of the entities related to the frame graph (like the post processing entity and preview entity) @@ -120,21 +114,6 @@ class QgsFrameGraph : public Qt3DCore::QEntity //! Sets whether frustum culling is enabled void setFrustumCullingEnabled( bool enabled ); - //! Returns whether shadow rendering is enabled - bool shadowRenderingEnabled() const { return mShadowRenderingEnabled; } - //! Sets whether the shadow rendering is enabled - void setShadowRenderingEnabled( bool enabled ); - - //! Returns the shadow bias value - float shadowBias() const { return mShadowBias; } - //! Sets the shadow bias value - void setShadowBias( float shadowBias ); - - //! Returns the shadow map resolution - int shadowMapResolution() const { return mShadowMapResolution; } - //! Sets the resolution of the shadow map - void setShadowMapResolution( int resolution ); - /** * Sets whether Screen Space Ambient Occlusion will be enabled @@ -184,12 +163,13 @@ class QgsFrameGraph : public Qt3DCore::QEntity */ float ambientOcclusionThreshold() const { return mAmbientOcclusionThreshold; } + Qt3DRender::QRenderTargetOutput *shadowRenderTargetOutput() const { return mShadowRenderTargetOutput;} + //! Sets the clear color of the scene (background color) void setClearColor( const QColor &clearColor ); //! Adds an preview entity that shows a texture in real time for debugging purposes QgsPreviewQuad *addTexturePreviewOverlay( Qt3DRender::QTexture2D *texture, const QPointF ¢erNDC, const QSizeF &size, QVector additionalShaderParameters = QVector() ); - //! 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, int distance ); //! Sets the shadow map debugging view port @@ -232,12 +212,16 @@ class QgsFrameGraph : public Qt3DCore::QEntity //! Enables or disables the render view named \a name according to \a enable void setEnableRenderView( const QString &name, bool enable ); + //! Returns true if the render view named \a name is enabled + bool isRenderViewEnabled( const QString &name ); + //! Returns the render view named \a name, if any QgsAbstractRenderView *renderView( const QString &name ); //! Returns the layer used to assign entities to the render view named \a name, if any Qt3DRender::QLayer *filterLayer( const QString &name ); + static const QString SHADOW_RENDERVIEW; static const QString AXIS3D_RENDERVIEW; private: @@ -246,7 +230,6 @@ class QgsFrameGraph : public Qt3DCore::QEntity bool mFrustumCullingEnabled = true; Qt3DRender::QCamera *mMainCamera = nullptr; - Qt3DRender::QCamera *mLightCamera = nullptr; // Forward rendering pass branch nodes: Qt3DRender::QCameraSelector *mMainCameraSelector = nullptr; @@ -260,14 +243,7 @@ class QgsFrameGraph : public Qt3DCore::QEntity // QDebugOverlay added in the forward pass Qt3DRender::QDebugOverlay *mDebugOverlay = nullptr; - // Shadow rendering pass branch nodes: - Qt3DRender::QCameraSelector *mLightCameraSelectorShadowPass = nullptr; - Qt3DRender::QLayerFilter *mShadowSceneEntitiesFilter = nullptr; - Qt3DRender::QRenderTargetSelector *mShadowRenderTargetSelector = nullptr; - Qt3DRender::QClearBuffers *mShadowClearBuffers = nullptr; - Qt3DRender::QRenderStateSet *mShadowRenderStateSet = nullptr; - // Shadow rendering pass texture related objects: - Qt3DRender::QTexture2D *mShadowMapTexture = nullptr; + Qt3DRender::QRenderTargetOutput *mShadowRenderTargetOutput = nullptr; // - The depth buffer render pass is made to copy the depth buffer into // an RGB texture that can be captured into a QImage and sent to the CPU for @@ -311,9 +287,7 @@ class QgsFrameGraph : public Qt3DCore::QEntity Qt3DRender::QRenderStateSet *mRubberBandsStateSet = nullptr; Qt3DRender::QRenderTargetSelector *mRubberBandsRenderTargetSelector = nullptr; - bool mShadowRenderingEnabled = false; - float mShadowBias = 0.00001f; - int mShadowMapResolution = 2048; + static constexpr int mDefaultShadowMapResolution = 2048; // Ambient occlusion related settings bool mAmbientOcclusionEnabled = false; @@ -338,7 +312,6 @@ class QgsFrameGraph : public Qt3DCore::QEntity Qt3DRender::QLayer *mPreviewLayer = nullptr; Qt3DRender::QLayer *mForwardRenderLayer = nullptr; - Qt3DRender::QLayer *mCastShadowsLayer = nullptr; Qt3DRender::QLayer *mDepthRenderPassLayer = nullptr; Qt3DRender::QLayer *mTransparentObjectsPassLayer = nullptr; Qt3DRender::QLayer *mRubberBandsLayer = nullptr; @@ -351,7 +324,7 @@ class QgsFrameGraph : public Qt3DCore::QEntity QVector mPreviewQuads; - Qt3DRender::QFrameGraphNode *constructShadowRenderPass(); + void constructShadowRenderPass(); Qt3DRender::QFrameGraphNode *constructForwardRenderPass(); Qt3DRender::QFrameGraphNode *constructPostprocessingPass(); Qt3DRender::QFrameGraphNode *constructDepthRenderPass(); diff --git a/src/3d/framegraph/qgspostprocessingentity.cpp b/src/3d/framegraph/qgspostprocessingentity.cpp index 1e562bee8aa71..14dd6af957d4d 100644 --- a/src/3d/framegraph/qgspostprocessingentity.cpp +++ b/src/3d/framegraph/qgspostprocessingentity.cpp @@ -41,14 +41,21 @@ typedef Qt3DCore::QGeometry Qt3DQGeometry; #include #include "qgsframegraph.h" +#include "qgsshadowrenderview.h" QgsPostprocessingEntity::QgsPostprocessingEntity( QgsFrameGraph *frameGraph, Qt3DRender::QLayer *layer, QNode *parent ) : QgsRenderPassQuad( layer, parent ) , mFrameGraph( frameGraph ) { + QgsShadowRenderView *shadowRenderView = dynamic_cast( frameGraph->renderView( QgsFrameGraph::SHADOW_RENDERVIEW ) ); + connect( shadowRenderView, &QgsShadowRenderView::shadowDirectionLightUpdated, this, &QgsPostprocessingEntity::setupDirectionalLight ); + connect( shadowRenderView, &QgsShadowRenderView::shadowExtentChanged, this, &QgsPostprocessingEntity::setupShadowRenderingExtent ); + connect( shadowRenderView, &QgsShadowRenderView::shadowBiasChanged, this, &QgsPostprocessingEntity::setShadowBias ); + connect( shadowRenderView, &QgsShadowRenderView::shadowRenderingEnabled, this, &QgsPostprocessingEntity::setShadowRenderingEnabled ); + mColorTextureParameter = new Qt3DRender::QParameter( QStringLiteral( "colorTexture" ), frameGraph->forwardRenderColorTexture() ); mDepthTextureParameter = new Qt3DRender::QParameter( QStringLiteral( "depthTexture" ), frameGraph->forwardRenderDepthTexture() ); - mShadowMapParameter = new Qt3DRender::QParameter( QStringLiteral( "shadowTexture" ), frameGraph->shadowMapTexture() ); + mShadowMapParameter = new Qt3DRender::QParameter( QStringLiteral( "shadowTexture" ), shadowRenderView->outputTexture( Qt3DRender::QRenderTargetOutput::Depth ) ); mAmbientOcclusionTextureParameter = new Qt3DRender::QParameter( QStringLiteral( "ssaoTexture" ), frameGraph->blurredAmbientOcclusionFactorMap() ); mMaterial->addParameter( mColorTextureParameter ); mMaterial->addParameter( mDepthTextureParameter ); @@ -56,7 +63,7 @@ QgsPostprocessingEntity::QgsPostprocessingEntity( QgsFrameGraph *frameGraph, Qt3 mMaterial->addParameter( mAmbientOcclusionTextureParameter ); mMainCamera = frameGraph->mainCamera(); - mLightCamera = frameGraph->lightCamera(); + mLightCamera = shadowRenderView->lightCamera(); mFarPlaneParameter = new Qt3DRender::QParameter( QStringLiteral( "farPlane" ), mMainCamera->farPlane() ); mMaterial->addParameter( mFarPlaneParameter ); @@ -134,7 +141,7 @@ QgsPostprocessingEntity::QgsPostprocessingEntity( QgsFrameGraph *frameGraph, Qt3 mShader->setFragmentShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( fragmentShaderPath ) ) ); } -void QgsPostprocessingEntity::setupShadowRenderingExtent( float minX, float maxX, float minZ, float maxZ ) +void QgsPostprocessingEntity::setupShadowRenderingExtent( float minX, float maxX, float, float, float minZ, float maxZ ) { mShadowMinX->setValue( minX ); mShadowMaxX->setValue( maxX ); diff --git a/src/3d/framegraph/qgspostprocessingentity.h b/src/3d/framegraph/qgspostprocessingentity.h index 71058fd8dee1e..b1c650f1a91b9 100644 --- a/src/3d/framegraph/qgspostprocessingentity.h +++ b/src/3d/framegraph/qgspostprocessingentity.h @@ -19,6 +19,7 @@ #include "qgsrenderpassquad.h" class QgsFrameGraph; +class QgsShadowRenderView; #define SIP_NO_FILE @@ -38,7 +39,7 @@ class QgsPostprocessingEntity : public QgsRenderPassQuad //! Constructor QgsPostprocessingEntity( QgsFrameGraph *frameGraph, Qt3DRender::QLayer *layer, QNode *parent = nullptr ); //! Sets the parts of the scene where objects cast shadows - void setupShadowRenderingExtent( float minX, float maxX, float minZ, float maxZ ); + void setupShadowRenderingExtent( float minX, float maxX, float minY, float maxY, float minZ, float maxZ ); //! Sets up a directional light that is used to render shadows void setupDirectionalLight( QVector3D position, QVector3D direction ); //! Sets whether shadow rendering is enabled diff --git a/src/3d/framegraph/qgsshadowrenderview.cpp b/src/3d/framegraph/qgsshadowrenderview.cpp new file mode 100644 index 0000000000000..89378ebb404b9 --- /dev/null +++ b/src/3d/framegraph/qgsshadowrenderview.cpp @@ -0,0 +1,182 @@ +/*************************************************************************** + qgsshadowrenderview.cpp + -------------------------------------- + Date : June 2024 + Copyright : (C) 2024 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 "qgsshadowrenderview.h" +#include "qgsdirectionallightsettings.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +QgsShadowRenderView::QgsShadowRenderView( QObject *parent ) + : QgsAbstractRenderView( parent, "shadow" ) +{ + mLightCamera = new Qt3DRender::QCamera; + mLightCamera->setObjectName( mViewName + "::LightCamera" ); + mLayer = new Qt3DRender::QLayer; + mLayer->setRecursive( true ); + mLayer->setObjectName( mViewName + "::Layer" ); + + // shadow rendering pass + buildRenderPass(); +} + +void QgsShadowRenderView::enableSubTree( bool enable ) +{ + QgsAbstractRenderView::enableSubTree( enable ); + emit shadowRenderingEnabled( enable ); + mLayerFilter->setEnabled( enable ); +} + +void QgsShadowRenderView::setupDirectionalLight( const QgsDirectionalLightSettings &light, float maximumShadowRenderingDistance, + const Qt3DRender::QCamera *mainCamera ) +{ + float minX, maxX, minY, maxY, minZ, maxZ; + QVector3D lookingAt = mainCamera->viewCenter(); + const float d = 2 * ( mainCamera->position() - mainCamera->viewCenter() ).length(); + + const QVector3D vertical = QVector3D( 0.0f, d, 0.0f ); + const QVector3D lightDirection = QVector3D( light.direction().x(), light.direction().y(), light.direction().z() ).normalized(); + QgsShadowRenderView::calculateViewExtent( mainCamera, maximumShadowRenderingDistance, lookingAt.y(), minX, maxX, minY, maxY, minZ, maxZ ); + + lookingAt = QVector3D( 0.5 * ( minX + maxX ), mainCamera->viewCenter().y(), 0.5 * ( minZ + maxZ ) ); + const QVector3D lightPosition = lookingAt + vertical; + mLightCamera->setPosition( lightPosition ); + mLightCamera->setViewCenter( lookingAt ); + mLightCamera->setUpVector( QVector3D( 0.0f, 1.0f, 0.0f ) ); + mLightCamera->rotateAboutViewCenter( QQuaternion::rotationTo( vertical.normalized(), -lightDirection.normalized() ) ); + + mLightCamera->setProjectionType( Qt3DRender::QCameraLens::ProjectionType::OrthographicProjection ); + mLightCamera->lens()->setOrthographicProjection( + - 0.7 * ( maxX - minX ), 0.7 * ( maxX - minX ), + - 0.7 * ( maxZ - minZ ), 0.7 * ( maxZ - minZ ), + 1.0f, 2 * ( lookingAt - lightPosition ).length() ); + + emit shadowExtentChanged( minX, maxX, minY, maxY, minZ, maxZ ); + emit shadowDirectionLightUpdated( lightPosition, lightDirection ); +} + +Qt3DRender::QFrameGraphNode *QgsShadowRenderView::buildRenderPass() +{ + mLightCameraSelector = new Qt3DRender::QCameraSelector( mRendererEnabler ); + mLightCameraSelector->setObjectName( mViewName + "::CameraSelector" ); + mLightCameraSelector->setCamera( mLightCamera ); + + mLayerFilter = new Qt3DRender::QLayerFilter( mLightCameraSelector ); + mLayerFilter->addLayer( mLayer ); + + mRenderTargetSelector = new Qt3DRender::QRenderTargetSelector( mLayerFilter ); + // no target output for now, updateTargetOutput() will be called later + + mClearBuffers = new Qt3DRender::QClearBuffers( mRenderTargetSelector ); + mClearBuffers->setBuffers( Qt3DRender::QClearBuffers::BufferType::ColorDepthBuffer ); + mClearBuffers->setClearColor( QColor::fromRgbF( 0.0f, 1.0f, 0.0f ) ); + + mRenderStateSet = new Qt3DRender::QRenderStateSet( mClearBuffers ); + + Qt3DRender::QDepthTest *depthTest = new Qt3DRender::QDepthTest; + depthTest->setDepthFunction( Qt3DRender::QDepthTest::Less ); + mRenderStateSet->addRenderState( depthTest ); + + Qt3DRender::QCullFace *cullFace = new Qt3DRender::QCullFace; + cullFace->setMode( Qt3DRender::QCullFace::CullingMode::Front ); + mRenderStateSet->addRenderState( cullFace ); + + Qt3DRender::QPolygonOffset *polygonOffset = new Qt3DRender::QPolygonOffset; + polygonOffset->setDepthSteps( 4.0 ); + polygonOffset->setScaleFactor( 1.1 ); + mRenderStateSet->addRenderState( polygonOffset ); + + return mLightCameraSelector; +} + +void QgsShadowRenderView::setShadowBias( float bias ) +{ + mBias = bias; + emit shadowBiasChanged( mBias ); +} + +// computes the portion of the Y=y plane the camera is looking at +void QgsShadowRenderView::calculateViewExtent( const Qt3DRender::QCamera *camera, float shadowRenderingDistance, float y, float &minX, float &maxX, float &minY, float &maxY, float &minZ, float &maxZ ) +{ + const QVector3D cameraPos = camera->position(); + const QMatrix4x4 projectionMatrix = camera->projectionMatrix(); + const QMatrix4x4 viewMatrix = camera->viewMatrix(); + float depth = 1.0f; + QVector4D viewCenter = viewMatrix * QVector4D( camera->viewCenter(), 1.0f ); + viewCenter /= viewCenter.w(); + viewCenter = projectionMatrix * viewCenter; + viewCenter /= viewCenter.w(); + depth = viewCenter.z(); + QVector viewFrustumPoints = + { + QVector3D( 0.0f, 0.0f, depth ), + QVector3D( 0.0f, 1.0f, depth ), + QVector3D( 1.0f, 0.0f, depth ), + QVector3D( 1.0f, 1.0f, depth ), + QVector3D( 0.0f, 0.0f, 0 ), + QVector3D( 0.0f, 1.0f, 0 ), + QVector3D( 1.0f, 0.0f, 0 ), + QVector3D( 1.0f, 1.0f, 0 ) + }; + maxX = std::numeric_limits::lowest(); + maxY = std::numeric_limits::lowest(); + maxZ = std::numeric_limits::lowest(); + minX = std::numeric_limits::max(); + minY = std::numeric_limits::max(); + minZ = std::numeric_limits::max(); + for ( int i = 0; i < viewFrustumPoints.size(); ++i ) + { + // convert from view port space to world space + viewFrustumPoints[i] = viewFrustumPoints[i].unproject( viewMatrix, projectionMatrix, QRect( 0, 0, 1, 1 ) ); + minX = std::min( minX, viewFrustumPoints[i].x() ); + maxX = std::max( maxX, viewFrustumPoints[i].x() ); + minY = std::min( minY, viewFrustumPoints[i].y() ); + maxY = std::max( maxY, viewFrustumPoints[i].y() ); + minZ = std::min( minZ, viewFrustumPoints[i].z() ); + maxZ = std::max( maxZ, viewFrustumPoints[i].z() ); + // find the intersection between the line going from cameraPos to the frustum quad point + // and the horizontal plane Y=y + // if the intersection is on the back side of the viewing panel we get a point that is + // shadowRenderingDistance units in front of the camera + const QVector3D pt = cameraPos; + const QVector3D vect = ( viewFrustumPoints[i] - pt ).normalized(); + float t = ( y - pt.y() ) / vect.y(); + if ( t < 0 ) + t = shadowRenderingDistance; + else + t = std::min( t, shadowRenderingDistance ); + viewFrustumPoints[i] = pt + t * vect; + minX = std::min( minX, viewFrustumPoints[i].x() ); + maxX = std::max( maxX, viewFrustumPoints[i].x() ); + minY = std::min( minY, viewFrustumPoints[i].y() ); + maxY = std::max( maxY, viewFrustumPoints[i].y() ); + minZ = std::min( minZ, viewFrustumPoints[i].z() ); + maxZ = std::max( maxZ, viewFrustumPoints[i].z() ); + } +} diff --git a/src/3d/framegraph/qgsshadowrenderview.h b/src/3d/framegraph/qgsshadowrenderview.h new file mode 100644 index 0000000000000..2ca439e03b196 --- /dev/null +++ b/src/3d/framegraph/qgsshadowrenderview.h @@ -0,0 +1,110 @@ +/*************************************************************************** + qgsshadowrenderview.h + -------------------------------------- + Date : June 2024 + Copyright : (C) 2024 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 QGSSHADOWRENDERVIEW_H +#define QGSSHADOWRENDERVIEW_H + +#include "qgsabstractrenderview.h" + +class QColor; +class QRect; +class QSurface; + +namespace Qt3DCore +{ + class QEntity; +} + +namespace Qt3DRender +{ + class QRenderSettings; + class QCamera; + class QFrameGraphNode; + class QLayer; + class QViewport; + class QSubtreeEnabler; + class QTexture2D; + class QCameraSelector; + class QLayerFilter; + class QRenderTargetSelector; + class QClearBuffers; + class QRenderStateSet; + class QRenderTargetOutput; +} + +namespace Qt3DExtras +{ + class Qt3DWindow; +} + +class Qgs3DMapSettings; +class QgsDirectionalLightSettings; + +#define SIP_NO_FILE + +/** + * \ingroup 3d + * \brief Container class that holds different objects related to shadow rendering + * + * \note Not available in Python bindings + * + * \since QGIS 3.40 + */ +class QgsShadowRenderView : public QgsAbstractRenderView +{ + Q_OBJECT + public: + QgsShadowRenderView( QObject *parent ); + + //! Enable or disable via \a enable the renderview sub tree + virtual void enableSubTree( bool enable ) override; + + //! Returns the shadow bias value + float shadowBias() const { return mBias; } + //! Sets the shadow bias value + void setShadowBias( float bias ); + + //! Returns the light camera + Qt3DRender::QCamera *lightCamera() { return mLightCamera; } + + //! Sets shadow rendering to use a directional light + void setupDirectionalLight( const QgsDirectionalLightSettings &light, float maximumShadowRenderingDistance, + const Qt3DRender::QCamera *mainCamera ); + + signals: + + void shadowDirectionLightUpdated( const QVector3D &lightPosition, const QVector3D &lightDirection ); + void shadowExtentChanged( float minX, float maxX, float minY, float maxY, float minZ, float maxZ ); + void shadowBiasChanged( float bias ); + void shadowRenderingEnabled( bool isEnabled ); + + private: + float mBias = 0.00001f; + + // Shadow rendering pass branch nodes: + Qt3DRender::QCameraSelector *mLightCameraSelector = nullptr; + Qt3DRender::QLayerFilter *mLayerFilter = nullptr; + Qt3DRender::QClearBuffers *mClearBuffers = nullptr; + Qt3DRender::QRenderStateSet *mRenderStateSet = nullptr; + + Qt3DRender::QCamera *mLightCamera = nullptr; + + Qt3DRender::QFrameGraphNode *buildRenderPass(); + + static void calculateViewExtent( const Qt3DRender::QCamera *camera, float shadowRenderingDistance, float y, float &minX, float &maxX, float &minY, float &maxY, float &minZ, float &maxZ ); + +}; + +#endif // QGSSHADOWRENDERVIEW_H diff --git a/src/3d/qgs3dmapscene.cpp b/src/3d/qgs3dmapscene.cpp index d59fa033f2649..bb764fb6a150c 100644 --- a/src/3d/qgs3dmapscene.cpp +++ b/src/3d/qgs3dmapscene.cpp @@ -79,6 +79,7 @@ #include "qgswindow3dengine.h" #include "qgspointcloudlayer.h" +#include "framegraph/qgsshadowrenderview.h" std::function< QMap< QString, Qgs3DMapScene * >() > Qgs3DMapScene::sOpenScenesFunction = [] { return QMap< QString, Qgs3DMapScene * >(); }; @@ -922,18 +923,22 @@ void Qgs3DMapScene::onShadowSettingsChanged() } } - QgsShadowSettings shadowSettings = mMap.shadowSettings(); - int selectedLight = shadowSettings.selectedDirectionalLight(); - if ( shadowSettings.renderShadows() && selectedLight >= 0 && selectedLight < directionalLightSources.count() ) + QgsShadowRenderView *shadowRenderView = dynamic_cast( frameGraph->renderView( QgsFrameGraph::SHADOW_RENDERVIEW ) ) ; + if ( shadowRenderView ) { - frameGraph->setShadowRenderingEnabled( true ); - frameGraph->setShadowBias( shadowSettings.shadowBias() ); - frameGraph->setShadowMapResolution( shadowSettings.shadowMapResolution() ); - QgsDirectionalLightSettings light = *directionalLightSources.at( selectedLight ); - frameGraph->setupDirectionalLight( light, shadowSettings.maximumShadowRenderingDistance() ); + QgsShadowSettings shadowSettings = mMap.shadowSettings(); + int selectedLight = shadowSettings.selectedDirectionalLight(); + if ( shadowSettings.renderShadows() && selectedLight >= 0 && selectedLight < directionalLightSources.count() ) + { + shadowRenderView->setShadowBias( shadowSettings.shadowBias() ); + shadowRenderView->updateTargetOutputSize( shadowSettings.shadowMapResolution(), shadowSettings.shadowMapResolution() ); + QgsDirectionalLightSettings light = *directionalLightSources.at( selectedLight ); + shadowRenderView->setupDirectionalLight( light, shadowSettings.maximumShadowRenderingDistance(), frameGraph->mainCamera() ); + shadowRenderView->enableSubTree( true ); + } + else + shadowRenderView->enableSubTree( false ); } - else - frameGraph->setShadowRenderingEnabled( false ); } void Qgs3DMapScene::onAmbientOcclusionSettingsChanged() diff --git a/src/3d/qgsoffscreen3dengine.cpp b/src/3d/qgsoffscreen3dengine.cpp index 9e2872818cfcd..a4aff14297028 100644 --- a/src/3d/qgsoffscreen3dengine.cpp +++ b/src/3d/qgsoffscreen3dengine.cpp @@ -35,6 +35,7 @@ #include #include #include +#include "framegraph/qgsabstractrenderview.h" QgsOffscreen3DEngine::QgsOffscreen3DEngine() { @@ -102,7 +103,7 @@ QgsOffscreen3DEngine::QgsOffscreen3DEngine() mFrameGraph = new QgsFrameGraph( mOffscreenSurface, mSize, mCamera, mRoot ); mFrameGraph->setRenderCaptureEnabled( true ); - mFrameGraph->setShadowRenderingEnabled( false ); + mFrameGraph->setEnableRenderView( QgsFrameGraph::SHADOW_RENDERVIEW, false ); // Set this frame graph to be in use. // the render settings also sets itself as the parent of mSurfaceSelector mRenderSettings->setActiveFrameGraph( mFrameGraph->frameGraphRoot() ); @@ -149,7 +150,8 @@ void QgsOffscreen3DEngine::setRootEntity( Qt3DCore::QEntity *root ) mSceneRoot = root; mSceneRoot->setParent( mRoot ); root->addComponent( mFrameGraph->forwardRenderLayer() ); - root->addComponent( mFrameGraph->castShadowsLayer() ); + if ( mFrameGraph->renderView( QgsFrameGraph::SHADOW_RENDERVIEW ) ) + root->addComponent( mFrameGraph->renderView( QgsFrameGraph::SHADOW_RENDERVIEW )->layerToFilter() ); } Qt3DRender::QRenderSettings *QgsOffscreen3DEngine::renderSettings() diff --git a/src/3d/qgswindow3dengine.cpp b/src/3d/qgswindow3dengine.cpp index 36797a8eee89f..231fb6e68a044 100644 --- a/src/3d/qgswindow3dengine.cpp +++ b/src/3d/qgswindow3dengine.cpp @@ -18,9 +18,11 @@ #include #include +#include "framegraph/qgsabstractrenderview.h" +#include "framegraph/qgspreviewquad.h" #include "qgs3dmapcanvas.h" -#include "framegraph/qgsframegraph.h" +#include "framegraph/qgsframegraph.h" QgsWindow3DEngine::QgsWindow3DEngine( Qgs3DMapCanvas *parent ) : QgsAbstract3DEngine( parent ) @@ -34,7 +36,7 @@ QgsWindow3DEngine::QgsWindow3DEngine( Qgs3DMapCanvas *parent ) mMapCanvas3D->setActiveFrameGraph( mFrameGraph->frameGraphRoot() ); // force switching to no shadow rendering - setShadowRenderingEnabled( false ); + mFrameGraph->setEnableRenderView( QgsFrameGraph::SHADOW_RENDERVIEW, false ); } QWindow *QgsWindow3DEngine::window() @@ -47,12 +49,6 @@ Qt3DCore::QEntity *QgsWindow3DEngine::root() const return mRoot; } -void QgsWindow3DEngine::setShadowRenderingEnabled( bool enabled ) -{ - mShadowRenderingEnabled = enabled; - mFrameGraph->setShadowRenderingEnabled( mShadowRenderingEnabled ); -} - void QgsWindow3DEngine::setClearColor( const QColor &color ) { mFrameGraph->setClearColor( color ); @@ -69,7 +65,8 @@ void QgsWindow3DEngine::setRootEntity( Qt3DCore::QEntity *root ) mSceneRoot = root; mSceneRoot->setParent( mRoot ); mSceneRoot->addComponent( mFrameGraph->forwardRenderLayer() ); - mSceneRoot->addComponent( mFrameGraph->castShadowsLayer() ); + if ( mFrameGraph->renderView( QgsFrameGraph::SHADOW_RENDERVIEW ) ) + mSceneRoot->addComponent( mFrameGraph->renderView( QgsFrameGraph::SHADOW_RENDERVIEW )->layerToFilter() ); } Qt3DRender::QRenderSettings *QgsWindow3DEngine::renderSettings() diff --git a/src/3d/qgswindow3dengine.h b/src/3d/qgswindow3dengine.h index 370f167c7d59b..aedea6eadfda6 100644 --- a/src/3d/qgswindow3dengine.h +++ b/src/3d/qgswindow3dengine.h @@ -58,11 +58,6 @@ class _3D_EXPORT QgsWindow3DEngine : public QgsAbstract3DEngine //! Returns the root entity Qt3DCore::QEntity *root() const; - //! Sets whether shadow rendering is enabled - void setShadowRenderingEnabled( bool enabled ); - //! Returns whether shadow rendering is enabled - bool shadowRenderingEnabled() { return mShadowRenderingEnabled; } - void setClearColor( const QColor &color ) override; void setFrustumCullingEnabled( bool enabled ) override; void setRootEntity( Qt3DCore::QEntity *root ) override; @@ -77,7 +72,6 @@ class _3D_EXPORT QgsWindow3DEngine : public QgsAbstract3DEngine //! 3D window with all the 3D magic inside Qgs3DMapCanvas *mMapCanvas3D = nullptr; //! Frame graph node for render capture - bool mShadowRenderingEnabled = false; Qt3DCore::QEntity *mRoot = nullptr; Qt3DCore::QEntity *mSceneRoot = nullptr; diff --git a/tests/testdata/control_files/3d/expected_ambient_occlusion_1/expected_framegraph.txt b/tests/testdata/control_files/3d/expected_ambient_occlusion_1/expected_framegraph.txt index 1cb7c9767b516..b2f0ef403b0f1 100644 --- a/tests/testdata/control_files/3d/expected_ambient_occlusion_1/expected_framegraph.txt +++ b/tests/testdata/control_files/3d/expected_ambient_occlusion_1/expected_framegraph.txt @@ -1,44 +1,46 @@ -(Qt3DRender::QRenderSurfaceSelector{16/}) - (Qt3DRender::QViewport{17/}) - (Qt3DRender::QCameraSelector{18/Forward render pass CameraSelector}) [ (Qt3DRender::QCamera:{0/}) ] - (Qt3DRender::QLayerFilter{19/}) [ (AcceptAnyMatchingLayers:[ {12/} ]) ] - (Qt3DRender::QRenderTargetSelector{25/}) [ (outputs:[ (Depth:{21[DepthFormat]/), (Color0:{20[RGB8_UNorm]/) ]) ] - (Qt3DRender::QLayerFilter{26/}) [ (DiscardAnyMatchingLayers:[ {14/} ]) ] - (Qt3DRender::QRenderStateSet{27/}) [ (QDepthTest:Less), (QCullFace:Back) ] - (Qt3DRender::QFrustumCulling{30/}) - (Qt3DRender::QClearBuffers{31/}) - (Qt3DRender::QDebugOverlay{44/}) [D] - (Qt3DRender::QLayerFilter{32/}) [ (AcceptAnyMatchingLayers:[ {14/} ]) ] - (Qt3DRender::QSortPolicy{33/}) - (Qt3DRender::QRenderStateSet{34/}) [ (QDepthTest:Less), (QNoDepthMask), (QCullFace:NoCulling), (QBlendEquation:Add), (QBlendEquationArguments:[ (sourceRgb:SourceAlpha), (destinationRgb:Source1Alpha), (sourceAlpha:One), (destinationAlpha:Zero), (bufferIndex:-1) ]) ] - (Qt3DRender::QRenderStateSet{40/}) [ (QDepthTest:Less), (QColorMask:[ (red:false), (green:false), (blue:false), (alpha:false) ]), (QCullFace:NoCulling) ] - (Qt3DRender::QCameraSelector{45/rubberBandsPass}) [ (Qt3DRender::QCamera:{0/}) ] - (Qt3DRender::QLayerFilter{46/}) [ (AcceptAnyMatchingLayers:[ {15/mRubberBandsLayer} ]) ] - (Qt3DRender::QRenderStateSet{47/}) [ (QDepthTest:Always) ] - (Qt3DRender::QRenderTargetSelector{49/}) [ (outputs:[ (Depth:{21[DepthFormat]/), (Color0:{20[RGB8_UNorm]/) ]) ] - (Qt3DRender::QCameraSelector{50/Shadow render pass CameraSelector}) [ (Qt3DRender::QCamera:{7/}) ] - (Qt3DRender::QLayerFilter{51/}) [D] [ (AcceptAnyMatchingLayers:[ {11/} ]) ] - (Qt3DRender::QRenderTargetSelector{55/}) [ (outputs:[ (Depth:{52[DepthFormat]/) ]) ] - (Qt3DRender::QClearBuffers{56/}) - (Qt3DRender::QRenderStateSet{57/}) [ (QDepthTest:Less), (QCullFace:Front), (QPolygonOffset:[ (scaleFactor:1.1), (depthSteps:4) ]) ] - (Qt3DRender::QCameraSelector{61/Depth render view CameraSelector}) [ (Qt3DRender::QCamera:{0/}) ] - (Qt3DRender::QRenderStateSet{62/}) [ (QDepthTest:Always), (QCullFace:NoCulling) ] - (Qt3DRender::QLayerFilter{65/}) [ (AcceptAnyMatchingLayers:[ {13/} ]) ] - (Qt3DRender::QRenderTargetSelector{66/}) [ (outputs:[ (Color0:{69[RGB8_UNorm]/), (Depth:{71[DepthFormat]/) ]) ] - (Qt3DRender::QRenderCapture{72/}) - (Qt3DRender::QCameraSelector{73/AmbientOcclusion render pass CameraSelector}) [ (Qt3DRender::QCamera:{0/}) ] - (Qt3DRender::QRenderStateSet{74/}) [ (QDepthTest:Always), (QCullFace:NoCulling) ] - (Qt3DRender::QLayerFilter{77/}) [ (AcceptAnyMatchingLayers:[ {82/} ]) ] - (Qt3DRender::QRenderTargetSelector{78/}) [ (outputs:[ (Color0:{81[R32F]/) ]) ] - (Qt3DRender::QCameraSelector{105/AmbientOcclusion blur pass CameraSelector}) [ (Qt3DRender::QCamera:{0/}) ] - (Qt3DRender::QRenderStateSet{106/}) [ (QDepthTest:Always), (QCullFace:NoCulling) ] - (Qt3DRender::QLayerFilter{109/}) [ (AcceptAnyMatchingLayers:[ {114/} ]) ] - (Qt3DRender::QRenderTargetSelector{110/}) [ (outputs:[ (Color0:{113[R32F]/) ]) ] - (Qt3DRender::QRenderTargetSelector{127/PostProcessingPass}) [ (outputs:[ (Color0:{130[RGB8_UNorm]/PostProcessingPass::ColorTarget), (Depth:{132[DepthFormat]/PostProcessingPass::DepthTarget) ]) ] - (Qt3DRender::QCameraSelector{133/Sub pass Postprocessing}) [ (Qt3DRender::QCamera:{7/}) ] - (Qt3DRender::QLayerFilter{134/}) [ (AcceptAnyMatchingLayers:[ {136/} ]) ] - (Qt3DRender::QClearBuffers{135/}) - (Qt3DRender::QLayerFilter{170/Sub pass TexturesPreview}) [ (AcceptAnyMatchingLayers:[ {10/} ]) ] - (Qt3DRender::QRenderStateSet{171/}) [ (QDepthTest:Always), (QCullFace:NoCulling) ] - (Qt3DRender::QNoDraw{174/Sub pass RenderCapture}) - (Qt3DRender::QRenderCapture{175/}) +(Qt3DRender::QRenderSurfaceSelector{12/}) + (Qt3DRender::QViewport{13/}) + (Qt3DRender::QCameraSelector{14/Forward render pass CameraSelector}) [ (Qt3DRender::QCamera:{0/}) ] + (Qt3DRender::QLayerFilter{15/}) [ (AcceptAnyMatchingLayers:[ {8/} ]) ] + (Qt3DRender::QRenderTargetSelector{21/}) [ (outputs:[ (Depth:{17[DepthFormat]/), (Color0:{16[RGB8_UNorm]/) ]) ] + (Qt3DRender::QLayerFilter{22/}) [ (DiscardAnyMatchingLayers:[ {10/} ]) ] + (Qt3DRender::QRenderStateSet{23/}) [ (QDepthTest:Less), (QCullFace:Back) ] + (Qt3DRender::QFrustumCulling{26/}) + (Qt3DRender::QClearBuffers{27/}) + (Qt3DRender::QDebugOverlay{40/}) [D] + (Qt3DRender::QLayerFilter{28/}) [ (AcceptAnyMatchingLayers:[ {10/} ]) ] + (Qt3DRender::QSortPolicy{29/}) + (Qt3DRender::QRenderStateSet{30/}) [ (QDepthTest:Less), (QNoDepthMask), (QCullFace:NoCulling), (QBlendEquation:Add), (QBlendEquationArguments:[ (sourceRgb:SourceAlpha), (destinationRgb:Source1Alpha), (sourceAlpha:One), (destinationAlpha:Zero), (bufferIndex:-1) ]) ] + (Qt3DRender::QRenderStateSet{36/}) [ (QDepthTest:Less), (QColorMask:[ (red:false), (green:false), (blue:false), (alpha:false) ]), (QCullFace:NoCulling) ] + (Qt3DRender::QCameraSelector{41/rubberBandsPass}) [ (Qt3DRender::QCamera:{0/}) ] + (Qt3DRender::QLayerFilter{42/}) [ (AcceptAnyMatchingLayers:[ {11/mRubberBandsLayer} ]) ] + (Qt3DRender::QRenderStateSet{43/}) [ (QDepthTest:Always) ] + (Qt3DRender::QRenderTargetSelector{45/}) [ (outputs:[ (Depth:{17[DepthFormat]/), (Color0:{16[RGB8_UNorm]/) ]) ] + (Qt3DRender::QNoDraw{48/}) + (Qt3DRender::QSubtreeEnabler{49/}) [D] + (Qt3DRender::QCameraSelector{54/shadow::CameraSelector}) [ (Qt3DRender::QCamera:{50/shadow::LightCamera}) ] + (Qt3DRender::QLayerFilter{55/}) [D] [ (AcceptAnyMatchingLayers:[ {53/shadow::Layer} ]) ] + (Qt3DRender::QRenderTargetSelector{56/}) [ (outputs:[ (Depth:{46[DepthFormat]/QgsShadowRenderView::DepthTarget) ]) ] + (Qt3DRender::QClearBuffers{57/}) + (Qt3DRender::QRenderStateSet{58/}) [ (QDepthTest:Less), (QCullFace:Front), (QPolygonOffset:[ (scaleFactor:1.1), (depthSteps:4) ]) ] + (Qt3DRender::QCameraSelector{63/Depth render view CameraSelector}) [ (Qt3DRender::QCamera:{0/}) ] + (Qt3DRender::QRenderStateSet{64/}) [ (QDepthTest:Always), (QCullFace:NoCulling) ] + (Qt3DRender::QLayerFilter{67/}) [ (AcceptAnyMatchingLayers:[ {9/} ]) ] + (Qt3DRender::QRenderTargetSelector{68/}) [ (outputs:[ (Color0:{71[RGB8_UNorm]/), (Depth:{73[DepthFormat]/) ]) ] + (Qt3DRender::QRenderCapture{74/}) + (Qt3DRender::QCameraSelector{75/AmbientOcclusion render pass CameraSelector}) [ (Qt3DRender::QCamera:{0/}) ] + (Qt3DRender::QRenderStateSet{76/}) [ (QDepthTest:Always), (QCullFace:NoCulling) ] + (Qt3DRender::QLayerFilter{79/}) [ (AcceptAnyMatchingLayers:[ {84/} ]) ] + (Qt3DRender::QRenderTargetSelector{80/}) [ (outputs:[ (Color0:{83[R32F]/) ]) ] + (Qt3DRender::QCameraSelector{107/AmbientOcclusion blur pass CameraSelector}) [ (Qt3DRender::QCamera:{0/}) ] + (Qt3DRender::QRenderStateSet{108/}) [ (QDepthTest:Always), (QCullFace:NoCulling) ] + (Qt3DRender::QLayerFilter{111/}) [ (AcceptAnyMatchingLayers:[ {116/} ]) ] + (Qt3DRender::QRenderTargetSelector{112/}) [ (outputs:[ (Color0:{115[R32F]/) ]) ] + (Qt3DRender::QRenderTargetSelector{129/PostProcessingPass}) [ (outputs:[ (Color0:{132[RGB8_UNorm]/PostProcessingPass::ColorTarget), (Depth:{134[DepthFormat]/PostProcessingPass::DepthTarget) ]) ] + (Qt3DRender::QCameraSelector{135/Sub pass Postprocessing}) [ (Qt3DRender::QCamera:{50/shadow::LightCamera}) ] + (Qt3DRender::QLayerFilter{136/}) [ (AcceptAnyMatchingLayers:[ {138/} ]) ] + (Qt3DRender::QClearBuffers{137/}) + (Qt3DRender::QLayerFilter{172/Sub pass TexturesPreview}) [ (AcceptAnyMatchingLayers:[ {7/} ]) ] + (Qt3DRender::QRenderStateSet{173/}) [ (QDepthTest:Always), (QCullFace:NoCulling) ] + (Qt3DRender::QNoDraw{176/Sub pass RenderCapture}) + (Qt3DRender::QRenderCapture{177/}) diff --git a/tests/testdata/control_files/3d/expected_ambient_occlusion_2/expected_framegraph.txt b/tests/testdata/control_files/3d/expected_ambient_occlusion_2/expected_framegraph.txt index 1cb7c9767b516..b2f0ef403b0f1 100644 --- a/tests/testdata/control_files/3d/expected_ambient_occlusion_2/expected_framegraph.txt +++ b/tests/testdata/control_files/3d/expected_ambient_occlusion_2/expected_framegraph.txt @@ -1,44 +1,46 @@ -(Qt3DRender::QRenderSurfaceSelector{16/}) - (Qt3DRender::QViewport{17/}) - (Qt3DRender::QCameraSelector{18/Forward render pass CameraSelector}) [ (Qt3DRender::QCamera:{0/}) ] - (Qt3DRender::QLayerFilter{19/}) [ (AcceptAnyMatchingLayers:[ {12/} ]) ] - (Qt3DRender::QRenderTargetSelector{25/}) [ (outputs:[ (Depth:{21[DepthFormat]/), (Color0:{20[RGB8_UNorm]/) ]) ] - (Qt3DRender::QLayerFilter{26/}) [ (DiscardAnyMatchingLayers:[ {14/} ]) ] - (Qt3DRender::QRenderStateSet{27/}) [ (QDepthTest:Less), (QCullFace:Back) ] - (Qt3DRender::QFrustumCulling{30/}) - (Qt3DRender::QClearBuffers{31/}) - (Qt3DRender::QDebugOverlay{44/}) [D] - (Qt3DRender::QLayerFilter{32/}) [ (AcceptAnyMatchingLayers:[ {14/} ]) ] - (Qt3DRender::QSortPolicy{33/}) - (Qt3DRender::QRenderStateSet{34/}) [ (QDepthTest:Less), (QNoDepthMask), (QCullFace:NoCulling), (QBlendEquation:Add), (QBlendEquationArguments:[ (sourceRgb:SourceAlpha), (destinationRgb:Source1Alpha), (sourceAlpha:One), (destinationAlpha:Zero), (bufferIndex:-1) ]) ] - (Qt3DRender::QRenderStateSet{40/}) [ (QDepthTest:Less), (QColorMask:[ (red:false), (green:false), (blue:false), (alpha:false) ]), (QCullFace:NoCulling) ] - (Qt3DRender::QCameraSelector{45/rubberBandsPass}) [ (Qt3DRender::QCamera:{0/}) ] - (Qt3DRender::QLayerFilter{46/}) [ (AcceptAnyMatchingLayers:[ {15/mRubberBandsLayer} ]) ] - (Qt3DRender::QRenderStateSet{47/}) [ (QDepthTest:Always) ] - (Qt3DRender::QRenderTargetSelector{49/}) [ (outputs:[ (Depth:{21[DepthFormat]/), (Color0:{20[RGB8_UNorm]/) ]) ] - (Qt3DRender::QCameraSelector{50/Shadow render pass CameraSelector}) [ (Qt3DRender::QCamera:{7/}) ] - (Qt3DRender::QLayerFilter{51/}) [D] [ (AcceptAnyMatchingLayers:[ {11/} ]) ] - (Qt3DRender::QRenderTargetSelector{55/}) [ (outputs:[ (Depth:{52[DepthFormat]/) ]) ] - (Qt3DRender::QClearBuffers{56/}) - (Qt3DRender::QRenderStateSet{57/}) [ (QDepthTest:Less), (QCullFace:Front), (QPolygonOffset:[ (scaleFactor:1.1), (depthSteps:4) ]) ] - (Qt3DRender::QCameraSelector{61/Depth render view CameraSelector}) [ (Qt3DRender::QCamera:{0/}) ] - (Qt3DRender::QRenderStateSet{62/}) [ (QDepthTest:Always), (QCullFace:NoCulling) ] - (Qt3DRender::QLayerFilter{65/}) [ (AcceptAnyMatchingLayers:[ {13/} ]) ] - (Qt3DRender::QRenderTargetSelector{66/}) [ (outputs:[ (Color0:{69[RGB8_UNorm]/), (Depth:{71[DepthFormat]/) ]) ] - (Qt3DRender::QRenderCapture{72/}) - (Qt3DRender::QCameraSelector{73/AmbientOcclusion render pass CameraSelector}) [ (Qt3DRender::QCamera:{0/}) ] - (Qt3DRender::QRenderStateSet{74/}) [ (QDepthTest:Always), (QCullFace:NoCulling) ] - (Qt3DRender::QLayerFilter{77/}) [ (AcceptAnyMatchingLayers:[ {82/} ]) ] - (Qt3DRender::QRenderTargetSelector{78/}) [ (outputs:[ (Color0:{81[R32F]/) ]) ] - (Qt3DRender::QCameraSelector{105/AmbientOcclusion blur pass CameraSelector}) [ (Qt3DRender::QCamera:{0/}) ] - (Qt3DRender::QRenderStateSet{106/}) [ (QDepthTest:Always), (QCullFace:NoCulling) ] - (Qt3DRender::QLayerFilter{109/}) [ (AcceptAnyMatchingLayers:[ {114/} ]) ] - (Qt3DRender::QRenderTargetSelector{110/}) [ (outputs:[ (Color0:{113[R32F]/) ]) ] - (Qt3DRender::QRenderTargetSelector{127/PostProcessingPass}) [ (outputs:[ (Color0:{130[RGB8_UNorm]/PostProcessingPass::ColorTarget), (Depth:{132[DepthFormat]/PostProcessingPass::DepthTarget) ]) ] - (Qt3DRender::QCameraSelector{133/Sub pass Postprocessing}) [ (Qt3DRender::QCamera:{7/}) ] - (Qt3DRender::QLayerFilter{134/}) [ (AcceptAnyMatchingLayers:[ {136/} ]) ] - (Qt3DRender::QClearBuffers{135/}) - (Qt3DRender::QLayerFilter{170/Sub pass TexturesPreview}) [ (AcceptAnyMatchingLayers:[ {10/} ]) ] - (Qt3DRender::QRenderStateSet{171/}) [ (QDepthTest:Always), (QCullFace:NoCulling) ] - (Qt3DRender::QNoDraw{174/Sub pass RenderCapture}) - (Qt3DRender::QRenderCapture{175/}) +(Qt3DRender::QRenderSurfaceSelector{12/}) + (Qt3DRender::QViewport{13/}) + (Qt3DRender::QCameraSelector{14/Forward render pass CameraSelector}) [ (Qt3DRender::QCamera:{0/}) ] + (Qt3DRender::QLayerFilter{15/}) [ (AcceptAnyMatchingLayers:[ {8/} ]) ] + (Qt3DRender::QRenderTargetSelector{21/}) [ (outputs:[ (Depth:{17[DepthFormat]/), (Color0:{16[RGB8_UNorm]/) ]) ] + (Qt3DRender::QLayerFilter{22/}) [ (DiscardAnyMatchingLayers:[ {10/} ]) ] + (Qt3DRender::QRenderStateSet{23/}) [ (QDepthTest:Less), (QCullFace:Back) ] + (Qt3DRender::QFrustumCulling{26/}) + (Qt3DRender::QClearBuffers{27/}) + (Qt3DRender::QDebugOverlay{40/}) [D] + (Qt3DRender::QLayerFilter{28/}) [ (AcceptAnyMatchingLayers:[ {10/} ]) ] + (Qt3DRender::QSortPolicy{29/}) + (Qt3DRender::QRenderStateSet{30/}) [ (QDepthTest:Less), (QNoDepthMask), (QCullFace:NoCulling), (QBlendEquation:Add), (QBlendEquationArguments:[ (sourceRgb:SourceAlpha), (destinationRgb:Source1Alpha), (sourceAlpha:One), (destinationAlpha:Zero), (bufferIndex:-1) ]) ] + (Qt3DRender::QRenderStateSet{36/}) [ (QDepthTest:Less), (QColorMask:[ (red:false), (green:false), (blue:false), (alpha:false) ]), (QCullFace:NoCulling) ] + (Qt3DRender::QCameraSelector{41/rubberBandsPass}) [ (Qt3DRender::QCamera:{0/}) ] + (Qt3DRender::QLayerFilter{42/}) [ (AcceptAnyMatchingLayers:[ {11/mRubberBandsLayer} ]) ] + (Qt3DRender::QRenderStateSet{43/}) [ (QDepthTest:Always) ] + (Qt3DRender::QRenderTargetSelector{45/}) [ (outputs:[ (Depth:{17[DepthFormat]/), (Color0:{16[RGB8_UNorm]/) ]) ] + (Qt3DRender::QNoDraw{48/}) + (Qt3DRender::QSubtreeEnabler{49/}) [D] + (Qt3DRender::QCameraSelector{54/shadow::CameraSelector}) [ (Qt3DRender::QCamera:{50/shadow::LightCamera}) ] + (Qt3DRender::QLayerFilter{55/}) [D] [ (AcceptAnyMatchingLayers:[ {53/shadow::Layer} ]) ] + (Qt3DRender::QRenderTargetSelector{56/}) [ (outputs:[ (Depth:{46[DepthFormat]/QgsShadowRenderView::DepthTarget) ]) ] + (Qt3DRender::QClearBuffers{57/}) + (Qt3DRender::QRenderStateSet{58/}) [ (QDepthTest:Less), (QCullFace:Front), (QPolygonOffset:[ (scaleFactor:1.1), (depthSteps:4) ]) ] + (Qt3DRender::QCameraSelector{63/Depth render view CameraSelector}) [ (Qt3DRender::QCamera:{0/}) ] + (Qt3DRender::QRenderStateSet{64/}) [ (QDepthTest:Always), (QCullFace:NoCulling) ] + (Qt3DRender::QLayerFilter{67/}) [ (AcceptAnyMatchingLayers:[ {9/} ]) ] + (Qt3DRender::QRenderTargetSelector{68/}) [ (outputs:[ (Color0:{71[RGB8_UNorm]/), (Depth:{73[DepthFormat]/) ]) ] + (Qt3DRender::QRenderCapture{74/}) + (Qt3DRender::QCameraSelector{75/AmbientOcclusion render pass CameraSelector}) [ (Qt3DRender::QCamera:{0/}) ] + (Qt3DRender::QRenderStateSet{76/}) [ (QDepthTest:Always), (QCullFace:NoCulling) ] + (Qt3DRender::QLayerFilter{79/}) [ (AcceptAnyMatchingLayers:[ {84/} ]) ] + (Qt3DRender::QRenderTargetSelector{80/}) [ (outputs:[ (Color0:{83[R32F]/) ]) ] + (Qt3DRender::QCameraSelector{107/AmbientOcclusion blur pass CameraSelector}) [ (Qt3DRender::QCamera:{0/}) ] + (Qt3DRender::QRenderStateSet{108/}) [ (QDepthTest:Always), (QCullFace:NoCulling) ] + (Qt3DRender::QLayerFilter{111/}) [ (AcceptAnyMatchingLayers:[ {116/} ]) ] + (Qt3DRender::QRenderTargetSelector{112/}) [ (outputs:[ (Color0:{115[R32F]/) ]) ] + (Qt3DRender::QRenderTargetSelector{129/PostProcessingPass}) [ (outputs:[ (Color0:{132[RGB8_UNorm]/PostProcessingPass::ColorTarget), (Depth:{134[DepthFormat]/PostProcessingPass::DepthTarget) ]) ] + (Qt3DRender::QCameraSelector{135/Sub pass Postprocessing}) [ (Qt3DRender::QCamera:{50/shadow::LightCamera}) ] + (Qt3DRender::QLayerFilter{136/}) [ (AcceptAnyMatchingLayers:[ {138/} ]) ] + (Qt3DRender::QClearBuffers{137/}) + (Qt3DRender::QLayerFilter{172/Sub pass TexturesPreview}) [ (AcceptAnyMatchingLayers:[ {7/} ]) ] + (Qt3DRender::QRenderStateSet{173/}) [ (QDepthTest:Always), (QCullFace:NoCulling) ] + (Qt3DRender::QNoDraw{176/Sub pass RenderCapture}) + (Qt3DRender::QRenderCapture{177/})