mirror of
https://github.com/qgis/QGIS.git
synced 2025-07-03 00:03:10 -04:00
Compare commits
8 Commits
94908afb9f
...
3933442314
Author | SHA1 | Date | |
---|---|---|---|
|
3933442314 | ||
|
b927df884f | ||
|
6fd32d92fd | ||
|
45c583a3fa | ||
|
cab9925a93 | ||
|
a0d4da9fae | ||
|
384ca812ef | ||
|
ee389586d9 |
@ -658,6 +658,9 @@ class Repositories(QObject):
|
|||||||
.text()
|
.text()
|
||||||
.strip()
|
.strip()
|
||||||
)
|
)
|
||||||
|
supports_qt6 = pluginNodes.item(i).firstChildElement(
|
||||||
|
"supports_qt6"
|
||||||
|
).text().strip().upper() in ["TRUE", "YES"]
|
||||||
if not qgisMaximumVersion:
|
if not qgisMaximumVersion:
|
||||||
if qgisMinimumVersion[0] == "3" and supports_qt6:
|
if qgisMinimumVersion[0] == "3" and supports_qt6:
|
||||||
qgisMaximumVersion = "4.99"
|
qgisMaximumVersion = "4.99"
|
||||||
|
@ -90,6 +90,7 @@ set(QGIS_3D_SRCS
|
|||||||
framegraph/qgsforwardrenderview.cpp
|
framegraph/qgsforwardrenderview.cpp
|
||||||
framegraph/qgspostprocessingentity.cpp
|
framegraph/qgspostprocessingentity.cpp
|
||||||
framegraph/qgsrenderpassquad.cpp
|
framegraph/qgsrenderpassquad.cpp
|
||||||
|
framegraph/qgspostprocessingrenderview.cpp
|
||||||
framegraph/qgsshadowrenderview.cpp
|
framegraph/qgsshadowrenderview.cpp
|
||||||
framegraph/qgsframegraph.cpp
|
framegraph/qgsframegraph.cpp
|
||||||
framegraph/qgsframegraphutils.cpp
|
framegraph/qgsframegraphutils.cpp
|
||||||
@ -207,6 +208,7 @@ set(QGIS_3D_HDRS
|
|||||||
framegraph/qgsframegraphutils.h
|
framegraph/qgsframegraphutils.h
|
||||||
framegraph/qgspostprocessingentity.h
|
framegraph/qgspostprocessingentity.h
|
||||||
framegraph/qgsrenderpassquad.h
|
framegraph/qgsrenderpassquad.h
|
||||||
|
framegraph/qgspostprocessingrenderview.h
|
||||||
framegraph/qgsshadowrenderview.h
|
framegraph/qgsshadowrenderview.h
|
||||||
|
|
||||||
symbols/qgsbillboardgeometry.h
|
symbols/qgsbillboardgeometry.h
|
||||||
|
@ -67,6 +67,9 @@ class QgsForwardRenderView : public QgsAbstractRenderView
|
|||||||
//! Sets whether debug overlay is enabled
|
//! Sets whether debug overlay is enabled
|
||||||
void setDebugOverlayEnabled( bool enabled );
|
void setDebugOverlayEnabled( bool enabled );
|
||||||
|
|
||||||
|
//! Returns main camera
|
||||||
|
Qt3DRender::QCamera *mainCamera() const { return mMainCamera; }
|
||||||
|
|
||||||
//! Returns current render target selector
|
//! Returns current render target selector
|
||||||
Qt3DRender::QRenderTargetSelector *renderTargetSelector() { return mRenderTargetSelector; }
|
Qt3DRender::QRenderTargetSelector *renderTargetSelector() { return mRenderTargetSelector; }
|
||||||
|
|
||||||
|
@ -58,6 +58,7 @@ typedef Qt3DCore::QGeometry Qt3DQGeometry;
|
|||||||
#include "qgsdebugtexturerenderview.h"
|
#include "qgsdebugtexturerenderview.h"
|
||||||
#include "qgsdebugtextureentity.h"
|
#include "qgsdebugtextureentity.h"
|
||||||
#include "qgsambientocclusionrenderview.h"
|
#include "qgsambientocclusionrenderview.h"
|
||||||
|
#include "qgspostprocessingrenderview.h"
|
||||||
|
|
||||||
const QString QgsFrameGraph::FORWARD_RENDERVIEW = "forward";
|
const QString QgsFrameGraph::FORWARD_RENDERVIEW = "forward";
|
||||||
const QString QgsFrameGraph::SHADOW_RENDERVIEW = "shadow";
|
const QString QgsFrameGraph::SHADOW_RENDERVIEW = "shadow";
|
||||||
@ -65,6 +66,7 @@ const QString QgsFrameGraph::AXIS3D_RENDERVIEW = "3daxis";
|
|||||||
const QString QgsFrameGraph::DEPTH_RENDERVIEW = "depth";
|
const QString QgsFrameGraph::DEPTH_RENDERVIEW = "depth";
|
||||||
const QString QgsFrameGraph::DEBUG_RENDERVIEW = "debug_texture";
|
const QString QgsFrameGraph::DEBUG_RENDERVIEW = "debug_texture";
|
||||||
const QString QgsFrameGraph::AMBIENT_OCCLUSION_RENDERVIEW = "ambient_occlusion";
|
const QString QgsFrameGraph::AMBIENT_OCCLUSION_RENDERVIEW = "ambient_occlusion";
|
||||||
|
const QString QgsFrameGraph::POSTPROC_RENDERVIEW = "post_processing";
|
||||||
|
|
||||||
void QgsFrameGraph::constructForwardRenderPass()
|
void QgsFrameGraph::constructForwardRenderPass()
|
||||||
{
|
{
|
||||||
@ -81,85 +83,24 @@ void QgsFrameGraph::constructDebugTexturePass( Qt3DRender::QFrameGraphNode *topN
|
|||||||
registerRenderView( std::make_unique<QgsDebugTextureRenderView>( DEBUG_RENDERVIEW ), DEBUG_RENDERVIEW, topNode );
|
registerRenderView( std::make_unique<QgsDebugTextureRenderView>( DEBUG_RENDERVIEW ), DEBUG_RENDERVIEW, topNode );
|
||||||
}
|
}
|
||||||
|
|
||||||
Qt3DRender::QFrameGraphNode *QgsFrameGraph::constructSubPostPassForProcessing()
|
void QgsFrameGraph::constructPostprocessingPass()
|
||||||
{
|
{
|
||||||
Qt3DRender::QCameraSelector *cameraSelector = new Qt3DRender::QCameraSelector;
|
// create post processing render view and register it
|
||||||
cameraSelector->setObjectName( "Sub pass Postprocessing" );
|
QgsPostprocessingRenderView *pprv = new QgsPostprocessingRenderView( POSTPROC_RENDERVIEW, //
|
||||||
cameraSelector->setCamera( shadowRenderView().lightCamera() );
|
shadowRenderView(), //
|
||||||
|
forwardRenderView(), //
|
||||||
|
ambientOcclusionRenderView(), //
|
||||||
|
mSize, //
|
||||||
|
mRootEntity );
|
||||||
|
registerRenderView( std::unique_ptr<QgsPostprocessingRenderView>( pprv ), POSTPROC_RENDERVIEW );
|
||||||
|
|
||||||
Qt3DRender::QLayerFilter *layerFilter = new Qt3DRender::QLayerFilter( cameraSelector );
|
// create debug texture render view and register it (will be detach from main framegraph and attach to postprocessing renderview)
|
||||||
|
constructDebugTexturePass();
|
||||||
|
|
||||||
// could be the first of this branch
|
// add debug texture render view to post processing subpasses (before the render capture one)
|
||||||
new Qt3DRender::QClearBuffers( layerFilter );
|
QVector<Qt3DRender::QFrameGraphNode *> subPasses = pprv->subPasses();
|
||||||
|
subPasses.insert( subPasses.length() - 1, renderView( DEBUG_RENDERVIEW )->topGraphNode() );
|
||||||
Qt3DRender::QLayer *postProcessingLayer = new Qt3DRender::QLayer();
|
pprv->setSubPasses( subPasses );
|
||||||
mPostprocessingEntity = new QgsPostprocessingEntity( this, postProcessingLayer, mRootEntity );
|
|
||||||
layerFilter->addLayer( postProcessingLayer );
|
|
||||||
mPostprocessingEntity->setObjectName( "PostProcessingPassEntity" );
|
|
||||||
|
|
||||||
return cameraSelector;
|
|
||||||
}
|
|
||||||
|
|
||||||
Qt3DRender::QFrameGraphNode *QgsFrameGraph::constructSubPostPassForRenderCapture()
|
|
||||||
{
|
|
||||||
Qt3DRender::QFrameGraphNode *top = new Qt3DRender::QNoDraw;
|
|
||||||
top->setObjectName( "Sub pass RenderCapture" );
|
|
||||||
|
|
||||||
mRenderCapture = new Qt3DRender::QRenderCapture( top );
|
|
||||||
|
|
||||||
return top;
|
|
||||||
}
|
|
||||||
|
|
||||||
Qt3DRender::QFrameGraphNode *QgsFrameGraph::constructPostprocessingPass()
|
|
||||||
{
|
|
||||||
mRenderCaptureTargetSelector = new Qt3DRender::QRenderTargetSelector;
|
|
||||||
mRenderCaptureTargetSelector->setObjectName( "Postprocessing render pass" );
|
|
||||||
mRenderCaptureTargetSelector->setEnabled( mRenderCaptureEnabled );
|
|
||||||
|
|
||||||
Qt3DRender::QRenderTarget *renderTarget = new Qt3DRender::QRenderTarget( mRenderCaptureTargetSelector );
|
|
||||||
|
|
||||||
// The lifetime of the objects created here is managed
|
|
||||||
// automatically, as they become children of this object.
|
|
||||||
|
|
||||||
// Create a render target output for rendering color.
|
|
||||||
Qt3DRender::QRenderTargetOutput *colorOutput = new Qt3DRender::QRenderTargetOutput( renderTarget );
|
|
||||||
colorOutput->setAttachmentPoint( Qt3DRender::QRenderTargetOutput::Color0 );
|
|
||||||
|
|
||||||
// Create a texture to render into.
|
|
||||||
mRenderCaptureColorTexture = new Qt3DRender::QTexture2D( colorOutput );
|
|
||||||
mRenderCaptureColorTexture->setSize( mSize.width(), mSize.height() );
|
|
||||||
mRenderCaptureColorTexture->setFormat( Qt3DRender::QAbstractTexture::RGB8_UNorm );
|
|
||||||
mRenderCaptureColorTexture->setMinificationFilter( Qt3DRender::QAbstractTexture::Linear );
|
|
||||||
mRenderCaptureColorTexture->setMagnificationFilter( Qt3DRender::QAbstractTexture::Linear );
|
|
||||||
mRenderCaptureColorTexture->setObjectName( "PostProcessingPass::ColorTarget" );
|
|
||||||
|
|
||||||
// Hook the texture up to our output, and the output up to this object.
|
|
||||||
colorOutput->setTexture( mRenderCaptureColorTexture );
|
|
||||||
renderTarget->addOutput( colorOutput );
|
|
||||||
|
|
||||||
Qt3DRender::QRenderTargetOutput *depthOutput = new Qt3DRender::QRenderTargetOutput( renderTarget );
|
|
||||||
|
|
||||||
depthOutput->setAttachmentPoint( Qt3DRender::QRenderTargetOutput::Depth );
|
|
||||||
mRenderCaptureDepthTexture = new Qt3DRender::QTexture2D( depthOutput );
|
|
||||||
mRenderCaptureDepthTexture->setSize( mSize.width(), mSize.height() );
|
|
||||||
mRenderCaptureDepthTexture->setFormat( Qt3DRender::QAbstractTexture::DepthFormat );
|
|
||||||
mRenderCaptureDepthTexture->setMinificationFilter( Qt3DRender::QAbstractTexture::Linear );
|
|
||||||
mRenderCaptureDepthTexture->setMagnificationFilter( Qt3DRender::QAbstractTexture::Linear );
|
|
||||||
mRenderCaptureDepthTexture->setComparisonFunction( Qt3DRender::QAbstractTexture::CompareLessEqual );
|
|
||||||
mRenderCaptureDepthTexture->setComparisonMode( Qt3DRender::QAbstractTexture::CompareRefToTexture );
|
|
||||||
mRenderCaptureDepthTexture->setObjectName( "PostProcessingPass::DepthTarget" );
|
|
||||||
|
|
||||||
depthOutput->setTexture( mRenderCaptureDepthTexture );
|
|
||||||
renderTarget->addOutput( depthOutput );
|
|
||||||
|
|
||||||
mRenderCaptureTargetSelector->setTarget( renderTarget );
|
|
||||||
|
|
||||||
// sub passes:
|
|
||||||
constructSubPostPassForProcessing()->setParent( mRenderCaptureTargetSelector );
|
|
||||||
constructDebugTexturePass( mRenderCaptureTargetSelector );
|
|
||||||
constructSubPostPassForRenderCapture()->setParent( mRenderCaptureTargetSelector );
|
|
||||||
|
|
||||||
return mRenderCaptureTargetSelector;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QgsFrameGraph::constructAmbientOcclusionRenderPass()
|
void QgsFrameGraph::constructAmbientOcclusionRenderPass()
|
||||||
@ -202,7 +143,6 @@ Qt3DRender::QFrameGraphNode *QgsFrameGraph::constructRubberBandsPass()
|
|||||||
return mRubberBandsCameraSelector;
|
return mRubberBandsCameraSelector;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void QgsFrameGraph::constructDepthRenderPass()
|
void QgsFrameGraph::constructDepthRenderPass()
|
||||||
{
|
{
|
||||||
// entity used to draw the depth texture and convert it to rgb image
|
// entity used to draw the depth texture and convert it to rgb image
|
||||||
@ -284,9 +224,7 @@ QgsFrameGraph::QgsFrameGraph( QSurface *surface, QSize s, Qt3DRender::QCamera *m
|
|||||||
constructAmbientOcclusionRenderPass();
|
constructAmbientOcclusionRenderPass();
|
||||||
|
|
||||||
// post process
|
// post process
|
||||||
Qt3DRender::QFrameGraphNode *postprocessingPass = constructPostprocessingPass();
|
constructPostprocessingPass();
|
||||||
postprocessingPass->setParent( mMainViewPort );
|
|
||||||
postprocessingPass->setObjectName( "PostProcessingPass" );
|
|
||||||
|
|
||||||
mRubberBandsRootEntity = new Qt3DCore::QEntity( mRootEntity );
|
mRubberBandsRootEntity = new Qt3DCore::QEntity( mRootEntity );
|
||||||
mRubberBandsRootEntity->setObjectName( "mRubberBandsRootEntity" );
|
mRubberBandsRootEntity->setObjectName( "mRubberBandsRootEntity" );
|
||||||
@ -349,14 +287,13 @@ void QgsFrameGraph::updateAmbientOcclusionSettings( const QgsAmbientOcclusionSet
|
|||||||
aoRenderView.setThreshold( settings.threshold() );
|
aoRenderView.setThreshold( settings.threshold() );
|
||||||
aoRenderView.setEnabled( settings.isEnabled() );
|
aoRenderView.setEnabled( settings.isEnabled() );
|
||||||
|
|
||||||
mPostprocessingEntity->setAmbientOcclusionEnabled( settings.isEnabled() );
|
postprocessingRenderView().entity()->setAmbientOcclusionEnabled( settings.isEnabled() );
|
||||||
}
|
}
|
||||||
|
|
||||||
void QgsFrameGraph::updateEyeDomeSettings( const Qgs3DMapSettings &settings )
|
void QgsFrameGraph::updateEyeDomeSettings( const Qgs3DMapSettings &settings )
|
||||||
{
|
{
|
||||||
mPostprocessingEntity->setEyeDomeLightingEnabled( settings.eyeDomeLightingEnabled() );
|
postprocessingRenderView().entity()->setEyeDomeLightingEnabled( settings.eyeDomeLightingEnabled() );
|
||||||
mPostprocessingEntity->setEyeDomeLightingStrength( settings.eyeDomeLightingStrength() );
|
postprocessingRenderView().entity()->updateEyeDomeSettings( settings );
|
||||||
mPostprocessingEntity->setEyeDomeLightingDistance( settings.eyeDomeLightingDistance() );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QgsFrameGraph::updateShadowSettings( const QgsShadowSettings &shadowSettings, const QList<QgsLightSource *> &lightSources )
|
void QgsFrameGraph::updateShadowSettings( const QgsShadowSettings &shadowSettings, const QList<QgsLightSource *> &lightSources )
|
||||||
@ -379,15 +316,14 @@ void QgsFrameGraph::updateShadowSettings( const QgsShadowSettings &shadowSetting
|
|||||||
{
|
{
|
||||||
shadowRenderView().setMapSize( shadowSettings.shadowMapResolution(), shadowSettings.shadowMapResolution() );
|
shadowRenderView().setMapSize( shadowSettings.shadowMapResolution(), shadowSettings.shadowMapResolution() );
|
||||||
shadowRenderView().setEnabled( true );
|
shadowRenderView().setEnabled( true );
|
||||||
mPostprocessingEntity->setShadowRenderingEnabled( true );
|
postprocessingRenderView().entity()->setShadowRenderingEnabled( true );
|
||||||
mPostprocessingEntity->setShadowBias( static_cast<float>( shadowSettings.shadowBias() ) );
|
postprocessingRenderView().entity()->updateShadowSettings( shadowSettings, *light );
|
||||||
mPostprocessingEntity->updateShadowSettings( *light, static_cast<float>( shadowSettings.maximumShadowRenderingDistance() ) );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
shadowRenderView().setEnabled( false );
|
shadowRenderView().setEnabled( false );
|
||||||
mPostprocessingEntity->setShadowRenderingEnabled( false );
|
postprocessingRenderView().entity()->setShadowRenderingEnabled( false );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -477,22 +413,17 @@ void QgsFrameGraph::setSize( QSize s )
|
|||||||
rv->updateWindowResize( mSize.width(), mSize.height() );
|
rv->updateWindowResize( mSize.width(), mSize.height() );
|
||||||
}
|
}
|
||||||
|
|
||||||
mRenderCaptureColorTexture->setSize( mSize.width(), mSize.height() );
|
|
||||||
mRenderCaptureDepthTexture->setSize( mSize.width(), mSize.height() );
|
|
||||||
mRenderSurfaceSelector->setExternalRenderTargetSize( mSize );
|
mRenderSurfaceSelector->setExternalRenderTargetSize( mSize );
|
||||||
}
|
}
|
||||||
|
|
||||||
Qt3DRender::QRenderCapture *QgsFrameGraph::renderCapture()
|
Qt3DRender::QRenderCapture *QgsFrameGraph::renderCapture()
|
||||||
{
|
{
|
||||||
return mRenderCapture;
|
return postprocessingRenderView().renderCapture();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QgsFrameGraph::setRenderCaptureEnabled( bool enabled )
|
void QgsFrameGraph::setRenderCaptureEnabled( bool enabled )
|
||||||
{
|
{
|
||||||
if ( enabled == mRenderCaptureEnabled )
|
postprocessingRenderView().setOffScreenRenderCaptureEnabled( enabled );
|
||||||
return;
|
|
||||||
mRenderCaptureEnabled = enabled;
|
|
||||||
mRenderCaptureTargetSelector->setEnabled( mRenderCaptureEnabled );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QgsFrameGraph::setDebugOverlayEnabled( bool enabled )
|
void QgsFrameGraph::setDebugOverlayEnabled( bool enabled )
|
||||||
@ -533,3 +464,9 @@ QgsAmbientOcclusionRenderView &QgsFrameGraph::ambientOcclusionRenderView()
|
|||||||
QgsAbstractRenderView *rv = mRenderViewMap[QgsFrameGraph::AMBIENT_OCCLUSION_RENDERVIEW].get();
|
QgsAbstractRenderView *rv = mRenderViewMap[QgsFrameGraph::AMBIENT_OCCLUSION_RENDERVIEW].get();
|
||||||
return *( dynamic_cast<QgsAmbientOcclusionRenderView *>( rv ) );
|
return *( dynamic_cast<QgsAmbientOcclusionRenderView *>( rv ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QgsPostprocessingRenderView &QgsFrameGraph::postprocessingRenderView()
|
||||||
|
{
|
||||||
|
QgsAbstractRenderView *rv = mRenderViewMap[QgsFrameGraph::POSTPROC_RENDERVIEW].get();
|
||||||
|
return *( dynamic_cast<QgsPostprocessingRenderView *>( rv ) );
|
||||||
|
}
|
||||||
|
@ -42,7 +42,6 @@
|
|||||||
class QgsDirectionalLightSettings;
|
class QgsDirectionalLightSettings;
|
||||||
class QgsCameraController;
|
class QgsCameraController;
|
||||||
class QgsRectangle;
|
class QgsRectangle;
|
||||||
class QgsPostprocessingEntity;
|
|
||||||
class QgsAbstractRenderView;
|
class QgsAbstractRenderView;
|
||||||
class QgsForwardRenderView;
|
class QgsForwardRenderView;
|
||||||
class QgsShadowRenderView;
|
class QgsShadowRenderView;
|
||||||
@ -51,6 +50,8 @@ class QgsShadowSettings;
|
|||||||
class QgsDebugTextureEntity;
|
class QgsDebugTextureEntity;
|
||||||
class QgsAmbientOcclusionRenderView;
|
class QgsAmbientOcclusionRenderView;
|
||||||
class QgsAmbientOcclusionSettings;
|
class QgsAmbientOcclusionSettings;
|
||||||
|
class QgsPostprocessingEntity;
|
||||||
|
class QgsPostprocessingRenderView;
|
||||||
|
|
||||||
#define SIP_NO_FILE
|
#define SIP_NO_FILE
|
||||||
|
|
||||||
@ -78,9 +79,6 @@ class QgsFrameGraph : public Qt3DCore::QEntity
|
|||||||
//! Returns the main camera
|
//! Returns the main camera
|
||||||
Qt3DRender::QCamera *mainCamera() { return mMainCamera; }
|
Qt3DRender::QCamera *mainCamera() { return mMainCamera; }
|
||||||
|
|
||||||
//! Returns the postprocessing entity
|
|
||||||
QgsPostprocessingEntity *postprocessingEntity() { return mPostprocessingEntity; }
|
|
||||||
|
|
||||||
//! Returns entity for all rubber bands (to show them always on top)
|
//! Returns entity for all rubber bands (to show them always on top)
|
||||||
Qt3DCore::QEntity *rubberBandsRootEntity() { return mRubberBandsRootEntity; }
|
Qt3DCore::QEntity *rubberBandsRootEntity() { return mRubberBandsRootEntity; }
|
||||||
|
|
||||||
@ -191,6 +189,12 @@ class QgsFrameGraph : public Qt3DCore::QEntity
|
|||||||
*/
|
*/
|
||||||
QgsAmbientOcclusionRenderView &ambientOcclusionRenderView();
|
QgsAmbientOcclusionRenderView &ambientOcclusionRenderView();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns post processing renderview
|
||||||
|
* \since QGIS 3.44
|
||||||
|
*/
|
||||||
|
QgsPostprocessingRenderView &postprocessingRenderView();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates shadow bias, light and texture size according to \a shadowSettings and \a lightSources
|
* Updates shadow bias, light and texture size according to \a shadowSettings and \a lightSources
|
||||||
* \since QGIS 3.44
|
* \since QGIS 3.44
|
||||||
@ -228,6 +232,8 @@ class QgsFrameGraph : public Qt3DCore::QEntity
|
|||||||
static const QString DEBUG_RENDERVIEW;
|
static const QString DEBUG_RENDERVIEW;
|
||||||
//! Ambient occlusion render view name
|
//! Ambient occlusion render view name
|
||||||
static const QString AMBIENT_OCCLUSION_RENDERVIEW;
|
static const QString AMBIENT_OCCLUSION_RENDERVIEW;
|
||||||
|
//! Postprocessing render view name
|
||||||
|
static const QString POSTPROC_RENDERVIEW;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Qt3DRender::QRenderSurfaceSelector *mRenderSurfaceSelector = nullptr;
|
Qt3DRender::QRenderSurfaceSelector *mRenderSurfaceSelector = nullptr;
|
||||||
@ -235,13 +241,6 @@ class QgsFrameGraph : public Qt3DCore::QEntity
|
|||||||
|
|
||||||
Qt3DRender::QCamera *mMainCamera = nullptr;
|
Qt3DRender::QCamera *mMainCamera = nullptr;
|
||||||
|
|
||||||
// Post processing pass branch nodes:
|
|
||||||
Qt3DRender::QRenderTargetSelector *mRenderCaptureTargetSelector = nullptr;
|
|
||||||
Qt3DRender::QRenderCapture *mRenderCapture = nullptr;
|
|
||||||
// Post processing pass texture related objects:
|
|
||||||
Qt3DRender::QTexture2D *mRenderCaptureColorTexture = nullptr;
|
|
||||||
Qt3DRender::QTexture2D *mRenderCaptureDepthTexture = nullptr;
|
|
||||||
|
|
||||||
// Rubber bands pass
|
// Rubber bands pass
|
||||||
Qt3DRender::QCameraSelector *mRubberBandsCameraSelector = nullptr;
|
Qt3DRender::QCameraSelector *mRubberBandsCameraSelector = nullptr;
|
||||||
Qt3DRender::QLayerFilter *mRubberBandsLayerFilter = nullptr;
|
Qt3DRender::QLayerFilter *mRubberBandsLayerFilter = nullptr;
|
||||||
@ -256,8 +255,6 @@ class QgsFrameGraph : public Qt3DCore::QEntity
|
|||||||
|
|
||||||
Qt3DRender::QLayer *mRubberBandsLayer = nullptr;
|
Qt3DRender::QLayer *mRubberBandsLayer = nullptr;
|
||||||
|
|
||||||
QgsPostprocessingEntity *mPostprocessingEntity = nullptr;
|
|
||||||
|
|
||||||
Qt3DCore::QEntity *mRubberBandsRootEntity = nullptr;
|
Qt3DCore::QEntity *mRubberBandsRootEntity = nullptr;
|
||||||
|
|
||||||
//! shadow texture debugging
|
//! shadow texture debugging
|
||||||
@ -268,16 +265,11 @@ class QgsFrameGraph : public Qt3DCore::QEntity
|
|||||||
void constructShadowRenderPass();
|
void constructShadowRenderPass();
|
||||||
void constructForwardRenderPass();
|
void constructForwardRenderPass();
|
||||||
void constructDebugTexturePass( Qt3DRender::QFrameGraphNode *topNode = nullptr );
|
void constructDebugTexturePass( Qt3DRender::QFrameGraphNode *topNode = nullptr );
|
||||||
Qt3DRender::QFrameGraphNode *constructPostprocessingPass();
|
void constructPostprocessingPass();
|
||||||
void constructDepthRenderPass();
|
void constructDepthRenderPass();
|
||||||
void constructAmbientOcclusionRenderPass();
|
void constructAmbientOcclusionRenderPass();
|
||||||
Qt3DRender::QFrameGraphNode *constructRubberBandsPass();
|
Qt3DRender::QFrameGraphNode *constructRubberBandsPass();
|
||||||
|
|
||||||
Qt3DRender::QFrameGraphNode *constructSubPostPassForProcessing();
|
|
||||||
Qt3DRender::QFrameGraphNode *constructSubPostPassForRenderCapture();
|
|
||||||
|
|
||||||
bool mRenderCaptureEnabled = false;
|
|
||||||
|
|
||||||
// holds renderviews according to their name
|
// holds renderviews according to their name
|
||||||
std::map<QString, std::unique_ptr<QgsAbstractRenderView>> mRenderViewMap;
|
std::map<QString, std::unique_ptr<QgsAbstractRenderView>> mRenderViewMap;
|
||||||
|
|
||||||
|
@ -43,28 +43,30 @@ typedef Qt3DCore::QGeometry Qt3DQGeometry;
|
|||||||
|
|
||||||
#include "qgs3dutils.h"
|
#include "qgs3dutils.h"
|
||||||
#include "qgsdirectionallightsettings.h"
|
#include "qgsdirectionallightsettings.h"
|
||||||
|
#include "qgsshadowsettings.h"
|
||||||
#include "qgsframegraph.h"
|
#include "qgsframegraph.h"
|
||||||
#include "qgsshadowrenderview.h"
|
#include "qgsshadowrenderview.h"
|
||||||
#include "qgsforwardrenderview.h"
|
#include "qgsforwardrenderview.h"
|
||||||
#include "qgsambientocclusionrenderview.h"
|
#include "qgsambientocclusionrenderview.h"
|
||||||
|
|
||||||
QgsPostprocessingEntity::QgsPostprocessingEntity( QgsFrameGraph *frameGraph, Qt3DRender::QLayer *layer, QNode *parent )
|
QgsPostprocessingEntity::QgsPostprocessingEntity( const QgsShadowRenderView &shadowRenderView, //
|
||||||
|
const QgsForwardRenderView &forwardRenderView, //
|
||||||
|
const QgsAmbientOcclusionRenderView &aoRenderView, //
|
||||||
|
Qt3DRender::QLayer *layer, //
|
||||||
|
QNode *parent )
|
||||||
: QgsRenderPassQuad( layer, parent )
|
: QgsRenderPassQuad( layer, parent )
|
||||||
{
|
{
|
||||||
QgsShadowRenderView &shadowRenderView = frameGraph->shadowRenderView();
|
|
||||||
QgsForwardRenderView &forwardRenderView = frameGraph->forwardRenderView();
|
|
||||||
QgsAmbientOcclusionRenderView &aoRenderView = frameGraph->ambientOcclusionRenderView();
|
|
||||||
|
|
||||||
mColorTextureParameter = new Qt3DRender::QParameter( QStringLiteral( "colorTexture" ), forwardRenderView.colorTexture() );
|
mColorTextureParameter = new Qt3DRender::QParameter( QStringLiteral( "colorTexture" ), forwardRenderView.colorTexture() );
|
||||||
mDepthTextureParameter = new Qt3DRender::QParameter( QStringLiteral( "depthTexture" ), forwardRenderView.depthTexture() );
|
mDepthTextureParameter = new Qt3DRender::QParameter( QStringLiteral( "depthTexture" ), forwardRenderView.depthTexture() );
|
||||||
mShadowMapParameter = new Qt3DRender::QParameter( QStringLiteral( "shadowTexture" ), shadowRenderView.mapTexture() );
|
mShadowMapParameter = new Qt3DRender::QParameter( QStringLiteral( "shadowTexture" ), shadowRenderView.mapTexture() );
|
||||||
mAmbientOcclusionTextureParameter = new Qt3DRender::QParameter( QStringLiteral( "ssaoTexture" ), aoRenderView.blurredFactorMapTexture() );
|
mAmbientOcclusionTextureParameter = new Qt3DRender::QParameter( QStringLiteral( "ssaoTexture" ), aoRenderView.blurredFactorMapTexture() );
|
||||||
|
|
||||||
mMaterial->addParameter( mColorTextureParameter );
|
mMaterial->addParameter( mColorTextureParameter );
|
||||||
mMaterial->addParameter( mDepthTextureParameter );
|
mMaterial->addParameter( mDepthTextureParameter );
|
||||||
mMaterial->addParameter( mShadowMapParameter );
|
mMaterial->addParameter( mShadowMapParameter );
|
||||||
mMaterial->addParameter( mAmbientOcclusionTextureParameter );
|
mMaterial->addParameter( mAmbientOcclusionTextureParameter );
|
||||||
|
|
||||||
mMainCamera = frameGraph->mainCamera();
|
mMainCamera = forwardRenderView.mainCamera();
|
||||||
mLightCamera = shadowRenderView.lightCamera();
|
mLightCamera = shadowRenderView.lightCamera();
|
||||||
|
|
||||||
mFarPlaneParameter = new Qt3DRender::QParameter( QStringLiteral( "farPlane" ), mMainCamera->farPlane() );
|
mFarPlaneParameter = new Qt3DRender::QParameter( QStringLiteral( "farPlane" ), mMainCamera->farPlane() );
|
||||||
@ -151,14 +153,15 @@ void QgsPostprocessingEntity::setupDirectionalLight( QVector3D position, QVector
|
|||||||
mLightDirection->setValue( QVariant::fromValue( direction.normalized() ) );
|
mLightDirection->setValue( QVariant::fromValue( direction.normalized() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void QgsPostprocessingEntity::updateShadowSettings( const QgsDirectionalLightSettings &light, float maximumShadowRenderingDistance )
|
void QgsPostprocessingEntity::updateShadowSettings( const QgsShadowSettings &shadowSettings, const QgsDirectionalLightSettings &light )
|
||||||
{
|
{
|
||||||
float minX, maxX, minY, maxY, minZ, maxZ;
|
float minX, maxX, minY, maxY, minZ, maxZ;
|
||||||
QVector3D lookingAt = mMainCamera->viewCenter();
|
QVector3D lookingAt = mMainCamera->viewCenter();
|
||||||
const float d = 2 * ( mMainCamera->position() - mMainCamera->viewCenter() ).length();
|
const float d = 2 * ( mMainCamera->position() - mMainCamera->viewCenter() ).length();
|
||||||
|
|
||||||
const QVector3D lightDirection = light.direction().toVector3D().normalized();
|
const QVector3D lightDirection = light.direction().toVector3D().normalized();
|
||||||
Qgs3DUtils::calculateViewExtent( mMainCamera, maximumShadowRenderingDistance, lookingAt.z(), minX, maxX, minY, maxY, minZ, maxZ );
|
Qgs3DUtils::calculateViewExtent( mMainCamera, static_cast<float>( shadowSettings.maximumShadowRenderingDistance() ), //
|
||||||
|
lookingAt.z(), minX, maxX, minY, maxY, minZ, maxZ );
|
||||||
|
|
||||||
lookingAt = QVector3D( 0.5f * ( minX + maxX ), 0.5f * ( minY + maxY ), mMainCamera->viewCenter().z() );
|
lookingAt = QVector3D( 0.5f * ( minX + maxX ), 0.5f * ( minY + maxY ), mMainCamera->viewCenter().z() );
|
||||||
const QVector3D lightPosition = lookingAt + QVector3D( 0.0f, 0.0f, d );
|
const QVector3D lightPosition = lookingAt + QVector3D( 0.0f, 0.0f, d );
|
||||||
@ -176,6 +179,7 @@ void QgsPostprocessingEntity::updateShadowSettings( const QgsDirectionalLightSet
|
|||||||
|
|
||||||
setupShadowRenderingExtent( minX, maxX, minY, maxY );
|
setupShadowRenderingExtent( minX, maxX, minY, maxY );
|
||||||
setupDirectionalLight( lightPosition, lightDirection );
|
setupDirectionalLight( lightPosition, lightDirection );
|
||||||
|
setShadowBias( shadowSettings.shadowBias() );
|
||||||
}
|
}
|
||||||
|
|
||||||
void QgsPostprocessingEntity::setShadowRenderingEnabled( bool enabled )
|
void QgsPostprocessingEntity::setShadowRenderingEnabled( bool enabled )
|
||||||
@ -183,11 +187,17 @@ void QgsPostprocessingEntity::setShadowRenderingEnabled( bool enabled )
|
|||||||
mRenderShadowsParameter->setValue( QVariant::fromValue( enabled ? 1 : 0 ) );
|
mRenderShadowsParameter->setValue( QVariant::fromValue( enabled ? 1 : 0 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void QgsPostprocessingEntity::setShadowBias( float shadowBias )
|
void QgsPostprocessingEntity::setShadowBias( double shadowBias )
|
||||||
{
|
{
|
||||||
mShadowBiasParameter->setValue( QVariant::fromValue( shadowBias ) );
|
mShadowBiasParameter->setValue( QVariant::fromValue( shadowBias ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QgsPostprocessingEntity::updateEyeDomeSettings( const Qgs3DMapSettings &settings )
|
||||||
|
{
|
||||||
|
setEyeDomeLightingStrength( settings.eyeDomeLightingStrength() );
|
||||||
|
setEyeDomeLightingDistance( settings.eyeDomeLightingDistance() );
|
||||||
|
}
|
||||||
|
|
||||||
void QgsPostprocessingEntity::setEyeDomeLightingEnabled( bool enabled )
|
void QgsPostprocessingEntity::setEyeDomeLightingEnabled( bool enabled )
|
||||||
{
|
{
|
||||||
mEyeDomeLightingEnabledParameter->setValue( QVariant::fromValue( enabled ? 1 : 0 ) );
|
mEyeDomeLightingEnabledParameter->setValue( QVariant::fromValue( enabled ? 1 : 0 ) );
|
||||||
|
@ -18,9 +18,12 @@
|
|||||||
|
|
||||||
#include "qgsrenderpassquad.h"
|
#include "qgsrenderpassquad.h"
|
||||||
|
|
||||||
class QgsFrameGraph;
|
|
||||||
class QgsShadowRenderView;
|
|
||||||
class QgsDirectionalLightSettings;
|
class QgsDirectionalLightSettings;
|
||||||
|
class QgsShadowRenderView;
|
||||||
|
class QgsForwardRenderView;
|
||||||
|
class QgsAmbientOcclusionRenderView;
|
||||||
|
class QgsShadowSettings;
|
||||||
|
class Qgs3DMapSettings;
|
||||||
|
|
||||||
#define SIP_NO_FILE
|
#define SIP_NO_FILE
|
||||||
|
|
||||||
@ -38,7 +41,11 @@ class QgsPostprocessingEntity : public QgsRenderPassQuad
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
//! Constructor
|
//! Constructor
|
||||||
QgsPostprocessingEntity( QgsFrameGraph *frameGraph, Qt3DRender::QLayer *layer, QNode *parent = nullptr );
|
QgsPostprocessingEntity( const QgsShadowRenderView &shadowRenderView, //
|
||||||
|
const QgsForwardRenderView &forwardRenderView, //
|
||||||
|
const QgsAmbientOcclusionRenderView &aoRenderView, //
|
||||||
|
Qt3DRender::QLayer *layer, //
|
||||||
|
QNode *parent = nullptr );
|
||||||
//! Sets the parts of the scene where objects cast shadows
|
//! Sets the parts of the scene where objects cast shadows
|
||||||
void setupShadowRenderingExtent( float minX, float maxX, float minY, float maxY );
|
void setupShadowRenderingExtent( float minX, float maxX, float minY, float maxY );
|
||||||
//! Sets up a directional light that is used to render shadows
|
//! Sets up a directional light that is used to render shadows
|
||||||
@ -46,7 +53,19 @@ class QgsPostprocessingEntity : public QgsRenderPassQuad
|
|||||||
//! Sets whether shadow rendering is enabled
|
//! Sets whether shadow rendering is enabled
|
||||||
void setShadowRenderingEnabled( bool enabled );
|
void setShadowRenderingEnabled( bool enabled );
|
||||||
//! Sets the shadow bias value
|
//! Sets the shadow bias value
|
||||||
void setShadowBias( float shadowBias );
|
void setShadowBias( double shadowBias );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets shadow rendering to use a directional light
|
||||||
|
* \since QGIS 3.44
|
||||||
|
*/
|
||||||
|
void updateShadowSettings( const QgsShadowSettings &shadowSettings, const QgsDirectionalLightSettings &light );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates eye dome lighting settings from \a settings
|
||||||
|
* \since QGIS 3.44
|
||||||
|
*/
|
||||||
|
void updateEyeDomeSettings( const Qgs3DMapSettings &settings );
|
||||||
//! Sets whether eye dome lighting is enabled
|
//! Sets whether eye dome lighting is enabled
|
||||||
void setEyeDomeLightingEnabled( bool enabled );
|
void setEyeDomeLightingEnabled( bool enabled );
|
||||||
//! Sets the eye dome lighting strength
|
//! Sets the eye dome lighting strength
|
||||||
@ -54,12 +73,6 @@ class QgsPostprocessingEntity : public QgsRenderPassQuad
|
|||||||
//! Sets the eye dome lighting distance (contributes to the contrast of the image)
|
//! Sets the eye dome lighting distance (contributes to the contrast of the image)
|
||||||
void setEyeDomeLightingDistance( int distance );
|
void setEyeDomeLightingDistance( int distance );
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets shadow rendering to use a directional light
|
|
||||||
* \since QGIS 3.44
|
|
||||||
*/
|
|
||||||
void updateShadowSettings( const QgsDirectionalLightSettings &light, float maximumShadowRenderingDistance );
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets whether screen space ambient occlusion is enabled
|
* Sets whether screen space ambient occlusion is enabled
|
||||||
* \since QGIS 3.28
|
* \since QGIS 3.28
|
||||||
|
196
src/3d/framegraph/qgspostprocessingrenderview.cpp
Normal file
196
src/3d/framegraph/qgspostprocessingrenderview.cpp
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
qgspostprocessingrenderview.cpp
|
||||||
|
--------------------------------------
|
||||||
|
Date : May 2025
|
||||||
|
Copyright : (C) 2025 by Benoit De Mezzo and (C) 2020 by Belgacem Nedjima
|
||||||
|
Email : benoit dot de dot mezzo at oslandia dot com
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include "qgspostprocessingrenderview.h"
|
||||||
|
#include <Qt3DRender/QRenderTargetSelector>
|
||||||
|
#include <Qt3DRender/QTexture>
|
||||||
|
#include <Qt3DRender/qsubtreeenabler.h>
|
||||||
|
#include <Qt3DRender/QRenderCapture>
|
||||||
|
#include <Qt3DRender/QRenderTarget>
|
||||||
|
#include <Qt3DRender/QRenderTargetOutput>
|
||||||
|
#include <Qt3DRender/QCameraSelector>
|
||||||
|
#include <Qt3DRender/QLayerFilter>
|
||||||
|
#include <Qt3DRender/QClearBuffers>
|
||||||
|
#include <Qt3DRender/QNoDraw>
|
||||||
|
#include <QNode>
|
||||||
|
#include "qgspostprocessingentity.h"
|
||||||
|
#include "qgsforwardrenderview.h"
|
||||||
|
#include "qgsshadowrenderview.h"
|
||||||
|
|
||||||
|
QgsPostprocessingRenderView::QgsPostprocessingRenderView( const QString &viewName, //
|
||||||
|
QgsShadowRenderView &shadowRenderView, //
|
||||||
|
QgsForwardRenderView &forwardRenderView, //
|
||||||
|
QgsAmbientOcclusionRenderView &aoRenderView, //
|
||||||
|
QSize mSize, //
|
||||||
|
Qt3DCore::QEntity *rootSceneEntity )
|
||||||
|
: QgsAbstractRenderView( viewName )
|
||||||
|
{
|
||||||
|
// postprocessing main rendering pass
|
||||||
|
constructPostprocessingMainPass( mSize );
|
||||||
|
|
||||||
|
// sub passes:
|
||||||
|
QVector<Qt3DRender::QFrameGraphNode *> subpasses;
|
||||||
|
// 1. postprocessing real render view
|
||||||
|
subpasses << constructSubPostPassForProcessing( shadowRenderView, forwardRenderView, aoRenderView, rootSceneEntity );
|
||||||
|
// 2. render capture render view
|
||||||
|
subpasses << constructSubPostPassForRenderCapture();
|
||||||
|
|
||||||
|
setSubPasses( subpasses );
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector<Qt3DRender::QFrameGraphNode *> QgsPostprocessingRenderView::subPasses() const
|
||||||
|
{
|
||||||
|
QVector<Qt3DRender::QFrameGraphNode *> out;
|
||||||
|
Qt3DCore::QNodeVector children = mSubPassesNode->childNodes();
|
||||||
|
for ( Qt3DCore::QNode *child : children )
|
||||||
|
if ( dynamic_cast<Qt3DRender::QFrameGraphNode *>( child ) && child->parent() == mSubPassesNode )
|
||||||
|
out << dynamic_cast<Qt3DRender::QFrameGraphNode *>( child );
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsPostprocessingRenderView::setSubPasses( QVector<Qt3DRender::QFrameGraphNode *> topNodes )
|
||||||
|
{
|
||||||
|
// detach all subpasses
|
||||||
|
Qt3DCore::QNodeVector children = mSubPassesNode->childNodes();
|
||||||
|
for ( Qt3DCore::QNode *child : children )
|
||||||
|
if ( dynamic_cast<Qt3DRender::QFrameGraphNode *>( child ) && child->parent() == mSubPassesNode )
|
||||||
|
child->setParent( ( Qt3DCore::QNode * ) nullptr );
|
||||||
|
|
||||||
|
// attach new subpasses
|
||||||
|
for ( Qt3DRender::QFrameGraphNode *child : topNodes )
|
||||||
|
child->setParent( mSubPassesNode );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsPostprocessingRenderView::updateWindowResize( int width, int height )
|
||||||
|
{
|
||||||
|
QgsAbstractRenderView::updateWindowResize( width, height );
|
||||||
|
mRenderCaptureColorTexture->setSize( width, height );
|
||||||
|
mRenderCaptureDepthTexture->setSize( width, height );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsPostprocessingRenderView::setOffScreenRenderCaptureEnabled( bool enabled )
|
||||||
|
{
|
||||||
|
if ( !isEnabled() || mRenderCaptureTargetSelector->isEnabled() == enabled )
|
||||||
|
return;
|
||||||
|
|
||||||
|
mRenderCaptureTargetSelector->setEnabled( enabled );
|
||||||
|
mRenderCapture->parentNode()->setEnabled( enabled ); // for NoDraw node
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Qt3DRender::QRenderTarget *QgsPostprocessingRenderView::buildRenderCaptureTextures( QSize mSize )
|
||||||
|
{
|
||||||
|
// =============== v NEEDED ONLY DURING UNIT TEST v
|
||||||
|
Qt3DRender::QRenderTarget *renderTarget = new Qt3DRender::QRenderTarget( mRenderCaptureTargetSelector );
|
||||||
|
|
||||||
|
// Create a render target output for rendering color.
|
||||||
|
Qt3DRender::QRenderTargetOutput *colorOutput = new Qt3DRender::QRenderTargetOutput( renderTarget );
|
||||||
|
colorOutput->setAttachmentPoint( Qt3DRender::QRenderTargetOutput::Color0 );
|
||||||
|
|
||||||
|
// Create a texture to render into.
|
||||||
|
mRenderCaptureColorTexture = new Qt3DRender::QTexture2D( colorOutput );
|
||||||
|
mRenderCaptureColorTexture->setSize( mSize.width(), mSize.height() );
|
||||||
|
mRenderCaptureColorTexture->setFormat( Qt3DRender::QAbstractTexture::RGB8_UNorm );
|
||||||
|
mRenderCaptureColorTexture->setMinificationFilter( Qt3DRender::QAbstractTexture::Linear );
|
||||||
|
mRenderCaptureColorTexture->setMagnificationFilter( Qt3DRender::QAbstractTexture::Linear );
|
||||||
|
mRenderCaptureColorTexture->setObjectName( mViewName + "::ColorTarget" );
|
||||||
|
|
||||||
|
// Hook the texture up to our output, and the output up to this object.
|
||||||
|
colorOutput->setTexture( mRenderCaptureColorTexture );
|
||||||
|
renderTarget->addOutput( colorOutput );
|
||||||
|
|
||||||
|
Qt3DRender::QRenderTargetOutput *depthOutput = new Qt3DRender::QRenderTargetOutput( renderTarget );
|
||||||
|
|
||||||
|
depthOutput->setAttachmentPoint( Qt3DRender::QRenderTargetOutput::Depth );
|
||||||
|
mRenderCaptureDepthTexture = new Qt3DRender::QTexture2D( depthOutput );
|
||||||
|
mRenderCaptureDepthTexture->setSize( mSize.width(), mSize.height() );
|
||||||
|
mRenderCaptureDepthTexture->setFormat( Qt3DRender::QAbstractTexture::DepthFormat );
|
||||||
|
mRenderCaptureDepthTexture->setMinificationFilter( Qt3DRender::QAbstractTexture::Linear );
|
||||||
|
mRenderCaptureDepthTexture->setMagnificationFilter( Qt3DRender::QAbstractTexture::Linear );
|
||||||
|
mRenderCaptureDepthTexture->setComparisonFunction( Qt3DRender::QAbstractTexture::CompareLessEqual );
|
||||||
|
mRenderCaptureDepthTexture->setComparisonMode( Qt3DRender::QAbstractTexture::CompareRefToTexture );
|
||||||
|
mRenderCaptureDepthTexture->setObjectName( mViewName + "::DepthTarget" );
|
||||||
|
|
||||||
|
depthOutput->setTexture( mRenderCaptureDepthTexture );
|
||||||
|
renderTarget->addOutput( depthOutput );
|
||||||
|
|
||||||
|
return renderTarget;
|
||||||
|
// =============== ^ NEEDED ONLY DURING UNIT TEST ^
|
||||||
|
}
|
||||||
|
|
||||||
|
Qt3DRender::QFrameGraphNode *QgsPostprocessingRenderView::constructPostprocessingMainPass( QSize mSize )
|
||||||
|
{
|
||||||
|
// Due to a bug in Qt5 (fixed in Qt6 - https://codereview.qt-project.org/c/qt/qt3d/+/462575) we need to move the render target selector at the top
|
||||||
|
// of this branch. Doing so this allows Qt3d to have a FBO format matching the one need to do the capture
|
||||||
|
mRenderCaptureTargetSelector = new Qt3DRender::QRenderTargetSelector( mRendererEnabler );
|
||||||
|
mRenderCaptureTargetSelector->setObjectName( mViewName + "::RenderTargetSelector" );
|
||||||
|
mRenderCaptureTargetSelector->setEnabled( false );
|
||||||
|
|
||||||
|
// build texture part
|
||||||
|
Qt3DRender::QRenderTarget *renderTarget = buildRenderCaptureTextures( mSize );
|
||||||
|
mRenderCaptureTargetSelector->setTarget( renderTarget );
|
||||||
|
|
||||||
|
// add node for sub passes
|
||||||
|
mSubPassesNode = new Qt3DRender::QFrameGraphNode( mRenderCaptureTargetSelector );
|
||||||
|
mSubPassesNode->setObjectName( mViewName + "::Sub passes top node" );
|
||||||
|
|
||||||
|
return mRenderCaptureTargetSelector;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Qt3DRender::QFrameGraphNode *QgsPostprocessingRenderView::constructSubPostPassForProcessing( QgsShadowRenderView &shadowRenderView, //
|
||||||
|
QgsForwardRenderView &forwardRenderView, //
|
||||||
|
QgsAmbientOcclusionRenderView &aoRenderView, //
|
||||||
|
Qt3DCore::QEntity *rootSceneEntity )
|
||||||
|
{
|
||||||
|
Qt3DRender::QLayerFilter *layerFilter = new Qt3DRender::QLayerFilter;
|
||||||
|
layerFilter->setObjectName( mViewName + "::Sub pass::Postprocessing" );
|
||||||
|
|
||||||
|
Qt3DRender::QLayer *postProcessingLayer = new Qt3DRender::QLayer();
|
||||||
|
postProcessingLayer->setRecursive( true );
|
||||||
|
layerFilter->addLayer( postProcessingLayer );
|
||||||
|
|
||||||
|
// end of this branch
|
||||||
|
new Qt3DRender::QClearBuffers( layerFilter );
|
||||||
|
|
||||||
|
mPostprocessingEntity = new QgsPostprocessingEntity( shadowRenderView, //
|
||||||
|
forwardRenderView, //
|
||||||
|
aoRenderView, //
|
||||||
|
postProcessingLayer, //
|
||||||
|
rootSceneEntity );
|
||||||
|
mPostprocessingEntity->setObjectName( "PostProcessingPassEntity" );
|
||||||
|
|
||||||
|
return layerFilter;
|
||||||
|
}
|
||||||
|
|
||||||
|
Qt3DRender::QFrameGraphNode *QgsPostprocessingRenderView::constructSubPostPassForRenderCapture()
|
||||||
|
{
|
||||||
|
Qt3DRender::QFrameGraphNode *top = new Qt3DRender::QNoDraw;
|
||||||
|
top->setObjectName( mViewName + "::Sub pass::RenderCapture" );
|
||||||
|
|
||||||
|
mRenderCapture = new Qt3DRender::QRenderCapture( top );
|
||||||
|
|
||||||
|
return top;
|
||||||
|
}
|
||||||
|
|
||||||
|
Qt3DRender::QRenderCapture *QgsPostprocessingRenderView::renderCapture() const
|
||||||
|
{
|
||||||
|
return mRenderCapture;
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsPostprocessingEntity *QgsPostprocessingRenderView::entity() const
|
||||||
|
{
|
||||||
|
return mPostprocessingEntity;
|
||||||
|
}
|
98
src/3d/framegraph/qgspostprocessingrenderview.h
Normal file
98
src/3d/framegraph/qgspostprocessingrenderview.h
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
qgspostprocessingrenderview.h
|
||||||
|
--------------------------------------
|
||||||
|
Date : May 2025
|
||||||
|
Copyright : (C) 2025 by Benoit De Mezzo and (C) 2020 by Belgacem Nedjima
|
||||||
|
Email : benoit dot de dot mezzo at oslandia dot com
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#ifndef QGSPOSTPROCESSINGRENDERVIEW_H
|
||||||
|
#define QGSPOSTPROCESSINGRENDERVIEW_H
|
||||||
|
|
||||||
|
#include "qgsabstractrenderview.h"
|
||||||
|
|
||||||
|
namespace Qt3DRender
|
||||||
|
{
|
||||||
|
class QTexture2D;
|
||||||
|
class QRenderTargetSelector;
|
||||||
|
class QClearBuffers;
|
||||||
|
class QRenderStateSet;
|
||||||
|
class QRenderCapture;
|
||||||
|
class QRenderTarget;
|
||||||
|
} //namespace Qt3DRender
|
||||||
|
|
||||||
|
class QgsPostprocessingEntity;
|
||||||
|
|
||||||
|
#define SIP_NO_FILE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \ingroup qgis_3d
|
||||||
|
* \brief Container class that holds different objects related to postprocessing rendering
|
||||||
|
*
|
||||||
|
* \note Not available in Python bindings
|
||||||
|
*
|
||||||
|
* The postprocessing pass apply post-processing effects (shadows, EDL, SSAO).
|
||||||
|
*
|
||||||
|
* \since QGIS 3.44
|
||||||
|
*/
|
||||||
|
class QgsPostprocessingRenderView : public QgsAbstractRenderView
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//! Default constructor
|
||||||
|
QgsPostprocessingRenderView( const QString &viewName, //
|
||||||
|
QgsShadowRenderView &shadowRenderView, //
|
||||||
|
QgsForwardRenderView &forwardRenderView, //
|
||||||
|
QgsAmbientOcclusionRenderView &aoRenderView, //
|
||||||
|
QSize mSize, //
|
||||||
|
Qt3DCore::QEntity *rootSceneEntity );
|
||||||
|
|
||||||
|
virtual void updateWindowResize( int width, int height ) override;
|
||||||
|
|
||||||
|
//! Returns the render capture object used to take an image of the postprocessing buffer of the scene
|
||||||
|
Qt3DRender::QRenderCapture *renderCapture() const;
|
||||||
|
|
||||||
|
//! Returns the QT3D entity used to do the rendering
|
||||||
|
QgsPostprocessingEntity *entity() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether it will be possible to render to an image
|
||||||
|
*/
|
||||||
|
void setOffScreenRenderCaptureEnabled( bool enabled );
|
||||||
|
|
||||||
|
//! Returns the top node of all subpasses
|
||||||
|
QVector<Qt3DRender::QFrameGraphNode *> subPasses() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the subpasses with the new \a topNodes
|
||||||
|
*/
|
||||||
|
void setSubPasses( QVector<Qt3DRender::QFrameGraphNode *> topNodes );
|
||||||
|
|
||||||
|
private:
|
||||||
|
Qt3DRender::QRenderTarget *buildRenderCaptureTextures( QSize mSize );
|
||||||
|
Qt3DRender::QFrameGraphNode *constructPostprocessingMainPass( QSize mSize );
|
||||||
|
Qt3DRender::QFrameGraphNode *constructSubPostPassForProcessing( QgsShadowRenderView &shadowRenderView, //
|
||||||
|
QgsForwardRenderView &forwardRenderView, //
|
||||||
|
QgsAmbientOcclusionRenderView &aoRenderView, //
|
||||||
|
Qt3DCore::QEntity *rootSceneEntity );
|
||||||
|
Qt3DRender::QFrameGraphNode *constructSubPostPassForRenderCapture();
|
||||||
|
|
||||||
|
Qt3DRender::QRenderTargetSelector *mRenderCaptureTargetSelector = nullptr;
|
||||||
|
Qt3DRender::QRenderCapture *mRenderCapture = nullptr;
|
||||||
|
|
||||||
|
QgsPostprocessingEntity *mPostprocessingEntity = nullptr;
|
||||||
|
|
||||||
|
// Post processing pass texture related objects:
|
||||||
|
Qt3DRender::QTexture2D *mRenderCaptureColorTexture = nullptr;
|
||||||
|
Qt3DRender::QTexture2D *mRenderCaptureDepthTexture = nullptr;
|
||||||
|
|
||||||
|
Qt3DRender::QFrameGraphNode *mSubPassesNode = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // QGSPOSTPROCESSINGRENDERVIEW_H
|
@ -74,7 +74,7 @@ class QgsShadowRenderView : public QgsAbstractRenderView
|
|||||||
virtual void setEnabled( bool enable ) override;
|
virtual void setEnabled( bool enable ) override;
|
||||||
|
|
||||||
//! Returns the light camera
|
//! Returns the light camera
|
||||||
Qt3DRender::QCamera *lightCamera() { return mLightCamera; }
|
Qt3DRender::QCamera *lightCamera() const { return mLightCamera; }
|
||||||
|
|
||||||
//! Returns shadow depth texture
|
//! Returns shadow depth texture
|
||||||
Qt3DRender::QTexture2D *mapTexture() const;
|
Qt3DRender::QTexture2D *mapTexture() const;
|
||||||
|
@ -39,13 +39,15 @@
|
|||||||
(Qt3DRender::QRenderStateSet{121/<no_name>}) [ (QDepthTest:Always), (QCullFace:NoCulling) ]
|
(Qt3DRender::QRenderStateSet{121/<no_name>}) [ (QDepthTest:Always), (QCullFace:NoCulling) ]
|
||||||
(Qt3DRender::QLayerFilter{124/<no_name>}) [ (AcceptAnyMatchingLayers:[ {90/ambient_occlusion::Layer(Blur)} ]) ]
|
(Qt3DRender::QLayerFilter{124/<no_name>}) [ (AcceptAnyMatchingLayers:[ {90/ambient_occlusion::Layer(Blur)} ]) ]
|
||||||
(Qt3DRender::QRenderTargetSelector{128/ambient_occlusion::RenderTargetSelector(Blur)}) [ (outputs:[ (Color0:{126[R32F]/ambient_occlusion::ColorTarget(blur)) ]) ]
|
(Qt3DRender::QRenderTargetSelector{128/ambient_occlusion::RenderTargetSelector(Blur)}) [ (outputs:[ (Color0:{126[R32F]/ambient_occlusion::ColorTarget(blur)) ]) ]
|
||||||
(Qt3DRender::QRenderTargetSelector{141/PostProcessingPass}) [D] [ (outputs:[ (Color0:{144[RGB8_UNorm]/PostProcessingPass::ColorTarget), (Depth:{146[DepthFormat]/PostProcessingPass::DepthTarget) ]) ]
|
(Qt3DRender::QNoDraw{141/post_processing::NoDraw}) [D]
|
||||||
(Qt3DRender::QCameraSelector{147/Sub pass Postprocessing}) [ (Qt3DRender::QCamera:{51/shadow::LightCamera}) ]
|
(Qt3DRender::QSubtreeEnabler{142/post_processing::SubtreeEnabler})
|
||||||
(Qt3DRender::QLayerFilter{148/<no_name>}) [ (AcceptAnyMatchingLayers:[ {150/<no_name>} ]) ]
|
(Qt3DRender::QRenderTargetSelector{143/post_processing::RenderTargetSelector}) [D] [ (outputs:[ (Color0:{146[RGB8_UNorm]/post_processing::ColorTarget), (Depth:{148[DepthFormat]/post_processing::DepthTarget) ]) ]
|
||||||
(Qt3DRender::QClearBuffers{149/<no_name>})
|
(Qt3DRender::QFrameGraphNode{149/post_processing::Sub passes top node})
|
||||||
(Qt3DRender::QNoDraw{184/debug_texture::NoDraw})
|
(Qt3DRender::QLayerFilter{150/post_processing::Sub pass::Postprocessing}) [ (AcceptAnyMatchingLayers:[ {151/<no_name>} ]) ]
|
||||||
(Qt3DRender::QSubtreeEnabler{185/debug_texture::SubtreeEnabler}) [D]
|
(Qt3DRender::QClearBuffers{152/<no_name>})
|
||||||
(Qt3DRender::QLayerFilter{187/<no_name>}) [ (AcceptAnyMatchingLayers:[ {186/debug_texture::Layer} ]) ]
|
(Qt3DRender::QNoDraw{188/debug_texture::NoDraw})
|
||||||
(Qt3DRender::QRenderStateSet{188/<no_name>}) [ (QDepthTest:Always), (QCullFace:NoCulling) ]
|
(Qt3DRender::QSubtreeEnabler{189/debug_texture::SubtreeEnabler}) [D]
|
||||||
(Qt3DRender::QNoDraw{191/Sub pass RenderCapture})
|
(Qt3DRender::QLayerFilter{191/<no_name>}) [ (AcceptAnyMatchingLayers:[ {190/debug_texture::Layer} ]) ]
|
||||||
(Qt3DRender::QRenderCapture{192/<no_name>})
|
(Qt3DRender::QRenderStateSet{192/<no_name>}) [ (QDepthTest:Always), (QCullFace:NoCulling) ]
|
||||||
|
(Qt3DRender::QNoDraw{186/post_processing::Sub pass::RenderCapture}) [D]
|
||||||
|
(Qt3DRender::QRenderCapture{187/<no_name>})
|
||||||
|
@ -39,13 +39,15 @@
|
|||||||
(Qt3DRender::QRenderStateSet{121/<no_name>}) [ (QDepthTest:Always), (QCullFace:NoCulling) ]
|
(Qt3DRender::QRenderStateSet{121/<no_name>}) [ (QDepthTest:Always), (QCullFace:NoCulling) ]
|
||||||
(Qt3DRender::QLayerFilter{124/<no_name>}) [ (AcceptAnyMatchingLayers:[ {90/ambient_occlusion::Layer(Blur)} ]) ]
|
(Qt3DRender::QLayerFilter{124/<no_name>}) [ (AcceptAnyMatchingLayers:[ {90/ambient_occlusion::Layer(Blur)} ]) ]
|
||||||
(Qt3DRender::QRenderTargetSelector{128/ambient_occlusion::RenderTargetSelector(Blur)}) [ (outputs:[ (Color0:{126[R32F]/ambient_occlusion::ColorTarget(blur)) ]) ]
|
(Qt3DRender::QRenderTargetSelector{128/ambient_occlusion::RenderTargetSelector(Blur)}) [ (outputs:[ (Color0:{126[R32F]/ambient_occlusion::ColorTarget(blur)) ]) ]
|
||||||
(Qt3DRender::QRenderTargetSelector{141/PostProcessingPass}) [D] [ (outputs:[ (Color0:{144[RGB8_UNorm]/PostProcessingPass::ColorTarget), (Depth:{146[DepthFormat]/PostProcessingPass::DepthTarget) ]) ]
|
(Qt3DRender::QNoDraw{141/post_processing::NoDraw}) [D]
|
||||||
(Qt3DRender::QCameraSelector{147/Sub pass Postprocessing}) [ (Qt3DRender::QCamera:{51/shadow::LightCamera}) ]
|
(Qt3DRender::QSubtreeEnabler{142/post_processing::SubtreeEnabler})
|
||||||
(Qt3DRender::QLayerFilter{148/<no_name>}) [ (AcceptAnyMatchingLayers:[ {150/<no_name>} ]) ]
|
(Qt3DRender::QRenderTargetSelector{143/post_processing::RenderTargetSelector}) [D] [ (outputs:[ (Color0:{146[RGB8_UNorm]/post_processing::ColorTarget), (Depth:{148[DepthFormat]/post_processing::DepthTarget) ]) ]
|
||||||
(Qt3DRender::QClearBuffers{149/<no_name>})
|
(Qt3DRender::QFrameGraphNode{149/post_processing::Sub passes top node})
|
||||||
(Qt3DRender::QNoDraw{184/debug_texture::NoDraw})
|
(Qt3DRender::QLayerFilter{150/post_processing::Sub pass::Postprocessing}) [ (AcceptAnyMatchingLayers:[ {151/<no_name>} ]) ]
|
||||||
(Qt3DRender::QSubtreeEnabler{185/debug_texture::SubtreeEnabler}) [D]
|
(Qt3DRender::QClearBuffers{152/<no_name>})
|
||||||
(Qt3DRender::QLayerFilter{187/<no_name>}) [ (AcceptAnyMatchingLayers:[ {186/debug_texture::Layer} ]) ]
|
(Qt3DRender::QNoDraw{188/debug_texture::NoDraw})
|
||||||
(Qt3DRender::QRenderStateSet{188/<no_name>}) [ (QDepthTest:Always), (QCullFace:NoCulling) ]
|
(Qt3DRender::QSubtreeEnabler{189/debug_texture::SubtreeEnabler}) [D]
|
||||||
(Qt3DRender::QNoDraw{191/Sub pass RenderCapture})
|
(Qt3DRender::QLayerFilter{191/<no_name>}) [ (AcceptAnyMatchingLayers:[ {190/debug_texture::Layer} ]) ]
|
||||||
(Qt3DRender::QRenderCapture{192/<no_name>})
|
(Qt3DRender::QRenderStateSet{192/<no_name>}) [ (QDepthTest:Always), (QCullFace:NoCulling) ]
|
||||||
|
(Qt3DRender::QNoDraw{186/post_processing::Sub pass::RenderCapture}) [D]
|
||||||
|
(Qt3DRender::QRenderCapture{187/<no_name>})
|
||||||
|
BIN
tests/testdata/control_images/3d/expected_debug_map_2/expected_debug_map_2_mask.png
vendored
Normal file
BIN
tests/testdata/control_images/3d/expected_debug_map_2/expected_debug_map_2_mask.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.4 KiB |
Loading…
x
Reference in New Issue
Block a user