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 mPostprocessPassLayer->setRecursive(
true );
190 mPreviewLayer->setRecursive(
true );
191 mCastShadowsLayer->setRecursive(
true );
192 mForwardRenderLayer->setRecursive(
true );
194 mRenderSurfaceSelector =
new Qt3DRender::QRenderSurfaceSelector;
196 QObject *surfaceObj =
dynamic_cast< QObject *
>( surface );
197 Q_ASSERT( surfaceObj );
199 mRenderSurfaceSelector->setSurface( surfaceObj );
200 mRenderSurfaceSelector->setExternalRenderTargetSize( mSize );
202 mMainViewPort =
new Qt3DRender::QViewport( mRenderSurfaceSelector );
203 mMainViewPort->setNormalizedRect( QRectF( 0.0f, 0.0f, 1.0f, 1.0f ) );
205 mMainCameraSelector =
new Qt3DRender::QCameraSelector( mMainViewPort );
206 mMainCameraSelector->setCamera( mMainCamera );
209 Qt3DRender::QFrameGraphNode *forwardRenderPass = constructForwardRenderPass();
210 forwardRenderPass->setParent( mMainCameraSelector );
213 mLightCameraSelector =
new Qt3DRender::QCameraSelector( mMainViewPort );
214 mLightCameraSelector->setCamera( mLightCamera );
216 Qt3DRender::QFrameGraphNode *shadowRenderPass = constructShadowRenderPass();
217 shadowRenderPass->setParent( mLightCameraSelector );
220 Qt3DRender::QFrameGraphNode *postprocessingPass = constructPostprocessingPass();
221 postprocessingPass->setParent( mLightCameraSelector );
224 mPostprocessingEntity->addComponent( mPostprocessPassLayer );
227 Qt3DRender::QFrameGraphNode *previewPass = constructTexturesPreviewPass();
228 previewPass->setParent( mRenderSurfaceSelector );
231 mDebugDepthMapPreviewQuad = this->
addTexturePreviewOverlay( mForwardDepthTexture, QPointF( 0.8f, 0.8f ), QSizeF( 0.2f, 0.2f ) );
232 mDebugShadowMapPreviewQuad = this->
addTexturePreviewOverlay( mShadowMapTexture, QPointF( -0.8f, -0.8f ), QSizeF( 0.2f, 0.2f ) );
233 mDebugDepthMapPreviewQuad->setEnabled(
false );
234 mDebugShadowMapPreviewQuad->setEnabled(
false );
240 previewQuad->addComponent( mPreviewLayer );
241 previewQuad->setParent( mRootEntity );
242 mPreviewQuads.push_back( previewQuad );
246 QVector3D
WorldPosFromDepth( QMatrix4x4 projMatrixInv, QMatrix4x4 viewMatrixInv,
float texCoordX,
float texCoordY,
float depth )
248 float z = depth * 2.0 - 1.0;
250 QVector4D clipSpacePosition( texCoordX * 2.0 - 1.0, texCoordY * 2.0 - 1.0, z, 1.0 );
251 QVector4D viewSpacePosition = projMatrixInv * clipSpacePosition;
254 viewSpacePosition /= viewSpacePosition.w();
255 QVector4D worldSpacePosition = viewMatrixInv * viewSpacePosition;
256 worldSpacePosition /= worldSpacePosition.w();
258 return QVector3D( worldSpacePosition.x(), worldSpacePosition.y(), worldSpacePosition.z() );
262 void calculateViewExtent( Qt3DRender::QCamera *camera,
float shadowRenderingDistance,
float y,
float &minX,
float &maxX,
float &minY,
float &maxY,
float &minZ,
float &maxZ )
264 QVector3D cameraPos = camera->position();
265 QMatrix4x4 projectionMatrix = camera->projectionMatrix();
266 QMatrix4x4 viewMatrix = camera->viewMatrix();
267 QMatrix4x4 projectionMatrixInv = projectionMatrix.inverted();
268 QMatrix4x4 viewMatrixInv = viewMatrix.inverted();
270 QVector4D viewCenter = viewMatrix * QVector4D( camera->viewCenter(), 1.0f );
271 viewCenter /= viewCenter.w();
272 viewCenter = projectionMatrix * viewCenter;
273 viewCenter /= viewCenter.w();
274 depth = viewCenter.z();
275 QVector<QVector3D> viewFrustumPoints =
277 QVector3D( 0.0f, 0.0f, depth ),
278 QVector3D( 0.0f, 1.0f, depth ),
279 QVector3D( 1.0f, 0.0f, depth ),
280 QVector3D( 1.0f, 1.0f, depth )
282 maxX = std::numeric_limits<float>::lowest();
283 maxY = std::numeric_limits<float>::lowest();
284 maxZ = std::numeric_limits<float>::lowest();
285 minX = std::numeric_limits<float>::max();
286 minY = std::numeric_limits<float>::max();
287 minZ = std::numeric_limits<float>::max();
288 for (
int i = 0; i < viewFrustumPoints.size(); ++i )
292 projectionMatrixInv, viewMatrixInv,
293 viewFrustumPoints[i].x(), viewFrustumPoints[i].y(), viewFrustumPoints[i].z() );
294 minX = std::min( minX, viewFrustumPoints[i].x() );
295 maxX = std::max( maxX, viewFrustumPoints[i].x() );
296 minY = std::min( minY, viewFrustumPoints[i].y() );
297 maxY = std::max( maxY, viewFrustumPoints[i].y() );
298 minZ = std::min( minZ, viewFrustumPoints[i].z() );
299 maxZ = std::max( maxZ, viewFrustumPoints[i].z() );
304 QVector3D pt = cameraPos;
305 QVector3D vect = ( viewFrustumPoints[i] - pt ).normalized();
306 float t = ( y - pt.y() ) / vect.y();
308 t = shadowRenderingDistance;
310 t = std::min( t, shadowRenderingDistance );
311 viewFrustumPoints[i] = pt + t * vect;
312 minX = std::min( minX, viewFrustumPoints[i].x() );
313 maxX = std::max( maxX, viewFrustumPoints[i].x() );
314 minY = std::min( minY, viewFrustumPoints[i].y() );
315 maxY = std::max( maxY, viewFrustumPoints[i].y() );
316 minZ = std::min( minZ, viewFrustumPoints[i].z() );
317 maxZ = std::max( maxZ, viewFrustumPoints[i].z() );
323 float minX, maxX, minY, maxY, minZ, maxZ;
324 QVector3D lookingAt = mMainCamera->viewCenter();
325 float d = 2 * ( mMainCamera->position() - mMainCamera->viewCenter() ).length();
327 QVector3D vertical = QVector3D( 0.0f, d, 0.0f );
329 calculateViewExtent( mMainCamera, maximumShadowRenderingDistance, lookingAt.y(), minX, maxX, minY, maxY, minZ, maxZ );
331 lookingAt = QVector3D( 0.5 * ( minX + maxX ), mMainCamera->viewCenter().y(), 0.5 * ( minZ + maxZ ) );
332 QVector3D lightPosition = lookingAt + vertical;
333 mLightCamera->setPosition( lightPosition );
334 mLightCamera->setViewCenter( lookingAt );
335 mLightCamera->setUpVector( QVector3D( 0.0f, 1.0f, 0.0f ) );
336 mLightCamera->rotateAboutViewCenter( QQuaternion::rotationTo( vertical.normalized(), -lightDirection.normalized() ) );
338 mLightCamera->setProjectionType( Qt3DRender::QCameraLens::ProjectionType::OrthographicProjection );
339 mLightCamera->lens()->setOrthographicProjection(
340 - 0.7 * ( maxX - minX ), 0.7 * ( maxX - minX ),
341 - 0.7 * ( maxZ - minZ ), 0.7 * ( maxZ - minZ ),
342 1.0f, 2 * ( lookingAt - lightPosition ).length() );
350 mForwardClearBuffers->setClearColor( clearColor );
355 mShadowRenderingEnabled = enabled;
357 if ( mShadowRenderingEnabled )
358 mShadowSceneEntitiesFilter->setEnabled(
true );
360 mShadowSceneEntitiesFilter->setEnabled(
false );
371 mShadowMapResolution = resolution;
372 mShadowMapTexture->setWidth( mShadowMapResolution );
373 mShadowMapTexture->setHeight( mShadowMapResolution );
378 if ( enabled == mFrustumCullingEnabled )
380 mFrustumCullingEnabled = enabled;
381 if ( mFrustumCullingEnabled )
382 mFrustumCulling->setParent( mForwardClearBuffers );
384 mFrustumCulling->setParent( ( Qt3DCore::QNode * )
nullptr );
389 mEyeDomeLightingEnabled = enabled;
390 mEyeDomeLightingStrength = strength;
391 mEyeDomeLightingDistance = distance;
399 mDebugShadowMapPreviewQuad->setEnabled( enabled );
404 case Qt::Corner::TopRightCorner:
405 mDebugShadowMapPreviewQuad->
setViewPort( QPointF( 1.0f - size, 1.0f - size ), QSizeF( size, size ) );
407 case Qt::Corner::TopLeftCorner:
408 mDebugShadowMapPreviewQuad->
setViewPort( QPointF( -1.0f + size, 1.0f - size ), QSizeF( size, size ) );
410 case Qt::Corner::BottomRightCorner:
411 mDebugShadowMapPreviewQuad->
setViewPort( QPointF( 1.0f - size, -1.0f + size ), QSizeF( size, size ) );
413 case Qt::Corner::BottomLeftCorner:
414 mDebugShadowMapPreviewQuad->
setViewPort( QPointF( -1.0f + size, -1.0f + size ), QSizeF( size, size ) );
422 mDebugDepthMapPreviewQuad->setEnabled( enabled );
428 case Qt::Corner::TopRightCorner:
429 mDebugDepthMapPreviewQuad->
setViewPort( QPointF( 1.0f - size, 1.0f - size ), QSizeF( size, size ) );
431 case Qt::Corner::TopLeftCorner:
432 mDebugDepthMapPreviewQuad->
setViewPort( QPointF( -1.0f + size, 1.0f - size ), QSizeF( size, size ) );
434 case Qt::Corner::BottomRightCorner:
435 mDebugDepthMapPreviewQuad->
setViewPort( QPointF( 1.0f - size, -1.0f + size ), QSizeF( size, size ) );
437 case Qt::Corner::BottomLeftCorner:
438 mDebugDepthMapPreviewQuad->
setViewPort( QPointF( -1.0f + size, -1.0f + size ), QSizeF( size, size ) );
447 mForwardColorTexture->setSize( mSize.width(), mSize.height() );
448 mForwardDepthTexture->setSize( mSize.width(), mSize.height() );
449 mRenderCaptureColorTexture->setSize( mSize.width(), mSize.height() );
450 mRenderCaptureDepthTexture->setSize( mSize.width(), mSize.height() );
451 mRenderSurfaceSelector->setExternalRenderTargetSize( mSize );
456 if ( enabled == mRenderCaptureEnabled )
458 mRenderCaptureEnabled = enabled;
459 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)