diff --git a/src/3d/CMakeLists.txt b/src/3d/CMakeLists.txt index c0c9cb3baa9..a84cfb68bc3 100644 --- a/src/3d/CMakeLists.txt +++ b/src/3d/CMakeLists.txt @@ -84,6 +84,7 @@ set(QGIS_3D_SRCS framegraph/qgspostprocessingentity.cpp framegraph/qgspreviewquad.cpp framegraph/qgsrenderpassquad.cpp + framegraph/qgsshadowrenderview.cpp framegraph/qgsframegraph.cpp framegraph/qgsframegraphutils.cpp @@ -194,6 +195,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 bfb7eb0ff9e..8e33aed8df8 100644 --- a/src/3d/framegraph/qgsframegraph.cpp +++ b/src/3d/framegraph/qgsframegraph.cpp @@ -21,6 +21,7 @@ #include "qgs3dutils.h" #include "qgsframegraphutils.h" #include "qgsabstractrenderview.h" +#include "qgsshadowrenderview.h" #include "qgsambientocclusionrenderentity.h" #include "qgsambientocclusionblurentity.h" @@ -54,8 +55,8 @@ typedef Qt3DCore::QGeometry Qt3DQGeometry; #include #include #include -#include "qgsabstractrenderview.h" +const QString QgsFrameGraph::SHADOW_RENDERVIEW = "shadow"; const QString QgsFrameGraph::AXIS3D_RENDERVIEW = "3daxis"; Qt3DRender::QFrameGraphNode *QgsFrameGraph::constructForwardRenderPass() @@ -224,54 +225,11 @@ 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; + QgsShadowRenderView *shadowRenderView = new QgsShadowRenderView( this, SHADOW_RENDERVIEW ); + registerRenderView( shadowRenderView, SHADOW_RENDERVIEW ); } Qt3DRender::QFrameGraphNode *QgsFrameGraph::constructSubPostPassForTexturesPreview() @@ -295,7 +253,7 @@ Qt3DRender::QFrameGraphNode *QgsFrameGraph::constructSubPostPassForProcessing() { Qt3DRender::QCameraSelector *cameraSelector = new Qt3DRender::QCameraSelector; cameraSelector->setObjectName( "Sub pass Postprocessing" ); - cameraSelector->setCamera( mLightCamera ); + cameraSelector->setCamera( shadowRenderView()->lightCamera() ); Qt3DRender::QLayerFilter *layerFilter = new Qt3DRender::QLayerFilter( cameraSelector ); @@ -672,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; @@ -684,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 ); @@ -711,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(); @@ -738,7 +692,10 @@ 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 } ); + + Qt3DRender::QTexture2D *shadowMapTexture = shadowRenderView()->mapTexture(); + mDebugShadowMapPreviewQuad = this->addTexturePreviewOverlay( shadowMapTexture, QPointF( 0.9f, 0.9f ), QSizeF( 0.1, 0.1 ), QVector { shadowMapIsDepthParam } ); + mDebugDepthMapPreviewQuad->setEnabled( false ); mDebugShadowMapPreviewQuad->setEnabled( false ); @@ -775,7 +732,7 @@ bool QgsFrameGraph::registerRenderView( QgsAbstractRenderView *renderView, const void QgsFrameGraph::setRenderViewEnabled( const QString &name, bool enable ) { - if ( mRenderViewMap[name] != nullptr ) + if ( mRenderViewMap[name] ) { mRenderViewMap[name]->setEnabled( enable ); } @@ -800,90 +757,36 @@ QgsPreviewQuad *QgsFrameGraph::addTexturePreviewOverlay( Qt3DRender::QTexture2D return previewQuad; } -// computes the portion of the Z=z plane the camera is looking at -void calculateViewExtent( Qt3DRender::QCamera *camera, float shadowRenderingDistance, float z, float &minX, float &maxX, float &minY, float &maxY, float &minZ, float &maxZ ) +void QgsFrameGraph::updateShadowSettings( const QgsShadowSettings &shadowSettings, const QList &lightSources ) { - 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 ) + if ( shadowSettings.renderShadows() ) { - // 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 Z=z - // 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 = ( z - pt.z() ) / vect.z(); - 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() ); + int selectedLight = shadowSettings.selectedDirectionalLight(); + QgsDirectionalLightSettings *light = nullptr; + for ( int i = 0, dirLight = 0; !light && i < lightSources.size(); i++ ) + { + if ( lightSources[i]->type() == Qgis::LightSourceType::Directional ) + { + if ( dirLight == selectedLight ) + light = qgis::down_cast< QgsDirectionalLightSettings * >( lightSources[i] ); + dirLight++; + } + } + + if ( light ) + { + shadowRenderView()->setMapSize( shadowSettings.shadowMapResolution(), shadowSettings.shadowMapResolution() ); + shadowRenderView()->setEnabled( true ); + mPostprocessingEntity->setShadowRenderingEnabled( true ); + mPostprocessingEntity->setShadowBias( static_cast( shadowSettings.shadowBias() ) ); + mPostprocessingEntity->updateShadowSettings( *light, static_cast( shadowSettings.maximumShadowRenderingDistance() ) ); + } + } + else + { + shadowRenderView()->setEnabled( false ); + mPostprocessingEntity->setShadowRenderingEnabled( false ); } -} - -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 lightDirection = QVector3D( light.direction().x(), light.direction().y(), light.direction().z() ).normalized(); - calculateViewExtent( mMainCamera, maximumShadowRenderingDistance, lookingAt.z(), minX, maxX, minY, maxY, minZ, maxZ ); - - lookingAt = QVector3D( 0.5f * ( minX + maxX ), 0.5f * ( minY + maxY ), mMainCamera->viewCenter().z() ); - const QVector3D lightPosition = lookingAt + QVector3D( 0.0f, 0.0f, d ); - mLightCamera->setPosition( lightPosition ); - mLightCamera->setViewCenter( lookingAt ); - mLightCamera->setUpVector( QVector3D( 0.0f, 1.0f, 0.0f ) ); - mLightCamera->rotateAboutViewCenter( QQuaternion::rotationTo( QVector3D( 0.0f, 0.0f, -1.0f ), lightDirection ) ); - - mLightCamera->setProjectionType( Qt3DRender::QCameraLens::ProjectionType::OrthographicProjection ); - mLightCamera->lens()->setOrthographicProjection( - -0.7f * ( maxX - minX ), 0.7f * ( maxX - minX ), - -0.7f * ( maxY - minY ), 0.7f * ( maxY - minY ), - 1.0f, 2 * ( lookingAt - lightPosition ).length() - ); - - mPostprocessingEntity->setupShadowRenderingExtent( minX, maxX, minY, maxY ); - mPostprocessingEntity->setupDirectionalLight( lightPosition, lightDirection ); } QString QgsFrameGraph::dumpFrameGraph() const @@ -910,29 +813,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; @@ -1082,3 +962,11 @@ void QgsFrameGraph::addClipPlanes( int nrClipPlanes ) mClipRenderStateSet->addRenderState( clipPlane ); } } + +QgsShadowRenderView *QgsFrameGraph::shadowRenderView() const +{ + QgsAbstractRenderView *rv = mRenderViewMap[QgsFrameGraph::SHADOW_RENDERVIEW].get(); + if ( rv ) + return qobject_cast( rv ); + return nullptr; +} diff --git a/src/3d/framegraph/qgsframegraph.h b/src/3d/framegraph/qgsframegraph.h index cf935d8eb43..585117bb5fc 100644 --- a/src/3d/framegraph/qgsframegraph.h +++ b/src/3d/framegraph/qgsframegraph.h @@ -46,6 +46,9 @@ class QgsAmbientOcclusionRenderEntity; class QgsPreviewQuad; class QgsAmbientOcclusionBlurEntity; class QgsAbstractRenderView; +class QgsForwardRenderView; +class QgsShadowRenderView; +class QgsShadowSettings; #define SIP_NO_FILE @@ -74,8 +77,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 +86,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 +97,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 +117,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 @@ -188,8 +170,7 @@ class QgsFrameGraph : public Qt3DCore::QEntity 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 @@ -261,7 +242,7 @@ class QgsFrameGraph : public Qt3DCore::QEntity void setRenderViewEnabled( const QString &name, bool enable ); /** - * Returns true if a render view is found and enabled + * Returns true if the render view named \a name is found and enabled * \since QGIS 3.44 */ bool isRenderViewEnabled( const QString &name ); @@ -272,6 +253,19 @@ class QgsFrameGraph : public Qt3DCore::QEntity */ QgsAbstractRenderView *renderView( const QString &name ); + /** + * Returns shadow renderview or nullptr if not defined + * \since QGIS 3.44 + */ + QgsShadowRenderView *shadowRenderView() const; + + /** + * Updates shadow bias, light and texture size according to \a shadowSettings and \a lightSources + * \since QGIS 3.44 + */ + void updateShadowSettings( const QgsShadowSettings &shadowSettings, const QList &lightSources ); + + static const QString SHADOW_RENDERVIEW; static const QString AXIS3D_RENDERVIEW; private: @@ -280,7 +274,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; @@ -294,15 +287,6 @@ 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; - // - 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 // calculating real 3D points from mouse coordinates (for zoom, rotation, drag..) @@ -345,10 +329,6 @@ class QgsFrameGraph : public Qt3DCore::QEntity Qt3DRender::QRenderStateSet *mRubberBandsStateSet = nullptr; Qt3DRender::QRenderTargetSelector *mRubberBandsRenderTargetSelector = nullptr; - bool mShadowRenderingEnabled = false; - float mShadowBias = 0.00001f; - int mShadowMapResolution = 2048; - // Ambient occlusion related settings bool mAmbientOcclusionEnabled = false; float mAmbientOcclusionIntensity = 0.5f; @@ -375,7 +355,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; @@ -388,7 +367,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 619f793aa09..bccf8dd01a6 100644 --- a/src/3d/framegraph/qgspostprocessingentity.cpp +++ b/src/3d/framegraph/qgspostprocessingentity.cpp @@ -41,15 +41,18 @@ typedef Qt3DCore::QGeometry Qt3DQGeometry; #include #include +#include "qgs3dutils.h" +#include "qgsdirectionallightsettings.h" #include "qgsframegraph.h" +#include "qgsshadowrenderview.h" QgsPostprocessingEntity::QgsPostprocessingEntity( QgsFrameGraph *frameGraph, Qt3DRender::QLayer *layer, QNode *parent ) : QgsRenderPassQuad( layer, parent ) { - Q_UNUSED( frameGraph ) + QgsShadowRenderView *shadowRenderView = frameGraph->shadowRenderView(); 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->mapTexture() ); mAmbientOcclusionTextureParameter = new Qt3DRender::QParameter( QStringLiteral( "ssaoTexture" ), frameGraph->blurredAmbientOcclusionFactorMap() ); mMaterial->addParameter( mColorTextureParameter ); mMaterial->addParameter( mDepthTextureParameter ); @@ -57,7 +60,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 ); @@ -143,6 +146,33 @@ void QgsPostprocessingEntity::setupDirectionalLight( QVector3D position, QVector mLightDirection->setValue( QVariant::fromValue( direction.normalized() ) ); } +void QgsPostprocessingEntity::updateShadowSettings( 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 lightDirection = light.direction().toVector3D().normalized(); + Qgs3DUtils::calculateViewExtent( mMainCamera, maximumShadowRenderingDistance, lookingAt.z(), minX, maxX, minY, maxY, minZ, maxZ ); + + lookingAt = QVector3D( 0.5f * ( minX + maxX ), 0.5f * ( minY + maxY ), mMainCamera->viewCenter().z() ); + const QVector3D lightPosition = lookingAt + QVector3D( 0.0f, 0.0f, d ); + mLightCamera->setPosition( lightPosition ); + mLightCamera->setViewCenter( lookingAt ); + mLightCamera->setUpVector( QVector3D( 0.0f, 1.0f, 0.0f ) ); + mLightCamera->rotateAboutViewCenter( QQuaternion::rotationTo( QVector3D( 0.0f, 0.0f, -1.0f ), lightDirection ) ); + + mLightCamera->setProjectionType( Qt3DRender::QCameraLens::ProjectionType::OrthographicProjection ); + mLightCamera->lens()->setOrthographicProjection( + -0.7f * ( maxX - minX ), 0.7f * ( maxX - minX ), + -0.7f * ( maxY - minY ), 0.7f * ( maxY - minY ), + 1.0f, 2 * ( lookingAt - lightPosition ).length() + ); + + setupShadowRenderingExtent( minX, maxX, minY, maxY ); + setupDirectionalLight( lightPosition, lightDirection ); +} + void QgsPostprocessingEntity::setShadowRenderingEnabled( bool enabled ) { mRenderShadowsParameter->setValue( QVariant::fromValue( enabled ? 1 : 0 ) ); diff --git a/src/3d/framegraph/qgspostprocessingentity.h b/src/3d/framegraph/qgspostprocessingentity.h index b941907f05b..b7df65d50b4 100644 --- a/src/3d/framegraph/qgspostprocessingentity.h +++ b/src/3d/framegraph/qgspostprocessingentity.h @@ -19,6 +19,8 @@ #include "qgsrenderpassquad.h" class QgsFrameGraph; +class QgsShadowRenderView; +class QgsDirectionalLightSettings; #define SIP_NO_FILE @@ -52,6 +54,12 @@ class QgsPostprocessingEntity : public QgsRenderPassQuad //! Sets the eye dome lighting distance (contributes to the contrast of the image) 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 * \since QGIS 3.28 diff --git a/src/3d/framegraph/qgsshadowrenderview.cpp b/src/3d/framegraph/qgsshadowrenderview.cpp new file mode 100644 index 00000000000..40f6aea3aa9 --- /dev/null +++ b/src/3d/framegraph/qgsshadowrenderview.cpp @@ -0,0 +1,132 @@ +/*************************************************************************** + 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 "moc_qgsshadowrenderview.cpp" +#include "qgsdirectionallightsettings.h" +#include "qgsshadowsettings.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +QgsShadowRenderView::QgsShadowRenderView( QObject *parent, const QString &viewName ) + : QgsAbstractRenderView( parent, viewName ) +{ + mLightCamera = new Qt3DRender::QCamera; + mLightCamera->setObjectName( objectName() + "::LightCamera" ); + mEntityCastingShadowsLayer = new Qt3DRender::QLayer; + mEntityCastingShadowsLayer->setRecursive( true ); + mEntityCastingShadowsLayer->setObjectName( objectName() + "::Layer" ); + + // shadow rendering pass + buildRenderPass(); +} + +void QgsShadowRenderView::setEnabled( bool enable ) +{ + QgsAbstractRenderView::setEnabled( enable ); + mLayerFilter->setEnabled( enable ); +} + +Qt3DRender::QRenderTarget *QgsShadowRenderView::buildTextures() +{ + mMapTexture = new Qt3DRender::QTexture2D; + mMapTexture->setWidth( mDefaultMapResolution ); + mMapTexture->setHeight( mDefaultMapResolution ); + mMapTexture->setFormat( Qt3DRender::QTexture2D::TextureFormat::DepthFormat ); + mMapTexture->setGenerateMipMaps( false ); + mMapTexture->setMagnificationFilter( Qt3DRender::QTexture2D::Linear ); + mMapTexture->setMinificationFilter( Qt3DRender::QTexture2D::Linear ); + mMapTexture->wrapMode()->setX( Qt3DRender::QTextureWrapMode::ClampToEdge ); + mMapTexture->wrapMode()->setY( Qt3DRender::QTextureWrapMode::ClampToEdge ); + mMapTexture->setObjectName( "QgsShadowRenderView::DepthTarget" ); + + Qt3DRender::QRenderTargetOutput *renderTargetOutput = new Qt3DRender::QRenderTargetOutput; + renderTargetOutput->setAttachmentPoint( Qt3DRender::QRenderTargetOutput::Depth ); + renderTargetOutput->setTexture( mMapTexture ); + + Qt3DRender::QRenderTarget *renderTarget = new Qt3DRender::QRenderTarget; + renderTarget->setObjectName( objectName() + "::Target" ); + renderTarget->addOutput( renderTargetOutput ); + + return renderTarget; +} + +void QgsShadowRenderView::buildRenderPass() +{ + // build render pass + mLightCameraSelector = new Qt3DRender::QCameraSelector( mRendererEnabler ); + mLightCameraSelector->setObjectName( objectName() + "::CameraSelector" ); + mLightCameraSelector->setCamera( mLightCamera ); + + mLayerFilter = new Qt3DRender::QLayerFilter( mLightCameraSelector ); + mLayerFilter->addLayer( mEntityCastingShadowsLayer ); + + mRenderTargetSelector = new Qt3DRender::QRenderTargetSelector( mLayerFilter ); + + 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 ); + + // build texture part + Qt3DRender::QRenderTarget *renderTarget = buildTextures(); + + mRenderTargetSelector->setTarget( renderTarget ); +} + +Qt3DRender::QLayer *QgsShadowRenderView::entityCastingShadowsLayer() const +{ + return mEntityCastingShadowsLayer; +} + +void QgsShadowRenderView::setMapSize( int width, int height ) +{ + mMapTexture->setSize( width, height ); +} + +Qt3DRender::QTexture2D *QgsShadowRenderView::mapTexture() const +{ + return mMapTexture; +} diff --git a/src/3d/framegraph/qgsshadowrenderview.h b/src/3d/framegraph/qgsshadowrenderview.h new file mode 100644 index 00000000000..b6675c0a663 --- /dev/null +++ b/src/3d/framegraph/qgsshadowrenderview.h @@ -0,0 +1,108 @@ +/*************************************************************************** + 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 QRenderTarget; + class QRenderTargetOutput; +} // namespace Qt3DRender + +namespace Qt3DExtras +{ + class Qt3DWindow; +} + +class QgsShadowSettings; +class QgsDirectionalLightSettings; +class QgsLightSource; + +#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.44 + */ +class QgsShadowRenderView : public QgsAbstractRenderView +{ + Q_OBJECT + public: + //! Default constructor + QgsShadowRenderView( QObject *parent, const QString &viewName ); + + //! Enable or disable via \a enable the renderview sub tree + virtual void setEnabled( bool enable ) override; + + //! Returns the light camera + Qt3DRender::QCamera *lightCamera() { return mLightCamera; } + + //! Returns shadow depth texture + Qt3DRender::QTexture2D *mapTexture() const; + + //! Returns the layer to be used by entities to be included in this renderview + Qt3DRender::QLayer *entityCastingShadowsLayer() const; + + //! Update shadow depth texture size + void setMapSize( int width, int height ); + + private: + static constexpr int mDefaultMapResolution = 2048; + + // Shadow rendering pass branch nodes: + Qt3DRender::QLayer *mEntityCastingShadowsLayer = nullptr; + Qt3DRender::QRenderTargetSelector *mRenderTargetSelector = nullptr; + Qt3DRender::QCameraSelector *mLightCameraSelector = nullptr; + Qt3DRender::QLayerFilter *mLayerFilter = nullptr; + Qt3DRender::QClearBuffers *mClearBuffers = nullptr; + Qt3DRender::QRenderStateSet *mRenderStateSet = nullptr; + + Qt3DRender::QCamera *mLightCamera = nullptr; + + Qt3DRender::QTexture2D *mMapTexture = nullptr; + + Qt3DRender::QRenderTarget *buildTextures(); + void buildRenderPass(); +}; + +#endif // QGSSHADOWRENDERVIEW_H diff --git a/src/3d/qgs3dmapcanvas.cpp b/src/3d/qgs3dmapcanvas.cpp index e3fe56c78eb..7bd84cdf323 100644 --- a/src/3d/qgs3dmapcanvas.cpp +++ b/src/3d/qgs3dmapcanvas.cpp @@ -30,7 +30,7 @@ #include "qgs3dmapsettings.h" #include "qgs3dmaptool.h" #include "qgstemporalcontroller.h" -#include "qgsframegraph.h" +#include "framegraph/qgsframegraph.h" #include "qgspointcloudlayer3drenderer.h" #include "qgsrubberband3d.h" diff --git a/src/3d/qgs3dmapscene.cpp b/src/3d/qgs3dmapscene.cpp index 41beb8ea350..b76e99d43ff 100644 --- a/src/3d/qgs3dmapscene.cpp +++ b/src/3d/qgs3dmapscene.cpp @@ -83,6 +83,7 @@ #include "qgswindow3dengine.h" #include "qgspointcloudlayer.h" +#include "framegraph/qgsshadowrenderview.h" std::function()> Qgs3DMapScene::sOpenScenesFunction = [] { return QMap(); }; @@ -983,29 +984,7 @@ void Qgs3DMapScene::onSkyboxSettingsChanged() void Qgs3DMapScene::onShadowSettingsChanged() { QgsFrameGraph *frameGraph = mEngine->frameGraph(); - - const QList lightSources = mMap.lightSources(); - QList directionalLightSources; - for ( QgsLightSource *source : lightSources ) - { - if ( source->type() == Qgis::LightSourceType::Directional ) - { - directionalLightSources << qgis::down_cast( source ); - } - } - - QgsShadowSettings shadowSettings = mMap.shadowSettings(); - int selectedLight = shadowSettings.selectedDirectionalLight(); - if ( shadowSettings.renderShadows() && selectedLight >= 0 && selectedLight < directionalLightSources.count() ) - { - frameGraph->setShadowRenderingEnabled( true ); - frameGraph->setShadowBias( shadowSettings.shadowBias() ); - frameGraph->setShadowMapResolution( shadowSettings.shadowMapResolution() ); - QgsDirectionalLightSettings light = *directionalLightSources.at( selectedLight ); - frameGraph->setupDirectionalLight( light, shadowSettings.maximumShadowRenderingDistance() ); - } - else - frameGraph->setShadowRenderingEnabled( false ); + frameGraph->updateShadowSettings( mMap.shadowSettings(), mMap.lightSources() ); } void Qgs3DMapScene::onAmbientOcclusionSettingsChanged() diff --git a/src/3d/qgs3dutils.cpp b/src/3d/qgs3dutils.cpp index 1f40461a2d7..5e29e71a828 100644 --- a/src/3d/qgs3dutils.cpp +++ b/src/3d/qgs3dutils.cpp @@ -1026,3 +1026,62 @@ QgsPoint Qgs3DUtils::screenPointToMapCoordinates( const QPoint &screenPoint, con const QgsPoint mapPoint( mapTransform.x(), mapTransform.y(), mapTransform.z() ); return mapPoint; } + +// computes the portion of the Y=y plane the camera is looking at +void Qgs3DUtils::calculateViewExtent( const Qt3DRender::QCamera *camera, float maxRenderingDistance, float z, 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 Z=z + // if the intersection is on the back side of the viewing panel we get a point that is + // maxRenderingDistance units in front of the camera + const QVector3D pt = cameraPos; + const QVector3D vect = ( viewFrustumPoints[i] - pt ).normalized(); + float t = ( z - pt.z() ) / vect.z(); + if ( t < 0 ) + t = maxRenderingDistance; + else + t = std::min( t, maxRenderingDistance ); + 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/qgs3dutils.h b/src/3d/qgs3dutils.h index acddf29b66f..bfa2751bf24 100644 --- a/src/3d/qgs3dutils.h +++ b/src/3d/qgs3dutils.h @@ -363,6 +363,12 @@ class _3D_EXPORT Qgs3DUtils * \since QGIS 3.44 */ static QgsPoint screenPointToMapCoordinates( const QPoint &screenPoint, QSize size, const QgsCameraController *cameraController, const Qgs3DMapSettings *mapSettings ); + + /** + * Computes the portion of the Y=y plane the camera is looking at + * \since QGIS 3.44 + */ + static void calculateViewExtent( const Qt3DRender::QCamera *camera, float maxRenderingDistance, float z, float &minX, float &maxX, float &minY, float &maxY, float &minZ, float &maxZ ); }; #endif // QGS3DUTILS_H diff --git a/src/3d/qgsoffscreen3dengine.cpp b/src/3d/qgsoffscreen3dengine.cpp index 980424b39ca..812d1e5da39 100644 --- a/src/3d/qgsoffscreen3dengine.cpp +++ b/src/3d/qgsoffscreen3dengine.cpp @@ -16,7 +16,7 @@ #include "qgsoffscreen3dengine.h" #include "moc_qgsoffscreen3dengine.cpp" -#include "framegraph/qgsframegraph.h" +#include "qgsframegraph.h" #include #include @@ -36,6 +36,8 @@ #include #include #include +#include "qgsabstractrenderview.h" +#include "qgsshadowrenderview.h" QgsOffscreen3DEngine::QgsOffscreen3DEngine() { @@ -103,7 +105,7 @@ QgsOffscreen3DEngine::QgsOffscreen3DEngine() mFrameGraph = new QgsFrameGraph( mOffscreenSurface, mSize, mCamera, mRoot ); mFrameGraph->setRenderCaptureEnabled( true ); - mFrameGraph->setShadowRenderingEnabled( false ); + mFrameGraph->shadowRenderView()->setEnabled( 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 +151,7 @@ void QgsOffscreen3DEngine::setRootEntity( Qt3DCore::QEntity *root ) mSceneRoot = root; mSceneRoot->setParent( mRoot ); root->addComponent( mFrameGraph->forwardRenderLayer() ); - root->addComponent( mFrameGraph->castShadowsLayer() ); + root->addComponent( mFrameGraph->shadowRenderView()->entityCastingShadowsLayer() ); } Qt3DRender::QRenderSettings *QgsOffscreen3DEngine::renderSettings() diff --git a/src/3d/qgswindow3dengine.cpp b/src/3d/qgswindow3dengine.cpp index 161adec1b04..c0eacea3975 100644 --- a/src/3d/qgswindow3dengine.cpp +++ b/src/3d/qgswindow3dengine.cpp @@ -19,9 +19,12 @@ #include #include +#include "qgsabstractrenderview.h" +#include "qgspreviewquad.h" #include "qgs3dmapcanvas.h" -#include "framegraph/qgsframegraph.h" +#include "qgsframegraph.h" +#include "qgsshadowrenderview.h" QgsWindow3DEngine::QgsWindow3DEngine( Qgs3DMapCanvas *parent ) : QgsAbstract3DEngine( parent ) @@ -35,7 +38,7 @@ QgsWindow3DEngine::QgsWindow3DEngine( Qgs3DMapCanvas *parent ) mMapCanvas3D->setActiveFrameGraph( mFrameGraph->frameGraphRoot() ); // force switching to no shadow rendering - setShadowRenderingEnabled( false ); + mFrameGraph->shadowRenderView()->setEnabled( false ); } QWindow *QgsWindow3DEngine::window() @@ -48,12 +51,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 ); @@ -70,7 +67,7 @@ void QgsWindow3DEngine::setRootEntity( Qt3DCore::QEntity *root ) mSceneRoot = root; mSceneRoot->setParent( mRoot ); mSceneRoot->addComponent( mFrameGraph->forwardRenderLayer() ); - mSceneRoot->addComponent( mFrameGraph->castShadowsLayer() ); + mSceneRoot->addComponent( mFrameGraph->shadowRenderView()->entityCastingShadowsLayer() ); } Qt3DRender::QRenderSettings *QgsWindow3DEngine::renderSettings() diff --git a/src/3d/qgswindow3dengine.h b/src/3d/qgswindow3dengine.h index dfbd5fa3ff3..02df2667e64 100644 --- a/src/3d/qgswindow3dengine.h +++ b/src/3d/qgswindow3dengine.h @@ -57,11 +57,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 51752e526a3..1b57c326981 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,45 +1,47 @@ -(Qt3DRender::QRenderSurfaceSelector{16/}) - (Qt3DRender::QViewport{17/}) - (Qt3DRender::QCameraSelector{18/Forward render pass CameraSelector}) [ (Qt3DRender::QCamera:{0/}) ] - (Qt3DRender::QLayerFilter{19/}) [ (AcceptAnyMatchingLayers:[ {12/} ]) ] - (Qt3DRender::QRenderStateSet{20/Forward render pass Clip Plane RenderStateSet}) [ ] - (Qt3DRender::QRenderTargetSelector{26/}) [ (outputs:[ (Depth:{22[DepthFormat]/), (Color0:{21[RGB8_UNorm]/) ]) ] - (Qt3DRender::QLayerFilter{27/}) [ (DiscardAnyMatchingLayers:[ {14/} ]) ] - (Qt3DRender::QRenderStateSet{28/}) [ (QDepthTest:Less), (QCullFace:Back) ] - (Qt3DRender::QFrustumCulling{31/}) - (Qt3DRender::QClearBuffers{32/}) - (Qt3DRender::QDebugOverlay{45/}) [D] - (Qt3DRender::QLayerFilter{33/}) [ (AcceptAnyMatchingLayers:[ {14/} ]) ] - (Qt3DRender::QSortPolicy{34/}) - (Qt3DRender::QRenderStateSet{35/}) [ (QDepthTest:Less), (QNoDepthMask), (QCullFace:NoCulling), (QBlendEquation:Add), (QBlendEquationArguments:[ (sourceRgb:SourceAlpha), (destinationRgb:Source1Alpha), (sourceAlpha:One), (destinationAlpha:Zero), (bufferIndex:-1) ]) ] - (Qt3DRender::QRenderStateSet{41/}) [ (QDepthTest:Less), (QColorMask:[ (red:false), (green:false), (blue:false), (alpha:false) ]), (QCullFace:NoCulling) ] - (Qt3DRender::QCameraSelector{46/rubberBandsPass}) [ (Qt3DRender::QCamera:{0/}) ] - (Qt3DRender::QLayerFilter{47/}) [ (AcceptAnyMatchingLayers:[ {15/mRubberBandsLayer} ]) ] - (Qt3DRender::QRenderStateSet{50/}) [ (QDepthTest:Always), (QBlendEquationArguments:[ (sourceRgb:SourceAlpha), (destinationRgb:Source1Alpha), (sourceAlpha:One), (destinationAlpha:Zero), (bufferIndex:-1) ]), (QBlendEquation:Add) ] - (Qt3DRender::QRenderTargetSelector{52/}) [ (outputs:[ (Depth:{22[DepthFormat]/), (Color0:{21[RGB8_UNorm]/) ]) ] - (Qt3DRender::QCameraSelector{53/Shadow render pass CameraSelector}) [ (Qt3DRender::QCamera:{7/}) ] - (Qt3DRender::QLayerFilter{54/}) [D] [ (AcceptAnyMatchingLayers:[ {11/} ]) ] - (Qt3DRender::QRenderTargetSelector{58/}) [ (outputs:[ (Depth:{55[DepthFormat]/) ]) ] - (Qt3DRender::QClearBuffers{59/}) - (Qt3DRender::QRenderStateSet{60/}) [ (QDepthTest:Less), (QCullFace:Front), (QPolygonOffset:[ (scaleFactor:1.1), (depthSteps:4) ]) ] - (Qt3DRender::QCameraSelector{64/Depth render view CameraSelector}) [ (Qt3DRender::QCamera:{0/}) ] - (Qt3DRender::QRenderStateSet{65/}) [ (QDepthTest:Always), (QCullFace:NoCulling) ] - (Qt3DRender::QLayerFilter{68/}) [ (AcceptAnyMatchingLayers:[ {13/} ]) ] - (Qt3DRender::QRenderTargetSelector{69/}) [ (outputs:[ (Color0:{72[RGB8_UNorm]/), (Depth:{74[DepthFormat]/) ]) ] - (Qt3DRender::QRenderCapture{75/}) - (Qt3DRender::QCameraSelector{76/AmbientOcclusion render pass CameraSelector}) [ (Qt3DRender::QCamera:{0/}) ] - (Qt3DRender::QRenderStateSet{77/}) [ (QDepthTest:Always), (QCullFace:NoCulling) ] - (Qt3DRender::QLayerFilter{80/}) [ (AcceptAnyMatchingLayers:[ {85/} ]) ] - (Qt3DRender::QRenderTargetSelector{81/}) [ (outputs:[ (Color0:{84[R32F]/) ]) ] - (Qt3DRender::QCameraSelector{108/AmbientOcclusion blur pass CameraSelector}) [ (Qt3DRender::QCamera:{0/}) ] - (Qt3DRender::QRenderStateSet{109/}) [ (QDepthTest:Always), (QCullFace:NoCulling) ] - (Qt3DRender::QLayerFilter{112/}) [ (AcceptAnyMatchingLayers:[ {117/} ]) ] - (Qt3DRender::QRenderTargetSelector{113/}) [ (outputs:[ (Color0:{116[R32F]/) ]) ] - (Qt3DRender::QRenderTargetSelector{130/PostProcessingPass}) [ (outputs:[ (Color0:{133[RGB8_UNorm]/PostProcessingPass::ColorTarget), (Depth:{135[DepthFormat]/PostProcessingPass::DepthTarget) ]) ] - (Qt3DRender::QCameraSelector{136/Sub pass Postprocessing}) [ (Qt3DRender::QCamera:{7/}) ] - (Qt3DRender::QLayerFilter{137/}) [ (AcceptAnyMatchingLayers:[ {139/} ]) ] - (Qt3DRender::QClearBuffers{138/}) - (Qt3DRender::QLayerFilter{173/Sub pass TexturesPreview}) [ (AcceptAnyMatchingLayers:[ {10/} ]) ] - (Qt3DRender::QRenderStateSet{174/}) [ (QDepthTest:Always), (QCullFace:NoCulling) ] - (Qt3DRender::QNoDraw{177/Sub pass RenderCapture}) - (Qt3DRender::QRenderCapture{178/}) +(Qt3DRender::QRenderSurfaceSelector{12/}) + (Qt3DRender::QViewport{13/}) + (Qt3DRender::QCameraSelector{14/Forward render pass CameraSelector}) [ (Qt3DRender::QCamera:{0/}) ] + (Qt3DRender::QLayerFilter{15/}) [ (AcceptAnyMatchingLayers:[ {8/} ]) ] + (Qt3DRender::QRenderStateSet{16/Forward render pass Clip Plane RenderStateSet}) [ ] + (Qt3DRender::QRenderTargetSelector{22/}) [ (outputs:[ (Depth:{18[DepthFormat]/), (Color0:{17[RGB8_UNorm]/) ]) ] + (Qt3DRender::QLayerFilter{23/}) [ (DiscardAnyMatchingLayers:[ {10/} ]) ] + (Qt3DRender::QRenderStateSet{24/}) [ (QDepthTest:Less), (QCullFace:Back) ] + (Qt3DRender::QFrustumCulling{27/}) + (Qt3DRender::QClearBuffers{28/}) + (Qt3DRender::QDebugOverlay{41/}) [D] + (Qt3DRender::QLayerFilter{29/}) [ (AcceptAnyMatchingLayers:[ {10/} ]) ] + (Qt3DRender::QSortPolicy{30/}) + (Qt3DRender::QRenderStateSet{31/}) [ (QDepthTest:Less), (QNoDepthMask), (QCullFace:NoCulling), (QBlendEquation:Add), (QBlendEquationArguments:[ (sourceRgb:SourceAlpha), (destinationRgb:Source1Alpha), (sourceAlpha:One), (destinationAlpha:Zero), (bufferIndex:-1) ]) ] + (Qt3DRender::QRenderStateSet{37/}) [ (QDepthTest:Less), (QColorMask:[ (red:false), (green:false), (blue:false), (alpha:false) ]), (QCullFace:NoCulling) ] + (Qt3DRender::QCameraSelector{42/rubberBandsPass}) [ (Qt3DRender::QCamera:{0/}) ] + (Qt3DRender::QLayerFilter{43/}) [ (AcceptAnyMatchingLayers:[ {11/mRubberBandsLayer} ]) ] + (Qt3DRender::QRenderStateSet{46/}) [ (QDepthTest:Always), (QBlendEquationArguments:[ (sourceRgb:SourceAlpha), (destinationRgb:Source1Alpha), (sourceAlpha:One), (destinationAlpha:Zero), (bufferIndex:-1) ]), (QBlendEquation:Add) ] + (Qt3DRender::QRenderTargetSelector{48/}) [ (outputs:[ (Depth:{18[DepthFormat]/), (Color0:{17[RGB8_UNorm]/) ]) ] + (Qt3DRender::QNoDraw{49/shadow::NoDraw}) + (Qt3DRender::QSubtreeEnabler{50/shadow::SubtreeEnabler}) [D] + (Qt3DRender::QCameraSelector{55/shadow::CameraSelector}) [ (Qt3DRender::QCamera:{51/shadow::LightCamera}) ] + (Qt3DRender::QLayerFilter{56/}) [D] [ (AcceptAnyMatchingLayers:[ {54/shadow::Layer} ]) ] + (Qt3DRender::QRenderTargetSelector{57/}) [ (outputs:[ (Depth:{63[DepthFormat]/QgsShadowRenderView::DepthTarget) ]) ] + (Qt3DRender::QClearBuffers{58/}) + (Qt3DRender::QRenderStateSet{59/}) [ (QDepthTest:Less), (QCullFace:Front), (QPolygonOffset:[ (scaleFactor:1.1), (depthSteps:4) ]) ] + (Qt3DRender::QCameraSelector{66/Depth render view CameraSelector}) [ (Qt3DRender::QCamera:{0/}) ] + (Qt3DRender::QRenderStateSet{67/}) [ (QDepthTest:Always), (QCullFace:NoCulling) ] + (Qt3DRender::QLayerFilter{70/}) [ (AcceptAnyMatchingLayers:[ {9/} ]) ] + (Qt3DRender::QRenderTargetSelector{71/}) [ (outputs:[ (Color0:{74[RGB8_UNorm]/), (Depth:{76[DepthFormat]/) ]) ] + (Qt3DRender::QRenderCapture{77/}) + (Qt3DRender::QCameraSelector{78/AmbientOcclusion render pass CameraSelector}) [ (Qt3DRender::QCamera:{0/}) ] + (Qt3DRender::QRenderStateSet{79/}) [ (QDepthTest:Always), (QCullFace:NoCulling) ] + (Qt3DRender::QLayerFilter{82/}) [ (AcceptAnyMatchingLayers:[ {87/} ]) ] + (Qt3DRender::QRenderTargetSelector{83/}) [ (outputs:[ (Color0:{86[R32F]/) ]) ] + (Qt3DRender::QCameraSelector{110/AmbientOcclusion blur pass CameraSelector}) [ (Qt3DRender::QCamera:{0/}) ] + (Qt3DRender::QRenderStateSet{111/}) [ (QDepthTest:Always), (QCullFace:NoCulling) ] + (Qt3DRender::QLayerFilter{114/}) [ (AcceptAnyMatchingLayers:[ {119/} ]) ] + (Qt3DRender::QRenderTargetSelector{115/}) [ (outputs:[ (Color0:{118[R32F]/) ]) ] + (Qt3DRender::QRenderTargetSelector{132/PostProcessingPass}) [ (outputs:[ (Color0:{135[RGB8_UNorm]/PostProcessingPass::ColorTarget), (Depth:{137[DepthFormat]/PostProcessingPass::DepthTarget) ]) ] + (Qt3DRender::QCameraSelector{138/Sub pass Postprocessing}) [ (Qt3DRender::QCamera:{51/shadow::LightCamera}) ] + (Qt3DRender::QLayerFilter{139/}) [ (AcceptAnyMatchingLayers:[ {141/} ]) ] + (Qt3DRender::QClearBuffers{140/}) + (Qt3DRender::QLayerFilter{175/Sub pass TexturesPreview}) [ (AcceptAnyMatchingLayers:[ {7/} ]) ] + (Qt3DRender::QRenderStateSet{176/}) [ (QDepthTest:Always), (QCullFace:NoCulling) ] + (Qt3DRender::QNoDraw{179/Sub pass RenderCapture}) + (Qt3DRender::QRenderCapture{180/}) 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 51752e526a3..1b57c326981 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,45 +1,47 @@ -(Qt3DRender::QRenderSurfaceSelector{16/}) - (Qt3DRender::QViewport{17/}) - (Qt3DRender::QCameraSelector{18/Forward render pass CameraSelector}) [ (Qt3DRender::QCamera:{0/}) ] - (Qt3DRender::QLayerFilter{19/}) [ (AcceptAnyMatchingLayers:[ {12/} ]) ] - (Qt3DRender::QRenderStateSet{20/Forward render pass Clip Plane RenderStateSet}) [ ] - (Qt3DRender::QRenderTargetSelector{26/}) [ (outputs:[ (Depth:{22[DepthFormat]/), (Color0:{21[RGB8_UNorm]/) ]) ] - (Qt3DRender::QLayerFilter{27/}) [ (DiscardAnyMatchingLayers:[ {14/} ]) ] - (Qt3DRender::QRenderStateSet{28/}) [ (QDepthTest:Less), (QCullFace:Back) ] - (Qt3DRender::QFrustumCulling{31/}) - (Qt3DRender::QClearBuffers{32/}) - (Qt3DRender::QDebugOverlay{45/}) [D] - (Qt3DRender::QLayerFilter{33/}) [ (AcceptAnyMatchingLayers:[ {14/} ]) ] - (Qt3DRender::QSortPolicy{34/}) - (Qt3DRender::QRenderStateSet{35/}) [ (QDepthTest:Less), (QNoDepthMask), (QCullFace:NoCulling), (QBlendEquation:Add), (QBlendEquationArguments:[ (sourceRgb:SourceAlpha), (destinationRgb:Source1Alpha), (sourceAlpha:One), (destinationAlpha:Zero), (bufferIndex:-1) ]) ] - (Qt3DRender::QRenderStateSet{41/}) [ (QDepthTest:Less), (QColorMask:[ (red:false), (green:false), (blue:false), (alpha:false) ]), (QCullFace:NoCulling) ] - (Qt3DRender::QCameraSelector{46/rubberBandsPass}) [ (Qt3DRender::QCamera:{0/}) ] - (Qt3DRender::QLayerFilter{47/}) [ (AcceptAnyMatchingLayers:[ {15/mRubberBandsLayer} ]) ] - (Qt3DRender::QRenderStateSet{50/}) [ (QDepthTest:Always), (QBlendEquationArguments:[ (sourceRgb:SourceAlpha), (destinationRgb:Source1Alpha), (sourceAlpha:One), (destinationAlpha:Zero), (bufferIndex:-1) ]), (QBlendEquation:Add) ] - (Qt3DRender::QRenderTargetSelector{52/}) [ (outputs:[ (Depth:{22[DepthFormat]/), (Color0:{21[RGB8_UNorm]/) ]) ] - (Qt3DRender::QCameraSelector{53/Shadow render pass CameraSelector}) [ (Qt3DRender::QCamera:{7/}) ] - (Qt3DRender::QLayerFilter{54/}) [D] [ (AcceptAnyMatchingLayers:[ {11/} ]) ] - (Qt3DRender::QRenderTargetSelector{58/}) [ (outputs:[ (Depth:{55[DepthFormat]/) ]) ] - (Qt3DRender::QClearBuffers{59/}) - (Qt3DRender::QRenderStateSet{60/}) [ (QDepthTest:Less), (QCullFace:Front), (QPolygonOffset:[ (scaleFactor:1.1), (depthSteps:4) ]) ] - (Qt3DRender::QCameraSelector{64/Depth render view CameraSelector}) [ (Qt3DRender::QCamera:{0/}) ] - (Qt3DRender::QRenderStateSet{65/}) [ (QDepthTest:Always), (QCullFace:NoCulling) ] - (Qt3DRender::QLayerFilter{68/}) [ (AcceptAnyMatchingLayers:[ {13/} ]) ] - (Qt3DRender::QRenderTargetSelector{69/}) [ (outputs:[ (Color0:{72[RGB8_UNorm]/), (Depth:{74[DepthFormat]/) ]) ] - (Qt3DRender::QRenderCapture{75/}) - (Qt3DRender::QCameraSelector{76/AmbientOcclusion render pass CameraSelector}) [ (Qt3DRender::QCamera:{0/}) ] - (Qt3DRender::QRenderStateSet{77/}) [ (QDepthTest:Always), (QCullFace:NoCulling) ] - (Qt3DRender::QLayerFilter{80/}) [ (AcceptAnyMatchingLayers:[ {85/} ]) ] - (Qt3DRender::QRenderTargetSelector{81/}) [ (outputs:[ (Color0:{84[R32F]/) ]) ] - (Qt3DRender::QCameraSelector{108/AmbientOcclusion blur pass CameraSelector}) [ (Qt3DRender::QCamera:{0/}) ] - (Qt3DRender::QRenderStateSet{109/}) [ (QDepthTest:Always), (QCullFace:NoCulling) ] - (Qt3DRender::QLayerFilter{112/}) [ (AcceptAnyMatchingLayers:[ {117/} ]) ] - (Qt3DRender::QRenderTargetSelector{113/}) [ (outputs:[ (Color0:{116[R32F]/) ]) ] - (Qt3DRender::QRenderTargetSelector{130/PostProcessingPass}) [ (outputs:[ (Color0:{133[RGB8_UNorm]/PostProcessingPass::ColorTarget), (Depth:{135[DepthFormat]/PostProcessingPass::DepthTarget) ]) ] - (Qt3DRender::QCameraSelector{136/Sub pass Postprocessing}) [ (Qt3DRender::QCamera:{7/}) ] - (Qt3DRender::QLayerFilter{137/}) [ (AcceptAnyMatchingLayers:[ {139/} ]) ] - (Qt3DRender::QClearBuffers{138/}) - (Qt3DRender::QLayerFilter{173/Sub pass TexturesPreview}) [ (AcceptAnyMatchingLayers:[ {10/} ]) ] - (Qt3DRender::QRenderStateSet{174/}) [ (QDepthTest:Always), (QCullFace:NoCulling) ] - (Qt3DRender::QNoDraw{177/Sub pass RenderCapture}) - (Qt3DRender::QRenderCapture{178/}) +(Qt3DRender::QRenderSurfaceSelector{12/}) + (Qt3DRender::QViewport{13/}) + (Qt3DRender::QCameraSelector{14/Forward render pass CameraSelector}) [ (Qt3DRender::QCamera:{0/}) ] + (Qt3DRender::QLayerFilter{15/}) [ (AcceptAnyMatchingLayers:[ {8/} ]) ] + (Qt3DRender::QRenderStateSet{16/Forward render pass Clip Plane RenderStateSet}) [ ] + (Qt3DRender::QRenderTargetSelector{22/}) [ (outputs:[ (Depth:{18[DepthFormat]/), (Color0:{17[RGB8_UNorm]/) ]) ] + (Qt3DRender::QLayerFilter{23/}) [ (DiscardAnyMatchingLayers:[ {10/} ]) ] + (Qt3DRender::QRenderStateSet{24/}) [ (QDepthTest:Less), (QCullFace:Back) ] + (Qt3DRender::QFrustumCulling{27/}) + (Qt3DRender::QClearBuffers{28/}) + (Qt3DRender::QDebugOverlay{41/}) [D] + (Qt3DRender::QLayerFilter{29/}) [ (AcceptAnyMatchingLayers:[ {10/} ]) ] + (Qt3DRender::QSortPolicy{30/}) + (Qt3DRender::QRenderStateSet{31/}) [ (QDepthTest:Less), (QNoDepthMask), (QCullFace:NoCulling), (QBlendEquation:Add), (QBlendEquationArguments:[ (sourceRgb:SourceAlpha), (destinationRgb:Source1Alpha), (sourceAlpha:One), (destinationAlpha:Zero), (bufferIndex:-1) ]) ] + (Qt3DRender::QRenderStateSet{37/}) [ (QDepthTest:Less), (QColorMask:[ (red:false), (green:false), (blue:false), (alpha:false) ]), (QCullFace:NoCulling) ] + (Qt3DRender::QCameraSelector{42/rubberBandsPass}) [ (Qt3DRender::QCamera:{0/}) ] + (Qt3DRender::QLayerFilter{43/}) [ (AcceptAnyMatchingLayers:[ {11/mRubberBandsLayer} ]) ] + (Qt3DRender::QRenderStateSet{46/}) [ (QDepthTest:Always), (QBlendEquationArguments:[ (sourceRgb:SourceAlpha), (destinationRgb:Source1Alpha), (sourceAlpha:One), (destinationAlpha:Zero), (bufferIndex:-1) ]), (QBlendEquation:Add) ] + (Qt3DRender::QRenderTargetSelector{48/}) [ (outputs:[ (Depth:{18[DepthFormat]/), (Color0:{17[RGB8_UNorm]/) ]) ] + (Qt3DRender::QNoDraw{49/shadow::NoDraw}) + (Qt3DRender::QSubtreeEnabler{50/shadow::SubtreeEnabler}) [D] + (Qt3DRender::QCameraSelector{55/shadow::CameraSelector}) [ (Qt3DRender::QCamera:{51/shadow::LightCamera}) ] + (Qt3DRender::QLayerFilter{56/}) [D] [ (AcceptAnyMatchingLayers:[ {54/shadow::Layer} ]) ] + (Qt3DRender::QRenderTargetSelector{57/}) [ (outputs:[ (Depth:{63[DepthFormat]/QgsShadowRenderView::DepthTarget) ]) ] + (Qt3DRender::QClearBuffers{58/}) + (Qt3DRender::QRenderStateSet{59/}) [ (QDepthTest:Less), (QCullFace:Front), (QPolygonOffset:[ (scaleFactor:1.1), (depthSteps:4) ]) ] + (Qt3DRender::QCameraSelector{66/Depth render view CameraSelector}) [ (Qt3DRender::QCamera:{0/}) ] + (Qt3DRender::QRenderStateSet{67/}) [ (QDepthTest:Always), (QCullFace:NoCulling) ] + (Qt3DRender::QLayerFilter{70/}) [ (AcceptAnyMatchingLayers:[ {9/} ]) ] + (Qt3DRender::QRenderTargetSelector{71/}) [ (outputs:[ (Color0:{74[RGB8_UNorm]/), (Depth:{76[DepthFormat]/) ]) ] + (Qt3DRender::QRenderCapture{77/}) + (Qt3DRender::QCameraSelector{78/AmbientOcclusion render pass CameraSelector}) [ (Qt3DRender::QCamera:{0/}) ] + (Qt3DRender::QRenderStateSet{79/}) [ (QDepthTest:Always), (QCullFace:NoCulling) ] + (Qt3DRender::QLayerFilter{82/}) [ (AcceptAnyMatchingLayers:[ {87/} ]) ] + (Qt3DRender::QRenderTargetSelector{83/}) [ (outputs:[ (Color0:{86[R32F]/) ]) ] + (Qt3DRender::QCameraSelector{110/AmbientOcclusion blur pass CameraSelector}) [ (Qt3DRender::QCamera:{0/}) ] + (Qt3DRender::QRenderStateSet{111/}) [ (QDepthTest:Always), (QCullFace:NoCulling) ] + (Qt3DRender::QLayerFilter{114/}) [ (AcceptAnyMatchingLayers:[ {119/} ]) ] + (Qt3DRender::QRenderTargetSelector{115/}) [ (outputs:[ (Color0:{118[R32F]/) ]) ] + (Qt3DRender::QRenderTargetSelector{132/PostProcessingPass}) [ (outputs:[ (Color0:{135[RGB8_UNorm]/PostProcessingPass::ColorTarget), (Depth:{137[DepthFormat]/PostProcessingPass::DepthTarget) ]) ] + (Qt3DRender::QCameraSelector{138/Sub pass Postprocessing}) [ (Qt3DRender::QCamera:{51/shadow::LightCamera}) ] + (Qt3DRender::QLayerFilter{139/}) [ (AcceptAnyMatchingLayers:[ {141/} ]) ] + (Qt3DRender::QClearBuffers{140/}) + (Qt3DRender::QLayerFilter{175/Sub pass TexturesPreview}) [ (AcceptAnyMatchingLayers:[ {7/} ]) ] + (Qt3DRender::QRenderStateSet{176/}) [ (QDepthTest:Always), (QCullFace:NoCulling) ] + (Qt3DRender::QNoDraw{179/Sub pass RenderCapture}) + (Qt3DRender::QRenderCapture{180/})