23#include <Qt3DRender/QBlendEquation>
24#include <Qt3DRender/QBlendEquationArguments>
25#include <Qt3DRender/QClearBuffers>
26#include <Qt3DRender/QDepthTest>
27#include <Qt3DRender/QFrameGraphNode>
28#include <Qt3DRender/QLayer>
29#include <Qt3DRender/QLayerFilter>
30#include <Qt3DRender/QParameter>
31#include <Qt3DRender/QRenderStateSet>
32#include <Qt3DRender/QRenderTarget>
33#include <Qt3DRender/QRenderTargetOutput>
34#include <Qt3DRender/QRenderTargetSelector>
35#include <Qt3DRender/QTexture>
36#include <Qt3DRender/qsubtreeenabler.h>
38using namespace Qt::StringLiterals;
44 mFilterRadiusParameter =
new Qt3DRender::QParameter( u
"filterRadius"_s, 0.005f, rootEntity );
46 const float aspectRatio =
static_cast<float>( size.width() ) /
static_cast<float>( size.height() );
47 mAspectRatioParameter =
new Qt3DRender::QParameter( u
"aspectRatio"_s, aspectRatio, rootEntity );
51 buildRenderPasses( sourceColorTexture, rootEntity );
63 mFilterRadiusParameter->setValue( radius );
68 mAspectRatioParameter->setValue( ratio );
71void QgsBloomRenderView::buildRenderPasses( Qt3DRender::QTexture2D *sourceTexture, Qt3DCore::QEntity *rootEntity )
73 Qt3DRender::QTexture2D *currentInputTexture = sourceTexture;
79 mTextures.reserve( MIP_PASSES );
81 Qt3DRender::QRenderStateSet *renderStateSet =
new Qt3DRender::QRenderStateSet(
mRendererEnabler );
84 for (
int i = 0; i < MIP_PASSES; ++i )
86 auto passLayer =
new Qt3DRender::QLayer( rootEntity );
87 passLayer->setRecursive(
true );
88 passLayer->setObjectName(
mViewName + u
"::Layer(DownsamplePass%1)"_s.arg( i + 1 ) );
90 auto renderTarget =
new Qt3DRender::QRenderTarget();
92 auto colorOutput =
new Qt3DRender::QRenderTargetOutput( renderTarget );
93 colorOutput->setAttachmentPoint( Qt3DRender::QRenderTargetOutput::Color0 );
95 auto mipTexture =
new Qt3DRender::QTexture2D( colorOutput );
97 mipTexture->setFormat( Qt3DRender::QAbstractTexture::RGBA16F );
99 mipTexture->setSize( 1, 1 );
100 mipTexture->setGenerateMipMaps(
false );
102 mipTexture->setMinificationFilter( Qt3DRender::QTexture2D::Linear );
103 mipTexture->setMagnificationFilter( Qt3DRender::QTexture2D::Linear );
104 mipTexture->wrapMode()->setX( Qt3DRender::QTextureWrapMode::ClampToEdge );
105 mipTexture->wrapMode()->setY( Qt3DRender::QTextureWrapMode::ClampToEdge );
106 mTextures.push_back( mipTexture );
108 colorOutput->setTexture( mipTexture );
109 renderTarget->addOutput( colorOutput );
111 auto targetSelector =
new Qt3DRender::QRenderTargetSelector( renderStateSet );
112 targetSelector->setTarget( renderTarget );
114 auto clearBuffers =
new Qt3DRender::QClearBuffers( targetSelector );
115 clearBuffers->setBuffers( Qt3DRender::QClearBuffers::ColorBuffer );
116 clearBuffers->setClearColor( QColor::fromRgbF( 0.0, 0.0, 0.0, 1.0 ) );
118 auto layerFilter =
new Qt3DRender::QLayerFilter( clearBuffers );
119 layerFilter->addLayer( passLayer );
124 currentInputTexture = mipTexture;
128 for (
int i = MIP_PASSES - 2; i >= 0; --i )
130 auto passLayer =
new Qt3DRender::QLayer( rootEntity );
131 passLayer->setRecursive(
true );
132 passLayer->setObjectName(
mViewName + u
"::Layer(UpsamplePass%1)"_s.arg( i + 1 ) );
134 Qt3DRender::QRenderTarget *renderTarget =
new Qt3DRender::QRenderTarget();
136 Qt3DRender::QRenderTargetOutput *colorOutput =
new Qt3DRender::QRenderTargetOutput( renderTarget );
137 colorOutput->setAttachmentPoint( Qt3DRender::QRenderTargetOutput::Color0 );
139 Qt3DRender::QTexture2D *targetTexture = mTextures[i];
140 colorOutput->setTexture( targetTexture );
141 renderTarget->addOutput( colorOutput );
143 auto targetSelector =
new Qt3DRender::QRenderTargetSelector( renderStateSet );
144 targetSelector->setTarget( renderTarget );
147 auto blendStateSet =
new Qt3DRender::QRenderStateSet( targetSelector );
149 auto blendEquation =
new Qt3DRender::QBlendEquation( blendStateSet );
150 blendEquation->setBlendFunction( Qt3DRender::QBlendEquation::Add );
151 blendStateSet->addRenderState( blendEquation );
153 auto blendEquationArgs =
new Qt3DRender::QBlendEquationArguments( blendStateSet );
154 blendEquationArgs->setSourceRgb( Qt3DRender::QBlendEquationArguments::Blending::One );
155 blendEquationArgs->setDestinationRgb( Qt3DRender::QBlendEquationArguments::Blending::One );
156 blendStateSet->addRenderState( blendEquationArgs );
159 auto quad =
new QgsBloomUpsampleEntity( currentInputTexture, passLayer, rootEntity );
160 quad->addParameters( { mFilterRadiusParameter, mAspectRatioParameter } );
162 auto layerFilter =
new Qt3DRender::QLayerFilter( blendStateSet );
163 layerFilter->addLayer( passLayer );
165 currentInputTexture = targetTexture;
171 mBaseSize = QSize( width, height );
175 int currentWidth = width;
176 int currentHeight = height;
177 for (
int i = 0; i < MIP_PASSES; ++i )
180 currentWidth = std::max( 1, currentWidth / 2 );
181 currentHeight = std::max( 1, currentHeight / 2 );
184 mTextures[i]->setSize( currentWidth, currentHeight );
189 mTextures[i]->setSize( 1, 1 );
193 const float aspectRatio =
static_cast<float>( width ) /
static_cast<float>( height );
194 mAspectRatioParameter->setValue( aspectRatio );
Qt3DRender::QSubtreeEnabler * mRendererEnabler
virtual void setEnabled(bool enable)
Enable or disable via enable the render view sub tree.
virtual bool isEnabled() const
Returns true if render view is enabled.
QgsAbstractRenderView(const QString &viewName)
Constructor for QgsAbstractRenderView with the specified parent object.
An entity responsible for applying a 13-tap downsample filter for physically based bloom.
~QgsBloomRenderView() override
QgsBloomRenderView(const QString &viewName, Qt3DRender::QTexture2D *sourceColorTexture, const QSize &size, Qt3DCore::QEntity *rootSceneEntity)
Default constructor.
void updateWindowResize(int width, int height) override
Called when 3D window is resized.
void setFilterRadius(float radius)
Sets the bloom filter radius.
Qt3DRender::QTexture2D * bloomTexture() const
Returns the texture containing the final bloom effect.
void setAspectRatio(float ratio)
Sets the aspect ratio of the view.
void setEnabled(bool enabled) override
Enable or disable via enable the render view sub tree.