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( mMainCameraSelector );
43 mForwardRenderLayerFilter->addLayer( mForwardRenderLayer );
45 mRenderCapture =
new Qt3DRender::QRenderCapture( mForwardRenderLayerFilter );
51 mForwardColorTexture =
new Qt3DRender::QTexture2D;
52 mForwardColorTexture->setWidth( width );
53 mForwardColorTexture->setHeight( height );
54 mForwardColorTexture->setFormat( Qt3DRender::QTexture2D::TextureFormat::RGBA16F );
55 mForwardColorTexture->setGenerateMipMaps(
false );
56 mForwardColorTexture->setMagnificationFilter( Qt3DRender::QTexture2D::Linear );
57 mForwardColorTexture->setMinificationFilter( Qt3DRender::QTexture2D::Linear );
58 mForwardColorTexture->wrapMode()->setX( Qt3DRender::QTextureWrapMode::ClampToEdge );
59 mForwardColorTexture->wrapMode()->setY( Qt3DRender::QTextureWrapMode::ClampToEdge );
61 mForwardDepthTexture =
new Qt3DRender::QTexture2D;
62 mForwardDepthTexture->setWidth( width );
63 mForwardDepthTexture->setHeight( height );
64 mForwardDepthTexture->setFormat( Qt3DRender::QTexture2D::TextureFormat::DepthFormat );
65 mForwardDepthTexture->setGenerateMipMaps(
false );
66 mForwardDepthTexture->setMagnificationFilter( Qt3DRender::QTexture2D::Linear );
67 mForwardDepthTexture->setMinificationFilter( Qt3DRender::QTexture2D::Linear );
68 mForwardDepthTexture->wrapMode()->setX( Qt3DRender::QTextureWrapMode::ClampToEdge );
69 mForwardDepthTexture->wrapMode()->setY( Qt3DRender::QTextureWrapMode::ClampToEdge );
70 mForwardDepthTexture->setComparisonFunction( Qt3DRender::QTexture2D::ComparisonFunction::CompareLessEqual );
71 mForwardDepthTexture->setComparisonMode( Qt3DRender::QTexture2D::ComparisonMode::CompareRefToTexture );
73 mForwardRenderTarget =
new Qt3DRender::QRenderTarget;
74 mForwardRenderTargetDepthOutput =
new Qt3DRender::QRenderTargetOutput;
75 mForwardRenderTargetDepthOutput->setAttachmentPoint( Qt3DRender::QRenderTargetOutput::Depth );
76 mForwardRenderTargetDepthOutput->setTexture( mForwardDepthTexture );
77 mForwardRenderTarget->addOutput( mForwardRenderTargetDepthOutput );
78 mForwardRenderTargetColorOutput =
new Qt3DRender::QRenderTargetOutput;
79 mForwardRenderTargetColorOutput->setAttachmentPoint( Qt3DRender::QRenderTargetOutput::Color0 );
80 mForwardRenderTargetColorOutput->setTexture( mForwardColorTexture );
81 mForwardRenderTarget->addOutput( mForwardRenderTargetColorOutput );
83 mForwardRenderTargetSelector =
new Qt3DRender::QRenderTargetSelector( mForwardRenderLayerFilter );
84 mForwardRenderTargetSelector->setTarget( mForwardRenderTarget );
86 mForwardClearBuffers =
new Qt3DRender::QClearBuffers( mForwardRenderTargetSelector );
87 mForwardClearBuffers->setClearColor( QColor::fromRgbF( 0.0, 1.0, 0.0, 1.0 ) );
88 mForwardClearBuffers->setBuffers( Qt3DRender::QClearBuffers::ColorDepthBuffer );
90 mFrustumCulling =
new Qt3DRender::QFrustumCulling;
91 mFrustumCulling->setParent( mForwardClearBuffers );
93 return mForwardRenderLayerFilter;
96 Qt3DRender::QFrameGraphNode *QgsShadowRenderingFrameGraph::constructShadowRenderPass()
98 mShadowSceneEntitiesFilter =
new Qt3DRender::QLayerFilter;
99 mShadowSceneEntitiesFilter->addLayer( mCastShadowsLayer );
101 mShadowMapTexture =
new Qt3DRender::QTexture2D;
102 mShadowMapTexture->setWidth( mShadowMapResolution );
103 mShadowMapTexture->setHeight( mShadowMapResolution );
104 mShadowMapTexture->setFormat( Qt3DRender::QTexture2D::TextureFormat::D32F );
105 mShadowMapTexture->setGenerateMipMaps(
false );
106 mShadowMapTexture->setMagnificationFilter( Qt3DRender::QTexture2D::Linear );
107 mShadowMapTexture->setMinificationFilter( Qt3DRender::QTexture2D::Linear );
108 mShadowMapTexture->wrapMode()->setX( Qt3DRender::QTextureWrapMode::ClampToEdge );
109 mShadowMapTexture->wrapMode()->setY( Qt3DRender::QTextureWrapMode::ClampToEdge );
111 mShadowRenderTarget =
new Qt3DRender::QRenderTarget;
112 mShadowRenderTargetOutput =
new Qt3DRender::QRenderTargetOutput;
113 mShadowRenderTargetOutput->setAttachmentPoint( Qt3DRender::QRenderTargetOutput::Depth );
114 mShadowRenderTargetOutput->setTexture( mShadowMapTexture );
115 mShadowRenderTarget->addOutput( mShadowRenderTargetOutput );
117 mShadowRenderTargetSelector =
new Qt3DRender::QRenderTargetSelector( mShadowSceneEntitiesFilter );
118 mShadowRenderTargetSelector->setTarget( mShadowRenderTarget );
120 mShadowClearBuffers =
new Qt3DRender::QClearBuffers( mShadowRenderTargetSelector );
121 mShadowClearBuffers ->setBuffers( Qt3DRender::QClearBuffers::BufferType::ColorDepthBuffer );
123 mShadowRenderStateSet =
new Qt3DRender::QRenderStateSet( mShadowClearBuffers );
124 mShadowDepthTest =
new Qt3DRender::QDepthTest;
125 mShadowDepthTest->setDepthFunction( Qt3DRender::QDepthTest::Less );
126 mShadowRenderStateSet->addRenderState( mShadowDepthTest );
127 mShadowCullFace =
new Qt3DRender::QCullFace;
128 mShadowCullFace->setMode( Qt3DRender::QCullFace::NoCulling );
129 mShadowRenderStateSet->addRenderState( mShadowCullFace );
131 return mShadowSceneEntitiesFilter;
134 Qt3DRender::QFrameGraphNode *QgsShadowRenderingFrameGraph::constructPostprocessingPass()
136 mPostprocessPassLayerFilter =
new Qt3DRender::QLayerFilter;
137 mPostprocessPassLayerFilter->addLayer( mPostprocessPassLayer );
139 mPostprocessClearBuffers =
new Qt3DRender::QClearBuffers( mPostprocessPassLayerFilter );
140 mPostprocessClearBuffers->setClearColor( QColor::fromRgbF( 0.0f, 0.0f, 0.0f ) );
143 return mPostprocessPassLayerFilter;
150 mLightCamera =
new Qt3DRender::QCamera;
152 mPostprocessPassLayer =
new Qt3DRender::QLayer;
153 mPreviewLayer =
new Qt3DRender::QLayer;
154 mCastShadowsLayer =
new Qt3DRender::QLayer;
155 mForwardRenderLayer =
new Qt3DRender::QLayer;
157 #if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
158 mPostprocessPassLayer->setRecursive(
true );
159 mPreviewLayer->setRecursive(
true );
160 mCastShadowsLayer->setRecursive(
true );
161 mForwardRenderLayer->setRecursive(
true );
164 mRenderSurfaceSelector =
new Qt3DRender::QRenderSurfaceSelector;
165 mRenderSurfaceSelector->setSurface( window );
167 mMainViewPort =
new Qt3DRender::QViewport( mRenderSurfaceSelector );
168 mMainViewPort->setNormalizedRect( QRectF( 0.0f, 0.0f, 1.0f, 1.0f ) );
170 mMainCameraSelector =
new Qt3DRender::QCameraSelector( mMainViewPort );
171 mMainCameraSelector->setCamera( mMainCamera );
174 Qt3DRender::QFrameGraphNode *forwardRenderPass = constructForwardRenderPass();
175 forwardRenderPass->setParent( mMainCameraSelector );
178 mLightCameraSelector =
new Qt3DRender::QCameraSelector( mMainViewPort );
179 mLightCameraSelector->setCamera( mLightCamera );
181 Qt3DRender::QFrameGraphNode *shadowRenderPass = constructShadowRenderPass();
182 shadowRenderPass->setParent( mLightCameraSelector );
185 Qt3DRender::QFrameGraphNode *postprocessingPass = constructPostprocessingPass();
186 postprocessingPass->setParent( mLightCameraSelector );
190 mPostprocessingEntity->addComponent( mPostprocessPassLayer );
193 Qt3DRender::QFrameGraphNode *previewPass = constructTexturesPreviewPass();
194 previewPass->setParent( mMainViewPort );
200 previewQuad->addComponent( mPreviewLayer );
201 previewQuad->setParent( mRootEntity );
204 QVector3D
WorldPosFromDepth( QMatrix4x4 projMatrixInv, QMatrix4x4 viewMatrixInv,
float texCoordX,
float texCoordY,
float depth )
206 float z = depth * 2.0 - 1.0;
208 QVector4D clipSpacePosition( texCoordX * 2.0 - 1.0, texCoordY * 2.0 - 1.0, z, 1.0 );
209 QVector4D viewSpacePosition = projMatrixInv * clipSpacePosition;
212 viewSpacePosition /= viewSpacePosition.w();
213 QVector4D worldSpacePosition = viewMatrixInv * viewSpacePosition;
214 worldSpacePosition /= worldSpacePosition.w();
216 return QVector3D( worldSpacePosition.x(), worldSpacePosition.y(), worldSpacePosition.z() );
220 void calculateViewExtent( Qt3DRender::QCamera *camera,
float shadowRenderingDistance,
float y,
float &minX,
float &maxX,
float &minY,
float &maxY,
float &minZ,
float &maxZ )
222 QVector3D cameraPos = camera->position();
223 QMatrix4x4 projectionMatrix = camera->projectionMatrix();
224 QMatrix4x4 viewMatrix = camera->viewMatrix();
225 QMatrix4x4 projectionMatrixInv = projectionMatrix.inverted();
226 QMatrix4x4 viewMatrixInv = viewMatrix.inverted();
228 QVector4D viewCenter = viewMatrix * QVector4D( camera->viewCenter(), 1.0f );
229 viewCenter /= viewCenter.w();
230 viewCenter = projectionMatrix * viewCenter;
231 viewCenter /= viewCenter.w();
232 depth = viewCenter.z();
233 QVector<QVector3D> viewFrustumPoints =
235 QVector3D( 0.0f, 0.0f, depth ),
236 QVector3D( 0.0f, 1.0f, depth ),
237 QVector3D( 1.0f, 0.0f, depth ),
238 QVector3D( 1.0f, 1.0f, depth )
240 maxX = std::numeric_limits<float>::lowest();
241 maxY = std::numeric_limits<float>::lowest();
242 maxZ = std::numeric_limits<float>::lowest();
243 minX = std::numeric_limits<float>::max();
244 minY = std::numeric_limits<float>::max();
245 minZ = std::numeric_limits<float>::max();
246 for (
int i = 0; i < viewFrustumPoints.size(); ++i )
250 projectionMatrixInv, viewMatrixInv,
251 viewFrustumPoints[i].x(), viewFrustumPoints[i].y(), viewFrustumPoints[i].z() );
252 minX = std::min( minX, viewFrustumPoints[i].x() );
253 maxX = std::max( maxX, viewFrustumPoints[i].x() );
254 minY = std::min( minY, viewFrustumPoints[i].y() );
255 maxY = std::max( maxY, viewFrustumPoints[i].y() );
256 minZ = std::min( minZ, viewFrustumPoints[i].z() );
257 maxZ = std::max( maxZ, viewFrustumPoints[i].z() );
262 QVector3D pt = cameraPos;
263 QVector3D vect = ( viewFrustumPoints[i] - pt ).normalized();
264 float t = ( y - pt.y() ) / vect.y();
266 t = shadowRenderingDistance;
268 t = std::min( t, shadowRenderingDistance );
269 viewFrustumPoints[i] = pt + t * vect;
270 minX = std::min( minX, viewFrustumPoints[i].x() );
271 maxX = std::max( maxX, viewFrustumPoints[i].x() );
272 minY = std::min( minY, viewFrustumPoints[i].y() );
273 maxY = std::max( maxY, viewFrustumPoints[i].y() );
274 minZ = std::min( minZ, viewFrustumPoints[i].z() );
275 maxZ = std::max( maxZ, viewFrustumPoints[i].z() );
281 float minX, maxX, minY, maxY, minZ, maxZ;
282 QVector3D lookingAt = mMainCamera->viewCenter();
283 float d = 2 * ( mMainCamera->position() - mMainCamera->viewCenter() ).length();
285 QVector3D vertical = QVector3D( 0.0f, d, 0.0f );
287 calculateViewExtent( mMainCamera, maximumShadowRenderingDistance, lookingAt.y(), minX, maxX, minY, maxY, minZ, maxZ );
289 lookingAt = QVector3D( 0.5 * ( minX + maxX ), mMainCamera->viewCenter().y(), 0.5 * ( minZ + maxZ ) );
290 QVector3D lightPosition = lookingAt + vertical;
291 mLightCamera->setPosition( lightPosition );
292 mLightCamera->setViewCenter( lookingAt );
293 mLightCamera->setUpVector( QVector3D( 0.0f, 1.0f, 0.0f ) );
294 mLightCamera->rotateAboutViewCenter( QQuaternion::rotationTo( vertical.normalized(), -lightDirection.normalized() ) );
296 mLightCamera->setProjectionType( Qt3DRender::QCameraLens::ProjectionType::OrthographicProjection );
297 mLightCamera->lens()->setOrthographicProjection(
298 - 0.7 * ( maxX - minX ), 0.7 * ( maxX - minX ),
299 - 0.7 * ( maxZ - minZ ), 0.7 * ( maxZ - minZ ),
300 1.0f, 2 * ( lookingAt - lightPosition ).length() );
308 mForwardClearBuffers->setClearColor( clearColor );
313 mShadowRenderingEnabled = enabled;
315 if ( mShadowRenderingEnabled )
316 mShadowSceneEntitiesFilter->setEnabled(
true );
318 mShadowSceneEntitiesFilter->setEnabled(
false );
329 mShadowMapResolution = resolution;
330 mShadowMapTexture->setWidth( mShadowMapResolution );
331 mShadowMapTexture->setHeight( mShadowMapResolution );
336 if ( enabled == mFrustumCullingEnabled )
338 mFrustumCullingEnabled = enabled;
339 if ( mFrustumCullingEnabled )
340 mFrustumCulling->setParent( mForwardClearBuffers );
342 mFrustumCulling->setParent( ( Qt3DCore::QNode * )
nullptr );