24 Qt3DRender::QFrameGraphNode *QgsShadowRenderingFrameGraph::constructTexturesPreviewPass()
26 mPreviewLayerFilter =
new Qt3DRender::QLayerFilter;
27 mPreviewLayerFilter->addLayer( mPreviewLayer );
29 mPreviewRenderStateSet =
new Qt3DRender::QRenderStateSet( mPreviewLayerFilter );
30 mPreviewDepthTest =
new Qt3DRender::QDepthTest;
31 mPreviewDepthTest->setDepthFunction( Qt3DRender::QDepthTest::Always );
32 mPreviewRenderStateSet->addRenderState( mPreviewDepthTest );
33 mPreviewCullFace =
new Qt3DRender::QCullFace;
34 mPreviewCullFace->setMode( Qt3DRender::QCullFace::NoCulling );
35 mPreviewRenderStateSet->addRenderState( mPreviewCullFace );
37 return mPreviewLayerFilter;
40 Qt3DRender::QFrameGraphNode *QgsShadowRenderingFrameGraph::constructForwardRenderPass()
42 mForwardRenderLayerFilter =
new Qt3DRender::QLayerFilter;
43 mForwardRenderLayerFilter->addLayer( mForwardRenderLayer );
45 mForwardColorTexture =
new Qt3DRender::QTexture2D;
46 mForwardColorTexture->setWidth( mSize.width() );
47 mForwardColorTexture->setHeight( mSize.height() );
48 mForwardColorTexture->setFormat( Qt3DRender::QAbstractTexture::RGBA16F );
49 mForwardColorTexture->setGenerateMipMaps(
false );
50 mForwardColorTexture->setMagnificationFilter( Qt3DRender::QTexture2D::Linear );
51 mForwardColorTexture->setMinificationFilter( Qt3DRender::QTexture2D::Linear );
52 mForwardColorTexture->wrapMode()->setX( Qt3DRender::QTextureWrapMode::ClampToEdge );
53 mForwardColorTexture->wrapMode()->setY( Qt3DRender::QTextureWrapMode::ClampToEdge );
55 mForwardDepthTexture =
new Qt3DRender::QTexture2D;
56 mForwardDepthTexture->setWidth( mSize.width() );
57 mForwardDepthTexture->setHeight( mSize.height() );
58 mForwardDepthTexture->setFormat( Qt3DRender::QTexture2D::TextureFormat::DepthFormat );
59 mForwardDepthTexture->setGenerateMipMaps(
false );
60 mForwardDepthTexture->setMagnificationFilter( Qt3DRender::QTexture2D::Linear );
61 mForwardDepthTexture->setMinificationFilter( Qt3DRender::QTexture2D::Linear );
62 mForwardDepthTexture->wrapMode()->setX( Qt3DRender::QTextureWrapMode::ClampToEdge );
63 mForwardDepthTexture->wrapMode()->setY( Qt3DRender::QTextureWrapMode::ClampToEdge );
65 mForwardRenderTarget =
new Qt3DRender::QRenderTarget;
66 mForwardRenderTargetDepthOutput =
new Qt3DRender::QRenderTargetOutput;
67 mForwardRenderTargetDepthOutput->setAttachmentPoint( Qt3DRender::QRenderTargetOutput::Depth );
68 mForwardRenderTargetDepthOutput->setTexture( mForwardDepthTexture );
69 mForwardRenderTarget->addOutput( mForwardRenderTargetDepthOutput );
70 mForwardRenderTargetColorOutput =
new Qt3DRender::QRenderTargetOutput;
71 mForwardRenderTargetColorOutput->setAttachmentPoint( Qt3DRender::QRenderTargetOutput::Color0 );
72 mForwardRenderTargetColorOutput->setTexture( mForwardColorTexture );
73 mForwardRenderTarget->addOutput( mForwardRenderTargetColorOutput );
75 mForwardRenderTargetSelector =
new Qt3DRender::QRenderTargetSelector( mForwardRenderLayerFilter );
76 mForwardRenderTargetSelector->setTarget( mForwardRenderTarget );
78 mForwardClearBuffers =
new Qt3DRender::QClearBuffers( mForwardRenderTargetSelector );
79 mForwardClearBuffers->setClearColor( QColor::fromRgbF( 0.0, 1.0, 0.0, 1.0 ) );
80 mForwardClearBuffers->setBuffers( Qt3DRender::QClearBuffers::ColorDepthBuffer );
82 mFrustumCulling =
new Qt3DRender::QFrustumCulling( mForwardClearBuffers );
84 return mForwardRenderLayerFilter;
87 Qt3DRender::QFrameGraphNode *QgsShadowRenderingFrameGraph::constructShadowRenderPass()
89 mShadowSceneEntitiesFilter =
new Qt3DRender::QLayerFilter;
90 mShadowSceneEntitiesFilter->addLayer( mCastShadowsLayer );
92 mShadowMapTexture =
new Qt3DRender::QTexture2D;
93 mShadowMapTexture->setWidth( mShadowMapResolution );
94 mShadowMapTexture->setHeight( mShadowMapResolution );
95 mShadowMapTexture->setFormat( Qt3DRender::QTexture2D::TextureFormat::D32F );
96 mShadowMapTexture->setGenerateMipMaps(
false );
97 mShadowMapTexture->setMagnificationFilter( Qt3DRender::QTexture2D::Linear );
98 mShadowMapTexture->setMinificationFilter( Qt3DRender::QTexture2D::Linear );
99 mShadowMapTexture->wrapMode()->setX( Qt3DRender::QTextureWrapMode::ClampToEdge );
100 mShadowMapTexture->wrapMode()->setY( Qt3DRender::QTextureWrapMode::ClampToEdge );
102 mShadowRenderTarget =
new Qt3DRender::QRenderTarget;
103 mShadowRenderTargetOutput =
new Qt3DRender::QRenderTargetOutput;
104 mShadowRenderTargetOutput->setAttachmentPoint( Qt3DRender::QRenderTargetOutput::Depth );
105 mShadowRenderTargetOutput->setTexture( mShadowMapTexture );
106 mShadowRenderTarget->addOutput( mShadowRenderTargetOutput );
108 mShadowRenderTargetSelector =
new Qt3DRender::QRenderTargetSelector( mShadowSceneEntitiesFilter );
109 mShadowRenderTargetSelector->setTarget( mShadowRenderTarget );
111 mShadowClearBuffers =
new Qt3DRender::QClearBuffers( mShadowRenderTargetSelector );
112 mShadowClearBuffers ->setBuffers( Qt3DRender::QClearBuffers::BufferType::ColorDepthBuffer );
114 mShadowRenderStateSet =
new Qt3DRender::QRenderStateSet( mShadowClearBuffers );
115 mShadowDepthTest =
new Qt3DRender::QDepthTest;
116 mShadowDepthTest->setDepthFunction( Qt3DRender::QDepthTest::Less );
117 mShadowRenderStateSet->addRenderState( mShadowDepthTest );
118 mShadowCullFace =
new Qt3DRender::QCullFace;
119 mShadowCullFace->setMode( Qt3DRender::QCullFace::NoCulling );
120 mShadowRenderStateSet->addRenderState( mShadowCullFace );
122 return mShadowSceneEntitiesFilter;
125 Qt3DRender::QFrameGraphNode *QgsShadowRenderingFrameGraph::constructPostprocessingPass()
127 mPostprocessPassLayerFilter =
new Qt3DRender::QLayerFilter;
128 mPostprocessPassLayerFilter->addLayer( mPostprocessPassLayer );
130 mPostprocessClearBuffers =
new Qt3DRender::QClearBuffers( mPostprocessPassLayerFilter );
131 mPostprocessClearBuffers->setClearColor( QColor::fromRgbF( 0.0f, 0.0f, 0.0f ) );
133 mRenderCaptureTargetSelector =
new Qt3DRender::QRenderTargetSelector( mPostprocessPassLayerFilter );
135 Qt3DRender::QRenderTarget *renderTarget =
new Qt3DRender::QRenderTarget( mRenderCaptureTargetSelector );
141 Qt3DRender::QRenderTargetOutput *colorOutput =
new Qt3DRender::QRenderTargetOutput( renderTarget );
142 colorOutput->setAttachmentPoint( Qt3DRender::QRenderTargetOutput::Color0 );
145 mRenderCaptureColorTexture =
new Qt3DRender::QTexture2D( colorOutput );
146 mRenderCaptureColorTexture->setSize( mSize.width(), mSize.height() );
147 mRenderCaptureColorTexture->setFormat( Qt3DRender::QAbstractTexture::RGB8_UNorm );
148 mRenderCaptureColorTexture->setMinificationFilter( Qt3DRender::QAbstractTexture::Linear );
149 mRenderCaptureColorTexture->setMagnificationFilter( Qt3DRender::QAbstractTexture::Linear );
152 colorOutput->setTexture( mRenderCaptureColorTexture );
153 renderTarget->addOutput( colorOutput );
155 Qt3DRender::QRenderTargetOutput *depthOutput =
new Qt3DRender::QRenderTargetOutput( renderTarget );
157 depthOutput->setAttachmentPoint( Qt3DRender::QRenderTargetOutput::Depth );
158 mRenderCaptureDepthTexture =
new Qt3DRender::QTexture2D( depthOutput );
159 mRenderCaptureDepthTexture->setSize( mSize.width(), mSize.height() );
160 mRenderCaptureDepthTexture->setFormat( Qt3DRender::QAbstractTexture::DepthFormat );
161 mRenderCaptureDepthTexture->setMinificationFilter( Qt3DRender::QAbstractTexture::Linear );
162 mRenderCaptureDepthTexture->setMagnificationFilter( Qt3DRender::QAbstractTexture::Linear );
163 mRenderCaptureDepthTexture->setComparisonFunction( Qt3DRender::QAbstractTexture::CompareLessEqual );
164 mRenderCaptureDepthTexture->setComparisonMode( Qt3DRender::QAbstractTexture::CompareRefToTexture );
166 depthOutput->setTexture( mRenderCaptureDepthTexture );
167 renderTarget->addOutput( depthOutput );
169 mRenderCaptureTargetSelector->setTarget( renderTarget );
171 mRenderCapture =
new Qt3DRender::QRenderCapture( mRenderCaptureTargetSelector );
173 return mPostprocessPassLayerFilter;
182 mLightCamera =
new Qt3DRender::QCamera;
184 mPostprocessPassLayer =
new Qt3DRender::QLayer;
185 mPreviewLayer =
new Qt3DRender::QLayer;
186 mCastShadowsLayer =
new Qt3DRender::QLayer;
187 mForwardRenderLayer =
new Qt3DRender::QLayer;
189 #if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
190 mPostprocessPassLayer->setRecursive(
true );
191 mPreviewLayer->setRecursive(
true );
192 mCastShadowsLayer->setRecursive(
true );
193 mForwardRenderLayer->setRecursive(
true );
196 mRenderSurfaceSelector =
new Qt3DRender::QRenderSurfaceSelector;
198 QObject *surfaceObj =
dynamic_cast< QObject *
>( surface );
199 Q_ASSERT( surfaceObj );
201 mRenderSurfaceSelector->setSurface( surfaceObj );
202 mRenderSurfaceSelector->setExternalRenderTargetSize( mSize );
204 mMainViewPort =
new Qt3DRender::QViewport( mRenderSurfaceSelector );
205 mMainViewPort->setNormalizedRect( QRectF( 0.0f, 0.0f, 1.0f, 1.0f ) );
207 mMainCameraSelector =
new Qt3DRender::QCameraSelector( mMainViewPort );
208 mMainCameraSelector->setCamera( mMainCamera );
211 Qt3DRender::QFrameGraphNode *forwardRenderPass = constructForwardRenderPass();
212 forwardRenderPass->setParent( mMainCameraSelector );
215 mLightCameraSelector =
new Qt3DRender::QCameraSelector( mMainViewPort );
216 mLightCameraSelector->setCamera( mLightCamera );
218 Qt3DRender::QFrameGraphNode *shadowRenderPass = constructShadowRenderPass();
219 shadowRenderPass->setParent( mLightCameraSelector );
222 Qt3DRender::QFrameGraphNode *postprocessingPass = constructPostprocessingPass();
223 postprocessingPass->setParent( mLightCameraSelector );
226 mPostprocessingEntity->addComponent( mPostprocessPassLayer );
229 Qt3DRender::QFrameGraphNode *previewPass = constructTexturesPreviewPass();
230 previewPass->setParent( mRenderSurfaceSelector );
233 mDebugDepthMapPreviewQuad = this->
addTexturePreviewOverlay( mForwardDepthTexture, QPointF( 0.8f, 0.8f ), QSizeF( 0.2f, 0.2f ) );
234 mDebugShadowMapPreviewQuad = this->
addTexturePreviewOverlay( mShadowMapTexture, QPointF( -0.8f, -0.8f ), QSizeF( 0.2f, 0.2f ) );
235 mDebugDepthMapPreviewQuad->setEnabled(
false );
236 mDebugShadowMapPreviewQuad->setEnabled(
false );
242 previewQuad->addComponent( mPreviewLayer );
243 previewQuad->setParent( mRootEntity );
244 mPreviewQuads.push_back( previewQuad );
248 QVector3D
WorldPosFromDepth( QMatrix4x4 projMatrixInv, QMatrix4x4 viewMatrixInv,
float texCoordX,
float texCoordY,
float depth )
250 float z = depth * 2.0 - 1.0;
252 QVector4D clipSpacePosition( texCoordX * 2.0 - 1.0, texCoordY * 2.0 - 1.0, z, 1.0 );
253 QVector4D viewSpacePosition = projMatrixInv * clipSpacePosition;
256 viewSpacePosition /= viewSpacePosition.w();
257 QVector4D worldSpacePosition = viewMatrixInv * viewSpacePosition;
258 worldSpacePosition /= worldSpacePosition.w();
260 return QVector3D( worldSpacePosition.x(), worldSpacePosition.y(), worldSpacePosition.z() );
264 void calculateViewExtent( Qt3DRender::QCamera *camera,
float shadowRenderingDistance,
float y,
float &minX,
float &maxX,
float &minY,
float &maxY,
float &minZ,
float &maxZ )
266 QVector3D cameraPos = camera->position();
267 QMatrix4x4 projectionMatrix = camera->projectionMatrix();
268 QMatrix4x4 viewMatrix = camera->viewMatrix();
269 QMatrix4x4 projectionMatrixInv = projectionMatrix.inverted();
270 QMatrix4x4 viewMatrixInv = viewMatrix.inverted();
272 QVector4D viewCenter = viewMatrix * QVector4D( camera->viewCenter(), 1.0f );
273 viewCenter /= viewCenter.w();
274 viewCenter = projectionMatrix * viewCenter;
275 viewCenter /= viewCenter.w();
276 depth = viewCenter.z();
277 QVector<QVector3D> viewFrustumPoints =
279 QVector3D( 0.0f, 0.0f, depth ),
280 QVector3D( 0.0f, 1.0f, depth ),
281 QVector3D( 1.0f, 0.0f, depth ),
282 QVector3D( 1.0f, 1.0f, depth )
284 maxX = std::numeric_limits<float>::lowest();
285 maxY = std::numeric_limits<float>::lowest();
286 maxZ = std::numeric_limits<float>::lowest();
287 minX = std::numeric_limits<float>::max();
288 minY = std::numeric_limits<float>::max();
289 minZ = std::numeric_limits<float>::max();
290 for (
int i = 0; i < viewFrustumPoints.size(); ++i )
294 projectionMatrixInv, viewMatrixInv,
295 viewFrustumPoints[i].x(), viewFrustumPoints[i].y(), viewFrustumPoints[i].z() );
296 minX = std::min( minX, viewFrustumPoints[i].x() );
297 maxX = std::max( maxX, viewFrustumPoints[i].x() );
298 minY = std::min( minY, viewFrustumPoints[i].y() );
299 maxY = std::max( maxY, viewFrustumPoints[i].y() );
300 minZ = std::min( minZ, viewFrustumPoints[i].z() );
301 maxZ = std::max( maxZ, viewFrustumPoints[i].z() );
306 QVector3D pt = cameraPos;
307 QVector3D vect = ( viewFrustumPoints[i] - pt ).normalized();
308 float t = ( y - pt.y() ) / vect.y();
310 t = shadowRenderingDistance;
312 t = std::min( t, shadowRenderingDistance );
313 viewFrustumPoints[i] = pt + t * vect;
314 minX = std::min( minX, viewFrustumPoints[i].x() );
315 maxX = std::max( maxX, viewFrustumPoints[i].x() );
316 minY = std::min( minY, viewFrustumPoints[i].y() );
317 maxY = std::max( maxY, viewFrustumPoints[i].y() );
318 minZ = std::min( minZ, viewFrustumPoints[i].z() );
319 maxZ = std::max( maxZ, viewFrustumPoints[i].z() );
325 float minX, maxX, minY, maxY, minZ, maxZ;
326 QVector3D lookingAt = mMainCamera->viewCenter();
327 float d = 2 * ( mMainCamera->position() - mMainCamera->viewCenter() ).length();
329 QVector3D vertical = QVector3D( 0.0f, d, 0.0f );
331 calculateViewExtent( mMainCamera, maximumShadowRenderingDistance, lookingAt.y(), minX, maxX, minY, maxY, minZ, maxZ );
333 lookingAt = QVector3D( 0.5 * ( minX + maxX ), mMainCamera->viewCenter().y(), 0.5 * ( minZ + maxZ ) );
334 QVector3D lightPosition = lookingAt + vertical;
335 mLightCamera->setPosition( lightPosition );
336 mLightCamera->setViewCenter( lookingAt );
337 mLightCamera->setUpVector( QVector3D( 0.0f, 1.0f, 0.0f ) );
338 mLightCamera->rotateAboutViewCenter( QQuaternion::rotationTo( vertical.normalized(), -lightDirection.normalized() ) );
340 mLightCamera->setProjectionType( Qt3DRender::QCameraLens::ProjectionType::OrthographicProjection );
341 mLightCamera->lens()->setOrthographicProjection(
342 - 0.7 * ( maxX - minX ), 0.7 * ( maxX - minX ),
343 - 0.7 * ( maxZ - minZ ), 0.7 * ( maxZ - minZ ),
344 1.0f, 2 * ( lookingAt - lightPosition ).length() );
352 mForwardClearBuffers->setClearColor( clearColor );
357 mShadowRenderingEnabled = enabled;
359 if ( mShadowRenderingEnabled )
360 mShadowSceneEntitiesFilter->setEnabled(
true );
362 mShadowSceneEntitiesFilter->setEnabled(
false );
373 mShadowMapResolution = resolution;
374 mShadowMapTexture->setWidth( mShadowMapResolution );
375 mShadowMapTexture->setHeight( mShadowMapResolution );
380 if ( enabled == mFrustumCullingEnabled )
382 mFrustumCullingEnabled = enabled;
383 if ( mFrustumCullingEnabled )
384 mFrustumCulling->setParent( mForwardClearBuffers );
386 mFrustumCulling->setParent( ( Qt3DCore::QNode * )
nullptr );
391 mEyeDomeLightingEnabled = enabled;
392 mEyeDomeLightingStrength = strength;
393 mEyeDomeLightingDistance = distance;
401 mDebugShadowMapPreviewQuad->setEnabled( enabled );
406 case Qt::Corner::TopRightCorner:
407 mDebugShadowMapPreviewQuad->
setViewPort( QPointF( 1.0f - size, 1.0f - size ), QSizeF( size, size ) );
409 case Qt::Corner::TopLeftCorner:
410 mDebugShadowMapPreviewQuad->
setViewPort( QPointF( -1.0f + size, 1.0f - size ), QSizeF( size, size ) );
412 case Qt::Corner::BottomRightCorner:
413 mDebugShadowMapPreviewQuad->
setViewPort( QPointF( 1.0f - size, -1.0f + size ), QSizeF( size, size ) );
415 case Qt::Corner::BottomLeftCorner:
416 mDebugShadowMapPreviewQuad->
setViewPort( QPointF( -1.0f + size, -1.0f + size ), QSizeF( size, size ) );
424 mDebugDepthMapPreviewQuad->setEnabled( enabled );
430 case Qt::Corner::TopRightCorner:
431 mDebugDepthMapPreviewQuad->
setViewPort( QPointF( 1.0f - size, 1.0f - size ), QSizeF( size, size ) );
433 case Qt::Corner::TopLeftCorner:
434 mDebugDepthMapPreviewQuad->
setViewPort( QPointF( -1.0f + size, 1.0f - size ), QSizeF( size, size ) );
436 case Qt::Corner::BottomRightCorner:
437 mDebugDepthMapPreviewQuad->
setViewPort( QPointF( 1.0f - size, -1.0f + size ), QSizeF( size, size ) );
439 case Qt::Corner::BottomLeftCorner:
440 mDebugDepthMapPreviewQuad->
setViewPort( QPointF( -1.0f + size, -1.0f + size ), QSizeF( size, size ) );
449 mForwardColorTexture->setSize( mSize.width(), mSize.height() );
450 mForwardDepthTexture->setSize( mSize.width(), mSize.height() );
451 mRenderCaptureColorTexture->setSize( mSize.width(), mSize.height() );
452 mRenderCaptureDepthTexture->setSize( mSize.width(), mSize.height() );
453 mRenderSurfaceSelector->setExternalRenderTargetSize( mSize );
458 if ( enabled == mRenderCaptureEnabled )
460 mRenderCaptureEnabled = enabled;
461 mRenderCaptureTargetSelector->setEnabled( mRenderCaptureEnabled );
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 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 ¢erNDC, const QSizeF &size)
Sets where the quad will be located on the scene.
void setupDepthMapDebugging(bool enabled, Qt::Corner corner, double size)
Sets the depth map debugging view port.
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 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 ¢erNDC, const QSizeF &size, QVector< Qt3DRender::QParameter * > additionalShaderParameters=QVector< Qt3DRender::QParameter * >())
Adds an preview entity that shows a texture in real time for debugging purposes.
Qt3DRender::QCamera * mainCamera()
Returns the main camera.
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.
void setShadowRenderingEnabled(bool enabled)
Sets whether the shadow rendering is enabled.
double y() const
Returns Y coordinate.
double z() const
Returns Z coordinate.
double x() const
Returns X coordinate.
QVector3D WorldPosFromDepth(QMatrix4x4 projMatrixInv, QMatrix4x4 viewMatrixInv, float texCoordX, float texCoordY, float depth)
void calculateViewExtent(Qt3DRender::QCamera *camera, float shadowRenderingDistance, float y, float &minX, float &maxX, float &minY, float &maxY, float &minZ, float &maxZ)