From 244cca3e75e72ef976a4b21cb0c368874024f19a Mon Sep 17 00:00:00 2001 From: bdm-oslandia Date: Fri, 30 Aug 2024 15:45:51 +0200 Subject: [PATCH 01/11] fix how framegraph dumps are output (remove qPrintable and qDebug) --- src/3d/qgsabstract3dengine.cpp | 7 +++---- src/3d/qgsframegraph.cpp | 6 +++--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/3d/qgsabstract3dengine.cpp b/src/3d/qgsabstract3dengine.cpp index 0e3ca3331609..318def3382af 100644 --- a/src/3d/qgsabstract3dengine.cpp +++ b/src/3d/qgsabstract3dengine.cpp @@ -17,6 +17,7 @@ #include "moc_qgsabstract3dengine.cpp" #include "qgsframegraph.h" +#include "qgslogger.h" #include #include @@ -62,10 +63,8 @@ void QgsAbstract3DEngine::dumpFrameGraphToConsole() const { if ( mFrameGraph ) { - qDebug() << "FrameGraph:\n" - << mFrameGraph->dumpFrameGraph(); - qDebug() << "SceneGraph:\n" - << mFrameGraph->dumpSceneGraph(); + QgsDebugMsgLevel( QString( "FrameGraph:\n%1" ).arg( mFrameGraph->dumpFrameGraph() ), 1 ); + QgsDebugMsgLevel( QString( "SceneGraph:\n%1" ).arg( mFrameGraph->dumpSceneGraph() ), 1 ); } } diff --git a/src/3d/qgsframegraph.cpp b/src/3d/qgsframegraph.cpp index f94ecbd9b502..4977f5d8fa09 100644 --- a/src/3d/qgsframegraph.cpp +++ b/src/3d/qgsframegraph.cpp @@ -19,6 +19,7 @@ #include "qgspostprocessingentity.h" #include "qgspreviewquad.h" #include "qgs3dutils.h" +#include "qgsfgutils.h" #include "qgsambientocclusionrenderentity.h" #include "qgsambientocclusionblurentity.h" @@ -49,7 +50,6 @@ typedef Qt3DCore::QGeometry Qt3DQGeometry; #include #include #include -#include "qgsfgutils.h" #include #include @@ -847,13 +847,13 @@ QString QgsFrameGraph::dumpFrameGraph() const context.lowestId = mMainCamera->id().id(); QStringList strList = QgsFgUtils::dumpFrameGraph( dynamic_cast( top ), context ); - return qPrintable( strList.join( "\n" ) ) + QString( "\n" ); + return strList.join( "\n" ) + QString( "\n" ); } QString QgsFrameGraph::dumpSceneGraph() const { QStringList strList = QgsFgUtils::dumpSceneGraph( mRootEntity, QgsFgUtils::FgDumpContext() ); - return qPrintable( strList.join( "\n" ) ) + QString( "\n" ); + return strList.join( "\n" ) + QString( "\n" ); } void QgsFrameGraph::setClearColor( const QColor &clearColor ) From 2313a19e01b83dce1e39749e6193577b71be6d83 Mon Sep 17 00:00:00 2001 From: bdm-oslandia Date: Mon, 22 Jul 2024 10:52:02 +0200 Subject: [PATCH 02/11] qgsframegraph: move framegraph files and dependencies to dedicated directory --- src/3d/CMakeLists.txt | 30 ++++++++++--------- .../qgsambientocclusionblurentity.cpp | 0 .../qgsambientocclusionblurentity.h | 0 .../qgsambientocclusionrenderentity.cpp | 0 .../qgsambientocclusionrenderentity.h | 0 src/3d/{ => framegraph}/qgsfgutils.cpp | 0 src/3d/{ => framegraph}/qgsfgutils.h | 0 src/3d/{ => framegraph}/qgsframegraph.cpp | 0 src/3d/{ => framegraph}/qgsframegraph.h | 0 .../qgspostprocessingentity.cpp | 0 .../qgspostprocessingentity.h | 0 src/3d/{ => framegraph}/qgspreviewquad.cpp | 0 src/3d/{ => framegraph}/qgspreviewquad.h | 0 src/3d/{ => framegraph}/qgsrenderpassquad.cpp | 0 src/3d/{ => framegraph}/qgsrenderpassquad.h | 0 src/3d/qgs3dmapscene.cpp | 2 +- src/3d/qgsabstract3dengine.cpp | 2 +- src/3d/qgsoffscreen3dengine.cpp | 2 +- src/3d/qgswindow3dengine.cpp | 2 +- src/app/3d/qgs3dmaptoolmeasureline.cpp | 3 +- tests/src/3d/testqgs3drendering.cpp | 2 +- 21 files changed, 23 insertions(+), 20 deletions(-) rename src/3d/{ => framegraph}/qgsambientocclusionblurentity.cpp (100%) rename src/3d/{ => framegraph}/qgsambientocclusionblurentity.h (100%) rename src/3d/{ => framegraph}/qgsambientocclusionrenderentity.cpp (100%) rename src/3d/{ => framegraph}/qgsambientocclusionrenderentity.h (100%) rename src/3d/{ => framegraph}/qgsfgutils.cpp (100%) rename src/3d/{ => framegraph}/qgsfgutils.h (100%) rename src/3d/{ => framegraph}/qgsframegraph.cpp (100%) rename src/3d/{ => framegraph}/qgsframegraph.h (100%) rename src/3d/{ => framegraph}/qgspostprocessingentity.cpp (100%) rename src/3d/{ => framegraph}/qgspostprocessingentity.h (100%) rename src/3d/{ => framegraph}/qgspreviewquad.cpp (100%) rename src/3d/{ => framegraph}/qgspreviewquad.h (100%) rename src/3d/{ => framegraph}/qgsrenderpassquad.cpp (100%) rename src/3d/{ => framegraph}/qgsrenderpassquad.h (100%) diff --git a/src/3d/CMakeLists.txt b/src/3d/CMakeLists.txt index f8a0583f4a38..1c5fa571a3f5 100644 --- a/src/3d/CMakeLists.txt +++ b/src/3d/CMakeLists.txt @@ -22,8 +22,6 @@ set(QGIS_3D_SRCS qgscameracontroller.cpp qgscamerapose.cpp qgsfeature3dhandler_p.cpp - qgsfgutils.cpp - qgsframegraph.cpp qgsgeotransform.cpp qgsgltf3dutils.cpp qgsimagetexture.cpp @@ -42,11 +40,6 @@ set(QGIS_3D_SRCS qgswindow3dengine.cpp qgsskyboxentity.cpp qgsskyboxsettings.cpp - qgspostprocessingentity.cpp - qgsrenderpassquad.cpp - qgsambientocclusionrenderentity.cpp - qgsambientocclusionblurentity.cpp - qgspreviewquad.cpp qgsshadowsettings.cpp qgscolorramptexture.cpp qgsrubberband3d.cpp @@ -83,6 +76,14 @@ set(QGIS_3D_SRCS processing/qgs3dalgorithms.cpp processing/qgsalgorithmtessellate.cpp + framegraph/qgsambientocclusionrenderentity.cpp + framegraph/qgsambientocclusionblurentity.cpp + framegraph/qgspostprocessingentity.cpp + framegraph/qgspreviewquad.cpp + framegraph/qgsrenderpassquad.cpp + framegraph/qgsframegraph.cpp + framegraph/qgsfgutils.cpp + symbols/qgsbillboardgeometry.cpp symbols/qgsline3dsymbol.cpp symbols/qgsline3dsymbol_p.cpp @@ -144,8 +145,6 @@ set(QGIS_3D_HDRS qgsabstractvectorlayer3drenderer.h qgscameracontroller.h qgscamerapose.h - qgsfgutils.h - qgsframegraph.h qgsgeotransform.h qgsgltf3dutils.h qgslayoutitem3dmap.h @@ -161,13 +160,8 @@ set(QGIS_3D_HDRS qgswindow3dengine.h qgsskyboxentity.h qgsskyboxsettings.h - qgspostprocessingentity.h - qgspreviewquad.h qgsshadowsettings.h qgspointcloudlayer3drenderer.h - qgsrenderpassquad.h - qgsambientocclusionrenderentity.h - qgsambientocclusionblurentity.h qgsambientocclusionsettings.h lights/qgsdirectionallightsettings.h @@ -187,6 +181,14 @@ set(QGIS_3D_HDRS materials/qgssimplelinematerialsettings.h materials/qgstexturematerial.h + framegraph/qgsambientocclusionrenderentity.h + framegraph/qgsambientocclusionblurentity.h + framegraph/qgsframegraph.h + framegraph/qgsfgutils.h + framegraph/qgspostprocessingentity.h + framegraph/qgspreviewquad.h + framegraph/qgsrenderpassquad.h + symbols/qgsbillboardgeometry.h symbols/qgsline3dsymbol.h symbols/qgsmesh3dsymbol.h diff --git a/src/3d/qgsambientocclusionblurentity.cpp b/src/3d/framegraph/qgsambientocclusionblurentity.cpp similarity index 100% rename from src/3d/qgsambientocclusionblurentity.cpp rename to src/3d/framegraph/qgsambientocclusionblurentity.cpp diff --git a/src/3d/qgsambientocclusionblurentity.h b/src/3d/framegraph/qgsambientocclusionblurentity.h similarity index 100% rename from src/3d/qgsambientocclusionblurentity.h rename to src/3d/framegraph/qgsambientocclusionblurentity.h diff --git a/src/3d/qgsambientocclusionrenderentity.cpp b/src/3d/framegraph/qgsambientocclusionrenderentity.cpp similarity index 100% rename from src/3d/qgsambientocclusionrenderentity.cpp rename to src/3d/framegraph/qgsambientocclusionrenderentity.cpp diff --git a/src/3d/qgsambientocclusionrenderentity.h b/src/3d/framegraph/qgsambientocclusionrenderentity.h similarity index 100% rename from src/3d/qgsambientocclusionrenderentity.h rename to src/3d/framegraph/qgsambientocclusionrenderentity.h diff --git a/src/3d/qgsfgutils.cpp b/src/3d/framegraph/qgsfgutils.cpp similarity index 100% rename from src/3d/qgsfgutils.cpp rename to src/3d/framegraph/qgsfgutils.cpp diff --git a/src/3d/qgsfgutils.h b/src/3d/framegraph/qgsfgutils.h similarity index 100% rename from src/3d/qgsfgutils.h rename to src/3d/framegraph/qgsfgutils.h diff --git a/src/3d/qgsframegraph.cpp b/src/3d/framegraph/qgsframegraph.cpp similarity index 100% rename from src/3d/qgsframegraph.cpp rename to src/3d/framegraph/qgsframegraph.cpp diff --git a/src/3d/qgsframegraph.h b/src/3d/framegraph/qgsframegraph.h similarity index 100% rename from src/3d/qgsframegraph.h rename to src/3d/framegraph/qgsframegraph.h diff --git a/src/3d/qgspostprocessingentity.cpp b/src/3d/framegraph/qgspostprocessingentity.cpp similarity index 100% rename from src/3d/qgspostprocessingentity.cpp rename to src/3d/framegraph/qgspostprocessingentity.cpp diff --git a/src/3d/qgspostprocessingentity.h b/src/3d/framegraph/qgspostprocessingentity.h similarity index 100% rename from src/3d/qgspostprocessingentity.h rename to src/3d/framegraph/qgspostprocessingentity.h diff --git a/src/3d/qgspreviewquad.cpp b/src/3d/framegraph/qgspreviewquad.cpp similarity index 100% rename from src/3d/qgspreviewquad.cpp rename to src/3d/framegraph/qgspreviewquad.cpp diff --git a/src/3d/qgspreviewquad.h b/src/3d/framegraph/qgspreviewquad.h similarity index 100% rename from src/3d/qgspreviewquad.h rename to src/3d/framegraph/qgspreviewquad.h diff --git a/src/3d/qgsrenderpassquad.cpp b/src/3d/framegraph/qgsrenderpassquad.cpp similarity index 100% rename from src/3d/qgsrenderpassquad.cpp rename to src/3d/framegraph/qgsrenderpassquad.cpp diff --git a/src/3d/qgsrenderpassquad.h b/src/3d/framegraph/qgsrenderpassquad.h similarity index 100% rename from src/3d/qgsrenderpassquad.h rename to src/3d/framegraph/qgsrenderpassquad.h diff --git a/src/3d/qgs3dmapscene.cpp b/src/3d/qgs3dmapscene.cpp index d897ba452728..a1ed06339495 100644 --- a/src/3d/qgs3dmapscene.cpp +++ b/src/3d/qgs3dmapscene.cpp @@ -75,7 +75,7 @@ #include "qgs3dsceneexporter.h" #include "qgs3dmapexportsettings.h" #include "qgsmessageoutput.h" -#include "qgsframegraph.h" +#include "framegraph/qgsframegraph.h" #include "qgsabstractterrainsettings.h" #include "qgsskyboxentity.h" diff --git a/src/3d/qgsabstract3dengine.cpp b/src/3d/qgsabstract3dengine.cpp index 318def3382af..49ae6884e499 100644 --- a/src/3d/qgsabstract3dengine.cpp +++ b/src/3d/qgsabstract3dengine.cpp @@ -16,7 +16,7 @@ #include "qgsabstract3dengine.h" #include "moc_qgsabstract3dengine.cpp" -#include "qgsframegraph.h" +#include "framegraph/qgsframegraph.h" #include "qgslogger.h" #include diff --git a/src/3d/qgsoffscreen3dengine.cpp b/src/3d/qgsoffscreen3dengine.cpp index 65a14f62c426..980424b39cae 100644 --- a/src/3d/qgsoffscreen3dengine.cpp +++ b/src/3d/qgsoffscreen3dengine.cpp @@ -16,7 +16,7 @@ #include "qgsoffscreen3dengine.h" #include "moc_qgsoffscreen3dengine.cpp" -#include "qgsframegraph.h" +#include "framegraph/qgsframegraph.h" #include #include diff --git a/src/3d/qgswindow3dengine.cpp b/src/3d/qgswindow3dengine.cpp index 3a56dfd4262c..161adec1b04e 100644 --- a/src/3d/qgswindow3dengine.cpp +++ b/src/3d/qgswindow3dengine.cpp @@ -20,7 +20,7 @@ #include #include "qgs3dmapcanvas.h" -#include "qgsframegraph.h" +#include "framegraph/qgsframegraph.h" QgsWindow3DEngine::QgsWindow3DEngine( Qgs3DMapCanvas *parent ) diff --git a/src/app/3d/qgs3dmaptoolmeasureline.cpp b/src/app/3d/qgs3dmaptoolmeasureline.cpp index 615add18cee3..d06c54c1c126 100644 --- a/src/app/3d/qgs3dmaptoolmeasureline.cpp +++ b/src/app/3d/qgs3dmaptoolmeasureline.cpp @@ -25,9 +25,10 @@ #include "qgs3dmeasuredialog.h" #include "qgsrubberband3d.h" #include "qgswindow3dengine.h" -#include "qgsframegraph.h" +#include "framegraph/qgsframegraph.h" #include "qgsabstractterrainsettings.h" + Qgs3DMapToolMeasureLine::Qgs3DMapToolMeasureLine( Qgs3DMapCanvas *canvas ) : Qgs3DMapTool( canvas ) { diff --git a/tests/src/3d/testqgs3drendering.cpp b/tests/src/3d/testqgs3drendering.cpp index 049e115752e2..60ca6b9835e5 100644 --- a/tests/src/3d/testqgs3drendering.cpp +++ b/tests/src/3d/testqgs3drendering.cpp @@ -36,7 +36,7 @@ #include "qgsflatterraingenerator.h" #include "qgsline3dsymbol.h" #include "qgsoffscreen3dengine.h" -#include "qgsframegraph.h" +#include "framegraph/qgsframegraph.h" #include "qgspolygon3dsymbol.h" #include "qgsrulebased3drenderer.h" #include "qgsvectorlayer3drenderer.h" From 4584950845b86b70f6a09dc89e8a029d0a1eca00 Mon Sep 17 00:00:00 2001 From: bdm-oslandia Date: Mon, 2 Sep 2024 15:47:06 +0200 Subject: [PATCH 03/11] add new framegraph directory to doc/CMakeLists.txt --- doc/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index d9572f277a82..1bd8bb14018c 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -148,6 +148,7 @@ if(WITH_APIDOC) ${CMAKE_SOURCE_DIR}/src/analysis/vector/geometry_checker ${CMAKE_SOURCE_DIR}/src/3d ${CMAKE_SOURCE_DIR}/src/3d/chunks + ${CMAKE_SOURCE_DIR}/src/3d/framegraph ${CMAKE_SOURCE_DIR}/src/3d/lights ${CMAKE_SOURCE_DIR}/src/3d/materials ${CMAKE_SOURCE_DIR}/src/3d/processing From 9e2ca303abad50390087dbcefdeeda8f7b89d573 Mon Sep 17 00:00:00 2001 From: bdm-oslandia Date: Mon, 2 Sep 2024 15:50:46 +0200 Subject: [PATCH 04/11] fix(qgsframegraphutils): expand qgsfgutils to qgsframegraphutils rename QgsFramegraphUtils to QgsFrameGraphUtils --- src/3d/CMakeLists.txt | 4 +-- src/3d/framegraph/qgsframegraph.cpp | 10 ++++--- ...{qgsfgutils.cpp => qgsframegraphutils.cpp} | 26 +++++++++---------- .../{qgsfgutils.h => qgsframegraphutils.h} | 10 +++---- 4 files changed, 26 insertions(+), 24 deletions(-) rename src/3d/framegraph/{qgsfgutils.cpp => qgsframegraphutils.cpp} (90%) rename src/3d/framegraph/{qgsfgutils.h => qgsframegraphutils.h} (95%) diff --git a/src/3d/CMakeLists.txt b/src/3d/CMakeLists.txt index 1c5fa571a3f5..deae6fbba4b5 100644 --- a/src/3d/CMakeLists.txt +++ b/src/3d/CMakeLists.txt @@ -82,7 +82,7 @@ set(QGIS_3D_SRCS framegraph/qgspreviewquad.cpp framegraph/qgsrenderpassquad.cpp framegraph/qgsframegraph.cpp - framegraph/qgsfgutils.cpp + framegraph/qgsframegraphutils.cpp symbols/qgsbillboardgeometry.cpp symbols/qgsline3dsymbol.cpp @@ -184,7 +184,7 @@ set(QGIS_3D_HDRS framegraph/qgsambientocclusionrenderentity.h framegraph/qgsambientocclusionblurentity.h framegraph/qgsframegraph.h - framegraph/qgsfgutils.h + framegraph/qgsframegraphutils.h framegraph/qgspostprocessingentity.h framegraph/qgspreviewquad.h framegraph/qgsrenderpassquad.h diff --git a/src/3d/framegraph/qgsframegraph.cpp b/src/3d/framegraph/qgsframegraph.cpp index 4977f5d8fa09..738306c7ad9b 100644 --- a/src/3d/framegraph/qgsframegraph.cpp +++ b/src/3d/framegraph/qgsframegraph.cpp @@ -19,7 +19,9 @@ #include "qgspostprocessingentity.h" #include "qgspreviewquad.h" #include "qgs3dutils.h" -#include "qgsfgutils.h" +#include "qgsframegraphutils.h" +#include "qgsabstractrenderview.h" + #include "qgsambientocclusionrenderentity.h" #include "qgsambientocclusionblurentity.h" @@ -843,16 +845,16 @@ QString QgsFrameGraph::dumpFrameGraph() const while ( top->parent() && dynamic_cast( top->parent() ) ) top = top->parent(); - QgsFgUtils::FgDumpContext context; + QgsFrameGraphUtils::FgDumpContext context; context.lowestId = mMainCamera->id().id(); - QStringList strList = QgsFgUtils::dumpFrameGraph( dynamic_cast( top ), context ); + QStringList strList = QgsFrameGraphUtils::dumpFrameGraph( dynamic_cast( top ), context ); return strList.join( "\n" ) + QString( "\n" ); } QString QgsFrameGraph::dumpSceneGraph() const { - QStringList strList = QgsFgUtils::dumpSceneGraph( mRootEntity, QgsFgUtils::FgDumpContext() ); + QStringList strList = QgsFrameGraphUtils::dumpSceneGraph( mRootEntity, QgsFrameGraphUtils::FgDumpContext() ); return strList.join( "\n" ) + QString( "\n" ); } diff --git a/src/3d/framegraph/qgsfgutils.cpp b/src/3d/framegraph/qgsframegraphutils.cpp similarity index 90% rename from src/3d/framegraph/qgsfgutils.cpp rename to src/3d/framegraph/qgsframegraphutils.cpp index 6552edc56356..ad2ef7ba9d34 100644 --- a/src/3d/framegraph/qgsfgutils.cpp +++ b/src/3d/framegraph/qgsframegraphutils.cpp @@ -13,7 +13,7 @@ * * ***************************************************************************/ -#include "qgsfgutils.h" +#include "qgsframegraphutils.h" #include #include @@ -31,30 +31,30 @@ #include #include -QStringList QgsFgUtils::dumpSceneGraph( const Qt3DCore::QNode *node, FgDumpContext context ) +QStringList QgsFrameGraphUtils::dumpSceneGraph( const Qt3DCore::QNode *node, FgDumpContext context ) { return dumpSG( context, node ); } -QStringList QgsFgUtils::dumpFrameGraph( const Qt3DCore::QNode *node, FgDumpContext context ) +QStringList QgsFrameGraphUtils::dumpFrameGraph( const Qt3DCore::QNode *node, FgDumpContext context ) { return dumpFG( context, node ); } -QString QgsFgUtils::formatIdName( FgDumpContext context, quint64 id, const QString &name ) +QString QgsFrameGraphUtils::formatIdName( FgDumpContext context, quint64 id, const QString &name ) { QString fixedName = name.isEmpty() ? QLatin1String( "" ) : name; return QLatin1String( "{%1/%2}" ).arg( QString::number( id - context.lowestId ) ).arg( fixedName ); } -QString QgsFgUtils::formatIdName( FgDumpContext context, const Qt3DRender::QAbstractTexture *texture ) +QString QgsFrameGraphUtils::formatIdName( FgDumpContext context, const Qt3DRender::QAbstractTexture *texture ) { QString fixedName = texture->objectName().isEmpty() ? QLatin1String( "" ) : texture->objectName(); return QLatin1String( "{%1[%2]/%3" ) .arg( QString::number( texture->id().id() - context.lowestId ), QString( QMetaEnum::fromType().valueToKey( texture->format() ) ), fixedName ); } -QString QgsFgUtils::formatNode( FgDumpContext context, const Qt3DCore::QNode *node ) +QString QgsFrameGraphUtils::formatNode( FgDumpContext context, const Qt3DCore::QNode *node ) { QString res = QLatin1String( "(%1%2)" ) .arg( QLatin1String( node->metaObject()->className() ) ) @@ -64,12 +64,12 @@ QString QgsFgUtils::formatNode( FgDumpContext context, const Qt3DCore::QNode *no return res; } -QString QgsFgUtils::formatList( const QStringList &lst ) +QString QgsFrameGraphUtils::formatList( const QStringList &lst ) { return QString( QLatin1String( "[ %1 ]" ) ).arg( lst.join( QLatin1String( ", " ) ) ); } -QString QgsFgUtils::formatLongList( const QStringList &lst, int level ) +QString QgsFrameGraphUtils::formatLongList( const QStringList &lst, int level ) { QString out = formatList( lst ); if ( out.size() < 200 ) @@ -85,14 +85,14 @@ QString QgsFgUtils::formatLongList( const QStringList &lst, int level ) return out + end.rightJustified( end.length() + ( 1 + level ) * 2, ' ' ); } -QString QgsFgUtils::formatField( const QString &name, const QString &value ) +QString QgsFrameGraphUtils::formatField( const QString &name, const QString &value ) { if ( value == "" ) return QString( QLatin1String( "(%1)" ) ).arg( name ); return QString( QLatin1String( "(%1:%2)" ) ).arg( name, value ); } -QString QgsFgUtils::dumpSGEntity( FgDumpContext context, const Qt3DCore::QEntity *node, int level ) +QString QgsFrameGraphUtils::dumpSGEntity( FgDumpContext context, const Qt3DCore::QEntity *node, int level ) { auto extractTextureParam = []( FgDumpContext context, const QVector ¶ms, QStringList &fl ) { for ( const auto *param : params ) @@ -158,7 +158,7 @@ QString QgsFgUtils::dumpSGEntity( FgDumpContext context, const Qt3DCore::QEntity return res; } -QStringList QgsFgUtils::dumpSG( FgDumpContext context, const Qt3DCore::QNode *node, int level ) +QStringList QgsFrameGraphUtils::dumpSG( FgDumpContext context, const Qt3DCore::QNode *node, int level ) { QStringList reply; const auto *entity = qobject_cast( node ); @@ -176,7 +176,7 @@ QStringList QgsFgUtils::dumpSG( FgDumpContext context, const Qt3DCore::QNode *no return reply; } -QString QgsFgUtils::dumpFGNode( FgDumpContext context, const Qt3DRender::QFrameGraphNode *node ) +QString QgsFrameGraphUtils::dumpFGNode( FgDumpContext context, const Qt3DRender::QFrameGraphNode *node ) { QString res = formatNode( context, node ); @@ -285,7 +285,7 @@ QString QgsFgUtils::dumpFGNode( FgDumpContext context, const Qt3DRender::QFrameG return res; } -QStringList QgsFgUtils::dumpFG( FgDumpContext context, const Qt3DCore::QNode *node, int level ) +QStringList QgsFrameGraphUtils::dumpFG( FgDumpContext context, const Qt3DCore::QNode *node, int level ) { QStringList reply; diff --git a/src/3d/framegraph/qgsfgutils.h b/src/3d/framegraph/qgsframegraphutils.h similarity index 95% rename from src/3d/framegraph/qgsfgutils.h rename to src/3d/framegraph/qgsframegraphutils.h index 20c19f8f75a6..97a95965f484 100644 --- a/src/3d/framegraph/qgsfgutils.h +++ b/src/3d/framegraph/qgsframegraphutils.h @@ -1,5 +1,5 @@ /*************************************************************************** - qgsfgutils.h + qgsframegraphutils.h -------------------------------------- Date : August 2024 Copyright : (C) 2024 by Mike Krus / Benoit De Mezzo @@ -13,8 +13,8 @@ * * ***************************************************************************/ -#ifndef QGSFG_UTILS_H -#define QGSFG_UTILS_H +#ifndef QGSFRAMEGRAPH_UTILS_H +#define QGSFRAMEGRAPH_UTILS_H #include #include @@ -44,7 +44,7 @@ * \brief Util class to dump Qt3D framegraph or scenegraph. * \since QGIS 3.40 */ -class QgsFgUtils +class QgsFrameGraphUtils { public: struct FgDumpContext @@ -80,4 +80,4 @@ class QgsFgUtils static QStringList dumpFG( FgDumpContext context, const Qt3DCore::QNode *n, int level = 0 ); }; -#endif // QGSFG_UTILS_H +#endif // QGSFRAMEGRAPH_UTILS_H From 299a41f127836f86348454382c48250daeadba91 Mon Sep 17 00:00:00 2001 From: bdm-oslandia Date: Wed, 18 May 2022 08:01:40 +0200 Subject: [PATCH 05/11] feat(3d/renderview): add abstractrenderview Co-authored-By: Mike Krus --- src/3d/CMakeLists.txt | 3 + src/3d/framegraph/qgsabstractrenderview.cpp | 55 ++++++++++++++++ src/3d/framegraph/qgsabstractrenderview.h | 72 +++++++++++++++++++++ src/3d/framegraph/qgsframegraph.cpp | 55 +++++++++++++++- src/3d/framegraph/qgsframegraph.h | 26 ++++++++ 5 files changed, 209 insertions(+), 2 deletions(-) create mode 100644 src/3d/framegraph/qgsabstractrenderview.cpp create mode 100644 src/3d/framegraph/qgsabstractrenderview.h diff --git a/src/3d/CMakeLists.txt b/src/3d/CMakeLists.txt index deae6fbba4b5..59990ae6b9df 100644 --- a/src/3d/CMakeLists.txt +++ b/src/3d/CMakeLists.txt @@ -76,6 +76,7 @@ set(QGIS_3D_SRCS processing/qgs3dalgorithms.cpp processing/qgsalgorithmtessellate.cpp + framegraph/qgsabstractrenderview.cpp framegraph/qgsambientocclusionrenderentity.cpp framegraph/qgsambientocclusionblurentity.cpp framegraph/qgspostprocessingentity.cpp @@ -181,6 +182,7 @@ set(QGIS_3D_HDRS materials/qgssimplelinematerialsettings.h materials/qgstexturematerial.h + framegraph/qgsabstractrenderview.h framegraph/qgsambientocclusionrenderentity.h framegraph/qgsambientocclusionblurentity.h framegraph/qgsframegraph.h @@ -277,6 +279,7 @@ endif() target_include_directories(qgis_3d PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/chunks + ${CMAKE_CURRENT_SOURCE_DIR}/framegraph ${CMAKE_CURRENT_SOURCE_DIR}/lights ${CMAKE_CURRENT_SOURCE_DIR}/materials ${CMAKE_CURRENT_SOURCE_DIR}/mesh diff --git a/src/3d/framegraph/qgsabstractrenderview.cpp b/src/3d/framegraph/qgsabstractrenderview.cpp new file mode 100644 index 000000000000..b2548df847a4 --- /dev/null +++ b/src/3d/framegraph/qgsabstractrenderview.cpp @@ -0,0 +1,55 @@ +/*************************************************************************** + qgsabstractrenderview.cpp + -------------------------------------- + Date : June 2024 + Copyright : (C) 2024 by Benoit De Mezzo + 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 "qgsabstractrenderview.h" +#include "moc_qgsabstractrenderview.cpp" +#include +#include + +QgsAbstractRenderView::QgsAbstractRenderView( QObject *parent, const QString &viewName ) + : QObject( parent ) +{ + setObjectName( viewName ); + // in order to avoid a render pass on the render view, we add a NoDraw node + // which is disabled when the enabler is enabled, and vice versa + using namespace Qt3DRender; + mRoot = new QNoDraw; + mRoot->setEnabled( false ); + mRoot->setObjectName( viewName + "::NoDraw" ); + mRendererEnabler = new QSubtreeEnabler( mRoot ); + mRendererEnabler->setEnablement( QSubtreeEnabler::Persistent ); + mRendererEnabler->setObjectName( viewName + "::SubtreeEnabler" ); +} + +void QgsAbstractRenderView::updateWindowResize( int, int ) +{ + // noop +} + +Qt3DRender::QFrameGraphNode *QgsAbstractRenderView::topGraphNode() const +{ + return mRoot; +} + +void QgsAbstractRenderView::setEnabled( bool enable ) +{ + mRoot->setEnabled( !enable ); + mRendererEnabler->setEnabled( enable ); +} + +bool QgsAbstractRenderView::isEnabled() const +{ + return !mRoot->isEnabled() && mRendererEnabler->isEnabled(); +} diff --git a/src/3d/framegraph/qgsabstractrenderview.h b/src/3d/framegraph/qgsabstractrenderview.h new file mode 100644 index 000000000000..a67fc5a54d36 --- /dev/null +++ b/src/3d/framegraph/qgsabstractrenderview.h @@ -0,0 +1,72 @@ +/*************************************************************************** + qgsabstractrenderview.h + -------------------------------------- + Date : June 2024 + Copyright : (C) 2024 by Benoit De Mezzo + 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 QGSABSTRACTRENDERVIEW_H +#define QGSABSTRACTRENDERVIEW_H + +#include "qgis_3d.h" + +#include + +#define SIP_NO_FILE + +namespace Qt3DRender +{ + class QFrameGraphNode; + class QSubtreeEnabler; +} // namespace Qt3DRender + +/** + * \ingroup 3d + * \brief Base class for 3D render view + * + * An instance of QgsAbstractRenderView is a branch (ie. a render pass, ie. a render view) of the framegraph. + * It may contains multiple render passes. + * + * Will be used with QgsFrameGraph::registerRenderView. + * + * \note Not available in Python bindings + * \since QGIS 3.40 + */ +class _3D_EXPORT QgsAbstractRenderView : public QObject +{ + Q_OBJECT + public: + /** + * Constructor for QgsAbstractRenderView with the specified \a parent object. + */ + QgsAbstractRenderView( QObject *parent, const QString &viewName ); + + /** + * Called when 3D window is resized. Render views may update their textures accordingly. + * Default implementation does nothing. + */ + virtual void updateWindowResize( int width, int height ); + + //! Returns the top node of this render view branch. Will be used to register the render view. + Qt3DRender::QFrameGraphNode *topGraphNode() const; + + //! Enable or disable via \a enable the render view sub tree + virtual void setEnabled( bool enable ); + + //! Returns true if render view is enabled + virtual bool isEnabled() const; + + protected: + Qt3DRender::QFrameGraphNode *mRoot = nullptr; + Qt3DRender::QSubtreeEnabler *mRendererEnabler = nullptr; +}; + +#endif // QGSABSTRACTRENDERVIEW_H diff --git a/src/3d/framegraph/qgsframegraph.cpp b/src/3d/framegraph/qgsframegraph.cpp index 738306c7ad9b..bf813ec22485 100644 --- a/src/3d/framegraph/qgsframegraph.cpp +++ b/src/3d/framegraph/qgsframegraph.cpp @@ -54,6 +54,8 @@ typedef Qt3DCore::QGeometry Qt3DQGeometry; #include #include #include +#include "qgsabstractrenderview.h" + Qt3DRender::QFrameGraphNode *QgsFrameGraph::constructForwardRenderPass() { @@ -744,6 +746,51 @@ QgsFrameGraph::QgsFrameGraph( QSurface *surface, QSize s, Qt3DRender::QCamera *m mDepthRenderQuad->setParent( mRootEntity ); } +void QgsFrameGraph::unregisterRenderView( const QString &name ) +{ + QgsAbstractRenderView *renderView = mRenderViewMap.find( name ).value().get(); + if ( renderView ) + { + renderView->topGraphNode()->setParent( ( QNode * )nullptr ); + mRenderViewMap.remove( name ); + } +} + +bool QgsFrameGraph::registerRenderView( QgsAbstractRenderView *renderView, const QString &name ) +{ + bool out; + if ( mRenderViewMap.find( name ) == mRenderViewMap.end() ) + { + mRenderViewMap.insert( name, std::shared_ptr( renderView ) ); + QgsAbstractRenderView *rv = mRenderViewMap.find( name ).value().get(); + rv->topGraphNode()->setParent( mMainViewPort ); + rv->updateWindowResize( mSize.width(), mSize.height() ); + out = true; + } + else + out = false; + + return out; +} + +void QgsFrameGraph::setRenderViewEnabled( const QString &name, bool enable ) +{ + if ( mRenderViewMap [name] != nullptr ) + { + mRenderViewMap [name]->setEnabled( enable ); + } +} + +QgsAbstractRenderView *QgsFrameGraph::renderView( const QString &name ) +{ + return mRenderViewMap[name].get(); +} + +bool QgsFrameGraph::isRenderViewEnabled( const QString &name ) +{ + return mRenderViewMap [name] != nullptr && mRenderViewMap [name]->isEnabled(); +} + QgsPreviewQuad *QgsFrameGraph::addTexturePreviewOverlay( Qt3DRender::QTexture2D *texture, const QPointF ¢erTexCoords, const QSizeF &sizeTexCoords, QVector additionalShaderParameters ) { QgsPreviewQuad *previewQuad = new QgsPreviewQuad( texture, centerTexCoords, sizeTexCoords, additionalShaderParameters ); @@ -982,8 +1029,12 @@ void QgsFrameGraph::setupDepthMapDebugging( bool enabled, Qt::Corner corner, dou void QgsFrameGraph::setSize( QSize s ) { mSize = s; - mForwardColorTexture->setSize( mSize.width(), mSize.height() ); - mForwardDepthTexture->setSize( mSize.width(), mSize.height() ); + for ( QMap>::iterator it = mRenderViewMap.begin(); it != mRenderViewMap.end(); ++it ) + { + QgsAbstractRenderView *rv = it.value().get(); + rv->updateWindowResize( mSize.width(), mSize.height() ); + } + mRenderCaptureColorTexture->setSize( mSize.width(), mSize.height() ); mRenderCaptureDepthTexture->setSize( mSize.width(), mSize.height() ); mDepthRenderCaptureDepthTexture->setSize( mSize.width(), mSize.height() ); diff --git a/src/3d/framegraph/qgsframegraph.h b/src/3d/framegraph/qgsframegraph.h index c1b0a91e8b96..a856f9f2f559 100644 --- a/src/3d/framegraph/qgsframegraph.h +++ b/src/3d/framegraph/qgsframegraph.h @@ -45,6 +45,7 @@ class QgsPostprocessingEntity; class QgsAmbientOcclusionRenderEntity; class QgsPreviewQuad; class QgsAmbientOcclusionBlurEntity; +class QgsAbstractRenderView; #define SIP_NO_FILE @@ -239,6 +240,28 @@ class QgsFrameGraph : public Qt3DCore::QEntity */ void removeClipPlanes(); + /** + * Registers a new the render view \a renderView with name \a name + * + * Will take owner ship of the renderView + */ + bool registerRenderView( QgsAbstractRenderView *renderView, const QString &name ); + + //! Unregisters the render view named \a name, if any + void unregisterRenderView( const QString &name ); + + //! Enables or disables the render view named \a name according to \a enable + void setRenderViewEnabled( const QString &name, bool enable ); + + //! Returns true if a render view is found and 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 ); + private: Qt3DRender::QRenderSurfaceSelector *mRenderSurfaceSelector = nullptr; Qt3DRender::QViewport *mMainViewPort = nullptr; @@ -369,6 +392,9 @@ class QgsFrameGraph : public Qt3DCore::QEntity bool mRenderCaptureEnabled = false; + // holds renderviews according to their name + QMap> mRenderViewMap; + Q_DISABLE_COPY( QgsFrameGraph ) }; From c62157708d941fb0510bcb299329048078cffa66 Mon Sep 17 00:00:00 2001 From: bdm-oslandia Date: Mon, 15 Jul 2024 15:59:23 +0200 Subject: [PATCH 06/11] feat(3d/renderView): extract 3dAxis viewport to dedicated renderview class feat(3daxis): move camera creations into render view fix(qgs3daxissettings): add checks in readXml to avoid disabled axis view When the project is saved in an old version, minViewportRatio or maxViewportRatio can have bad saved data (ie. 0 values) leading to always disable axis view. --- src/3d/CMakeLists.txt | 2 + src/3d/framegraph/qgs3daxisrenderview.cpp | 248 ++++++++++++++++++++++ src/3d/framegraph/qgs3daxisrenderview.h | 112 ++++++++++ src/3d/framegraph/qgsframegraph.cpp | 9 +- src/3d/framegraph/qgsframegraph.h | 2 + src/3d/qgs3daxis.cpp | 229 +++++--------------- src/3d/qgs3daxis.h | 16 +- src/3d/qgs3daxissettings.cpp | 16 +- src/3d/qgs3daxissettings.h | 2 +- 9 files changed, 438 insertions(+), 198 deletions(-) create mode 100644 src/3d/framegraph/qgs3daxisrenderview.cpp create mode 100644 src/3d/framegraph/qgs3daxisrenderview.h diff --git a/src/3d/CMakeLists.txt b/src/3d/CMakeLists.txt index 59990ae6b9df..6ce583c56603 100644 --- a/src/3d/CMakeLists.txt +++ b/src/3d/CMakeLists.txt @@ -77,6 +77,7 @@ set(QGIS_3D_SRCS processing/qgsalgorithmtessellate.cpp framegraph/qgsabstractrenderview.cpp + framegraph/qgs3daxisrenderview.cpp framegraph/qgsambientocclusionrenderentity.cpp framegraph/qgsambientocclusionblurentity.cpp framegraph/qgspostprocessingentity.cpp @@ -183,6 +184,7 @@ set(QGIS_3D_HDRS materials/qgstexturematerial.h framegraph/qgsabstractrenderview.h + framegraph/qgs3daxisrenderview.h framegraph/qgsambientocclusionrenderentity.h framegraph/qgsambientocclusionblurentity.h framegraph/qgsframegraph.h diff --git a/src/3d/framegraph/qgs3daxisrenderview.cpp b/src/3d/framegraph/qgs3daxisrenderview.cpp new file mode 100644 index 000000000000..8b77a1abaed2 --- /dev/null +++ b/src/3d/framegraph/qgs3daxisrenderview.cpp @@ -0,0 +1,248 @@ +/*************************************************************************** + qgs3daxisrenderview.cpp + -------------------------------------- + Date : June 2024 + Copyright : (C) 2024 by Benoit De Mezzo + 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 "qgs3daxisrenderview.h" +#include "moc_qgs3daxisrenderview.cpp" + +#include "qgsframegraph.h" +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 ) +#include +typedef Qt3DRender::QBuffer Qt3DQBuffer; +#else +#include +typedef Qt3DCore::QBuffer Qt3DQBuffer; +#endif +#include + +#include "qgsmapsettings.h" +#include "qgs3dmapsettings.h" +#include "qgs3dmapcanvas.h" +#include "qgscameracontroller.h" + +Qgs3DAxisRenderView::Qgs3DAxisRenderView( QObject *parent, const QString &viewName, Qgs3DMapCanvas *canvas, // + QgsCameraController *cameraCtrl, Qgs3DMapSettings *settings ) + : QgsAbstractRenderView( parent, viewName ) + , mCanvas( canvas ) + , mMapSettings( settings ) +{ + mViewport = new Qt3DRender::QViewport( mRendererEnabler ); + mViewport->setObjectName( objectName() + "::Viewport" ); + + mObjectLayer = new Qt3DRender::QLayer; + mObjectLayer->setObjectName( objectName() + "::ObjectLayer" ); + mObjectLayer->setRecursive( true ); + + mLabelLayer = new Qt3DRender::QLayer; + mLabelLayer->setObjectName( objectName() + "::LabelLayer" ); + mLabelLayer->setRecursive( true ); + + // render pass for the object (axis or cube) + Qt3DRender::QLayerFilter *objectFilter = new Qt3DRender::QLayerFilter( mViewport ); + objectFilter->addLayer( mObjectLayer ); + + mObjectCamera = new Qt3DRender::QCamera; + mObjectCamera->setObjectName( objectName() + "::ObjectCamera" ); + mObjectCamera->setProjectionType( cameraCtrl->camera()->projectionType() ); + mObjectCamera->lens()->setFieldOfView( cameraCtrl->camera()->lens()->fieldOfView() * 0.5f ); + + Qt3DRender::QCameraSelector *cameraSelector = new Qt3DRender::QCameraSelector( objectFilter ); + cameraSelector->setCamera( mObjectCamera ); + + // This ensures to have the label (Text2DEntity) rendered after the other objects and therefore + // avoid any transparency issue on the label. + Qt3DRender::QSortPolicy *objectSortPolicy = new Qt3DRender::QSortPolicy( cameraSelector ); + QVector objectSortTypes = QVector(); + objectSortTypes << Qt3DRender::QSortPolicy::BackToFront; + objectSortPolicy->setSortTypes( objectSortTypes ); + + Qt3DRender::QClearBuffers *objectClearBuffers = new Qt3DRender::QClearBuffers( objectSortPolicy ); + objectClearBuffers->setBuffers( Qt3DRender::QClearBuffers::DepthBuffer ); + + // render pass for the axis label + // mTwoDLabelceneEntity->addComponent( twoDLayer ); + + Qt3DRender::QLayerFilter *labelFilter = new Qt3DRender::QLayerFilter( mViewport ); + labelFilter->addLayer( mLabelLayer ); + + mLabelCamera = new Qt3DRender::QCamera; + mLabelCamera->setObjectName( objectName() + "::LabelCamera" ); + mLabelCamera->setProjectionType( Qt3DRender::QCameraLens::ProjectionType::OrthographicProjection ); + + Qt3DRender::QCameraSelector *labelCameraSelector = new Qt3DRender::QCameraSelector( labelFilter ); + labelCameraSelector->setCamera( mLabelCamera ); + + // this ensures to have the label (Text2DEntity) rendered after the other objects and therefore + // avoid any transparency issue on the label. + Qt3DRender::QSortPolicy *labelSortPolicy = new Qt3DRender::QSortPolicy( labelCameraSelector ); + QVector labelSortTypes = QVector(); + labelSortTypes << Qt3DRender::QSortPolicy::BackToFront; + labelSortPolicy->setSortTypes( labelSortTypes ); + + Qt3DRender::QClearBuffers *clearBuffers = new Qt3DRender::QClearBuffers( labelSortPolicy ); + clearBuffers->setBuffers( Qt3DRender::QClearBuffers::DepthBuffer ); + + // update viewport size + onViewportSizeUpdate(); +} + +Qt3DRender::QViewport *Qgs3DAxisRenderView::viewport() const +{ + return mViewport; +} + +Qt3DRender::QLayer *Qgs3DAxisRenderView::objectLayer() const +{ + return mObjectLayer; +} + +Qt3DRender::QLayer *Qgs3DAxisRenderView::labelLayer() const +{ + return mLabelLayer; +} + +Qt3DRender::QCamera *Qgs3DAxisRenderView::objectCamera() const +{ + return mObjectCamera; +} + +Qt3DRender::QCamera *Qgs3DAxisRenderView::labelCamera() const +{ + return mLabelCamera; +} + +void Qgs3DAxisRenderView::updateWindowResize( int width, int height ) +{ + onViewportSizeUpdate( width, height ); +} + + +void Qgs3DAxisRenderView::onViewportSizeUpdate( int width, int height ) +{ + Qgs3DAxisSettings settings = mMapSettings->get3DAxisSettings(); + + double windowWidth = static_cast( width ); + double windowHeight = static_cast( height ); + + if ( 2 <= QgsLogger::debugLevel() ) + { + QgsMapSettings set; + QgsDebugMsgLevel( QString( "onViewportSizeUpdate window w/h: %1px / %2px" ).arg( windowWidth ).arg( windowHeight ), 2 ); + QgsDebugMsgLevel( QString( "onViewportSizeUpdate window physicalDpi %1 (%2, %3)" ).arg( mCanvas->screen()->physicalDotsPerInch() ).arg( mCanvas->screen()->physicalDotsPerInchX() ).arg( mCanvas->screen()->physicalDotsPerInchY() ), 2 ); + QgsDebugMsgLevel( QString( "onViewportSizeUpdate window logicalDotsPerInch %1 (%2, %3)" ).arg( mCanvas->screen()->logicalDotsPerInch() ).arg( mCanvas->screen()->logicalDotsPerInchX() ).arg( mCanvas->screen()->logicalDotsPerInchY() ), 2 ); + + QgsDebugMsgLevel( QString( "onViewportSizeUpdate window pixel ratio %1" ).arg( mCanvas->screen()->devicePixelRatio() ), 2 ); + + QgsDebugMsgLevel( QString( "onViewportSizeUpdate set pixel ratio %1" ).arg( set.devicePixelRatio() ), 2 ); + QgsDebugMsgLevel( QString( "onViewportSizeUpdate set outputDpi %1" ).arg( set.outputDpi() ), 2 ); + QgsDebugMsgLevel( QString( "onViewportSizeUpdate set dpiTarget %1" ).arg( set.dpiTarget() ), 2 ); + } + + // default viewport size in pixel according to 92 dpi + double defaultViewportPixelSize = ( ( double ) settings.defaultViewportSize() / 25.4 ) * 92.0; + + // computes the viewport size according to screen dpi but as the viewport size growths too fast + // then we limit the growth by using a factor on the dpi difference. + double viewportPixelSize = defaultViewportPixelSize + ( ( double ) settings.defaultViewportSize() / 25.4 ) * ( mCanvas->screen()->physicalDotsPerInch() - 92.0 ) * 0.7; + QgsDebugMsgLevel( QString( "onViewportSizeUpdate viewportPixelSize %1" ).arg( viewportPixelSize ), 2 ); + double widthRatio = viewportPixelSize / windowWidth; + double heightRatio = widthRatio * windowWidth / windowHeight; + + QgsDebugMsgLevel( QString( "3DAxis viewport ratios width: %1% / height: %2%" ).arg( widthRatio * 100.0 ).arg( heightRatio * 100.0 ), 2 ); + + if ( heightRatio * windowHeight < viewportPixelSize ) + { + heightRatio = viewportPixelSize / windowHeight; + widthRatio = heightRatio * windowHeight / windowWidth; + QgsDebugMsgLevel( QString( "3DAxis viewport, height too small, ratios adjusted to width: %1% / height: %2%" ).arg( widthRatio * 100.0 ).arg( heightRatio * 100.0 ), 2 ); + } + + if ( heightRatio > settings.maxViewportRatio() || widthRatio > settings.maxViewportRatio() ) + { + qDebug() << heightRatio << settings.maxViewportRatio() << widthRatio << settings.maxViewportRatio(); + QgsDebugMsgLevel( QString( "3DAxis viewport takes too much place into the 3d view, disabling it (maxViewportRatio: %1)." ).arg( settings.maxViewportRatio() ), 2 ); + // take too much place into the 3d view + mViewport->setEnabled( false ); + emit viewportScaleFactorChanged( 0.0 ); + } + else + { + if ( !mViewport->isEnabled() ) + { + // will be used to adjust the axis label translations/sizes + emit viewportScaleFactorChanged( viewportPixelSize / defaultViewportPixelSize ); + } + mViewport->setEnabled( true ); + + float xRatio = 1.0f; + float yRatio = 1.0f; + if ( settings.horizontalPosition() == Qt::AnchorPoint::AnchorLeft ) + xRatio = 0.0f; + else if ( settings.horizontalPosition() == Qt::AnchorPoint::AnchorHorizontalCenter ) + xRatio = 0.5f - static_cast( widthRatio ) / 2.0f; + else + xRatio = 1.0f - static_cast( widthRatio ); + + if ( settings.verticalPosition() == Qt::AnchorPoint::AnchorTop ) + yRatio = 0.0f; + else if ( settings.verticalPosition() == Qt::AnchorPoint::AnchorVerticalCenter ) + yRatio = 0.5f - static_cast( heightRatio ) / 2.0f; + else + yRatio = 1.0f - static_cast( heightRatio ); + + QgsDebugMsgLevel( QString( "Qgs3DAxis: update viewport: %1 x %2 x %3 x %4" ).arg( xRatio ).arg( yRatio ).arg( widthRatio ).arg( heightRatio ), 2 ); + mViewport->setNormalizedRect( QRectF( xRatio, yRatio, widthRatio, heightRatio ) ); + + if ( settings.mode() == Qgs3DAxisSettings::Mode::Crs ) + { + const float halfWidthSize = static_cast( windowWidth * widthRatio / 2.0 ); + const float halfHeightSize = static_cast( windowWidth * widthRatio / 2.0 ); + mLabelCamera->lens()->setOrthographicProjection( + -halfWidthSize, halfWidthSize, + -halfHeightSize, halfHeightSize, + mLabelCamera->lens()->nearPlane(), mLabelCamera->lens()->farPlane() + ); + } + } +} + +void Qgs3DAxisRenderView::onHorizontalPositionChanged( Qt::AnchorPoint pos ) +{ + Qgs3DAxisSettings axisSettings = mMapSettings->get3DAxisSettings(); + axisSettings.setHorizontalPosition( pos ); + mMapSettings->set3DAxisSettings( axisSettings ); + onViewportSizeUpdate(); +} + +void Qgs3DAxisRenderView::onVerticalPositionChanged( Qt::AnchorPoint pos ) +{ + Qgs3DAxisSettings axisSettings = mMapSettings->get3DAxisSettings(); + axisSettings.setVerticalPosition( pos ); + mMapSettings->set3DAxisSettings( axisSettings ); + onViewportSizeUpdate(); +} diff --git a/src/3d/framegraph/qgs3daxisrenderview.h b/src/3d/framegraph/qgs3daxisrenderview.h new file mode 100644 index 000000000000..c6818cb6a2b9 --- /dev/null +++ b/src/3d/framegraph/qgs3daxisrenderview.h @@ -0,0 +1,112 @@ +/*************************************************************************** + qgs3daxisrenderview.h + -------------------------------------- + Date : June 2024 + Copyright : (C) 2024 by Benoit De Mezzo + 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 QGS3DAXISRENDERVIEW_H +#define QGS3DAXISRENDERVIEW_H + +#include "qgis_3d.h" +#include "qgsabstractrenderview.h" +#include + +#define SIP_NO_FILE + +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 QRenderTargetSelector; +} // namespace Qt3DRender + +class Qgs3DMapCanvas; +class QgsCameraController; + +class QgsFrameGraph; +class Qgs3DMapSettings; + +#define SIP_NO_FILE + +/** + * \ingroup 3d + * \brief 3d axis render view class + * + * \note Not available in Python bindings + * \since QGIS 3.40 + */ +class _3D_EXPORT Qgs3DAxisRenderView : public QgsAbstractRenderView +{ + Q_OBJECT + public: + /** + * Constructor for Qgs3DAxisRenderView with the specified \a parent object. + */ + Qgs3DAxisRenderView( QObject *parent, const QString &viewName, Qgs3DMapCanvas *canvas, // + QgsCameraController *cameraCtrl, Qgs3DMapSettings *settings ); + + //! Returns the viewport associated to this renderview + Qt3DRender::QViewport *viewport() const; + + //! Returns the layer to be used by entities to be included in the label renderpass + Qt3DRender::QLayer *labelLayer() const; + + //! Returns main object layer + Qt3DRender::QLayer *objectLayer() const; + + //! Returns main object camera (used for axis or cube) + Qt3DRender::QCamera *objectCamera() const; + + //! Returns camera used for billboarded labels + Qt3DRender::QCamera *labelCamera() const; + + virtual void updateWindowResize( int width, int height ) override; + + public slots: + //! Updates viewport horizontal \a position + void onHorizontalPositionChanged( Qt::AnchorPoint position ); + + //! Updates viewport vertical \a position + void onVerticalPositionChanged( Qt::AnchorPoint position ); + + //! Updates viewport \a size. Uses canvas size by default. + void onViewportSizeUpdate( int width = -1, int height = -1 ); + + signals: + //! Emits new viewport scale factor when it change + void viewportScaleFactorChanged( double scaleFactor ); + + private: + Qgs3DMapCanvas *mCanvas; + Qt3DRender::QCamera *mObjectCamera; + Qt3DRender::QCamera *mLabelCamera; + Qt3DRender::QLayer *mObjectLayer = nullptr; + Qt3DRender::QLayer *mLabelLayer = nullptr; + Qt3DRender::QViewport *mViewport = nullptr; + Qgs3DMapSettings *mMapSettings = nullptr; +}; + + +#endif // QGS3DAXISRENDERVIEW_H diff --git a/src/3d/framegraph/qgsframegraph.cpp b/src/3d/framegraph/qgsframegraph.cpp index bf813ec22485..fc7de4195962 100644 --- a/src/3d/framegraph/qgsframegraph.cpp +++ b/src/3d/framegraph/qgsframegraph.cpp @@ -56,6 +56,7 @@ typedef Qt3DCore::QGeometry Qt3DQGeometry; #include #include "qgsabstractrenderview.h" +const QString QgsFrameGraph::AXIS3D_RENDERVIEW = "3daxis"; Qt3DRender::QFrameGraphNode *QgsFrameGraph::constructForwardRenderPass() { @@ -751,7 +752,7 @@ void QgsFrameGraph::unregisterRenderView( const QString &name ) QgsAbstractRenderView *renderView = mRenderViewMap.find( name ).value().get(); if ( renderView ) { - renderView->topGraphNode()->setParent( ( QNode * )nullptr ); + renderView->topGraphNode()->setParent( ( QNode * ) nullptr ); mRenderViewMap.remove( name ); } } @@ -775,9 +776,9 @@ bool QgsFrameGraph::registerRenderView( QgsAbstractRenderView *renderView, const void QgsFrameGraph::setRenderViewEnabled( const QString &name, bool enable ) { - if ( mRenderViewMap [name] != nullptr ) + if ( mRenderViewMap[name] != nullptr ) { - mRenderViewMap [name]->setEnabled( enable ); + mRenderViewMap[name]->setEnabled( enable ); } } @@ -788,7 +789,7 @@ QgsAbstractRenderView *QgsFrameGraph::renderView( const QString &name ) bool QgsFrameGraph::isRenderViewEnabled( const QString &name ) { - return mRenderViewMap [name] != nullptr && mRenderViewMap [name]->isEnabled(); + return mRenderViewMap[name] != nullptr && mRenderViewMap[name]->isEnabled(); } QgsPreviewQuad *QgsFrameGraph::addTexturePreviewOverlay( Qt3DRender::QTexture2D *texture, const QPointF ¢erTexCoords, const QSizeF &sizeTexCoords, QVector additionalShaderParameters ) diff --git a/src/3d/framegraph/qgsframegraph.h b/src/3d/framegraph/qgsframegraph.h index a856f9f2f559..d2897b76b598 100644 --- a/src/3d/framegraph/qgsframegraph.h +++ b/src/3d/framegraph/qgsframegraph.h @@ -262,6 +262,8 @@ class QgsFrameGraph : public Qt3DCore::QEntity //! 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 AXIS3D_RENDERVIEW; + private: Qt3DRender::QRenderSurfaceSelector *mRenderSurfaceSelector = nullptr; Qt3DRender::QViewport *mMainViewPort = nullptr; diff --git a/src/3d/qgs3daxis.cpp b/src/3d/qgs3daxis.cpp index cb2e178bc4e7..83f021b6e00a 100644 --- a/src/3d/qgs3daxis.cpp +++ b/src/3d/qgs3daxis.cpp @@ -36,6 +36,7 @@ #include #include "qgsmapsettings.h" +#include "qgs3dmapsettings.h" #include "qgs3dmapscene.h" #include "qgsterrainentity.h" #include "qgscoordinatereferencesystemutils.h" @@ -43,9 +44,11 @@ #include "qgswindow3dengine.h" #include "qgsraycastingutils_p.h" #include "qgs3dwiredmesh_p.h" +#include "framegraph/qgsframegraph.h" #include "qgsabstractterrainsettings.h" -Qgs3DAxis::Qgs3DAxis( Qgs3DMapCanvas *canvas, Qt3DCore::QEntity *parent3DScene, Qgs3DMapScene *mapScene, QgsCameraController *cameraCtrl, Qgs3DMapSettings *map ) +Qgs3DAxis::Qgs3DAxis( Qgs3DMapCanvas *canvas, Qt3DCore::QEntity *parent3DScene, Qgs3DMapScene *mapScene, // + QgsCameraController *cameraCtrl, Qgs3DMapSettings *map ) : QObject( canvas ) , mMapSettings( map ) , mCanvas( canvas ) @@ -53,14 +56,18 @@ Qgs3DAxis::Qgs3DAxis( Qgs3DMapCanvas *canvas, Qt3DCore::QEntity *parent3DScene, , mCameraController( cameraCtrl ) , mCrs( map->crs() ) { - mViewport = constructAxisScene( parent3DScene ); - mViewport->setParent( mCanvas->activeFrameGraph() ); + mRenderView = new Qgs3DAxisRenderView( mMapScene->engine()->frameGraph(), QgsFrameGraph::AXIS3D_RENDERVIEW, // + mCanvas, mCameraController, mMapSettings ); + mMapScene->engine()->frameGraph()->registerRenderView( mRenderView, QgsFrameGraph::AXIS3D_RENDERVIEW ); + constructAxisScene( parent3DScene ); constructLabelsScene( parent3DScene ); + mTwoDLabelSceneEntity->addComponent( mRenderView->labelLayer() ); + connect( cameraCtrl, &QgsCameraController::cameraChanged, this, &Qgs3DAxis::onCameraUpdate ); - connect( mCanvas, &Qgs3DMapCanvas::widthChanged, this, &Qgs3DAxis::onAxisViewportSizeUpdate ); - connect( mCanvas, &Qgs3DMapCanvas::heightChanged, this, &Qgs3DAxis::onAxisViewportSizeUpdate ); + // callback for Qgs3DAxisRenderView::onViewportSizeUpdate: + connect( mRenderView, &Qgs3DAxisRenderView::viewportScaleFactorChanged, this, &Qgs3DAxis::onViewportScaleFactorChanged ); createAxisScene(); onAxisViewportSizeUpdate(); @@ -95,6 +102,8 @@ Qgs3DAxis::~Qgs3DAxis() mCubeRoot = nullptr; break; } + + // render view unregistration will be done by framegraph destructor! } void Qgs3DAxis::init3DObjectPicking() @@ -106,7 +115,7 @@ void Qgs3DAxis::init3DObjectPicking() // 2- connect screencaster results to onTouchedByRay // 3- screencaster will be triggered by EventFilter mScreenRayCaster = new Qt3DRender::QScreenRayCaster( mAxisSceneEntity ); - mScreenRayCaster->addLayer( mAxisObjectLayer ); // to only filter on axis objects + mScreenRayCaster->addLayer( mRenderView->objectLayer() ); // to only filter on axis objects mScreenRayCaster->setFilterMode( Qt3DRender::QScreenRayCaster::AcceptAllMatchingLayers ); mScreenRayCaster->setRunMode( Qt3DRender::QAbstractRayCaster::SingleShot ); @@ -158,11 +167,11 @@ bool Qgs3DAxis::eventFilter( QObject *watched, QEvent *event ) if ( 2 <= QgsLogger::debugLevel() && event->type() == QEvent::MouseButtonRelease ) { std::ostringstream os; - os << "QGS3DAxis: normalized pos: " << normalizedPos << " / viewport: " << mViewport->normalizedRect(); + os << "QGS3DAxis: normalized pos: " << normalizedPos << " / viewport: " << mRenderView->viewport()->normalizedRect(); QgsDebugMsgLevel( os.str().c_str(), 2 ); } - if ( mViewport->normalizedRect().contains( normalizedPos ) ) + if ( mRenderView->viewport()->normalizedRect().contains( normalizedPos ) ) { mLastClickedButton = mouseEvent->button(); mLastClickedPos = mouseEvent->pos(); @@ -297,49 +306,16 @@ void Qgs3DAxis::onTouchedByRay( const Qt3DRender::QAbstractRayCaster::Hits &hits } } -Qt3DRender::QViewport *Qgs3DAxis::constructAxisScene( Qt3DCore::QEntity *parent3DScene ) +void Qgs3DAxis::constructAxisScene( Qt3DCore::QEntity *parent3DScene ) { - Qt3DRender::QViewport *axisViewport = new Qt3DRender::QViewport; - // parent will be set later - // size will be set later - mAxisSceneEntity = new Qt3DCore::QEntity; mAxisSceneEntity->setParent( parent3DScene ); mAxisSceneEntity->setObjectName( "3DAxis_SceneEntity" ); - mAxisObjectLayer = new Qt3DRender::QLayer; - mAxisObjectLayer->setObjectName( "3DAxis_ObjectLayer" ); - mAxisObjectLayer->setParent( mAxisSceneEntity ); - mAxisObjectLayer->setRecursive( true ); - - mAxisCamera = new Qt3DRender::QCamera; - mAxisCamera->setParent( mAxisSceneEntity ); - mAxisCamera->setProjectionType( mCameraController->camera()->projectionType() ); - mAxisCamera->lens()->setFieldOfView( mCameraController->camera()->lens()->fieldOfView() * 0.5f ); - + mAxisCamera = mRenderView->objectCamera(); mAxisCamera->setUpVector( QVector3D( 0.0f, 1.0f, 0.0f ) ); mAxisCamera->setViewCenter( QVector3D( 0.0f, 0.0f, 0.0f ) ); // position will be set later - - Qt3DRender::QLayerFilter *axisLayerFilter = new Qt3DRender::QLayerFilter( axisViewport ); - axisLayerFilter->addLayer( mAxisObjectLayer ); - - Qt3DRender::QCameraSelector *axisCameraSelector = new Qt3DRender::QCameraSelector; - axisCameraSelector->setParent( axisLayerFilter ); - axisCameraSelector->setCamera( mAxisCamera ); - - // This ensures to have the labels (Text2DEntity) rendered after the other objects and therefore - // avoid any transparency issue on the labels. - Qt3DRender::QSortPolicy *sortPolicy = new Qt3DRender::QSortPolicy( axisCameraSelector ); - QVector sortTypes = QVector(); - sortTypes << Qt3DRender::QSortPolicy::BackToFront; - sortPolicy->setSortTypes( sortTypes ); - - Qt3DRender::QClearBuffers *clearBuffers = new Qt3DRender::QClearBuffers( sortPolicy ); - clearBuffers->setBuffers( Qt3DRender::QClearBuffers::DepthBuffer ); - - // cppcheck-suppress memleak - return axisViewport; } void Qgs3DAxis::constructLabelsScene( Qt3DCore::QEntity *parent3DScene ) @@ -348,39 +324,10 @@ void Qgs3DAxis::constructLabelsScene( Qt3DCore::QEntity *parent3DScene ) mTwoDLabelSceneEntity->setParent( parent3DScene ); mTwoDLabelSceneEntity->setEnabled( true ); - mTwoDLabelCamera = new Qt3DRender::QCamera; - mTwoDLabelCamera->setParent( mTwoDLabelSceneEntity ); - mTwoDLabelCamera->setProjectionType( Qt3DRender::QCameraLens::ProjectionType::OrthographicProjection ); - // the camera lens parameters are defined by onAxisViewportSizeUpdate() - + mTwoDLabelCamera = mRenderView->labelCamera(); mTwoDLabelCamera->setUpVector( QVector3D( 0.0f, 0.0f, 1.0f ) ); mTwoDLabelCamera->setViewCenter( QVector3D( 0.0f, 0.0f, 0.0f ) ); - mTwoDLabelCamera->setPosition( QVector3D( 0.0f, 0.0f, 100.0f ) ); - - Qt3DRender::QLayer *twoDLayer = new Qt3DRender::QLayer; - twoDLayer->setObjectName( "3DAxis_LabelsLayer" ); - twoDLayer->setRecursive( true ); - mTwoDLabelSceneEntity->addComponent( twoDLayer ); - - Qt3DRender::QLayerFilter *twoDLayerFilter = new Qt3DRender::QLayerFilter; - twoDLayerFilter->addLayer( twoDLayer ); - - Qt3DRender::QCameraSelector *twoDCameraSelector = new Qt3DRender::QCameraSelector; - twoDCameraSelector->setParent( twoDLayerFilter ); - twoDCameraSelector->setCamera( mTwoDLabelCamera ); - - // this ensures to have the labels (Text2DEntity) rendered after the other objects and therefore - // avoid any transparency issue on the labels. - Qt3DRender::QSortPolicy *sortPolicy = new Qt3DRender::QSortPolicy( twoDCameraSelector ); - QVector sortTypes = QVector(); - sortTypes << Qt3DRender::QSortPolicy::BackToFront; - sortPolicy->setSortTypes( sortTypes ); - - Qt3DRender::QClearBuffers *clearBuffers = new Qt3DRender::QClearBuffers( sortPolicy ); - clearBuffers->setBuffers( Qt3DRender::QClearBuffers::DepthBuffer ); - - twoDLayerFilter->setParent( mViewport ); } QVector3D Qgs3DAxis::from3DTo2DLabelPosition( const QVector3D &sourcePos, Qt3DRender::QCamera *sourceCamera, Qt3DRender::QCamera *destCamera ) @@ -431,7 +378,7 @@ void Qgs3DAxis::createAxisScene() mAxisRoot = new Qt3DCore::QEntity; mAxisRoot->setParent( mAxisSceneEntity ); mAxisRoot->setObjectName( "3DAxis_AxisRoot" ); - mAxisRoot->addComponent( mAxisObjectLayer ); // raycaster will filter object containing this layer + mAxisRoot->addComponent( mRenderView->objectLayer() ); // raycaster will filter object containing this layer createAxis( Qt::Axis::XAxis ); createAxis( Qt::Axis::YAxis ); @@ -440,7 +387,7 @@ void Qgs3DAxis::createAxisScene() mCubeRoot = new Qt3DCore::QEntity; mCubeRoot->setParent( mAxisSceneEntity ); mCubeRoot->setObjectName( "3DAxis_CubeRoot" ); - mCubeRoot->addComponent( mAxisObjectLayer ); // raycaster will filter object containing this layer + mCubeRoot->addComponent( mRenderView->objectLayer() ); // raycaster will filter object containing this layer createCube(); } @@ -452,9 +399,11 @@ void Qgs3DAxis::createAxisScene() mAxisSceneEntity->setEnabled( false ); setEnableAxis( false ); setEnableCube( false ); + mRenderView->setEnabled( false ); } else { + mRenderView->setEnabled( true ); mAxisSceneEntity->setEnabled( true ); if ( mode == Qgs3DAxisSettings::Mode::Crs ) { @@ -601,9 +550,9 @@ void Qgs3DAxis::createMenu() hPosGroup->addAction( hPosMiddleAct ); hPosGroup->addAction( hPosRightAct ); - connect( hPosLeftAct, &QAction::triggered, this, [this]( bool ) { onAxisHorizPositionChanged( Qt::AnchorPoint::AnchorLeft ); } ); - connect( hPosMiddleAct, &QAction::triggered, this, [this]( bool ) { onAxisHorizPositionChanged( Qt::AnchorPoint::AnchorHorizontalCenter ); } ); - connect( hPosRightAct, &QAction::triggered, this, [this]( bool ) { onAxisHorizPositionChanged( Qt::AnchorPoint::AnchorRight ); } ); + connect( hPosLeftAct, &QAction::triggered, this, [this]( bool ) { mRenderView->onHorizontalPositionChanged( Qt::AnchorPoint::AnchorLeft ); } ); + connect( hPosMiddleAct, &QAction::triggered, this, [this]( bool ) { mRenderView->onHorizontalPositionChanged( Qt::AnchorPoint::AnchorHorizontalCenter ); } ); + connect( hPosRightAct, &QAction::triggered, this, [this]( bool ) { mRenderView->onHorizontalPositionChanged( Qt::AnchorPoint::AnchorRight ); } ); QMenu *horizPosMenu = new QMenu( QStringLiteral( "Horizontal Position" ), mMenu ); horizPosMenu->addAction( hPosLeftAct ); @@ -638,9 +587,9 @@ void Qgs3DAxis::createMenu() vPosGroup->addAction( vPosMiddleAct ); vPosGroup->addAction( vPosBottomAct ); - connect( vPosTopAct, &QAction::triggered, this, [this]( bool ) { onAxisVertPositionChanged( Qt::AnchorPoint::AnchorTop ); } ); - connect( vPosMiddleAct, &QAction::triggered, this, [this]( bool ) { onAxisVertPositionChanged( Qt::AnchorPoint::AnchorVerticalCenter ); } ); - connect( vPosBottomAct, &QAction::triggered, this, [this]( bool ) { onAxisVertPositionChanged( Qt::AnchorPoint::AnchorBottom ); } ); + connect( vPosTopAct, &QAction::triggered, this, [this]( bool ) { mRenderView->onVerticalPositionChanged( Qt::AnchorPoint::AnchorTop ); } ); + connect( vPosMiddleAct, &QAction::triggered, this, [this]( bool ) { mRenderView->onVerticalPositionChanged( Qt::AnchorPoint::AnchorVerticalCenter ); } ); + connect( vPosBottomAct, &QAction::triggered, this, [this]( bool ) { mRenderView->onVerticalPositionChanged( Qt::AnchorPoint::AnchorBottom ); } ); QMenu *vertPosMenu = new QMenu( QStringLiteral( "Vertical Position" ), mMenu ); vertPosMenu->addAction( vPosTopAct ); @@ -702,20 +651,6 @@ void Qgs3DAxis::onAxisModeChanged( Qgs3DAxisSettings::Mode mode ) mMapSettings->set3DAxisSettings( s ); } -void Qgs3DAxis::onAxisHorizPositionChanged( Qt::AnchorPoint pos ) -{ - Qgs3DAxisSettings s = mMapSettings->get3DAxisSettings(); - s.setHorizontalPosition( pos ); - mMapSettings->set3DAxisSettings( s ); -} - -void Qgs3DAxis::onAxisVertPositionChanged( Qt::AnchorPoint pos ) -{ - Qgs3DAxisSettings s = mMapSettings->get3DAxisSettings(); - s.setVerticalPosition( pos ); - mMapSettings->set3DAxisSettings( s ); -} - void Qgs3DAxis::onCameraViewChange( float pitch, float yaw ) { QgsVector3D pos = mCameraController->lookingAtPoint(); @@ -990,100 +925,36 @@ void Qgs3DAxis::onAxisSettingsChanged() onAxisViewportSizeUpdate(); } -void Qgs3DAxis::onAxisViewportSizeUpdate( int ) +void Qgs3DAxis::onAxisViewportSizeUpdate() { - Qgs3DAxisSettings settings = mMapSettings->get3DAxisSettings(); + mRenderView->onViewportSizeUpdate( mCanvas->width(), mCanvas->height() ); // will call onViewportScaleFactorChanged as callback - double windowWidth = ( double ) mCanvas->width(); - double windowHeight = ( double ) mCanvas->height(); - - QgsMapSettings set; - if ( 2 <= QgsLogger::debugLevel() ) + // mRenderView->onViewportSizeUpdate() has updated `mTwoDLabelCamera` lens parameters. + // The position of the labels needs to be updated. + const Qgs3DAxisSettings axisSettings = mMapSettings->get3DAxisSettings(); + if ( axisSettings.mode() == Qgs3DAxisSettings::Mode::Crs && mAxisRoot->isEnabled() ) { - QgsDebugMsgLevel( QString( "onAxisViewportSizeUpdate window w/h: %1px / %2px" ).arg( windowWidth ).arg( windowHeight ), 2 ); - QgsDebugMsgLevel( QString( "onAxisViewportSizeUpdate window physicalDpi %1 (%2, %3)" ).arg( mCanvas->screen()->physicalDotsPerInch() ).arg( mCanvas->screen()->physicalDotsPerInchX() ).arg( mCanvas->screen()->physicalDotsPerInchY() ), 2 ); - QgsDebugMsgLevel( QString( "onAxisViewportSizeUpdate window logicalDotsPerInch %1 (%2, %3)" ).arg( mCanvas->screen()->logicalDotsPerInch() ).arg( mCanvas->screen()->logicalDotsPerInchX() ).arg( mCanvas->screen()->logicalDotsPerInchY() ), 2 ); - - QgsDebugMsgLevel( QString( "onAxisViewportSizeUpdate window pixel ratio %1" ).arg( mCanvas->screen()->devicePixelRatio() ), 2 ); - - QgsDebugMsgLevel( QString( "onAxisViewportSizeUpdate set pixel ratio %1" ).arg( set.devicePixelRatio() ), 2 ); - QgsDebugMsgLevel( QString( "onAxisViewportSizeUpdate set outputDpi %1" ).arg( set.outputDpi() ), 2 ); - QgsDebugMsgLevel( QString( "onAxisViewportSizeUpdate set dpiTarget %1" ).arg( set.dpiTarget() ), 2 ); + updateAxisLabelPosition(); } +} - // default viewport size in pixel according to 92 dpi - double defaultViewportPixelSize = ( ( double ) settings.defaultViewportSize() / 25.4 ) * 92.0; - - // computes the viewport size according to screen dpi but as the viewport size growths too fast - // then we limit the growth by using a factor on the dpi difference. - double viewportPixelSize = defaultViewportPixelSize + ( ( double ) settings.defaultViewportSize() / 25.4 ) * ( mCanvas->screen()->physicalDotsPerInch() - 92.0 ) * 0.7; - QgsDebugMsgLevel( QString( "onAxisViewportSizeUpdate viewportPixelSize %1" ).arg( viewportPixelSize ), 2 ); - double widthRatio = viewportPixelSize / windowWidth; - double heightRatio = widthRatio * windowWidth / windowHeight; - - QgsDebugMsgLevel( QString( "3DAxis viewport ratios width: %1% / height: %2%" ).arg( widthRatio ).arg( heightRatio ), 2 ); - - if ( heightRatio * windowHeight < viewportPixelSize ) +void Qgs3DAxis::onViewportScaleFactorChanged( double scaleFactor ) +{ + if ( scaleFactor > 0.0 ) { - heightRatio = viewportPixelSize / windowHeight; - widthRatio = heightRatio * windowHeight / windowWidth; - QgsDebugMsgLevel( QString( "3DAxis viewport, height too small, ratios adjusted to width: %1% / height: %2%" ).arg( widthRatio ).arg( heightRatio ), 2 ); - } + Qgs3DAxisSettings settings = mMapSettings->get3DAxisSettings(); + if ( settings.mode() == Qgs3DAxisSettings::Mode::Crs ) + setEnableAxis( true ); + else if ( settings.mode() == Qgs3DAxisSettings::Mode::Cube ) + setEnableCube( true ); - if ( heightRatio > settings.maxViewportRatio() || widthRatio > settings.maxViewportRatio() ) - { - QgsDebugMsgLevel( "viewport takes too much place into the 3d view, disabling it", 2 ); - // take too much place into the 3d view - mViewport->setEnabled( false ); - setEnableCube( false ); - setEnableAxis( false ); + mAxisScaleFactor = scaleFactor; + QgsDebugMsgLevel( QString( "3DAxis viewport mAxisScaleFactor %1" ).arg( mAxisScaleFactor ), 2 ); } else { - // will be used to adjust the axis label translations/sizes - mAxisScaleFactor = viewportPixelSize / defaultViewportPixelSize; - QgsDebugMsgLevel( QString( "3DAxis viewport mAxisScaleFactor %1" ).arg( mAxisScaleFactor ), 2 ); - - if ( !mViewport->isEnabled() ) - { - if ( settings.mode() == Qgs3DAxisSettings::Mode::Crs ) - setEnableAxis( true ); - else if ( settings.mode() == Qgs3DAxisSettings::Mode::Cube ) - setEnableCube( true ); - } - mViewport->setEnabled( true ); - - float xRatio = 1.0f; - float yRatio = 1.0f; - if ( settings.horizontalPosition() == Qt::AnchorPoint::AnchorLeft ) - xRatio = 0.0f; - else if ( settings.horizontalPosition() == Qt::AnchorPoint::AnchorHorizontalCenter ) - xRatio = 0.5f - static_cast( widthRatio ) / 2.0f; - else - xRatio = 1.0f - static_cast( widthRatio ); - - if ( settings.verticalPosition() == Qt::AnchorPoint::AnchorTop ) - yRatio = 0.0f; - else if ( settings.verticalPosition() == Qt::AnchorPoint::AnchorVerticalCenter ) - yRatio = 0.5f - static_cast( heightRatio ) / 2.0f; - else - yRatio = 1.0f - static_cast( heightRatio ); - - QgsDebugMsgLevel( QString( "Qgs3DAxis: update viewport: %1 x %2 x %3 x %4" ).arg( xRatio ).arg( yRatio ).arg( widthRatio ).arg( heightRatio ), 2 ); - mViewport->setNormalizedRect( QRectF( xRatio, yRatio, widthRatio, heightRatio ) ); - - if ( settings.mode() == Qgs3DAxisSettings::Mode::Crs ) - { - const float halfWidthSize = static_cast( windowWidth * widthRatio / 2.0 ); - const float halfHeightSize = static_cast( windowWidth * widthRatio / 2.0 ); - mTwoDLabelCamera->lens()->setOrthographicProjection( - -halfWidthSize, halfWidthSize, - -halfHeightSize, halfHeightSize, - mTwoDLabelCamera->lens()->nearPlane(), mTwoDLabelCamera->lens()->farPlane() - ); - - updateAxisLabelPosition(); - } + setEnableCube( false ); + setEnableAxis( false ); } } diff --git a/src/3d/qgs3daxis.h b/src/3d/qgs3daxis.h index a4f26f845d5f..04e2d210c501 100644 --- a/src/3d/qgs3daxis.h +++ b/src/3d/qgs3daxis.h @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -32,12 +31,13 @@ #include #include -#include "qgs3dmapsettings.h" +#include "qgs3daxissettings.h" #define SIP_NO_FILE class QgsCameraController; class Qgs3DMapScene; +class Qgs3DAxisRenderView; /** * \ingroup 3d @@ -86,14 +86,12 @@ class _3D_EXPORT Qgs3DAxis : public QObject private slots: void onCameraUpdate(); - void onAxisViewportSizeUpdate( int val = 0 ); + void onAxisViewportSizeUpdate(); + void onViewportScaleFactorChanged( double scaleFactor ); // axis picking and menu void onTouchedByRay( const Qt3DRender::QAbstractRayCaster::Hits &hits ); - void onAxisModeChanged( Qgs3DAxisSettings::Mode mode ); - void onAxisHorizPositionChanged( Qt::AnchorPoint pos ); - void onAxisVertPositionChanged( Qt::AnchorPoint pos ); void onCameraViewChange( float pitch, float yaw ); void onCameraViewChangeHome() { onCameraViewChange( 45.0f, 45.0f ); } @@ -114,7 +112,7 @@ class _3D_EXPORT Qgs3DAxis : public QObject void updateAxisLabelText( Qt3DExtras::QText2DEntity *textEntity, const QString &text ); QFont createFont( int pointSize ); - Qt3DRender::QViewport *constructAxisScene( Qt3DCore::QEntity *parent3DScene ); + void constructAxisScene( Qt3DCore::QEntity *parent3DScene ); void constructLabelsScene( Qt3DCore::QEntity *parent3DScene ); Qt3DExtras::QText2DEntity *addCubeText( const QString &text, float textHeight, float textWidth, const QFont &font, const QMatrix4x4 &rotation, const QVector3D &translation ); @@ -135,10 +133,8 @@ class _3D_EXPORT Qgs3DAxis : public QObject float mCylinderLength = 40.0f; int mFontSize = 12; - Qt3DRender::QViewport *mViewport = nullptr; - + Qgs3DAxisRenderView *mRenderView = nullptr; Qt3DCore::QEntity *mAxisSceneEntity = nullptr; - Qt3DRender::QLayer *mAxisObjectLayer = nullptr; Qt3DRender::QCamera *mAxisCamera = nullptr; Qt3DCore::QEntity *mAxisRoot = nullptr; diff --git a/src/3d/qgs3daxissettings.cpp b/src/3d/qgs3daxissettings.cpp index 3b9044cbb270..2bbf01e88e7e 100644 --- a/src/3d/qgs3daxissettings.cpp +++ b/src/3d/qgs3daxissettings.cpp @@ -41,13 +41,21 @@ void Qgs3DAxisSettings::readXml( const QDomElement &element, const QgsReadWriteC if ( !sizeStr.isEmpty() ) mDefaultViewportSize = sizeStr.toInt(); + double minViewportRatio = 0.0; + double maxViewportRatio = 0.0; sizeStr = element.attribute( QStringLiteral( "minViewportRatio" ) ); - if ( !sizeStr.isEmpty() ) - mMinViewportRatio = sizeStr.toDouble(); + if ( !sizeStr.isEmpty() && sizeStr.toDouble() != 0.0 ) + minViewportRatio = sizeStr.toDouble(); sizeStr = element.attribute( QStringLiteral( "maxViewportRatio" ) ); - if ( !sizeStr.isEmpty() ) - mMaxViewportRatio = sizeStr.toDouble(); + if ( !sizeStr.isEmpty() && sizeStr.toDouble() != 0.0 ) + maxViewportRatio = sizeStr.toDouble(); + + if ( maxViewportRatio > 0.0 ) + mMaxViewportRatio = maxViewportRatio; + + if ( minViewportRatio > 0.0 && mMaxViewportRatio > minViewportRatio ) + mMinViewportRatio = minViewportRatio; const QString modeStr = element.attribute( QStringLiteral( "mode" ) ); if ( modeStr == QLatin1String( "Off" ) ) diff --git a/src/3d/qgs3daxissettings.h b/src/3d/qgs3daxissettings.h index ce1b8e7fe23a..e6084861fd1d 100644 --- a/src/3d/qgs3daxissettings.h +++ b/src/3d/qgs3daxissettings.h @@ -19,7 +19,7 @@ #include #include -#include "qgis_3d.h" +#include "qgs3daxisrenderview.h" class QgsReadWriteContext; class QDomElement; From 8330c2c33486d063769e487a118b5bb74586a8b4 Mon Sep 17 00:00:00 2001 From: bdm-oslandia Date: Tue, 2 Aug 2022 12:23:41 +0200 Subject: [PATCH 07/11] feat(3d/renderView): extract shadow renderview to dedicated renderview class feat(3d/shadow): move shadow setting updates from qgs3dmapscene into render view --- src/3d/CMakeLists.txt | 2 + src/3d/framegraph/qgsframegraph.cpp | 208 ++++-------------- src/3d/framegraph/qgsframegraph.h | 56 ++--- src/3d/framegraph/qgspostprocessingentity.cpp | 36 ++- src/3d/framegraph/qgspostprocessingentity.h | 4 + src/3d/framegraph/qgsshadowrenderview.cpp | 132 +++++++++++ src/3d/framegraph/qgsshadowrenderview.h | 108 +++++++++ src/3d/qgs3dmapcanvas.cpp | 2 +- src/3d/qgs3dmapscene.cpp | 25 +-- src/3d/qgs3dutils.cpp | 59 +++++ src/3d/qgs3dutils.h | 16 ++ src/3d/qgsoffscreen3dengine.cpp | 8 +- src/3d/qgswindow3dengine.cpp | 15 +- src/3d/qgswindow3dengine.h | 6 - .../expected_framegraph.txt | 92 ++++---- .../expected_framegraph.txt | 92 ++++---- 16 files changed, 525 insertions(+), 336 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 6ce583c56603..86ba863cfa00 100644 --- a/src/3d/CMakeLists.txt +++ b/src/3d/CMakeLists.txt @@ -83,6 +83,7 @@ set(QGIS_3D_SRCS framegraph/qgspostprocessingentity.cpp framegraph/qgspreviewquad.cpp framegraph/qgsrenderpassquad.cpp + framegraph/qgsshadowrenderview.cpp framegraph/qgsframegraph.cpp framegraph/qgsframegraphutils.cpp @@ -192,6 +193,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 fc7de4195962..bb2c4e8bfd89 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 ); @@ -776,7 +733,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 ); } @@ -801,90 +758,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++; + } + } -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 ); + 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 ); + } } QString QgsFrameGraph::dumpFrameGraph() const @@ -911,29 +814,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; @@ -1083,3 +963,11 @@ void QgsFrameGraph::addClipPlanes( int nrClipPlanes ) mClipRenderStateSet->addRenderState( clipPlane ); } } + +QgsShadowRenderView *QgsFrameGraph::shadowRenderView() const +{ + QgsAbstractRenderView *rv = mRenderViewMap[QgsFrameGraph::SHADOW_RENDERVIEW].get(); + if ( rv ) + return dynamic_cast( rv ); + return nullptr; +} diff --git a/src/3d/framegraph/qgsframegraph.h b/src/3d/framegraph/qgsframegraph.h index d2897b76b598..d439072c0ad5 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 @@ -184,12 +166,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 @@ -253,15 +236,19 @@ class QgsFrameGraph : public Qt3DCore::QEntity //! Enables or disables the render view named \a name according to \a enable 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 bool isRenderViewEnabled( const QString &name ); + //! Returns shadow renderview or nullptr if not defined + QgsShadowRenderView *shadowRenderView() const; + //! 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 ); + //! Updates shadow bias, light and texture size according to \a shadowSettings and \a lightSources + void updateShadowSettings( const QgsShadowSettings &shadowSettings, const QList &lightSources ); + static const QString SHADOW_RENDERVIEW; static const QString AXIS3D_RENDERVIEW; private: @@ -270,7 +257,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; @@ -284,14 +270,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 @@ -335,10 +314,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; @@ -365,7 +340,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; @@ -378,7 +352,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 619f793aa095..0c9cb737eb96 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 = QVector3D( light.direction().x(), light.direction().y(), light.direction().z() ).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 b941907f05bf..0b6696e52041 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 @@ -51,6 +53,8 @@ class QgsPostprocessingEntity : public QgsRenderPassQuad void setEyeDomeLightingStrength( double strength ); //! 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 + void updateShadowSettings( const QgsDirectionalLightSettings &light, float maximumShadowRenderingDistance ); /** * Sets whether screen space ambient occlusion is enabled diff --git a/src/3d/framegraph/qgsshadowrenderview.cpp b/src/3d/framegraph/qgsshadowrenderview.cpp new file mode 100644 index 000000000000..40f6aea3aa98 --- /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 000000000000..2b349694b26e --- /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.40 + */ +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 dc920edafab2..424229643cf9 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 a1ed06339495..a7ad937902c7 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(); }; @@ -945,29 +946,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 1f40461a2d7a..5e29e71a8286 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 acddf29b66f4..bd3251346332 100644 --- a/src/3d/qgs3dutils.h +++ b/src/3d/qgs3dutils.h @@ -363,6 +363,22 @@ 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 + * \param camera + * \param maxRenderingDistance + * \param z the horizontal plane Z + * \param minX + * \param maxX + * \param minY + * \param maxY + * \param minZ + * \param maxZ + * + * \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 980424b39cae..0100769cedda 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->setRenderViewEnabled( 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 +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 161adec1b04e..1fe2a10431a4 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->setRenderViewEnabled( QgsFrameGraph::SHADOW_RENDERVIEW, 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 dfbd5fa3ff39..02df2667e648 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 51752e526a39..1b57c326981b 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 51752e526a39..1b57c326981b 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/}) From 2c922e3fb8489f343408a86c8d26ab8647b88982 Mon Sep 17 00:00:00 2001 From: bdm-oslandia Date: Tue, 3 Sep 2024 11:44:42 +0200 Subject: [PATCH 08/11] fix(qgsframegraph): remove useless class member mShadowRenderTargetOutput --- src/3d/framegraph/qgsframegraph.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/3d/framegraph/qgsframegraph.h b/src/3d/framegraph/qgsframegraph.h index d439072c0ad5..870261534762 100644 --- a/src/3d/framegraph/qgsframegraph.h +++ b/src/3d/framegraph/qgsframegraph.h @@ -166,8 +166,6 @@ 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 @@ -270,8 +268,6 @@ class QgsFrameGraph : public Qt3DCore::QEntity // QDebugOverlay added in the forward pass Qt3DRender::QDebugOverlay *mDebugOverlay = 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 // calculating real 3D points from mouse coordinates (for zoom, rotation, drag..) From af7d3a50b3dab4dfc7774ba3856093dcdbc8f2fc Mon Sep 17 00:00:00 2001 From: bdm-oslandia Date: Tue, 22 Oct 2024 10:46:49 +0200 Subject: [PATCH 09/11] fix(src/3d/CMakeLists.txt): fix framegraph includes --- src/3d/qgs3daxis.cpp | 2 +- src/3d/qgs3dmapcanvas.cpp | 2 +- src/3d/qgs3dmapscene.cpp | 4 ++-- src/3d/qgsabstract3dengine.cpp | 2 +- src/app/3d/qgs3dmaptoolmeasureline.cpp | 2 +- tests/src/3d/testqgs3drendering.cpp | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/3d/qgs3daxis.cpp b/src/3d/qgs3daxis.cpp index 83f021b6e00a..da864d37f1b9 100644 --- a/src/3d/qgs3daxis.cpp +++ b/src/3d/qgs3daxis.cpp @@ -44,7 +44,7 @@ #include "qgswindow3dengine.h" #include "qgsraycastingutils_p.h" #include "qgs3dwiredmesh_p.h" -#include "framegraph/qgsframegraph.h" +#include "qgsframegraph.h" #include "qgsabstractterrainsettings.h" Qgs3DAxis::Qgs3DAxis( Qgs3DMapCanvas *canvas, Qt3DCore::QEntity *parent3DScene, Qgs3DMapScene *mapScene, // diff --git a/src/3d/qgs3dmapcanvas.cpp b/src/3d/qgs3dmapcanvas.cpp index 424229643cf9..dc920edafab2 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 "framegraph/qgsframegraph.h" +#include "qgsframegraph.h" #include "qgspointcloudlayer3drenderer.h" #include "qgsrubberband3d.h" diff --git a/src/3d/qgs3dmapscene.cpp b/src/3d/qgs3dmapscene.cpp index a7ad937902c7..16d99a21160e 100644 --- a/src/3d/qgs3dmapscene.cpp +++ b/src/3d/qgs3dmapscene.cpp @@ -75,7 +75,7 @@ #include "qgs3dsceneexporter.h" #include "qgs3dmapexportsettings.h" #include "qgsmessageoutput.h" -#include "framegraph/qgsframegraph.h" +#include "qgsframegraph.h" #include "qgsabstractterrainsettings.h" #include "qgsskyboxentity.h" @@ -83,7 +83,7 @@ #include "qgswindow3dengine.h" #include "qgspointcloudlayer.h" -#include "framegraph/qgsshadowrenderview.h" +#include "qgsshadowrenderview.h" std::function()> Qgs3DMapScene::sOpenScenesFunction = [] { return QMap(); }; diff --git a/src/3d/qgsabstract3dengine.cpp b/src/3d/qgsabstract3dengine.cpp index 49ae6884e499..318def3382af 100644 --- a/src/3d/qgsabstract3dengine.cpp +++ b/src/3d/qgsabstract3dengine.cpp @@ -16,7 +16,7 @@ #include "qgsabstract3dengine.h" #include "moc_qgsabstract3dengine.cpp" -#include "framegraph/qgsframegraph.h" +#include "qgsframegraph.h" #include "qgslogger.h" #include diff --git a/src/app/3d/qgs3dmaptoolmeasureline.cpp b/src/app/3d/qgs3dmaptoolmeasureline.cpp index d06c54c1c126..16ddb6861822 100644 --- a/src/app/3d/qgs3dmaptoolmeasureline.cpp +++ b/src/app/3d/qgs3dmaptoolmeasureline.cpp @@ -25,7 +25,7 @@ #include "qgs3dmeasuredialog.h" #include "qgsrubberband3d.h" #include "qgswindow3dengine.h" -#include "framegraph/qgsframegraph.h" +#include "qgsframegraph.h" #include "qgsabstractterrainsettings.h" diff --git a/tests/src/3d/testqgs3drendering.cpp b/tests/src/3d/testqgs3drendering.cpp index 60ca6b9835e5..049e115752e2 100644 --- a/tests/src/3d/testqgs3drendering.cpp +++ b/tests/src/3d/testqgs3drendering.cpp @@ -36,7 +36,7 @@ #include "qgsflatterraingenerator.h" #include "qgsline3dsymbol.h" #include "qgsoffscreen3dengine.h" -#include "framegraph/qgsframegraph.h" +#include "qgsframegraph.h" #include "qgspolygon3dsymbol.h" #include "qgsrulebased3drenderer.h" #include "qgsvectorlayer3drenderer.h" From 2f319af6819131cfba536bfe4d55810ca8ab8b82 Mon Sep 17 00:00:00 2001 From: bdm-oslandia Date: Tue, 4 Mar 2025 15:43:41 +0100 Subject: [PATCH 10/11] fixup! feat(3d/renderView): extract shadow renderview to dedicated renderview class --- src/3d/framegraph/qgspostprocessingentity.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/3d/framegraph/qgspostprocessingentity.cpp b/src/3d/framegraph/qgspostprocessingentity.cpp index 0c9cb737eb96..bccf8dd01a64 100644 --- a/src/3d/framegraph/qgspostprocessingentity.cpp +++ b/src/3d/framegraph/qgspostprocessingentity.cpp @@ -152,7 +152,7 @@ void QgsPostprocessingEntity::updateShadowSettings( const QgsDirectionalLightSet 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(); + 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() ); From 3e6ac7666c1b2e3bb24df612c71f7fc6807439a6 Mon Sep 17 00:00:00 2001 From: bdm-oslandia Date: Tue, 4 Mar 2025 15:44:11 +0100 Subject: [PATCH 11/11] feat(3d/renderview): extract forward render view to dedicated renderview class --- src/3d/CMakeLists.txt | 2 + src/3d/framegraph/qgsforwardrenderview.cpp | 248 ++++++++++++++++++ src/3d/framegraph/qgsforwardrenderview.h | 170 ++++++++++++ src/3d/framegraph/qgsframegraph.cpp | 236 +++-------------- src/3d/framegraph/qgsframegraph.h | 40 +-- src/3d/framegraph/qgspostprocessingentity.cpp | 6 +- src/3d/qgs3dmapscene.cpp | 9 +- src/3d/qgsoffscreen3dengine.cpp | 3 +- src/3d/qgswindow3dengine.cpp | 4 +- .../expected_framegraph.txt | 96 +++---- .../expected_framegraph.txt | 96 +++---- 11 files changed, 570 insertions(+), 340 deletions(-) create mode 100644 src/3d/framegraph/qgsforwardrenderview.cpp create mode 100644 src/3d/framegraph/qgsforwardrenderview.h diff --git a/src/3d/CMakeLists.txt b/src/3d/CMakeLists.txt index 86ba863cfa00..6c3ba7aa3469 100644 --- a/src/3d/CMakeLists.txt +++ b/src/3d/CMakeLists.txt @@ -80,6 +80,7 @@ set(QGIS_3D_SRCS framegraph/qgs3daxisrenderview.cpp framegraph/qgsambientocclusionrenderentity.cpp framegraph/qgsambientocclusionblurentity.cpp + framegraph/qgsforwardrenderview.cpp framegraph/qgspostprocessingentity.cpp framegraph/qgspreviewquad.cpp framegraph/qgsrenderpassquad.cpp @@ -188,6 +189,7 @@ set(QGIS_3D_HDRS framegraph/qgs3daxisrenderview.h framegraph/qgsambientocclusionrenderentity.h framegraph/qgsambientocclusionblurentity.h + framegraph/qgsforwardrenderview.h framegraph/qgsframegraph.h framegraph/qgsframegraphutils.h framegraph/qgspostprocessingentity.h diff --git a/src/3d/framegraph/qgsforwardrenderview.cpp b/src/3d/framegraph/qgsforwardrenderview.cpp new file mode 100644 index 000000000000..dd01c6392045 --- /dev/null +++ b/src/3d/framegraph/qgsforwardrenderview.cpp @@ -0,0 +1,248 @@ +/*************************************************************************** + qgsforwardrenderview.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 "qgsforwardrenderview.h" +#include "moc_qgsforwardrenderview.cpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if QT_VERSION >= QT_VERSION_CHECK( 5, 15, 0 ) +#include +#endif + +QgsForwardRenderView::QgsForwardRenderView( QObject *parent, Qt3DRender::QCamera *mainCamera ) + : QgsAbstractRenderView( parent, "forward" ) + , mMainCamera( mainCamera ) +{ + mRenderLayer = new Qt3DRender::QLayer; + mRenderLayer->setRecursive( true ); + mRenderLayer->setObjectName( objectName() + "::Layer" ); + + mTransparentObjectsLayer = new Qt3DRender::QLayer; + mTransparentObjectsLayer->setRecursive( true ); + mTransparentObjectsLayer->setObjectName( objectName() + "::TransparentLayer" ); + + // forward rendering pass + buildRenderPasses(); +} + +Qt3DRender::QRenderTarget *QgsForwardRenderView::buildTextures() +{ + mColorTexture = new Qt3DRender::QTexture2D; + mColorTexture->setFormat( Qt3DRender::QAbstractTexture::RGB8_UNorm ); + mColorTexture->setGenerateMipMaps( false ); + mColorTexture->setMagnificationFilter( Qt3DRender::QTexture2D::Linear ); + mColorTexture->setMinificationFilter( Qt3DRender::QTexture2D::Linear ); + mColorTexture->wrapMode()->setX( Qt3DRender::QTextureWrapMode::ClampToEdge ); + mColorTexture->wrapMode()->setY( Qt3DRender::QTextureWrapMode::ClampToEdge ); + + mDepthTexture = new Qt3DRender::QTexture2D; + mDepthTexture->setFormat( Qt3DRender::QTexture2D::TextureFormat::DepthFormat ); + mDepthTexture->setGenerateMipMaps( false ); + mDepthTexture->setMagnificationFilter( Qt3DRender::QTexture2D::Linear ); + mDepthTexture->setMinificationFilter( Qt3DRender::QTexture2D::Linear ); + mDepthTexture->wrapMode()->setX( Qt3DRender::QTextureWrapMode::ClampToEdge ); + mDepthTexture->wrapMode()->setY( Qt3DRender::QTextureWrapMode::ClampToEdge ); + + Qt3DRender::QRenderTarget *renderTarget = new Qt3DRender::QRenderTarget; + Qt3DRender::QRenderTargetOutput *renderTargetDepthOutput = new Qt3DRender::QRenderTargetOutput; + renderTargetDepthOutput->setAttachmentPoint( Qt3DRender::QRenderTargetOutput::Depth ); + renderTargetDepthOutput->setTexture( mDepthTexture ); + renderTarget->addOutput( renderTargetDepthOutput ); + + Qt3DRender::QRenderTargetOutput *renderTargetColorOutput = new Qt3DRender::QRenderTargetOutput; + renderTargetColorOutput->setAttachmentPoint( Qt3DRender::QRenderTargetOutput::Color0 ); + renderTargetColorOutput->setTexture( mColorTexture ); + renderTarget->addOutput( renderTargetColorOutput ); + + return renderTarget; +} + +void QgsForwardRenderView::buildRenderPasses() +{ + mMainCameraSelector = new Qt3DRender::QCameraSelector( mRendererEnabler ); + mMainCameraSelector->setObjectName( objectName() + "::CameraSelector" ); + mMainCameraSelector->setCamera( mMainCamera ); + + mLayerFilter = new Qt3DRender::QLayerFilter( mMainCameraSelector ); + mLayerFilter->addLayer( mRenderLayer ); + + mClipRenderStateSet = new Qt3DRender::QRenderStateSet( mLayerFilter ); + mClipRenderStateSet->setObjectName( objectName() + "::Clip Plane RenderStateSet" ); + + Qt3DRender::QRenderTarget *renderTarget = buildTextures(); + + mRenderTargetSelector = new Qt3DRender::QRenderTargetSelector( mClipRenderStateSet ); + mRenderTargetSelector->setTarget( renderTarget ); + + // first branch: opaque layer filter + Qt3DRender::QLayerFilter *opaqueObjectsFilter = new Qt3DRender::QLayerFilter( mRenderTargetSelector ); + opaqueObjectsFilter->addLayer( mTransparentObjectsLayer ); + opaqueObjectsFilter->setFilterMode( Qt3DRender::QLayerFilter::DiscardAnyMatchingLayers ); + + Qt3DRender::QRenderStateSet *renderStateSet = new Qt3DRender::QRenderStateSet( opaqueObjectsFilter ); + + Qt3DRender::QDepthTest *depthTest = new Qt3DRender::QDepthTest; + depthTest->setDepthFunction( Qt3DRender::QDepthTest::Less ); + renderStateSet->addRenderState( depthTest ); + + Qt3DRender::QCullFace *cullFace = new Qt3DRender::QCullFace; + cullFace->setMode( Qt3DRender::QCullFace::CullingMode::Back ); + renderStateSet->addRenderState( cullFace ); + + mFrustumCulling = new Qt3DRender::QFrustumCulling( renderStateSet ); + + mClearBuffers = new Qt3DRender::QClearBuffers( mFrustumCulling ); + mClearBuffers->setClearColor( QColor::fromRgbF( 0.0, 0.0, 1.0, 1.0 ) ); + mClearBuffers->setBuffers( Qt3DRender::QClearBuffers::ColorDepthBuffer ); + mClearBuffers->setClearDepthValue( 1.0f ); + + // second branch: transparent layer filter - color + Qt3DRender::QLayerFilter *transparentObjectsLayerFilter = new Qt3DRender::QLayerFilter( mRenderTargetSelector ); + transparentObjectsLayerFilter->addLayer( mTransparentObjectsLayer ); + transparentObjectsLayerFilter->setFilterMode( Qt3DRender::QLayerFilter::AcceptAnyMatchingLayers ); + + Qt3DRender::QSortPolicy *sortPolicy = new Qt3DRender::QSortPolicy( transparentObjectsLayerFilter ); + QVector sortTypes; + sortTypes.push_back( Qt3DRender::QSortPolicy::BackToFront ); + sortPolicy->setSortTypes( sortTypes ); + + Qt3DRender::QRenderStateSet *transparentObjectsRenderStateSetColor = new Qt3DRender::QRenderStateSet( sortPolicy ); + { + Qt3DRender::QDepthTest *depthTest = new Qt3DRender::QDepthTest; + depthTest->setDepthFunction( Qt3DRender::QDepthTest::Less ); + transparentObjectsRenderStateSetColor->addRenderState( depthTest ); + + Qt3DRender::QNoDepthMask *noDepthMask = new Qt3DRender::QNoDepthMask; + transparentObjectsRenderStateSetColor->addRenderState( noDepthMask ); + + Qt3DRender::QCullFace *cullFace = new Qt3DRender::QCullFace; + cullFace->setMode( Qt3DRender::QCullFace::CullingMode::NoCulling ); + transparentObjectsRenderStateSetColor->addRenderState( cullFace ); + + Qt3DRender::QBlendEquation *blendEquation = new Qt3DRender::QBlendEquation; + blendEquation->setBlendFunction( Qt3DRender::QBlendEquation::Add ); + transparentObjectsRenderStateSetColor->addRenderState( blendEquation ); + + Qt3DRender::QBlendEquationArguments *blendEquationArgs = new Qt3DRender::QBlendEquationArguments; + blendEquationArgs->setSourceRgb( Qt3DRender::QBlendEquationArguments::Blending::SourceAlpha ); + blendEquationArgs->setDestinationRgb( Qt3DRender::QBlendEquationArguments::Blending::OneMinusSourceAlpha ); + transparentObjectsRenderStateSetColor->addRenderState( blendEquationArgs ); + } + + // third branch: transparent layer filter - depth + Qt3DRender::QRenderStateSet *transparentObjectsRenderStateSetDepth = new Qt3DRender::QRenderStateSet( sortPolicy ); + { + Qt3DRender::QDepthTest *depthTest = new Qt3DRender::QDepthTest; + depthTest->setDepthFunction( Qt3DRender::QDepthTest::Less ); + transparentObjectsRenderStateSetDepth->addRenderState( depthTest ); + + Qt3DRender::QColorMask *noColorMask = new Qt3DRender::QColorMask; + noColorMask->setAlphaMasked( false ); + noColorMask->setRedMasked( false ); + noColorMask->setGreenMasked( false ); + noColorMask->setBlueMasked( false ); + transparentObjectsRenderStateSetDepth->addRenderState( noColorMask ); + + Qt3DRender::QCullFace *cullFace = new Qt3DRender::QCullFace; + cullFace->setMode( Qt3DRender::QCullFace::CullingMode::NoCulling ); + transparentObjectsRenderStateSetDepth->addRenderState( cullFace ); + } + + mDebugOverlay = new Qt3DRender::QDebugOverlay( mClearBuffers ); + mDebugOverlay->setEnabled( false ); +} + +void QgsForwardRenderView::updateWindowResize( int width, int height ) +{ + mColorTexture->setSize( width, height ); + mDepthTexture->setSize( width, height ); +} + + +void QgsForwardRenderView::setClearColor( const QColor &clearColor ) +{ + mClearBuffers->setClearColor( clearColor ); +} + + +void QgsForwardRenderView::setFrustumCullingEnabled( bool enabled ) +{ + if ( enabled == mFrustumCullingEnabled ) + return; + mFrustumCullingEnabled = enabled; + mFrustumCulling->setEnabled( enabled ); +} + + +void QgsForwardRenderView::setDebugOverlayEnabled( bool enabled ) +{ + mDebugOverlay->setEnabled( enabled ); +} + +Qt3DRender::QTexture2D *QgsForwardRenderView::depthTexture() const +{ + return mDepthTexture; +} + +Qt3DRender::QTexture2D *QgsForwardRenderView::colorTexture() const +{ + return mColorTexture; +} + +void QgsForwardRenderView::removeClipPlanes() +{ + for ( Qt3DRender::QRenderState *state : mClipRenderStateSet->renderStates() ) + { + if ( qobject_cast( state ) ) + { + mClipRenderStateSet->removeRenderState( state ); + } + } +} + +void QgsForwardRenderView::addClipPlanes( int nrClipPlanes ) +{ + // remove existing QClipPlane + removeClipPlanes(); + + // create new QClipPlane + for ( int i = 0; i < nrClipPlanes; ++i ) + { + Qt3DRender::QClipPlane *clipPlane = new Qt3DRender::QClipPlane; + clipPlane->setPlaneIndex( i ); + mClipRenderStateSet->addRenderState( clipPlane ); + } +} diff --git a/src/3d/framegraph/qgsforwardrenderview.h b/src/3d/framegraph/qgsforwardrenderview.h new file mode 100644 index 000000000000..de1e5c7b04b9 --- /dev/null +++ b/src/3d/framegraph/qgsforwardrenderview.h @@ -0,0 +1,170 @@ +/*************************************************************************** + qgsforwardrenderview.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 QGSFORWARDRENDERVIEW_H +#define QGSFORWARDRENDERVIEW_H + +#include "qgsabstractrenderview.h" + +namespace Qt3DRender +{ + class QRenderSettings; + class QLayer; + class QSubtreeEnabler; + class QTexture2D; + class QCamera; + class QCameraSelector; + class QLayerFilter; + class QRenderTargetSelector; + class QRenderTarget; + class QClearBuffers; + class QFrustumCulling; + class QRenderStateSet; + class QDebugOverlay; +} // namespace Qt3DRender + +#define SIP_NO_FILE + +/** + * \ingroup 3d + * \brief Container class that holds different objects related to forward rendering + * + * The branch structure: + * We define two forward passes: one for solid objects, followed by one for transparent objects. + * + * | + * +-----------------+ + * | QCameraSelector | (using the main camera) + * +-----------------+ + * | + * +-----------------+ + * | QLayerFilter | (using mForwardRenderLayer) + * +-----------------+ + * | + * +-----------------+ + * | QRenderStateSet | define clip planes + * +-----------------+ + * | + * +-----------------------+ + * | QRenderTargetSelector | (write mForwardColorTexture + mForwardDepthTexture) + * +-----------------------+ + * | + * +------------------------+---------------------+ + * | | + * +-----------------+ discard +-----------------+ accept + * | QLayerFilter | transparent | QLayerFilter | transparent + * +-----------------+ objects +-----------------+ objects + * | | + * +-----------------+ use depth test +-----------------+ sort entities + * | QRenderStateSet | cull back faces | QSortPolicy | back to front + * +-----------------+ +-----------------+ + * | | + * +-----------------+ +--------------------+--------------------+ + * | QFrustumCulling | | | + * +-----------------+ +-----------------+ use depth tests +-----------------+ use depth tests + * | | QRenderStateSet | don't write depths | QRenderStateSet | write depths + * | +-----------------+ write colors +-----------------+ don't write colors + * +-----------------+ use alpha blending don't use alpha blending + * | QClearBuffers | color and depth no culling no culling + * +-----------------+ + * | + * +-----------------+ + * | QDebugOverlay | + * +-----------------+ + * + * \note Not available in Python bindings + * + * \since QGIS 3.40 + */ +class QgsForwardRenderView : public QgsAbstractRenderView +{ + Q_OBJECT + public: + //! Constructor with 3D scene camera + QgsForwardRenderView( QObject *parent, Qt3DRender::QCamera *mainCamera ); + + //! Returns a layer object used to indicate that the object is transparent + Qt3DRender::QLayer *renderLayer() { return mRenderLayer; } + + //! Returns a layer object used to indicate that the object is transparent + Qt3DRender::QLayer *transparentObjectLayer() { return mTransparentObjectsLayer; } + + //! Sets the clear color of the scene (background color) + void setClearColor( const QColor &clearColor ); + + //! Returns whether frustum culling is enabled + bool isFrustumCullingEnabled() const { return mFrustumCullingEnabled; } + //! Sets whether frustum culling is enabled + void setFrustumCullingEnabled( bool enabled ); + + //! Sets whether debug overlay is enabled + void setDebugOverlayEnabled( bool enabled ); + + //! Returns current render target selector + Qt3DRender::QRenderTargetSelector *renderTargetSelector() { return mRenderTargetSelector; } + + virtual void updateWindowResize( int width, int height ) override; + + //! Returns forward depth texture + Qt3DRender::QTexture2D *depthTexture() const; + + //! Returns forward color texture + Qt3DRender::QTexture2D *colorTexture() const; + + /** + * Setups \a nrClipPlanes clip planes in the forward pass to enable OpenGL clipping. + * If \a nrClipPlanes is equal to 0, the clipping is disabled. + * + * \see removeClipPlanes() + * \since QGIS 3.40 + */ + void addClipPlanes( int nrClipPlanes ); + + /** + * Disables OpenGL clipping + * + * \see addClipPlanes() + * \since QGIS 3.40 + */ + void removeClipPlanes(); + + private: + Qt3DRender::QCamera *mMainCamera = nullptr; + + Qt3DRender::QCameraSelector *mMainCameraSelector = nullptr; + Qt3DRender::QLayerFilter *mLayerFilter = nullptr; + Qt3DRender::QRenderTargetSelector *mRenderTargetSelector = nullptr; + + // clip planes render state + Qt3DRender::QRenderStateSet *mClipRenderStateSet = nullptr; + + Qt3DRender::QLayer *mRenderLayer = nullptr; + Qt3DRender::QLayer *mTransparentObjectsLayer = nullptr; + Qt3DRender::QClearBuffers *mClearBuffers = nullptr; + bool mFrustumCullingEnabled = true; + Qt3DRender::QFrustumCulling *mFrustumCulling = nullptr; + // Forward rendering pass texture related objects: + Qt3DRender::QTexture2D *mColorTexture = nullptr; + Qt3DRender::QTexture2D *mDepthTexture = nullptr; + // QDebugOverlay added in the forward pass +#if QT_VERSION >= QT_VERSION_CHECK( 5, 15, 0 ) + Qt3DRender::QDebugOverlay *mDebugOverlay = nullptr; +#endif + + void buildRenderPasses(); + Qt3DRender::QRenderTarget *buildTextures(); +}; + +#endif // QGSFORWARDRENDERVIEW_H diff --git a/src/3d/framegraph/qgsframegraph.cpp b/src/3d/framegraph/qgsframegraph.cpp index bb2c4e8bfd89..bb5cdbb7a1c6 100644 --- a/src/3d/framegraph/qgsframegraph.cpp +++ b/src/3d/framegraph/qgsframegraph.cpp @@ -54,177 +54,24 @@ typedef Qt3DCore::QGeometry Qt3DQGeometry; #include #include #include -#include +#include "qgsshadowrenderview.h" +#include "qgsforwardrenderview.h" +const QString QgsFrameGraph::FORWARD_RENDERVIEW = "forward"; const QString QgsFrameGraph::SHADOW_RENDERVIEW = "shadow"; const QString QgsFrameGraph::AXIS3D_RENDERVIEW = "3daxis"; -Qt3DRender::QFrameGraphNode *QgsFrameGraph::constructForwardRenderPass() +void QgsFrameGraph::constructForwardRenderPass() { // This is where rendering of the 3D scene actually happens. - // We define two forward passes: one for solid objects, followed by one for transparent objects. - // - // | - // +-----------------+ - // | QCameraSelector | (using the main camera) - // +-----------------+ - // | - // +-----------------+ - // | QLayerFilter | (using mForwardRenderLayer) - // +-----------------+ - // | - // +-----------------+ - // | QRenderStateSet | define clip planes - // +-----------------+ - // | - // +-----------------------+ - // | QRenderTargetSelector | (write mForwardColorTexture + mForwardDepthTexture) - // +-----------------------+ - // | - // +------------------------+---------------------+ - // | | - // +-----------------+ discard +-----------------+ accept - // | QLayerFilter | transparent | QLayerFilter | transparent - // +-----------------+ objects +-----------------+ objects - // | | - // +-----------------+ use depth test +-----------------+ sort entities - // | QRenderStateSet | cull back faces | QSortPolicy | back to front - // +-----------------+ +-----------------+ - // | | - // +-----------------+ +--------------------+--------------------+ - // | QFrustumCulling | | | - // +-----------------+ +-----------------+ use depth tests +-----------------+ use depth tests - // | | QRenderStateSet | don't write depths | QRenderStateSet | write depths - // | +-----------------+ write colors +-----------------+ don't write colors - // +-----------------+ use alpha blending don't use alpha blending - // | QClearBuffers | color and depth no culling no culling - // +-----------------+ - - mMainCameraSelector = new Qt3DRender::QCameraSelector; - mMainCameraSelector->setObjectName( "Forward render pass CameraSelector" ); - mMainCameraSelector->setCamera( mMainCamera ); - - mForwardRenderLayerFilter = new Qt3DRender::QLayerFilter( mMainCameraSelector ); - mForwardRenderLayerFilter->addLayer( mForwardRenderLayer ); - - mClipRenderStateSet = new Qt3DRender::QRenderStateSet( mForwardRenderLayerFilter ); - mClipRenderStateSet->setObjectName( "Forward render pass Clip Plane RenderStateSet" ); - - mForwardColorTexture = new Qt3DRender::QTexture2D; - mForwardColorTexture->setWidth( mSize.width() ); - mForwardColorTexture->setHeight( mSize.height() ); - mForwardColorTexture->setFormat( Qt3DRender::QAbstractTexture::RGB8_UNorm ); - mForwardColorTexture->setGenerateMipMaps( false ); - mForwardColorTexture->setMagnificationFilter( Qt3DRender::QTexture2D::Linear ); - mForwardColorTexture->setMinificationFilter( Qt3DRender::QTexture2D::Linear ); - mForwardColorTexture->wrapMode()->setX( Qt3DRender::QTextureWrapMode::ClampToEdge ); - mForwardColorTexture->wrapMode()->setY( Qt3DRender::QTextureWrapMode::ClampToEdge ); - - mForwardDepthTexture = new Qt3DRender::QTexture2D; - mForwardDepthTexture->setWidth( mSize.width() ); - mForwardDepthTexture->setHeight( mSize.height() ); - mForwardDepthTexture->setFormat( Qt3DRender::QTexture2D::TextureFormat::DepthFormat ); - mForwardDepthTexture->setGenerateMipMaps( false ); - mForwardDepthTexture->setMagnificationFilter( Qt3DRender::QTexture2D::Linear ); - mForwardDepthTexture->setMinificationFilter( Qt3DRender::QTexture2D::Linear ); - mForwardDepthTexture->wrapMode()->setX( Qt3DRender::QTextureWrapMode::ClampToEdge ); - mForwardDepthTexture->wrapMode()->setY( Qt3DRender::QTextureWrapMode::ClampToEdge ); - - Qt3DRender::QRenderTarget *forwardRenderTarget = new Qt3DRender::QRenderTarget; - Qt3DRender::QRenderTargetOutput *forwardRenderTargetDepthOutput = new Qt3DRender::QRenderTargetOutput; - forwardRenderTargetDepthOutput->setAttachmentPoint( Qt3DRender::QRenderTargetOutput::Depth ); - forwardRenderTargetDepthOutput->setTexture( mForwardDepthTexture ); - forwardRenderTarget->addOutput( forwardRenderTargetDepthOutput ); - Qt3DRender::QRenderTargetOutput *forwardRenderTargetColorOutput = new Qt3DRender::QRenderTargetOutput; - forwardRenderTargetColorOutput->setAttachmentPoint( Qt3DRender::QRenderTargetOutput::Color0 ); - forwardRenderTargetColorOutput->setTexture( mForwardColorTexture ); - forwardRenderTarget->addOutput( forwardRenderTargetColorOutput ); - - mForwardRenderTargetSelector = new Qt3DRender::QRenderTargetSelector( mClipRenderStateSet ); - mForwardRenderTargetSelector->setTarget( forwardRenderTarget ); - - // first branch: opaque layer filter - Qt3DRender::QLayerFilter *opaqueObjectsFilter = new Qt3DRender::QLayerFilter( mForwardRenderTargetSelector ); - opaqueObjectsFilter->addLayer( mTransparentObjectsPassLayer ); - opaqueObjectsFilter->setFilterMode( Qt3DRender::QLayerFilter::DiscardAnyMatchingLayers ); - - Qt3DRender::QRenderStateSet *forwardedRenderStateSet = new Qt3DRender::QRenderStateSet( opaqueObjectsFilter ); - - Qt3DRender::QDepthTest *depthTest = new Qt3DRender::QDepthTest; - depthTest->setDepthFunction( Qt3DRender::QDepthTest::Less ); - forwardedRenderStateSet->addRenderState( depthTest ); - - Qt3DRender::QCullFace *cullFace = new Qt3DRender::QCullFace; - cullFace->setMode( Qt3DRender::QCullFace::CullingMode::Back ); - forwardedRenderStateSet->addRenderState( cullFace ); - - mFrustumCulling = new Qt3DRender::QFrustumCulling( forwardedRenderStateSet ); - - mForwardClearBuffers = new Qt3DRender::QClearBuffers( mFrustumCulling ); - mForwardClearBuffers->setClearColor( QColor::fromRgbF( 0.0, 0.0, 1.0, 1.0 ) ); - mForwardClearBuffers->setBuffers( Qt3DRender::QClearBuffers::ColorDepthBuffer ); - mForwardClearBuffers->setClearDepthValue( 1.0f ); - - // second branch: transparent layer filter - color - Qt3DRender::QLayerFilter *transparentObjectsLayerFilter = new Qt3DRender::QLayerFilter( mForwardRenderTargetSelector ); - transparentObjectsLayerFilter->addLayer( mTransparentObjectsPassLayer ); - transparentObjectsLayerFilter->setFilterMode( Qt3DRender::QLayerFilter::AcceptAnyMatchingLayers ); - - Qt3DRender::QSortPolicy *sortPolicy = new Qt3DRender::QSortPolicy( transparentObjectsLayerFilter ); - QVector sortTypes; - sortTypes.push_back( Qt3DRender::QSortPolicy::BackToFront ); - sortPolicy->setSortTypes( sortTypes ); - - Qt3DRender::QRenderStateSet *transparentObjectsRenderStateSetColor = new Qt3DRender::QRenderStateSet( sortPolicy ); - { - Qt3DRender::QDepthTest *depthTest = new Qt3DRender::QDepthTest; - depthTest->setDepthFunction( Qt3DRender::QDepthTest::Less ); - transparentObjectsRenderStateSetColor->addRenderState( depthTest ); - - Qt3DRender::QNoDepthMask *noDepthMask = new Qt3DRender::QNoDepthMask; - transparentObjectsRenderStateSetColor->addRenderState( noDepthMask ); - - Qt3DRender::QCullFace *cullFace = new Qt3DRender::QCullFace; - cullFace->setMode( Qt3DRender::QCullFace::CullingMode::NoCulling ); - transparentObjectsRenderStateSetColor->addRenderState( cullFace ); - - Qt3DRender::QBlendEquation *blendEquation = new Qt3DRender::QBlendEquation; - blendEquation->setBlendFunction( Qt3DRender::QBlendEquation::Add ); - transparentObjectsRenderStateSetColor->addRenderState( blendEquation ); - - Qt3DRender::QBlendEquationArguments *blendEquationArgs = new Qt3DRender::QBlendEquationArguments; - blendEquationArgs->setSourceRgb( Qt3DRender::QBlendEquationArguments::Blending::SourceAlpha ); - blendEquationArgs->setDestinationRgb( Qt3DRender::QBlendEquationArguments::Blending::OneMinusSourceAlpha ); - transparentObjectsRenderStateSetColor->addRenderState( blendEquationArgs ); - } - - // third branch: transparent layer filter - depth - Qt3DRender::QRenderStateSet *transparentObjectsRenderStateSetDepth = new Qt3DRender::QRenderStateSet( sortPolicy ); - { - Qt3DRender::QDepthTest *depthTest = new Qt3DRender::QDepthTest; - depthTest->setDepthFunction( Qt3DRender::QDepthTest::Less ); - transparentObjectsRenderStateSetDepth->addRenderState( depthTest ); - - Qt3DRender::QColorMask *noColorMask = new Qt3DRender::QColorMask; - noColorMask->setAlphaMasked( false ); - noColorMask->setRedMasked( false ); - noColorMask->setGreenMasked( false ); - noColorMask->setBlueMasked( false ); - transparentObjectsRenderStateSetDepth->addRenderState( noColorMask ); - - Qt3DRender::QCullFace *cullFace = new Qt3DRender::QCullFace; - cullFace->setMode( Qt3DRender::QCullFace::CullingMode::NoCulling ); - transparentObjectsRenderStateSetDepth->addRenderState( cullFace ); - } - - mDebugOverlay = new Qt3DRender::QDebugOverlay( mForwardClearBuffers ); - mDebugOverlay->setEnabled( false ); - - // cppcheck wrongly believes transparentObjectsRenderStateSetColor and transparentObjectsRenderStateSetDepth will leak - // cppcheck-suppress memleak - return mMainCameraSelector; + QgsForwardRenderView *forwardRenderView = new QgsForwardRenderView( this, mMainCamera ); + registerRenderView( forwardRenderView, FORWARD_RENDERVIEW ); } +Qt3DRender::QLayer *QgsFrameGraph::transparentObjectLayer() +{ + return forwardRenderView()->transparentObjectLayer(); +} void QgsFrameGraph::constructShadowRenderPass() { @@ -373,7 +220,8 @@ Qt3DRender::QFrameGraphNode *QgsFrameGraph::constructAmbientOcclusionRenderPass( mAmbientOcclusionRenderCaptureTargetSelector->setTarget( colorRenderTarget ); Qt3DRender::QLayer *ambientOcclusionRenderLayer = new Qt3DRender::QLayer(); - mAmbientOcclusionRenderEntity = new QgsAmbientOcclusionRenderEntity( mForwardDepthTexture, ambientOcclusionRenderLayer, mMainCamera, mRootEntity ); + Qt3DRender::QTexture2D *forwardDepthTexture = forwardRenderView()->depthTexture(); + mAmbientOcclusionRenderEntity = new QgsAmbientOcclusionRenderEntity( forwardDepthTexture, ambientOcclusionRenderLayer, mMainCamera, mRootEntity ); mAmbientOcclusionRenderLayerFilter->addLayer( ambientOcclusionRenderLayer ); return mAmbientOcclusionRenderCameraSelector; @@ -456,7 +304,7 @@ Qt3DRender::QFrameGraphNode *QgsFrameGraph::constructRubberBandsPass() // This is kind of okay, but as a result, post-processing effects get applied // to rubber bands too. Ideally we would want them on top of everything. mRubberBandsRenderTargetSelector = new Qt3DRender::QRenderTargetSelector( mRubberBandsStateSet ); - mRubberBandsRenderTargetSelector->setTarget( mForwardRenderTargetSelector->target() ); + mRubberBandsRenderTargetSelector->setTarget( forwardRenderView()->renderTargetSelector()->target() ); return mRubberBandsCameraSelector; } @@ -564,7 +412,8 @@ Qt3DCore::QEntity *QgsFrameGraph::constructDepthRenderQuad() // construct material Qt3DRender::QMaterial *material = new Qt3DRender::QMaterial; - Qt3DRender::QParameter *textureParameter = new Qt3DRender::QParameter( "depthTexture", mForwardDepthTexture ); + Qt3DRender::QTexture2D *forwardDepthTexture = forwardRenderView()->depthTexture(); + Qt3DRender::QParameter *textureParameter = new Qt3DRender::QParameter( "depthTexture", forwardDepthTexture ); Qt3DRender::QParameter *textureTransformParameter = new Qt3DRender::QParameter( "modelMatrix", QVariant::fromValue( modelMatrix ) ); material->addParameter( textureParameter ); material->addParameter( textureTransformParameter ); @@ -632,17 +481,13 @@ QgsFrameGraph::QgsFrameGraph( QSurface *surface, QSize s, Qt3DRender::QCamera *m mMainCamera = mainCamera; mPreviewLayer = new Qt3DRender::QLayer; - mForwardRenderLayer = new Qt3DRender::QLayer; mDepthRenderPassLayer = new Qt3DRender::QLayer; - mTransparentObjectsPassLayer = new Qt3DRender::QLayer; mRubberBandsLayer = new Qt3DRender::QLayer; mRubberBandsLayer->setObjectName( "mRubberBandsLayer" ); mPreviewLayer->setRecursive( true ); - mForwardRenderLayer->setRecursive( true ); mDepthRenderPassLayer->setRecursive( true ); - mTransparentObjectsPassLayer->setRecursive( true ); mRubberBandsLayer->setRecursive( true ); mRenderSurfaceSelector = new Qt3DRender::QRenderSurfaceSelector; @@ -657,8 +502,7 @@ QgsFrameGraph::QgsFrameGraph( QSurface *surface, QSize s, Qt3DRender::QCamera *m mMainViewPort->setNormalizedRect( QRectF( 0.0f, 0.0f, 1.0f, 1.0f ) ); // Forward render - Qt3DRender::QFrameGraphNode *forwardRenderPass = constructForwardRenderPass(); - forwardRenderPass->setParent( mMainViewPort ); + constructForwardRenderPass(); // rubber bands (they should be always on top) Qt3DRender::QFrameGraphNode *rubberBandsPass = constructRubberBandsPass(); @@ -691,7 +535,8 @@ QgsFrameGraph::QgsFrameGraph( QSurface *surface, QSize s, Qt3DRender::QCamera *m Qt3DRender::QParameter *depthMapIsDepthParam = new Qt3DRender::QParameter( "isDepth", true ); Qt3DRender::QParameter *shadowMapIsDepthParam = new Qt3DRender::QParameter( "isDepth", true ); - mDebugDepthMapPreviewQuad = this->addTexturePreviewOverlay( mForwardDepthTexture, QPointF( 0.9f, 0.9f ), QSizeF( 0.1, 0.1 ), QVector { depthMapIsDepthParam } ); + Qt3DRender::QTexture2D *forwardDepthTexture = forwardRenderView()->depthTexture(); + mDebugDepthMapPreviewQuad = this->addTexturePreviewOverlay( forwardDepthTexture, QPointF( 0.9f, 0.9f ), QSizeF( 0.1, 0.1 ), QVector { depthMapIsDepthParam } ); Qt3DRender::QTexture2D *shadowMapTexture = shadowRenderView()->mapTexture(); mDebugShadowMapPreviewQuad = this->addTexturePreviewOverlay( shadowMapTexture, QPointF( 0.9f, 0.9f ), QSizeF( 0.1, 0.1 ), QVector { shadowMapIsDepthParam } ); @@ -811,7 +656,9 @@ QString QgsFrameGraph::dumpSceneGraph() const void QgsFrameGraph::setClearColor( const QColor &clearColor ) { - mForwardClearBuffers->setClearColor( clearColor ); + QgsForwardRenderView *rv = forwardRenderView(); + if ( rv ) + rv->setClearColor( clearColor ); } void QgsFrameGraph::setAmbientOcclusionEnabled( bool enabled ) @@ -841,13 +688,9 @@ void QgsFrameGraph::setAmbientOcclusionThreshold( float threshold ) void QgsFrameGraph::setFrustumCullingEnabled( bool enabled ) { - if ( enabled == mFrustumCullingEnabled ) - return; - mFrustumCullingEnabled = enabled; - if ( mFrustumCullingEnabled ) - mFrustumCulling->setParent( mForwardClearBuffers ); - else - mFrustumCulling->setParent( ( Qt3DCore::QNode * ) nullptr ); + QgsForwardRenderView *rv = forwardRenderView(); + if ( rv ) + rv->setFrustumCullingEnabled( enabled ); } void QgsFrameGraph::setupEyeDomeLighting( bool enabled, double strength, int distance ) @@ -936,32 +779,17 @@ void QgsFrameGraph::setRenderCaptureEnabled( bool enabled ) void QgsFrameGraph::setDebugOverlayEnabled( bool enabled ) { - mDebugOverlay->setEnabled( enabled ); -} - -void QgsFrameGraph::removeClipPlanes() -{ - for ( Qt3DRender::QRenderState *state : mClipRenderStateSet->renderStates() ) - { - if ( qobject_cast( state ) ) - { - mClipRenderStateSet->removeRenderState( state ); - } - } + QgsForwardRenderView *rv = forwardRenderView(); + if ( rv ) + rv->setDebugOverlayEnabled( enabled ); } -void QgsFrameGraph::addClipPlanes( int nrClipPlanes ) +QgsForwardRenderView *QgsFrameGraph::forwardRenderView() const { - // remove existing QClipPlane - removeClipPlanes(); - - // create new QClipPlane - for ( int i = 0; i < nrClipPlanes; ++i ) - { - Qt3DRender::QClipPlane *clipPlane = new Qt3DRender::QClipPlane; - clipPlane->setPlaneIndex( i ); - mClipRenderStateSet->addRenderState( clipPlane ); - } + QgsAbstractRenderView *rv = mRenderViewMap[QgsFrameGraph::FORWARD_RENDERVIEW].get(); + if ( rv ) + return dynamic_cast( rv ); + return nullptr; } QgsShadowRenderView *QgsFrameGraph::shadowRenderView() const diff --git a/src/3d/framegraph/qgsframegraph.h b/src/3d/framegraph/qgsframegraph.h index 870261534762..e958f51503d9 100644 --- a/src/3d/framegraph/qgsframegraph.h +++ b/src/3d/framegraph/qgsframegraph.h @@ -73,11 +73,6 @@ class QgsFrameGraph : public Qt3DCore::QEntity //! Returns the root of the frame graph object Qt3DRender::QFrameGraphNode *frameGraphRoot() { return mRenderSurfaceSelector; } - //! Returns the color texture of the forward rendering pass - Qt3DRender::QTexture2D *forwardRenderColorTexture() { return mForwardColorTexture; } - //! Returns the depth texture of the forward rendering pass - Qt3DRender::QTexture2D *forwardRenderDepthTexture() { return mForwardDepthTexture; } - /** * Returns blurred ambient occlusion factor values texture * \since QGIS 3.28 @@ -86,21 +81,17 @@ 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 be rendered during the forward rendering pass - Qt3DRender::QLayer *forwardRenderLayer() { return mForwardRenderLayer; } /** * Returns a layer object used to indicate that the object is transparent * \since QGIS 3.26 */ - Qt3DRender::QLayer *transparentObjectLayer() { return mTransparentObjectsPassLayer; } + Qt3DRender::QLayer *transparentObjectLayer(); //! Returns the main camera Qt3DRender::QCamera *mainCamera() { return mMainCamera; } //! 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) - Qt3DCore::QEntity *rootEntity() { return mRootEntity; } //! Returns entity for all rubber bands (to show them always on top) Qt3DCore::QEntity *rubberBandsRootEntity() { return mRubberBandsRootEntity; } @@ -111,13 +102,9 @@ class QgsFrameGraph : public Qt3DCore::QEntity //! Returns the render capture object used to take an image of the depth buffer of the scene Qt3DRender::QRenderCapture *depthRenderCapture() { return mDepthRenderCapture; } - - //! Returns whether frustum culling is enabled - bool frustumCullingEnabled() const { return mFrustumCullingEnabled; } //! Sets whether frustum culling is enabled void setFrustumCullingEnabled( bool enabled ); - /** * Sets whether Screen Space Ambient Occlusion will be enabled * \since QGIS 3.28 @@ -240,34 +227,25 @@ class QgsFrameGraph : public Qt3DCore::QEntity //! Returns shadow renderview or nullptr if not defined QgsShadowRenderView *shadowRenderView() const; + //! Returns forward renderview or nullptr if not defined + QgsForwardRenderView *forwardRenderView() const; + //! Returns the render view named \a name, if any QgsAbstractRenderView *renderView( const QString &name ); //! Updates shadow bias, light and texture size according to \a shadowSettings and \a lightSources void updateShadowSettings( const QgsShadowSettings &shadowSettings, const QList &lightSources ); + static const QString FORWARD_RENDERVIEW; static const QString SHADOW_RENDERVIEW; static const QString AXIS3D_RENDERVIEW; private: Qt3DRender::QRenderSurfaceSelector *mRenderSurfaceSelector = nullptr; Qt3DRender::QViewport *mMainViewPort = nullptr; - bool mFrustumCullingEnabled = true; Qt3DRender::QCamera *mMainCamera = nullptr; - // Forward rendering pass branch nodes: - Qt3DRender::QCameraSelector *mMainCameraSelector = nullptr; - Qt3DRender::QLayerFilter *mForwardRenderLayerFilter = nullptr; - Qt3DRender::QRenderTargetSelector *mForwardRenderTargetSelector = nullptr; - Qt3DRender::QClearBuffers *mForwardClearBuffers = nullptr; - Qt3DRender::QFrustumCulling *mFrustumCulling = nullptr; - // Forward rendering pass texture related objects: - Qt3DRender::QTexture2D *mForwardColorTexture = nullptr; - Qt3DRender::QTexture2D *mForwardDepthTexture = nullptr; - // QDebugOverlay added in the forward pass - Qt3DRender::QDebugOverlay *mDebugOverlay = 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..) @@ -329,15 +307,10 @@ class QgsFrameGraph : public Qt3DCore::QEntity QVector3D mLightDirection = QVector3D( 0.0, -1.0f, 0.0f ); - // clip planes render state - Qt3DRender::QRenderStateSet *mClipRenderStateSet = nullptr; - Qt3DCore::QEntity *mRootEntity = nullptr; Qt3DRender::QLayer *mPreviewLayer = nullptr; - Qt3DRender::QLayer *mForwardRenderLayer = nullptr; Qt3DRender::QLayer *mDepthRenderPassLayer = nullptr; - Qt3DRender::QLayer *mTransparentObjectsPassLayer = nullptr; Qt3DRender::QLayer *mRubberBandsLayer = nullptr; QgsPostprocessingEntity *mPostprocessingEntity = nullptr; @@ -349,7 +322,8 @@ class QgsFrameGraph : public Qt3DCore::QEntity QVector mPreviewQuads; void constructShadowRenderPass(); - Qt3DRender::QFrameGraphNode *constructForwardRenderPass(); + void constructForwardRenderPass(); + Qt3DRender::QFrameGraphNode *constructTexturesPreviewPass(); Qt3DRender::QFrameGraphNode *constructPostprocessingPass(); Qt3DRender::QFrameGraphNode *constructDepthRenderPass(); Qt3DRender::QFrameGraphNode *constructAmbientOcclusionRenderPass(); diff --git a/src/3d/framegraph/qgspostprocessingentity.cpp b/src/3d/framegraph/qgspostprocessingentity.cpp index bccf8dd01a64..ff55c8344152 100644 --- a/src/3d/framegraph/qgspostprocessingentity.cpp +++ b/src/3d/framegraph/qgspostprocessingentity.cpp @@ -45,13 +45,15 @@ typedef Qt3DCore::QGeometry Qt3DQGeometry; #include "qgsdirectionallightsettings.h" #include "qgsframegraph.h" #include "qgsshadowrenderview.h" +#include "qgsforwardrenderview.h" QgsPostprocessingEntity::QgsPostprocessingEntity( QgsFrameGraph *frameGraph, Qt3DRender::QLayer *layer, QNode *parent ) : QgsRenderPassQuad( layer, parent ) { QgsShadowRenderView *shadowRenderView = frameGraph->shadowRenderView(); - mColorTextureParameter = new Qt3DRender::QParameter( QStringLiteral( "colorTexture" ), frameGraph->forwardRenderColorTexture() ); - mDepthTextureParameter = new Qt3DRender::QParameter( QStringLiteral( "depthTexture" ), frameGraph->forwardRenderDepthTexture() ); + QgsForwardRenderView *forwardRenderView = frameGraph->forwardRenderView(); + mColorTextureParameter = new Qt3DRender::QParameter( QStringLiteral( "colorTexture" ), forwardRenderView->colorTexture() ); + mDepthTextureParameter = new Qt3DRender::QParameter( QStringLiteral( "depthTexture" ), forwardRenderView->depthTexture() ); mShadowMapParameter = new Qt3DRender::QParameter( QStringLiteral( "shadowTexture" ), shadowRenderView->mapTexture() ); mAmbientOcclusionTextureParameter = new Qt3DRender::QParameter( QStringLiteral( "ssaoTexture" ), frameGraph->blurredAmbientOcclusionFactorMap() ); mMaterial->addParameter( mColorTextureParameter ); diff --git a/src/3d/qgs3dmapscene.cpp b/src/3d/qgs3dmapscene.cpp index 16d99a21160e..b919c6f426b6 100644 --- a/src/3d/qgs3dmapscene.cpp +++ b/src/3d/qgs3dmapscene.cpp @@ -84,6 +84,7 @@ #include "qgswindow3dengine.h" #include "qgspointcloudlayer.h" #include "qgsshadowrenderview.h" +#include "qgsforwardrenderview.h" std::function()> Qgs3DMapScene::sOpenScenesFunction = [] { return QMap(); }; @@ -1238,8 +1239,8 @@ void Qgs3DMapScene::enableClipping( const QList &clipPlaneEquations ) mClipPlanesEquations = clipPlaneEquations.mid( 0, mMaxClipPlanes ); // enable the clip planes on the framegraph - QgsFrameGraph *frameGraph = mEngine->frameGraph(); - frameGraph->addClipPlanes( clipPlaneEquations.size() ); + QgsForwardRenderView *forwardRenderView = mEngine->frameGraph()->forwardRenderView(); + forwardRenderView->addClipPlanes( clipPlaneEquations.size() ); // Enable the clip planes for the material of each entity. handleClippingOnAllEntities(); @@ -1250,8 +1251,8 @@ void Qgs3DMapScene::disableClipping() mClipPlanesEquations.clear(); // disable the clip planes on the framegraph - QgsFrameGraph *frameGraph = mEngine->frameGraph(); - frameGraph->removeClipPlanes(); + QgsForwardRenderView *forwardRenderView = mEngine->frameGraph()->forwardRenderView(); + forwardRenderView->removeClipPlanes(); // Disable the clip planes for the material of each entity. handleClippingOnAllEntities(); diff --git a/src/3d/qgsoffscreen3dengine.cpp b/src/3d/qgsoffscreen3dengine.cpp index 0100769cedda..c8607030fa7e 100644 --- a/src/3d/qgsoffscreen3dengine.cpp +++ b/src/3d/qgsoffscreen3dengine.cpp @@ -38,6 +38,7 @@ #include #include "qgsabstractrenderview.h" #include "qgsshadowrenderview.h" +#include "qgsforwardrenderview.h" QgsOffscreen3DEngine::QgsOffscreen3DEngine() { @@ -150,7 +151,7 @@ void QgsOffscreen3DEngine::setRootEntity( Qt3DCore::QEntity *root ) // Parent the incoming scene root to our current root entity. mSceneRoot = root; mSceneRoot->setParent( mRoot ); - root->addComponent( mFrameGraph->forwardRenderLayer() ); + root->addComponent( mFrameGraph->forwardRenderView()->renderLayer() ); root->addComponent( mFrameGraph->shadowRenderView()->entityCastingShadowsLayer() ); } diff --git a/src/3d/qgswindow3dengine.cpp b/src/3d/qgswindow3dengine.cpp index 1fe2a10431a4..fb5c6754b41b 100644 --- a/src/3d/qgswindow3dengine.cpp +++ b/src/3d/qgswindow3dengine.cpp @@ -20,11 +20,11 @@ #include #include "qgsabstractrenderview.h" -#include "qgspreviewquad.h" #include "qgs3dmapcanvas.h" #include "qgsframegraph.h" #include "qgsshadowrenderview.h" +#include "qgsforwardrenderview.h" QgsWindow3DEngine::QgsWindow3DEngine( Qgs3DMapCanvas *parent ) : QgsAbstract3DEngine( parent ) @@ -66,7 +66,7 @@ void QgsWindow3DEngine::setRootEntity( Qt3DCore::QEntity *root ) { mSceneRoot = root; mSceneRoot->setParent( mRoot ); - mSceneRoot->addComponent( mFrameGraph->forwardRenderLayer() ); + mSceneRoot->addComponent( mFrameGraph->forwardRenderView()->renderLayer() ); mSceneRoot->addComponent( mFrameGraph->shadowRenderView()->entityCastingShadowsLayer() ); } 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 1b57c326981b..cddd8f96f593 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,47 +1,49 @@ -(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/}) +(Qt3DRender::QRenderSurfaceSelector{10/}) + (Qt3DRender::QViewport{11/}) + (Qt3DRender::QNoDraw{12/forward::NoDraw}) [D] + (Qt3DRender::QSubtreeEnabler{13/forward::SubtreeEnabler}) + (Qt3DRender::QCameraSelector{16/forward::CameraSelector}) [ (Qt3DRender::QCamera:{0/}) ] + (Qt3DRender::QLayerFilter{17/}) [ (AcceptAnyMatchingLayers:[ {14/forward::Layer} ]) ] + (Qt3DRender::QRenderStateSet{18/forward::Clip Plane RenderStateSet}) [ ] + (Qt3DRender::QRenderTargetSelector{24/}) [ (outputs:[ (Depth:{20[DepthFormat]/), (Color0:{19[RGB8_UNorm]/) ]) ] + (Qt3DRender::QLayerFilter{25/}) [ (DiscardAnyMatchingLayers:[ {15/forward::TransparentLayer} ]) ] + (Qt3DRender::QRenderStateSet{26/}) [ (QDepthTest:Less), (QCullFace:Back) ] + (Qt3DRender::QFrustumCulling{29/}) + (Qt3DRender::QClearBuffers{30/}) + (Qt3DRender::QDebugOverlay{43/}) [D] + (Qt3DRender::QLayerFilter{31/}) [ (AcceptAnyMatchingLayers:[ {15/forward::TransparentLayer} ]) ] + (Qt3DRender::QSortPolicy{32/}) + (Qt3DRender::QRenderStateSet{33/}) [ (QDepthTest:Less), (QNoDepthMask), (QCullFace:NoCulling), (QBlendEquation:Add), (QBlendEquationArguments:[ (sourceRgb:SourceAlpha), (destinationRgb:Source1Alpha), (sourceAlpha:One), (destinationAlpha:Zero), (bufferIndex:-1) ]) ] + (Qt3DRender::QRenderStateSet{39/}) [ (QDepthTest:Less), (QColorMask:[ (red:false), (green:false), (blue:false), (alpha:false) ]), (QCullFace:NoCulling) ] + (Qt3DRender::QCameraSelector{44/rubberBandsPass}) [ (Qt3DRender::QCamera:{0/}) ] + (Qt3DRender::QLayerFilter{45/}) [ (AcceptAnyMatchingLayers:[ {9/mRubberBandsLayer} ]) ] + (Qt3DRender::QRenderStateSet{48/}) [ (QDepthTest:Always), (QBlendEquationArguments:[ (sourceRgb:SourceAlpha), (destinationRgb:Source1Alpha), (sourceAlpha:One), (destinationAlpha:Zero), (bufferIndex:-1) ]), (QBlendEquation:Add) ] + (Qt3DRender::QRenderTargetSelector{50/}) [ (outputs:[ (Depth:{20[DepthFormat]/), (Color0:{19[RGB8_UNorm]/) ]) ] + (Qt3DRender::QNoDraw{51/shadow::NoDraw}) + (Qt3DRender::QSubtreeEnabler{52/shadow::SubtreeEnabler}) [D] + (Qt3DRender::QCameraSelector{57/shadow::CameraSelector}) [ (Qt3DRender::QCamera:{53/shadow::LightCamera}) ] + (Qt3DRender::QLayerFilter{58/}) [D] [ (AcceptAnyMatchingLayers:[ {56/shadow::Layer} ]) ] + (Qt3DRender::QRenderTargetSelector{59/}) [ (outputs:[ (Depth:{65[DepthFormat]/QgsShadowRenderView::DepthTarget) ]) ] + (Qt3DRender::QClearBuffers{60/}) + (Qt3DRender::QRenderStateSet{61/}) [ (QDepthTest:Less), (QCullFace:Front), (QPolygonOffset:[ (scaleFactor:1.1), (depthSteps:4) ]) ] + (Qt3DRender::QCameraSelector{68/Depth render view CameraSelector}) [ (Qt3DRender::QCamera:{0/}) ] + (Qt3DRender::QRenderStateSet{69/}) [ (QDepthTest:Always), (QCullFace:NoCulling) ] + (Qt3DRender::QLayerFilter{72/}) [ (AcceptAnyMatchingLayers:[ {8/} ]) ] + (Qt3DRender::QRenderTargetSelector{73/}) [ (outputs:[ (Color0:{76[RGB8_UNorm]/), (Depth:{78[DepthFormat]/) ]) ] + (Qt3DRender::QRenderCapture{79/}) + (Qt3DRender::QCameraSelector{80/AmbientOcclusion render pass CameraSelector}) [ (Qt3DRender::QCamera:{0/}) ] + (Qt3DRender::QRenderStateSet{81/}) [ (QDepthTest:Always), (QCullFace:NoCulling) ] + (Qt3DRender::QLayerFilter{84/}) [ (AcceptAnyMatchingLayers:[ {89/} ]) ] + (Qt3DRender::QRenderTargetSelector{85/}) [ (outputs:[ (Color0:{88[R32F]/) ]) ] + (Qt3DRender::QCameraSelector{112/AmbientOcclusion blur pass CameraSelector}) [ (Qt3DRender::QCamera:{0/}) ] + (Qt3DRender::QRenderStateSet{113/}) [ (QDepthTest:Always), (QCullFace:NoCulling) ] + (Qt3DRender::QLayerFilter{116/}) [ (AcceptAnyMatchingLayers:[ {121/} ]) ] + (Qt3DRender::QRenderTargetSelector{117/}) [ (outputs:[ (Color0:{120[R32F]/) ]) ] + (Qt3DRender::QRenderTargetSelector{134/PostProcessingPass}) [ (outputs:[ (Color0:{137[RGB8_UNorm]/PostProcessingPass::ColorTarget), (Depth:{139[DepthFormat]/PostProcessingPass::DepthTarget) ]) ] + (Qt3DRender::QCameraSelector{140/Sub pass Postprocessing}) [ (Qt3DRender::QCamera:{53/shadow::LightCamera}) ] + (Qt3DRender::QLayerFilter{141/}) [ (AcceptAnyMatchingLayers:[ {143/} ]) ] + (Qt3DRender::QClearBuffers{142/}) + (Qt3DRender::QLayerFilter{177/Sub pass TexturesPreview}) [ (AcceptAnyMatchingLayers:[ {7/} ]) ] + (Qt3DRender::QRenderStateSet{178/}) [ (QDepthTest:Always), (QCullFace:NoCulling) ] + (Qt3DRender::QNoDraw{181/Sub pass RenderCapture}) + (Qt3DRender::QRenderCapture{182/}) 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 1b57c326981b..cddd8f96f593 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,47 +1,49 @@ -(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/}) +(Qt3DRender::QRenderSurfaceSelector{10/}) + (Qt3DRender::QViewport{11/}) + (Qt3DRender::QNoDraw{12/forward::NoDraw}) [D] + (Qt3DRender::QSubtreeEnabler{13/forward::SubtreeEnabler}) + (Qt3DRender::QCameraSelector{16/forward::CameraSelector}) [ (Qt3DRender::QCamera:{0/}) ] + (Qt3DRender::QLayerFilter{17/}) [ (AcceptAnyMatchingLayers:[ {14/forward::Layer} ]) ] + (Qt3DRender::QRenderStateSet{18/forward::Clip Plane RenderStateSet}) [ ] + (Qt3DRender::QRenderTargetSelector{24/}) [ (outputs:[ (Depth:{20[DepthFormat]/), (Color0:{19[RGB8_UNorm]/) ]) ] + (Qt3DRender::QLayerFilter{25/}) [ (DiscardAnyMatchingLayers:[ {15/forward::TransparentLayer} ]) ] + (Qt3DRender::QRenderStateSet{26/}) [ (QDepthTest:Less), (QCullFace:Back) ] + (Qt3DRender::QFrustumCulling{29/}) + (Qt3DRender::QClearBuffers{30/}) + (Qt3DRender::QDebugOverlay{43/}) [D] + (Qt3DRender::QLayerFilter{31/}) [ (AcceptAnyMatchingLayers:[ {15/forward::TransparentLayer} ]) ] + (Qt3DRender::QSortPolicy{32/}) + (Qt3DRender::QRenderStateSet{33/}) [ (QDepthTest:Less), (QNoDepthMask), (QCullFace:NoCulling), (QBlendEquation:Add), (QBlendEquationArguments:[ (sourceRgb:SourceAlpha), (destinationRgb:Source1Alpha), (sourceAlpha:One), (destinationAlpha:Zero), (bufferIndex:-1) ]) ] + (Qt3DRender::QRenderStateSet{39/}) [ (QDepthTest:Less), (QColorMask:[ (red:false), (green:false), (blue:false), (alpha:false) ]), (QCullFace:NoCulling) ] + (Qt3DRender::QCameraSelector{44/rubberBandsPass}) [ (Qt3DRender::QCamera:{0/}) ] + (Qt3DRender::QLayerFilter{45/}) [ (AcceptAnyMatchingLayers:[ {9/mRubberBandsLayer} ]) ] + (Qt3DRender::QRenderStateSet{48/}) [ (QDepthTest:Always), (QBlendEquationArguments:[ (sourceRgb:SourceAlpha), (destinationRgb:Source1Alpha), (sourceAlpha:One), (destinationAlpha:Zero), (bufferIndex:-1) ]), (QBlendEquation:Add) ] + (Qt3DRender::QRenderTargetSelector{50/}) [ (outputs:[ (Depth:{20[DepthFormat]/), (Color0:{19[RGB8_UNorm]/) ]) ] + (Qt3DRender::QNoDraw{51/shadow::NoDraw}) + (Qt3DRender::QSubtreeEnabler{52/shadow::SubtreeEnabler}) [D] + (Qt3DRender::QCameraSelector{57/shadow::CameraSelector}) [ (Qt3DRender::QCamera:{53/shadow::LightCamera}) ] + (Qt3DRender::QLayerFilter{58/}) [D] [ (AcceptAnyMatchingLayers:[ {56/shadow::Layer} ]) ] + (Qt3DRender::QRenderTargetSelector{59/}) [ (outputs:[ (Depth:{65[DepthFormat]/QgsShadowRenderView::DepthTarget) ]) ] + (Qt3DRender::QClearBuffers{60/}) + (Qt3DRender::QRenderStateSet{61/}) [ (QDepthTest:Less), (QCullFace:Front), (QPolygonOffset:[ (scaleFactor:1.1), (depthSteps:4) ]) ] + (Qt3DRender::QCameraSelector{68/Depth render view CameraSelector}) [ (Qt3DRender::QCamera:{0/}) ] + (Qt3DRender::QRenderStateSet{69/}) [ (QDepthTest:Always), (QCullFace:NoCulling) ] + (Qt3DRender::QLayerFilter{72/}) [ (AcceptAnyMatchingLayers:[ {8/} ]) ] + (Qt3DRender::QRenderTargetSelector{73/}) [ (outputs:[ (Color0:{76[RGB8_UNorm]/), (Depth:{78[DepthFormat]/) ]) ] + (Qt3DRender::QRenderCapture{79/}) + (Qt3DRender::QCameraSelector{80/AmbientOcclusion render pass CameraSelector}) [ (Qt3DRender::QCamera:{0/}) ] + (Qt3DRender::QRenderStateSet{81/}) [ (QDepthTest:Always), (QCullFace:NoCulling) ] + (Qt3DRender::QLayerFilter{84/}) [ (AcceptAnyMatchingLayers:[ {89/} ]) ] + (Qt3DRender::QRenderTargetSelector{85/}) [ (outputs:[ (Color0:{88[R32F]/) ]) ] + (Qt3DRender::QCameraSelector{112/AmbientOcclusion blur pass CameraSelector}) [ (Qt3DRender::QCamera:{0/}) ] + (Qt3DRender::QRenderStateSet{113/}) [ (QDepthTest:Always), (QCullFace:NoCulling) ] + (Qt3DRender::QLayerFilter{116/}) [ (AcceptAnyMatchingLayers:[ {121/} ]) ] + (Qt3DRender::QRenderTargetSelector{117/}) [ (outputs:[ (Color0:{120[R32F]/) ]) ] + (Qt3DRender::QRenderTargetSelector{134/PostProcessingPass}) [ (outputs:[ (Color0:{137[RGB8_UNorm]/PostProcessingPass::ColorTarget), (Depth:{139[DepthFormat]/PostProcessingPass::DepthTarget) ]) ] + (Qt3DRender::QCameraSelector{140/Sub pass Postprocessing}) [ (Qt3DRender::QCamera:{53/shadow::LightCamera}) ] + (Qt3DRender::QLayerFilter{141/}) [ (AcceptAnyMatchingLayers:[ {143/} ]) ] + (Qt3DRender::QClearBuffers{142/}) + (Qt3DRender::QLayerFilter{177/Sub pass TexturesPreview}) [ (AcceptAnyMatchingLayers:[ {7/} ]) ] + (Qt3DRender::QRenderStateSet{178/}) [ (QDepthTest:Always), (QCullFace:NoCulling) ] + (Qt3DRender::QNoDraw{181/Sub pass RenderCapture}) + (Qt3DRender::QRenderCapture{182/})