QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
qgsframegraph.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsframegraph.cpp
3 --------------------------------------
4 Date : August 2020
5 Copyright : (C) 2020 by Belgacem Nedjima
6 Email : gb underscore nedjima at esi dot dz
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
16#include "qgsframegraph.h"
19#include "qgspreviewquad.h"
20#include "qgs3dutils.h"
23
24#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
25#include <Qt3DRender/QAttribute>
26#include <Qt3DRender/QBuffer>
27#include <Qt3DRender/QGeometry>
28
29typedef Qt3DRender::QAttribute Qt3DQAttribute;
30typedef Qt3DRender::QBuffer Qt3DQBuffer;
31typedef Qt3DRender::QGeometry Qt3DQGeometry;
32#else
33#include <Qt3DCore/QAttribute>
34#include <Qt3DCore/QBuffer>
35#include <Qt3DCore/QGeometry>
36
37typedef Qt3DCore::QAttribute Qt3DQAttribute;
38typedef Qt3DCore::QBuffer Qt3DQBuffer;
39typedef Qt3DCore::QGeometry Qt3DQGeometry;
40#endif
41
42#include <Qt3DRender/QGeometryRenderer>
43#include <Qt3DRender/QTechnique>
44#include <Qt3DRender/QGraphicsApiFilter>
45#include <Qt3DRender/QBlendEquation>
46#include <Qt3DRender/QColorMask>
47#include <Qt3DRender/QSortPolicy>
48#include <Qt3DRender/QNoDepthMask>
49#include <Qt3DRender/QBlendEquationArguments>
50
51Qt3DRender::QFrameGraphNode *QgsFrameGraph::constructTexturesPreviewPass()
52{
53 mPreviewLayerFilter = new Qt3DRender::QLayerFilter;
54 mPreviewLayerFilter->addLayer( mPreviewLayer );
55
56 mPreviewRenderStateSet = new Qt3DRender::QRenderStateSet( mPreviewLayerFilter );
57 mPreviewDepthTest = new Qt3DRender::QDepthTest;
58 mPreviewDepthTest->setDepthFunction( Qt3DRender::QDepthTest::Always );
59 mPreviewRenderStateSet->addRenderState( mPreviewDepthTest );
60 mPreviewCullFace = new Qt3DRender::QCullFace;
61 mPreviewCullFace->setMode( Qt3DRender::QCullFace::NoCulling );
62 mPreviewRenderStateSet->addRenderState( mPreviewCullFace );
63
64 return mPreviewLayerFilter;
65}
66
67Qt3DRender::QFrameGraphNode *QgsFrameGraph::constructForwardRenderPass()
68{
69 // This is where rendering of the 3D scene actually happens.
70 // We define two forward passes: one for solid objects, followed by one for transparent objects.
71 //
72 // |
73 // +-----------------+
74 // | QCameraSelector | (using the main camera)
75 // +-----------------+
76 // |
77 // +-----------------+
78 // | QLayerFilter | (using mForwardRenderLayer)
79 // +-----------------+
80 // |
81 // +-----------------------+
82 // | QRenderTargetSelector | (write mForwardColorTexture + mForwardDepthTexture)
83 // +-----------------------+
84 // |
85 // +------------------------+---------------------+
86 // | |
87 // +-----------------+ discard +-----------------+ accept
88 // | QLayerFilter | transparent | QLayerFilter | transparent
89 // +-----------------+ objects +-----------------+ objects
90 // | |
91 // +-----------------+ use depth test +-----------------+ sort entities
92 // | QRenderStateSet | cull back faces | QSortPolicy | back to front
93 // +-----------------+ +-----------------+
94 // | |
95 // +-----------------+ +--------------------+--------------------+
96 // | QFrustumCulling | | |
97 // +-----------------+ +-----------------+ use depth tests +-----------------+ use depth tests
98 // | | QRenderStateSet | don't write depths | QRenderStateSet | write depths
99 // | +-----------------+ write colors +-----------------+ don't write colors
100 // +-----------------+ use alpha blending don't use alpha blending
101 // | QClearBuffers | color and depth no culling no culling
102 // +-----------------+
103
104 mMainCameraSelector = new Qt3DRender::QCameraSelector;
105 mMainCameraSelector->setCamera( mMainCamera );
106
107 mForwardRenderLayerFilter = new Qt3DRender::QLayerFilter( mMainCameraSelector );
108 mForwardRenderLayerFilter->addLayer( mForwardRenderLayer );
109
110 mForwardColorTexture = new Qt3DRender::QTexture2D;
111 mForwardColorTexture->setWidth( mSize.width() );
112 mForwardColorTexture->setHeight( mSize.height() );
113 mForwardColorTexture->setFormat( Qt3DRender::QAbstractTexture::RGB8_UNorm );
114 mForwardColorTexture->setGenerateMipMaps( false );
115 mForwardColorTexture->setMagnificationFilter( Qt3DRender::QTexture2D::Linear );
116 mForwardColorTexture->setMinificationFilter( Qt3DRender::QTexture2D::Linear );
117 mForwardColorTexture->wrapMode()->setX( Qt3DRender::QTextureWrapMode::ClampToEdge );
118 mForwardColorTexture->wrapMode()->setY( Qt3DRender::QTextureWrapMode::ClampToEdge );
119
120 mForwardDepthTexture = new Qt3DRender::QTexture2D;
121 mForwardDepthTexture->setWidth( mSize.width() );
122 mForwardDepthTexture->setHeight( mSize.height() );
123 mForwardDepthTexture->setFormat( Qt3DRender::QTexture2D::TextureFormat::DepthFormat );
124 mForwardDepthTexture->setGenerateMipMaps( false );
125 mForwardDepthTexture->setMagnificationFilter( Qt3DRender::QTexture2D::Linear );
126 mForwardDepthTexture->setMinificationFilter( Qt3DRender::QTexture2D::Linear );
127 mForwardDepthTexture->wrapMode()->setX( Qt3DRender::QTextureWrapMode::ClampToEdge );
128 mForwardDepthTexture->wrapMode()->setY( Qt3DRender::QTextureWrapMode::ClampToEdge );
129
130 Qt3DRender::QRenderTarget *forwardRenderTarget = new Qt3DRender::QRenderTarget;
131 Qt3DRender::QRenderTargetOutput *forwardRenderTargetDepthOutput = new Qt3DRender::QRenderTargetOutput;
132 forwardRenderTargetDepthOutput->setAttachmentPoint( Qt3DRender::QRenderTargetOutput::Depth );
133 forwardRenderTargetDepthOutput->setTexture( mForwardDepthTexture );
134 forwardRenderTarget->addOutput( forwardRenderTargetDepthOutput );
135 Qt3DRender::QRenderTargetOutput *forwardRenderTargetColorOutput = new Qt3DRender::QRenderTargetOutput;
136 forwardRenderTargetColorOutput->setAttachmentPoint( Qt3DRender::QRenderTargetOutput::Color0 );
137 forwardRenderTargetColorOutput->setTexture( mForwardColorTexture );
138 forwardRenderTarget->addOutput( forwardRenderTargetColorOutput );
139
140 mForwardRenderTargetSelector = new Qt3DRender::QRenderTargetSelector( mForwardRenderLayerFilter );
141 mForwardRenderTargetSelector->setTarget( forwardRenderTarget );
142
143 // first branch: opaque layer filter
144 Qt3DRender::QLayerFilter *opaqueObjectsFilter = new Qt3DRender::QLayerFilter( mForwardRenderTargetSelector );
145 opaqueObjectsFilter->addLayer( mTransparentObjectsPassLayer );
146 opaqueObjectsFilter->setFilterMode( Qt3DRender::QLayerFilter::DiscardAnyMatchingLayers );
147
148 Qt3DRender::QRenderStateSet *forwardedRenderStateSet = new Qt3DRender::QRenderStateSet( opaqueObjectsFilter );
149
150 Qt3DRender::QDepthTest *depthTest = new Qt3DRender::QDepthTest;
151 depthTest->setDepthFunction( Qt3DRender::QDepthTest::Less );
152 forwardedRenderStateSet->addRenderState( depthTest );
153
154 Qt3DRender::QCullFace *cullFace = new Qt3DRender::QCullFace;
155 cullFace->setMode( Qt3DRender::QCullFace::CullingMode::Back );
156 forwardedRenderStateSet->addRenderState( cullFace );
157
158 mFrustumCulling = new Qt3DRender::QFrustumCulling( forwardedRenderStateSet );
159
160 mForwardClearBuffers = new Qt3DRender::QClearBuffers( mFrustumCulling );
161 mForwardClearBuffers->setClearColor( QColor::fromRgbF( 0.0, 0.0, 1.0, 1.0 ) );
162 mForwardClearBuffers->setBuffers( Qt3DRender::QClearBuffers::ColorDepthBuffer );
163 mForwardClearBuffers->setClearDepthValue( 1.0f );
164
165 // second branch: transparent layer filter - color
166 Qt3DRender::QLayerFilter *transparentObjectsLayerFilter = new Qt3DRender::QLayerFilter( mForwardRenderTargetSelector );
167 transparentObjectsLayerFilter->addLayer( mTransparentObjectsPassLayer );
168 transparentObjectsLayerFilter->setFilterMode( Qt3DRender::QLayerFilter::AcceptAnyMatchingLayers );
169
170 Qt3DRender::QSortPolicy *sortPolicy = new Qt3DRender::QSortPolicy( transparentObjectsLayerFilter );
171 QVector<Qt3DRender::QSortPolicy::SortType> sortTypes;
172 sortTypes.push_back( Qt3DRender::QSortPolicy::BackToFront );
173 sortPolicy->setSortTypes( sortTypes );
174
175 Qt3DRender::QRenderStateSet *transparentObjectsRenderStateSetColor = new Qt3DRender::QRenderStateSet( sortPolicy );
176 {
177 Qt3DRender::QDepthTest *depthTest = new Qt3DRender::QDepthTest;
178 depthTest->setDepthFunction( Qt3DRender::QDepthTest::Less );
179 transparentObjectsRenderStateSetColor->addRenderState( depthTest );
180
181 Qt3DRender::QNoDepthMask *noDepthMask = new Qt3DRender::QNoDepthMask;
182 transparentObjectsRenderStateSetColor->addRenderState( noDepthMask );
183
184 Qt3DRender::QCullFace *cullFace = new Qt3DRender::QCullFace;
185 cullFace->setMode( Qt3DRender::QCullFace::CullingMode::NoCulling );
186 transparentObjectsRenderStateSetColor->addRenderState( cullFace );
187
188 Qt3DRender::QBlendEquation *blendEquation = new Qt3DRender::QBlendEquation;
189 blendEquation->setBlendFunction( Qt3DRender::QBlendEquation::Add );
190 transparentObjectsRenderStateSetColor->addRenderState( blendEquation );
191
192 Qt3DRender::QBlendEquationArguments *blendEquationArgs = new Qt3DRender::QBlendEquationArguments;
193 blendEquationArgs->setSourceRgb( Qt3DRender::QBlendEquationArguments::Blending::SourceAlpha );
194 blendEquationArgs->setDestinationRgb( Qt3DRender::QBlendEquationArguments::Blending::OneMinusSourceAlpha );
195 transparentObjectsRenderStateSetColor->addRenderState( blendEquationArgs );
196 }
197
198 // third branch: transparent layer filter - depth
199 Qt3DRender::QRenderStateSet *transparentObjectsRenderStateSetDepth = new Qt3DRender::QRenderStateSet( sortPolicy );
200 {
201 Qt3DRender::QDepthTest *depthTest = new Qt3DRender::QDepthTest;
202 depthTest->setDepthFunction( Qt3DRender::QDepthTest::Less );
203 transparentObjectsRenderStateSetDepth->addRenderState( depthTest );
204
205 Qt3DRender::QColorMask *noColorMask = new Qt3DRender::QColorMask;
206 noColorMask->setAlphaMasked( false );
207 noColorMask->setRedMasked( false );
208 noColorMask->setGreenMasked( false );
209 noColorMask->setBlueMasked( false );
210 transparentObjectsRenderStateSetDepth->addRenderState( noColorMask );
211
212 Qt3DRender::QCullFace *cullFace = new Qt3DRender::QCullFace;
213 cullFace->setMode( Qt3DRender::QCullFace::CullingMode::NoCulling );
214 transparentObjectsRenderStateSetDepth->addRenderState( cullFace );
215 }
216
217 mDebugOverlay = new Qt3DRender::QDebugOverlay( mForwardClearBuffers );
218 mDebugOverlay->setEnabled( false );
219
220 // cppcheck wrongly believes transparentObjectsRenderStateSetColor and transparentObjectsRenderStateSetDepth will leak
221 // cppcheck-suppress memleak
222 return mMainCameraSelector;
223}
224
225Qt3DRender::QFrameGraphNode *QgsFrameGraph::constructShadowRenderPass()
226{
227 mLightCameraSelectorShadowPass = new Qt3DRender::QCameraSelector;
228 mLightCameraSelectorShadowPass->setCamera( mLightCamera );
229
230 mShadowSceneEntitiesFilter = new Qt3DRender::QLayerFilter( mLightCameraSelectorShadowPass );
231 mShadowSceneEntitiesFilter->addLayer( mCastShadowsLayer );
232
233 mShadowMapTexture = new Qt3DRender::QTexture2D;
234 mShadowMapTexture->setWidth( mShadowMapResolution );
235 mShadowMapTexture->setHeight( mShadowMapResolution );
236 mShadowMapTexture->setFormat( Qt3DRender::QTexture2D::TextureFormat::DepthFormat );
237 mShadowMapTexture->setGenerateMipMaps( false );
238 mShadowMapTexture->setMagnificationFilter( Qt3DRender::QTexture2D::Linear );
239 mShadowMapTexture->setMinificationFilter( Qt3DRender::QTexture2D::Linear );
240 mShadowMapTexture->wrapMode()->setX( Qt3DRender::QTextureWrapMode::ClampToEdge );
241 mShadowMapTexture->wrapMode()->setY( Qt3DRender::QTextureWrapMode::ClampToEdge );
242
243 Qt3DRender::QRenderTarget *shadowRenderTarget = new Qt3DRender::QRenderTarget;
244 Qt3DRender::QRenderTargetOutput *shadowRenderTargetOutput = new Qt3DRender::QRenderTargetOutput;
245 shadowRenderTargetOutput->setAttachmentPoint( Qt3DRender::QRenderTargetOutput::Depth );
246 shadowRenderTargetOutput->setTexture( mShadowMapTexture );
247 shadowRenderTarget->addOutput( shadowRenderTargetOutput );
248
249 mShadowRenderTargetSelector = new Qt3DRender::QRenderTargetSelector( mShadowSceneEntitiesFilter );
250 mShadowRenderTargetSelector->setTarget( shadowRenderTarget );
251
252 mShadowClearBuffers = new Qt3DRender::QClearBuffers( mShadowRenderTargetSelector );
253 mShadowClearBuffers->setBuffers( Qt3DRender::QClearBuffers::BufferType::ColorDepthBuffer );
254 mShadowClearBuffers->setClearColor( QColor::fromRgbF( 0.0f, 1.0f, 0.0f ) );
255
256 mShadowRenderStateSet = new Qt3DRender::QRenderStateSet( mShadowClearBuffers );
257
258 Qt3DRender::QDepthTest *shadowDepthTest = new Qt3DRender::QDepthTest;
259 shadowDepthTest->setDepthFunction( Qt3DRender::QDepthTest::Less );
260 mShadowRenderStateSet->addRenderState( shadowDepthTest );
261
262 Qt3DRender::QCullFace *shadowCullFace = new Qt3DRender::QCullFace;
263 shadowCullFace->setMode( Qt3DRender::QCullFace::CullingMode::Front );
264 mShadowRenderStateSet->addRenderState( shadowCullFace );
265
266 Qt3DRender::QPolygonOffset *polygonOffset = new Qt3DRender::QPolygonOffset;
267 polygonOffset->setDepthSteps( 4.0 );
268 polygonOffset->setScaleFactor( 1.1 );
269 mShadowRenderStateSet->addRenderState( polygonOffset );
270
271 return mLightCameraSelectorShadowPass;
272}
273
274Qt3DRender::QFrameGraphNode *QgsFrameGraph::constructPostprocessingPass()
275{
276 mPostProcessingCameraSelector = new Qt3DRender::QCameraSelector;
277 mPostProcessingCameraSelector->setCamera( mLightCamera );
278
279 mPostprocessPassLayerFilter = new Qt3DRender::QLayerFilter( mPostProcessingCameraSelector );
280
281 mPostprocessClearBuffers = new Qt3DRender::QClearBuffers( mPostprocessPassLayerFilter );
282
283 mRenderCaptureTargetSelector = new Qt3DRender::QRenderTargetSelector( mPostprocessClearBuffers );
284
285 Qt3DRender::QRenderTarget *renderTarget = new Qt3DRender::QRenderTarget( mRenderCaptureTargetSelector );
286
287 // The lifetime of the objects created here is managed
288 // automatically, as they become children of this object.
289
290 // Create a render target output for rendering color.
291 Qt3DRender::QRenderTargetOutput *colorOutput = new Qt3DRender::QRenderTargetOutput( renderTarget );
292 colorOutput->setAttachmentPoint( Qt3DRender::QRenderTargetOutput::Color0 );
293
294 // Create a texture to render into.
295 mRenderCaptureColorTexture = new Qt3DRender::QTexture2D( colorOutput );
296 mRenderCaptureColorTexture->setSize( mSize.width(), mSize.height() );
297 mRenderCaptureColorTexture->setFormat( Qt3DRender::QAbstractTexture::RGB8_UNorm );
298 mRenderCaptureColorTexture->setMinificationFilter( Qt3DRender::QAbstractTexture::Linear );
299 mRenderCaptureColorTexture->setMagnificationFilter( Qt3DRender::QAbstractTexture::Linear );
300
301 // Hook the texture up to our output, and the output up to this object.
302 colorOutput->setTexture( mRenderCaptureColorTexture );
303 renderTarget->addOutput( colorOutput );
304
305 Qt3DRender::QRenderTargetOutput *depthOutput = new Qt3DRender::QRenderTargetOutput( renderTarget );
306
307 depthOutput->setAttachmentPoint( Qt3DRender::QRenderTargetOutput::Depth );
308 mRenderCaptureDepthTexture = new Qt3DRender::QTexture2D( depthOutput );
309 mRenderCaptureDepthTexture->setSize( mSize.width(), mSize.height() );
310 mRenderCaptureDepthTexture->setFormat( Qt3DRender::QAbstractTexture::DepthFormat );
311 mRenderCaptureDepthTexture->setMinificationFilter( Qt3DRender::QAbstractTexture::Linear );
312 mRenderCaptureDepthTexture->setMagnificationFilter( Qt3DRender::QAbstractTexture::Linear );
313 mRenderCaptureDepthTexture->setComparisonFunction( Qt3DRender::QAbstractTexture::CompareLessEqual );
314 mRenderCaptureDepthTexture->setComparisonMode( Qt3DRender::QAbstractTexture::CompareRefToTexture );
315
316 depthOutput->setTexture( mRenderCaptureDepthTexture );
317 renderTarget->addOutput( depthOutput );
318
319 mRenderCaptureTargetSelector->setTarget( renderTarget );
320
321 mRenderCapture = new Qt3DRender::QRenderCapture( mRenderCaptureTargetSelector );
322
323 mPostprocessingEntity = new QgsPostprocessingEntity( this, mRootEntity );
324 mPostprocessPassLayerFilter->addLayer( mPostprocessingEntity->layer() );
325
326 return mPostProcessingCameraSelector;
327}
328
329Qt3DRender::QFrameGraphNode *QgsFrameGraph::constructAmbientOcclusionRenderPass()
330{
331 mAmbientOcclusionRenderCameraSelector = new Qt3DRender::QCameraSelector;
332 mAmbientOcclusionRenderCameraSelector->setCamera( mMainCamera );
333
334 mAmbientOcclusionRenderStateSet = new Qt3DRender::QRenderStateSet( mAmbientOcclusionRenderCameraSelector );
335
336 Qt3DRender::QDepthTest *depthRenderDepthTest = new Qt3DRender::QDepthTest;
337 depthRenderDepthTest->setDepthFunction( Qt3DRender::QDepthTest::Always );;
338 Qt3DRender::QCullFace *depthRenderCullFace = new Qt3DRender::QCullFace;
339 depthRenderCullFace->setMode( Qt3DRender::QCullFace::NoCulling );
340
341 mAmbientOcclusionRenderStateSet->addRenderState( depthRenderDepthTest );
342 mAmbientOcclusionRenderStateSet->addRenderState( depthRenderCullFace );
343
344 mAmbientOcclusionRenderLayerFilter = new Qt3DRender::QLayerFilter( mAmbientOcclusionRenderStateSet );
345
346 mAmbientOcclusionRenderCaptureTargetSelector = new Qt3DRender::QRenderTargetSelector( mAmbientOcclusionRenderLayerFilter );
347 Qt3DRender::QRenderTarget *depthRenderTarget = new Qt3DRender::QRenderTarget( mAmbientOcclusionRenderCaptureTargetSelector );
348
349 // The lifetime of the objects created here is managed
350 // automatically, as they become children of this object.
351
352 // Create a render target output for rendering color.
353 Qt3DRender::QRenderTargetOutput *colorOutput = new Qt3DRender::QRenderTargetOutput( depthRenderTarget );
354 colorOutput->setAttachmentPoint( Qt3DRender::QRenderTargetOutput::Color0 );
355
356 // Create a texture to render into.
357 mAmbientOcclusionRenderTexture = new Qt3DRender::QTexture2D( colorOutput );
358 mAmbientOcclusionRenderTexture->setSize( mSize.width(), mSize.height() );
359 mAmbientOcclusionRenderTexture->setFormat( Qt3DRender::QAbstractTexture::R32F );
360 mAmbientOcclusionRenderTexture->setMinificationFilter( Qt3DRender::QAbstractTexture::Linear );
361 mAmbientOcclusionRenderTexture->setMagnificationFilter( Qt3DRender::QAbstractTexture::Linear );
362
363 // Hook the texture up to our output, and the output up to this object.
364 colorOutput->setTexture( mAmbientOcclusionRenderTexture );
365 depthRenderTarget->addOutput( colorOutput );
366
367 mAmbientOcclusionRenderCaptureTargetSelector->setTarget( depthRenderTarget );
368
369 mAmbientOcclusionRenderEntity = new QgsAmbientOcclusionRenderEntity( mForwardDepthTexture, mMainCamera, mRootEntity );
370 mAmbientOcclusionRenderLayerFilter->addLayer( mAmbientOcclusionRenderEntity->layer() );
371
372 return mAmbientOcclusionRenderCameraSelector;
373}
374
375Qt3DRender::QFrameGraphNode *QgsFrameGraph::constructAmbientOcclusionBlurPass()
376{
377 mAmbientOcclusionBlurCameraSelector = new Qt3DRender::QCameraSelector;
378 mAmbientOcclusionBlurCameraSelector->setCamera( mMainCamera );
379
380 mAmbientOcclusionBlurStateSet = new Qt3DRender::QRenderStateSet( mAmbientOcclusionBlurCameraSelector );
381
382 Qt3DRender::QDepthTest *depthRenderDepthTest = new Qt3DRender::QDepthTest;
383 depthRenderDepthTest->setDepthFunction( Qt3DRender::QDepthTest::Always );;
384 Qt3DRender::QCullFace *depthRenderCullFace = new Qt3DRender::QCullFace;
385 depthRenderCullFace->setMode( Qt3DRender::QCullFace::NoCulling );
386
387 mAmbientOcclusionBlurStateSet->addRenderState( depthRenderDepthTest );
388 mAmbientOcclusionBlurStateSet->addRenderState( depthRenderCullFace );
389
390 mAmbientOcclusionBlurLayerFilter = new Qt3DRender::QLayerFilter( mAmbientOcclusionBlurStateSet );
391
392 mAmbientOcclusionBlurRenderCaptureTargetSelector = new Qt3DRender::QRenderTargetSelector( mAmbientOcclusionBlurLayerFilter );
393 Qt3DRender::QRenderTarget *depthRenderTarget = new Qt3DRender::QRenderTarget( mAmbientOcclusionBlurRenderCaptureTargetSelector );
394
395 // The lifetime of the objects created here is managed
396 // automatically, as they become children of this object.
397
398 // Create a render target output for rendering color.
399 Qt3DRender::QRenderTargetOutput *colorOutput = new Qt3DRender::QRenderTargetOutput( depthRenderTarget );
400 colorOutput->setAttachmentPoint( Qt3DRender::QRenderTargetOutput::Color0 );
401
402 // Create a texture to render into.
403 mAmbientOcclusionBlurTexture = new Qt3DRender::QTexture2D( colorOutput );
404 mAmbientOcclusionBlurTexture->setSize( mSize.width(), mSize.height() );
405 mAmbientOcclusionBlurTexture->setFormat( Qt3DRender::QAbstractTexture::R32F );
406 mAmbientOcclusionBlurTexture->setMinificationFilter( Qt3DRender::QAbstractTexture::Linear );
407 mAmbientOcclusionBlurTexture->setMagnificationFilter( Qt3DRender::QAbstractTexture::Linear );
408
409 // Hook the texture up to our output, and the output up to this object.
410 colorOutput->setTexture( mAmbientOcclusionBlurTexture );
411 depthRenderTarget->addOutput( colorOutput );
412
413 mAmbientOcclusionBlurRenderCaptureTargetSelector->setTarget( depthRenderTarget );
414
415 mAmbientOcclusionBlurEntity = new QgsAmbientOcclusionBlurEntity( mAmbientOcclusionRenderTexture, mRootEntity );
416 mAmbientOcclusionBlurLayerFilter->addLayer( mAmbientOcclusionBlurEntity->layer() );
417
418 return mAmbientOcclusionBlurCameraSelector;
419}
420
421
422Qt3DRender::QFrameGraphNode *QgsFrameGraph::constructRubberBandsPass()
423{
424 mRubberBandsCameraSelector = new Qt3DRender::QCameraSelector;
425 mRubberBandsCameraSelector->setCamera( mMainCamera );
426
427 mRubberBandsLayerFilter = new Qt3DRender::QLayerFilter( mRubberBandsCameraSelector );
428 mRubberBandsLayerFilter->addLayer( mRubberBandsLayer );
429
430 mRubberBandsStateSet = new Qt3DRender::QRenderStateSet( mRubberBandsLayerFilter );
431 Qt3DRender::QDepthTest *depthTest = new Qt3DRender::QDepthTest;
432 depthTest->setDepthFunction( Qt3DRender::QDepthTest::Always );
433 mRubberBandsStateSet->addRenderState( depthTest );
434
435 // Here we attach our drawings to the render target also used by forward pass.
436 // This is kind of okay, but as a result, post-processing effects get applied
437 // to rubber bands too. Ideally we would want them on top of everything.
438 mRubberBandsRenderTargetSelector = new Qt3DRender::QRenderTargetSelector( mRubberBandsStateSet );
439 mRubberBandsRenderTargetSelector->setTarget( mForwardRenderTargetSelector->target() );
440
441 return mRubberBandsCameraSelector;
442}
443
444
445
446Qt3DRender::QFrameGraphNode *QgsFrameGraph::constructDepthRenderPass()
447{
448 // depth buffer render to copy pass
449
450 mDepthRenderCameraSelector = new Qt3DRender::QCameraSelector;
451 mDepthRenderCameraSelector->setCamera( mMainCamera );
452
453 mDepthRenderStateSet = new Qt3DRender::QRenderStateSet( mDepthRenderCameraSelector );
454
455 Qt3DRender::QDepthTest *depthRenderDepthTest = new Qt3DRender::QDepthTest;
456 depthRenderDepthTest->setDepthFunction( Qt3DRender::QDepthTest::Always );;
457 Qt3DRender::QCullFace *depthRenderCullFace = new Qt3DRender::QCullFace;
458 depthRenderCullFace->setMode( Qt3DRender::QCullFace::NoCulling );
459
460 mDepthRenderStateSet->addRenderState( depthRenderDepthTest );
461 mDepthRenderStateSet->addRenderState( depthRenderCullFace );
462
463 mDepthRenderLayerFilter = new Qt3DRender::QLayerFilter( mDepthRenderStateSet );
464 mDepthRenderLayerFilter->addLayer( mDepthRenderPassLayer );
465
466 mDepthRenderCaptureTargetSelector = new Qt3DRender::QRenderTargetSelector( mDepthRenderLayerFilter );
467 Qt3DRender::QRenderTarget *depthRenderTarget = new Qt3DRender::QRenderTarget( mDepthRenderCaptureTargetSelector );
468
469 // The lifetime of the objects created here is managed
470 // automatically, as they become children of this object.
471
472 // Create a render target output for rendering color.
473 Qt3DRender::QRenderTargetOutput *colorOutput = new Qt3DRender::QRenderTargetOutput( depthRenderTarget );
474 colorOutput->setAttachmentPoint( Qt3DRender::QRenderTargetOutput::Color0 );
475
476 // Create a texture to render into.
477 mDepthRenderCaptureColorTexture = new Qt3DRender::QTexture2D( colorOutput );
478 mDepthRenderCaptureColorTexture->setSize( mSize.width(), mSize.height() );
479 mDepthRenderCaptureColorTexture->setFormat( Qt3DRender::QAbstractTexture::RGB8_UNorm );
480 mDepthRenderCaptureColorTexture->setMinificationFilter( Qt3DRender::QAbstractTexture::Linear );
481 mDepthRenderCaptureColorTexture->setMagnificationFilter( Qt3DRender::QAbstractTexture::Linear );
482
483 // Hook the texture up to our output, and the output up to this object.
484 colorOutput->setTexture( mDepthRenderCaptureColorTexture );
485 depthRenderTarget->addOutput( colorOutput );
486
487 Qt3DRender::QRenderTargetOutput *depthOutput = new Qt3DRender::QRenderTargetOutput( depthRenderTarget );
488
489 depthOutput->setAttachmentPoint( Qt3DRender::QRenderTargetOutput::Depth );
490 mDepthRenderCaptureDepthTexture = new Qt3DRender::QTexture2D( depthOutput );
491 mDepthRenderCaptureDepthTexture->setSize( mSize.width(), mSize.height() );
492 mDepthRenderCaptureDepthTexture->setFormat( Qt3DRender::QAbstractTexture::DepthFormat );
493 mDepthRenderCaptureDepthTexture->setMinificationFilter( Qt3DRender::QAbstractTexture::Linear );
494 mDepthRenderCaptureDepthTexture->setMagnificationFilter( Qt3DRender::QAbstractTexture::Linear );
495 mDepthRenderCaptureDepthTexture->setComparisonFunction( Qt3DRender::QAbstractTexture::CompareLessEqual );
496 mDepthRenderCaptureDepthTexture->setComparisonMode( Qt3DRender::QAbstractTexture::CompareRefToTexture );
497
498 depthOutput->setTexture( mDepthRenderCaptureDepthTexture );
499 depthRenderTarget->addOutput( depthOutput );
500
501 mDepthRenderCaptureTargetSelector->setTarget( depthRenderTarget );
502
503 // Note: We do not a clear buffers node since we are drawing a quad that will override the buffer's content anyway
504 mDepthRenderCapture = new Qt3DRender::QRenderCapture( mDepthRenderCaptureTargetSelector );
505
506 return mDepthRenderCameraSelector;
507}
508
509Qt3DCore::QEntity *QgsFrameGraph::constructDepthRenderQuad()
510{
511 Qt3DCore::QEntity *quad = new Qt3DCore::QEntity;
512 quad->setObjectName( "depthRenderQuad" );
513
514 Qt3DQGeometry *geom = new Qt3DQGeometry;
515 Qt3DQAttribute *positionAttribute = new Qt3DQAttribute;
516 const QVector<float> vert = { -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f };
517
518 const QByteArray vertexArr( ( const char * ) vert.constData(), vert.size() * sizeof( float ) );
519 Qt3DQBuffer *vertexBuffer = nullptr;
520 vertexBuffer = new Qt3DQBuffer( this );
521 vertexBuffer->setData( vertexArr );
522
523 positionAttribute->setName( Qt3DQAttribute::defaultPositionAttributeName() );
524 positionAttribute->setVertexBaseType( Qt3DQAttribute::Float );
525 positionAttribute->setVertexSize( 3 );
526 positionAttribute->setAttributeType( Qt3DQAttribute::VertexAttribute );
527 positionAttribute->setBuffer( vertexBuffer );
528 positionAttribute->setByteOffset( 0 );
529 positionAttribute->setByteStride( 3 * sizeof( float ) );
530 positionAttribute->setCount( 6 );
531
532 geom->addAttribute( positionAttribute );
533
534 Qt3DRender::QGeometryRenderer *renderer = new Qt3DRender::QGeometryRenderer;
535 renderer->setPrimitiveType( Qt3DRender::QGeometryRenderer::PrimitiveType::Triangles );
536 renderer->setGeometry( geom );
537
538 quad->addComponent( renderer );
539
540 QMatrix4x4 modelMatrix;
541 modelMatrix.setToIdentity();
542
543 // construct material
544
545 Qt3DRender::QMaterial *material = new Qt3DRender::QMaterial;
546 Qt3DRender::QParameter *textureParameter = new Qt3DRender::QParameter( "depthTexture", mForwardDepthTexture );
547 Qt3DRender::QParameter *textureTransformParameter = new Qt3DRender::QParameter( "modelMatrix", QVariant::fromValue( modelMatrix ) );
548 material->addParameter( textureParameter );
549 material->addParameter( textureTransformParameter );
550
551 Qt3DRender::QEffect *effect = new Qt3DRender::QEffect;
552
553 Qt3DRender::QTechnique *technique = new Qt3DRender::QTechnique;
554
555 Qt3DRender::QGraphicsApiFilter *graphicsApiFilter = technique->graphicsApiFilter();
556 graphicsApiFilter->setApi( Qt3DRender::QGraphicsApiFilter::Api::OpenGL );
557 graphicsApiFilter->setProfile( Qt3DRender::QGraphicsApiFilter::OpenGLProfile::CoreProfile );
558 graphicsApiFilter->setMajorVersion( 1 );
559 graphicsApiFilter->setMinorVersion( 5 );
560
561 Qt3DRender::QRenderPass *renderPass = new Qt3DRender::QRenderPass;
562
563 Qt3DRender::QShaderProgram *shader = new Qt3DRender::QShaderProgram;
564 shader->setVertexShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( "qrc:/shaders/depth_render.vert" ) ) );
565 shader->setFragmentShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( "qrc:/shaders/depth_render.frag" ) ) );
566 renderPass->setShaderProgram( shader );
567
568 technique->addRenderPass( renderPass );
569
570 effect->addTechnique( technique );
571 material->setEffect( effect );
572
573 quad->addComponent( material );
574
575 return quad;
576}
577
578QgsFrameGraph::QgsFrameGraph( QSurface *surface, QSize s, Qt3DRender::QCamera *mainCamera, Qt3DCore::QEntity *root )
579 : Qt3DCore::QEntity( root )
580 , mSize( s )
581{
582
583 // general overview of how the frame graph looks:
584 //
585 // +------------------------+ using window or
586 // | QRenderSurfaceSelector | offscreen surface
587 // +------------------------+
588 // |
589 // +-----------+
590 // | QViewport | (0,0,1,1)
591 // +-----------+
592 // |
593 // +--------------------------+-------------------+-----------------+
594 // | | | |
595 // +--------------------+ +--------------+ +-----------------+ +-----------------+
596 // | two forward passes | | shadows pass | | depth buffer | | post-processing |
597 // | (solid objects | | | | processing pass | | passes |
598 // | and transparent) | +--------------+ +-----------------+ +-----------------+
599 // +--------------------+
600 //
601 // Notes:
602 // - depth buffer processing pass is used whenever we need depth map information
603 // (for camera navigation) and it converts depth texture to a color texture
604 // so that we can capture it with QRenderCapture - currently it is unable
605 // to capture depth buffer, only colors (see QTBUG-65155)
606 // - there are multiple post-processing passes that take rendered output
607 // of the scene, optionally apply effects (add shadows, ambient occlusion,
608 // eye dome lighting) and finally output to the given surface
609 // - there may be also two more passes when 3D axis is shown - see Qgs3DAxis
610
611 mRootEntity = root;
612 mMainCamera = mainCamera;
613 mLightCamera = new Qt3DRender::QCamera;
614
615 mPreviewLayer = new Qt3DRender::QLayer;
616 mCastShadowsLayer = new Qt3DRender::QLayer;
617 mForwardRenderLayer = new Qt3DRender::QLayer;
618 mDepthRenderPassLayer = new Qt3DRender::QLayer;
619 mTransparentObjectsPassLayer = new Qt3DRender::QLayer;
620 mRubberBandsLayer = new Qt3DRender::QLayer;
621
622 mPreviewLayer->setRecursive( true );
623 mCastShadowsLayer->setRecursive( true );
624 mForwardRenderLayer->setRecursive( true );
625 mDepthRenderPassLayer->setRecursive( true );
626 mTransparentObjectsPassLayer->setRecursive( true );
627 mRubberBandsLayer->setRecursive( true );
628
629 mRenderSurfaceSelector = new Qt3DRender::QRenderSurfaceSelector;
630
631 QObject *surfaceObj = dynamic_cast< QObject * >( surface );
632 Q_ASSERT( surfaceObj );
633
634 mRenderSurfaceSelector->setSurface( surfaceObj );
635 mRenderSurfaceSelector->setExternalRenderTargetSize( mSize );
636
637 mMainViewPort = new Qt3DRender::QViewport( mRenderSurfaceSelector );
638 mMainViewPort->setNormalizedRect( QRectF( 0.0f, 0.0f, 1.0f, 1.0f ) );
639
640 // Forward render
641 Qt3DRender::QFrameGraphNode *forwardRenderPass = constructForwardRenderPass();
642 forwardRenderPass->setParent( mMainViewPort );
643
644 // rubber bands (they should be always on top)
645 Qt3DRender::QFrameGraphNode *rubberBandsPass = constructRubberBandsPass();
646 rubberBandsPass->setParent( mMainViewPort );
647
648 // shadow rendering pass
649 Qt3DRender::QFrameGraphNode *shadowRenderPass = constructShadowRenderPass();
650 shadowRenderPass->setParent( mMainViewPort );
651
652 // depth buffer processing
653 Qt3DRender::QFrameGraphNode *depthBufferProcessingPass = constructDepthRenderPass();
654 depthBufferProcessingPass->setParent( mMainViewPort );
655
656 // Ambient occlusion factor render pass
657 Qt3DRender::QFrameGraphNode *ambientOcclusionFactorRender = constructAmbientOcclusionRenderPass();
658 ambientOcclusionFactorRender->setParent( mMainViewPort );
659
660 Qt3DRender::QFrameGraphNode *ambientOcclusionBlurPass = constructAmbientOcclusionBlurPass();
661 ambientOcclusionBlurPass->setParent( mMainViewPort );
662
663 // post process
664 Qt3DRender::QFrameGraphNode *postprocessingPass = constructPostprocessingPass();
665 postprocessingPass->setParent( mMainViewPort );
666
667 mRubberBandsRootEntity = new Qt3DCore::QEntity( mRootEntity );
668 mRubberBandsRootEntity->addComponent( mRubberBandsLayer );
669
670 // textures preview pass
671 Qt3DRender::QFrameGraphNode *previewPass = constructTexturesPreviewPass();
672 previewPass->setParent( mMainViewPort );
673
674 Qt3DRender::QParameter *depthMapIsDepthParam = new Qt3DRender::QParameter( "isDepth", true );
675 Qt3DRender::QParameter *shadowMapIsDepthParam = new Qt3DRender::QParameter( "isDepth", true );
676
677 mDebugDepthMapPreviewQuad = this->addTexturePreviewOverlay( mForwardDepthTexture, QPointF( 0.9f, 0.9f ), QSizeF( 0.1, 0.1 ), QVector<Qt3DRender::QParameter *> { depthMapIsDepthParam } );
678 mDebugShadowMapPreviewQuad = this->addTexturePreviewOverlay( mShadowMapTexture, QPointF( 0.9f, 0.9f ), QSizeF( 0.1, 0.1 ), QVector<Qt3DRender::QParameter *> { shadowMapIsDepthParam } );
679 mDebugDepthMapPreviewQuad->setEnabled( false );
680 mDebugShadowMapPreviewQuad->setEnabled( false );
681
682 mDepthRenderQuad = constructDepthRenderQuad();
683 mDepthRenderQuad->addComponent( mDepthRenderPassLayer );
684 mDepthRenderQuad->setParent( mRootEntity );
685}
686
687QgsPreviewQuad *QgsFrameGraph::addTexturePreviewOverlay( Qt3DRender::QTexture2D *texture, const QPointF &centerTexCoords, const QSizeF &sizeTexCoords, QVector<Qt3DRender::QParameter *> additionalShaderParameters )
688{
689 QgsPreviewQuad *previewQuad = new QgsPreviewQuad( texture, centerTexCoords, sizeTexCoords, additionalShaderParameters );
690 previewQuad->addComponent( mPreviewLayer );
691 previewQuad->setParent( mRootEntity );
692 mPreviewQuads.push_back( previewQuad );
693 return previewQuad;
694}
695
696// computes the portion of the Y=y plane the camera is looking at
697void calculateViewExtent( Qt3DRender::QCamera *camera, float shadowRenderingDistance, float y, float &minX, float &maxX, float &minY, float &maxY, float &minZ, float &maxZ )
698{
699 const QVector3D cameraPos = camera->position();
700 const QMatrix4x4 projectionMatrix = camera->projectionMatrix();
701 const QMatrix4x4 viewMatrix = camera->viewMatrix();
702 float depth = 1.0f;
703 QVector4D viewCenter = viewMatrix * QVector4D( camera->viewCenter(), 1.0f );
704 viewCenter /= viewCenter.w();
705 viewCenter = projectionMatrix * viewCenter;
706 viewCenter /= viewCenter.w();
707 depth = viewCenter.z();
708 QVector<QVector3D> viewFrustumPoints =
709 {
710 QVector3D( 0.0f, 0.0f, depth ),
711 QVector3D( 0.0f, 1.0f, depth ),
712 QVector3D( 1.0f, 0.0f, depth ),
713 QVector3D( 1.0f, 1.0f, depth ),
714 QVector3D( 0.0f, 0.0f, 0 ),
715 QVector3D( 0.0f, 1.0f, 0 ),
716 QVector3D( 1.0f, 0.0f, 0 ),
717 QVector3D( 1.0f, 1.0f, 0 )
718 };
719 maxX = std::numeric_limits<float>::lowest();
720 maxY = std::numeric_limits<float>::lowest();
721 maxZ = std::numeric_limits<float>::lowest();
722 minX = std::numeric_limits<float>::max();
723 minY = std::numeric_limits<float>::max();
724 minZ = std::numeric_limits<float>::max();
725 for ( int i = 0; i < viewFrustumPoints.size(); ++i )
726 {
727 // convert from view port space to world space
728 viewFrustumPoints[i] = viewFrustumPoints[i].unproject( viewMatrix, projectionMatrix, QRect( 0, 0, 1, 1 ) );
729 minX = std::min( minX, viewFrustumPoints[i].x() );
730 maxX = std::max( maxX, viewFrustumPoints[i].x() );
731 minY = std::min( minY, viewFrustumPoints[i].y() );
732 maxY = std::max( maxY, viewFrustumPoints[i].y() );
733 minZ = std::min( minZ, viewFrustumPoints[i].z() );
734 maxZ = std::max( maxZ, viewFrustumPoints[i].z() );
735 // find the intersection between the line going from cameraPos to the frustum quad point
736 // and the horizontal plane Y=y
737 // if the intersection is on the back side of the viewing panel we get a point that is
738 // shadowRenderingDistance units in front of the camera
739 const QVector3D pt = cameraPos;
740 const QVector3D vect = ( viewFrustumPoints[i] - pt ).normalized();
741 float t = ( y - pt.y() ) / vect.y();
742 if ( t < 0 )
743 t = shadowRenderingDistance;
744 else
745 t = std::min( t, shadowRenderingDistance );
746 viewFrustumPoints[i] = pt + t * vect;
747 minX = std::min( minX, viewFrustumPoints[i].x() );
748 maxX = std::max( maxX, viewFrustumPoints[i].x() );
749 minY = std::min( minY, viewFrustumPoints[i].y() );
750 maxY = std::max( maxY, viewFrustumPoints[i].y() );
751 minZ = std::min( minZ, viewFrustumPoints[i].z() );
752 maxZ = std::max( maxZ, viewFrustumPoints[i].z() );
753 }
754}
755
756void QgsFrameGraph::setupDirectionalLight( const QgsDirectionalLightSettings &light, float maximumShadowRenderingDistance )
757{
758 float minX, maxX, minY, maxY, minZ, maxZ;
759 QVector3D lookingAt = mMainCamera->viewCenter();
760 const float d = 2 * ( mMainCamera->position() - mMainCamera->viewCenter() ).length();
761
762 const QVector3D vertical = QVector3D( 0.0f, d, 0.0f );
763 const QVector3D lightDirection = QVector3D( light.direction().x(), light.direction().y(), light.direction().z() ).normalized();
764 calculateViewExtent( mMainCamera, maximumShadowRenderingDistance, lookingAt.y(), minX, maxX, minY, maxY, minZ, maxZ );
765
766 lookingAt = QVector3D( 0.5 * ( minX + maxX ), mMainCamera->viewCenter().y(), 0.5 * ( minZ + maxZ ) );
767 const QVector3D lightPosition = lookingAt + vertical;
768 mLightCamera->setPosition( lightPosition );
769 mLightCamera->setViewCenter( lookingAt );
770 mLightCamera->setUpVector( QVector3D( 0.0f, 1.0f, 0.0f ) );
771 mLightCamera->rotateAboutViewCenter( QQuaternion::rotationTo( vertical.normalized(), -lightDirection.normalized() ) );
772
773 mLightCamera->setProjectionType( Qt3DRender::QCameraLens::ProjectionType::OrthographicProjection );
774 mLightCamera->lens()->setOrthographicProjection(
775 - 0.7 * ( maxX - minX ), 0.7 * ( maxX - minX ),
776 - 0.7 * ( maxZ - minZ ), 0.7 * ( maxZ - minZ ),
777 1.0f, 2 * ( lookingAt - lightPosition ).length() );
778
779 mPostprocessingEntity->setupShadowRenderingExtent( minX, maxX, minZ, maxZ );
780 mPostprocessingEntity->setupDirectionalLight( lightPosition, lightDirection );
781}
782
783void QgsFrameGraph::setClearColor( const QColor &clearColor )
784{
785 mForwardClearBuffers->setClearColor( clearColor );
786}
787
789{
790 mShadowRenderingEnabled = enabled;
791 mPostprocessingEntity->setShadowRenderingEnabled( mShadowRenderingEnabled );
792 if ( mShadowRenderingEnabled )
793 mShadowSceneEntitiesFilter->setEnabled( true );
794 else
795 mShadowSceneEntitiesFilter->setEnabled( false );
796}
797
798void QgsFrameGraph::setShadowBias( float shadowBias )
799{
800 mShadowBias = shadowBias;
801 mPostprocessingEntity->setShadowBias( mShadowBias );
802}
803
805{
806 mShadowMapResolution = resolution;
807 mShadowMapTexture->setWidth( mShadowMapResolution );
808 mShadowMapTexture->setHeight( mShadowMapResolution );
809}
810
812{
813 mAmbientOcclusionEnabled = enabled;
814 mAmbientOcclusionRenderEntity->setEnabled( enabled );
815 mPostprocessingEntity->setAmbientOcclusionEnabled( enabled );
816}
817
819{
820 mAmbientOcclusionIntensity = intensity;
821 mAmbientOcclusionRenderEntity->setIntensity( intensity );
822}
823
825{
826 mAmbientOcclusionRadius = radius;
827 mAmbientOcclusionRenderEntity->setRadius( radius );
828}
829
831{
832 mAmbientOcclusionThreshold = threshold;
833 mAmbientOcclusionRenderEntity->setThreshold( threshold );
834}
835
837{
838 if ( enabled == mFrustumCullingEnabled )
839 return;
840 mFrustumCullingEnabled = enabled;
841 if ( mFrustumCullingEnabled )
842 mFrustumCulling->setParent( mForwardClearBuffers );
843 else
844 mFrustumCulling->setParent( ( Qt3DCore::QNode * )nullptr );
845}
846
847void QgsFrameGraph::setupEyeDomeLighting( bool enabled, double strength, int distance )
848{
849 mEyeDomeLightingEnabled = enabled;
850 mEyeDomeLightingStrength = strength;
851 mEyeDomeLightingDistance = distance;
852 mPostprocessingEntity->setEyeDomeLightingEnabled( enabled );
853 mPostprocessingEntity->setEyeDomeLightingStrength( strength );
854 mPostprocessingEntity->setEyeDomeLightingDistance( distance );
855}
856
857void QgsFrameGraph::setupShadowMapDebugging( bool enabled, Qt::Corner corner, double size )
858{
859 mDebugShadowMapPreviewQuad->setEnabled( enabled );
860 if ( enabled )
861 {
862 switch ( corner )
863 {
864 case Qt::Corner::TopRightCorner:
865 mDebugShadowMapPreviewQuad->setViewPort( QPointF( 1.0f - size / 2, 0.0f + size / 2 ), 0.5 * QSizeF( size, size ) );
866 break;
867 case Qt::Corner::TopLeftCorner:
868 mDebugShadowMapPreviewQuad->setViewPort( QPointF( 0.0f + size / 2, 0.0f + size / 2 ), 0.5 * QSizeF( size, size ) );
869 break;
870 case Qt::Corner::BottomRightCorner:
871 mDebugShadowMapPreviewQuad->setViewPort( QPointF( 1.0f - size / 2, 1.0f - size / 2 ), 0.5 * QSizeF( size, size ) );
872 break;
873 case Qt::Corner::BottomLeftCorner:
874 mDebugShadowMapPreviewQuad->setViewPort( QPointF( 0.0f + size / 2, 1.0f - size / 2 ), 0.5 * QSizeF( size, size ) );
875 break;
876 }
877 }
878}
879
880void QgsFrameGraph::setupDepthMapDebugging( bool enabled, Qt::Corner corner, double size )
881{
882 mDebugDepthMapPreviewQuad->setEnabled( enabled );
883
884 if ( enabled )
885 {
886 switch ( corner )
887 {
888 case Qt::Corner::TopRightCorner:
889 mDebugDepthMapPreviewQuad->setViewPort( QPointF( 1.0f - size / 2, 0.0f + size / 2 ), 0.5 * QSizeF( size, size ) );
890 break;
891 case Qt::Corner::TopLeftCorner:
892 mDebugDepthMapPreviewQuad->setViewPort( QPointF( 0.0f + size / 2, 0.0f + size / 2 ), 0.5 * QSizeF( size, size ) );
893 break;
894 case Qt::Corner::BottomRightCorner:
895 mDebugDepthMapPreviewQuad->setViewPort( QPointF( 1.0f - size / 2, 1.0f - size / 2 ), 0.5 * QSizeF( size, size ) );
896 break;
897 case Qt::Corner::BottomLeftCorner:
898 mDebugDepthMapPreviewQuad->setViewPort( QPointF( 0.0f + size / 2, 1.0f - size / 2 ), 0.5 * QSizeF( size, size ) );
899 break;
900 }
901 }
902}
903
905{
906 mSize = s;
907 mForwardColorTexture->setSize( mSize.width(), mSize.height() );
908 mForwardDepthTexture->setSize( mSize.width(), mSize.height() );
909 mRenderCaptureColorTexture->setSize( mSize.width(), mSize.height() );
910 mRenderCaptureDepthTexture->setSize( mSize.width(), mSize.height() );
911 mDepthRenderCaptureDepthTexture->setSize( mSize.width(), mSize.height() );
912 mDepthRenderCaptureColorTexture->setSize( mSize.width(), mSize.height() );
913 mRenderSurfaceSelector->setExternalRenderTargetSize( mSize );
914
915 mAmbientOcclusionRenderTexture->setSize( mSize.width(), mSize.height() );
916 mAmbientOcclusionBlurTexture->setSize( mSize.width(), mSize.height() );
917}
918
920{
921 if ( enabled == mRenderCaptureEnabled )
922 return;
923 mRenderCaptureEnabled = enabled;
924 mRenderCaptureTargetSelector->setEnabled( mRenderCaptureEnabled );
925}
926
928{
929 mDebugOverlay->setEnabled( enabled );
930}
void setThreshold(float threshold)
Sets the amount of occlusion when the effects starts to kick in.
void setRadius(float radius)
Sets the radius for the ambient occlusion effect.
void setIntensity(float intensity)
Sets the intensity for the ambient occlusion effect.
QgsVector3D direction() const
Returns the direction of the light in degrees.
void setRenderCaptureEnabled(bool enabled)
Sets whether it will be possible to render to an image.
void setShadowBias(float shadowBias)
Sets the shadow bias value.
void setupShadowMapDebugging(bool enabled, Qt::Corner corner, double size)
Sets the shadow map debugging view port.
void setClearColor(const QColor &clearColor)
Sets the clear color of the scene (background color)
void setShadowMapResolution(int resolution)
Sets the resolution of the shadow map.
QgsPreviewQuad * addTexturePreviewOverlay(Qt3DRender::QTexture2D *texture, const QPointF &centerNDC, const QSizeF &size, QVector< Qt3DRender::QParameter * > additionalShaderParameters=QVector< Qt3DRender::QParameter * >())
Adds an preview entity that shows a texture in real time for debugging purposes.
void setAmbientOcclusionIntensity(float intensity)
Sets the ambient occlusion intensity.
float shadowBias() const
Returns the shadow bias value.
void setFrustumCullingEnabled(bool enabled)
Sets whether frustum culling is enabled.
void setDebugOverlayEnabled(bool enabled)
Sets whether debug overlay is enabled.
void setShadowRenderingEnabled(bool enabled)
Sets whether the shadow rendering is enabled.
void setupDepthMapDebugging(bool enabled, Qt::Corner corner, double size)
Sets the depth map debugging view port.
void setupDirectionalLight(const QgsDirectionalLightSettings &light, float maximumShadowRenderingDistance)
Sets shadow rendering to use a directional light.
void setAmbientOcclusionThreshold(float threshold)
Sets the ambient occlusion threshold.
void setupEyeDomeLighting(bool enabled, double strength, int distance)
Sets eye dome lighting shading related settings.
void setSize(QSize s)
Sets the size of the buffers used for rendering.
void setAmbientOcclusionEnabled(bool enabled)
Sets whether Screen Space Ambient Occlusion will be enabled.
void setAmbientOcclusionRadius(float radius)
Sets the ambient occlusion radius.
Qt3DRender::QCamera * mainCamera()
Returns the main camera.
QgsFrameGraph(QSurface *surface, QSize s, Qt3DRender::QCamera *mainCamera, Qt3DCore::QEntity *root)
Constructor.
void setupShadowRenderingExtent(float minX, float maxX, float minZ, float maxZ)
Sets the parts of the scene where objects cast shadows.
void setAmbientOcclusionEnabled(bool enabled)
Sets whether screen space ambient occlusion is enabled.
void setShadowRenderingEnabled(bool enabled)
Sets whether shadow rendering is enabled.
void setEyeDomeLightingDistance(int distance)
Sets the eye dome lighting distance (contributes to the contrast of the image)
void setShadowBias(float shadowBias)
Sets the shadow bias value.
void setEyeDomeLightingStrength(double strength)
Sets the eye dome lighting strength.
void setupDirectionalLight(QVector3D position, QVector3D direction)
Sets up a directional light that is used to render shadows.
void setEyeDomeLightingEnabled(bool enabled)
Sets whether eye dome lighting is enabled.
void setViewPort(const QPointF &centerNDC, const QSizeF &size)
Sets where the quad will be located on the scene.
Qt3DRender::QLayer * layer()
Returns the layer object used to select this entity for rendering in a specific rendering pass.
double y() const
Returns Y coordinate.
Definition: qgsvector3d.h:50
double z() const
Returns Z coordinate.
Definition: qgsvector3d.h:52
double x() const
Returns X coordinate.
Definition: qgsvector3d.h:48
Qt3DCore::QAttribute Qt3DQAttribute
Definition: qgs3daxis.cpp:28
Qt3DCore::QBuffer Qt3DQBuffer
Definition: qgs3daxis.cpp:30
Qt3DCore::QGeometry Qt3DQGeometry
Definition: qgs3daxis.cpp:29
Qt3DCore::QAttribute Qt3DQAttribute
Qt3DCore::QBuffer Qt3DQBuffer
void calculateViewExtent(Qt3DRender::QCamera *camera, float shadowRenderingDistance, float y, float &minX, float &maxX, float &minY, float &maxY, float &minZ, float &maxZ)
Qt3DCore::QGeometry Qt3DQGeometry