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