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