321 MAX_TEMPORAL_AA_LEVELS = 2,
324 using InstanceTransforms = QSSGGlobalRenderNodeData::InstanceTransforms;
325 using ModelViewProjections = QSSGRenderModelData::ModelViewProjections;
327 using QSSGModelsView = QSSGDataView<QSSGRenderModel *>;
328 using QSSGParticlesView = QSSGDataView<QSSGRenderParticles *>;
329 using QSSGItem2DsView = QSSGDataView<QSSGRenderItem2D *>;
330 using QSSGCamerasView = QSSGDataView<QSSGRenderCamera *>;
331 using QSSGLightsView = QSSGDataView<QSSGRenderLight *>;
332 using QSSGReflectionProbesView = QSSGDataView<QSSGRenderReflectionProbe *>;
333 using QSSGNonCategorizedView = QSSGDataView<QSSGRenderNode *>;
335 using RenderableFilter = std::function<
bool(QSSGModelContext *)>;
337 QSSGLayerRenderData(QSSGRenderLayer &inLayer, QSSGRenderer &inRenderer);
338 ~QSSGLayerRenderData();
340 typedef QVector<QSSGModelContext *> TModelContextPtrList;
341 using RenderableNodeEntries = QVector<QSSGRenderableNodeEntry>;
342 using RenderableItem2DEntries = QVector<QSSGRenderItem2D *>;
344 void prepareImageForRender(QSSGRenderImage &inImage,
345 QSSGRenderableImage::Type inMapType,
346 QSSGRenderableImage *&ioFirstImage,
347 QSSGRenderableImage *&ioNextImage,
348 QSSGRenderableObjectFlags &ioFlags,
349 QSSGShaderDefaultMaterialKey &ioGeneratedShaderKey,
350 quint32 inImageIndex, QSSGRenderDefaultMaterial *inMaterial =
nullptr);
352 void setVertexInputPresence(
const QSSGRenderableObjectFlags &renderableFlags,
353 QSSGShaderDefaultMaterialKey &key);
355 static void prepareModelBoneTextures(
const QSSGRenderContextInterface &contextInterface,
356 const RenderableNodeEntries &renderableModels);
360 bool prepareModelsForRender(QSSGRenderContextInterface &ctx,
361 const RenderableNodeEntries &renderableModels,
362 QSSGLayerRenderPreparationResultFlags &ioFlags,
363 const QSSGRenderCameraList &allCameras,
364 const QSSGRenderCameraDataList &allCameraData,
365 TModelContextPtrList &modelContexts,
366 QSSGRenderableObjectList &opaqueObjects,
367 QSSGRenderableObjectList &transparentObjects,
368 QSSGRenderableObjectList &screenTextureObjects,
369 float lodThreshold = 0.0f);
370 bool prepareParticlesForRender(
const RenderableNodeEntries &renderableParticles,
const QSSGRenderCameraData &cameraData, QSSGLayerRenderPreparationResultFlags &ioFlags);
372 void prepareResourceLoaders();
374 void prepareForRender();
376 void prepareReflectionProbesForRender();
378 [[nodiscard]]
static qsizetype frustumCullingInline(
const QSSGClippingFrustum &clipFrustum, QSSGRenderableObjectList &renderables);
380 [[nodiscard]]
static qsizetype filterLayerMaskInline(quint32 layerMask, QSSGRenderableObjectList &renderables);
384 const QSSGRenderableObjectList &getSortedOpaqueRenderableObjects(
const QSSGRenderCamera &camera, size_t index = 0, quint32 layerMask = 0xFFFFFFFF);
386 const QSSGRenderableObjectList &getSortedTransparentRenderableObjects(
const QSSGRenderCamera &camera, size_t index = 0, quint32 layerMask = 0xFFFFFFFF);
387 const QSSGRenderableObjectList &getSortedScreenTextureRenderableObjects(
const QSSGRenderCamera &camera, size_t index = 0);
388 const QVector<QSSGBakedLightingModel> &getSortedBakedLightingModels();
389 const RenderableItem2DEntries &getRenderableItem2Ds();
390 const QSSGRenderableObjectList &getSortedRenderedDepthWriteObjects(
const QSSGRenderCamera &camera, size_t index = 0);
391 const QSSGRenderableObjectList &getSortedrenderedOpaqueDepthPrepassObjects(
const QSSGRenderCamera &camera, size_t index = 0);
392 void getShadowCastingObjects(
const QSSGRenderCamera &camera,
393 QSSGRenderableObjectList &outObjects,
394 QSSGBounds3 &outBoundsCasting,
395 QSSGBounds3 &outBoundsReceiving);
397 void resetForFrame();
399 QSSGFrameData &getFrameData();
401 ShadowMapPass shadowMapPass;
402 ReflectionMapPass reflectionMapPass;
403 ZPrePassPass zPrePassPass;
404 SSAOMapPass ssaoMapPass;
405 DepthMapPass depthMapPass;
406 DepthMapPass depthMapPassMS;
407 SkyMaterialPass skyMaterialPass;
408 ScreenMapPass screenMapPass;
409 ScreenReflectionPass reflectionPass;
410 Item2DPass item2DPass;
411 SkyboxPass skyboxPass;
412 SkyMaterialBackgroundPass skyMaterialBackgroundPass;
413 SkyboxCubeMapPass skyboxCubeMapPass;
414 UserRenderPass userRenderPasses;
415 static constexpr size_t USERPASSES = 3;
416 UserExtensionPass userPasses[USERPASSES];
417 OpaquePass opaquePass;
418 TransparentPass transparentPass;
419 OITRenderPass oitRenderPass;
420 OITCompositePass oitCompositePass;
421 InfiniteGridPass infiniteGridPass;
422 DebugDrawPass debugDrawPass;
423 NormalPass normalPass;
424 MotionVectorMapPass motionVectorMapPass;
427 QVarLengthArray<QSSGRenderPass *, 16> activePasses;
429 QSSGRenderLayer &layer;
430 QSSGRenderer *renderer =
nullptr;
434 using LayerNodes = std::vector<QSSGRenderNode *>;
435 QSSGGlobalRenderNodeData::LayerNodeView layerNodes;
438 RenderableNodeEntries renderableModels;
439 RenderableNodeEntries renderableParticles;
444 Q_DISABLE_COPY(NodeCollection)
446 NodeCollection() =
default;
448 QSSGModelsView modelsView;
449 QSSGParticlesView particlesView;
450 QSSGItem2DsView item2DsView;
451 QSSGCamerasView camerasView;
452 QSSGLightsView lightsView;
453 QSSGReflectionProbesView reflectionProbesView;
454 QSSGNonCategorizedView nonCategorizedView;
455 LayerNodes layerNodesCategorized;
457 NodeCollection nodeCollection;
459 QSSGModelsView &modelsView = nodeCollection.modelsView;
460 QSSGParticlesView &particlesView = nodeCollection.particlesView;
461 QSSGItem2DsView &item2DsView = nodeCollection.item2DsView;
462 QSSGCamerasView &camerasView = nodeCollection.camerasView;
463 QSSGLightsView &lightsView = nodeCollection.lightsView;
464 QSSGReflectionProbesView &reflectionProbesView = nodeCollection.reflectionProbesView;
465 QSSGNonCategorizedView &nonCategorizedView = nodeCollection.nonCategorizedView;
468 QSSGRenderCameraList renderedCameras;
469 QSSGShaderLightList globalLights;
471 QVector<QSSGBakedLightingModel> bakedLightingModels;
474 QVector<QSSGBakedLightingModel> renderedBakedLightingModels;
475 RenderableItem2DEntries renderedItem2Ds;
477 QSSGLayerRenderPreparationResult layerPrepResult;
478 std::optional<QSSGRenderCameraDataList> renderedCameraData;
480 TModelContextPtrList modelContexts;
482 QQsbCollection::EntryMap m_particleShaderEntries;
484 bool nonExplicitCameraWithLayerMaskWarningShown =
false;
485 bool tooManyLightsWarningShown =
false;
486 bool tooManyDirectionalLightsWarningShown =
false;
487 bool oitWarningUnsupportedShown =
false;
488 bool oitWarningInvalidBlendModeShown =
false;
489 bool orderIndependentTransparencyEnabled =
false;
490 bool disableMainPasses =
true;
492 std::unique_ptr<QSSGLightmapBaker> lightmapBaker =
nullptr;
494 QSSGShaderFeatures getShaderFeatures()
const {
return features; }
495 QSSGRhiGraphicsPipelineState getPipelineState()
const {
return ps; }
497 void initializeLightmapBaking(QSSGLightmapBaker::Context &ctx);
498 void maybeProcessLightmapBaking();
500 [[nodiscard]] QSSGRenderGraphObject *getCamera(QSSGCameraId id)
const;
501 [[nodiscard]] QSSGRenderCamera *activeCamera()
const {
return !renderedCameras.isEmpty() ? renderedCameras[0] :
nullptr; }
503 [[nodiscard]] QSSGRenderCameraData getCameraRenderData(
const QSSGRenderCamera *camera);
504 [[nodiscard]] QSSGRenderCameraData getCameraRenderData(
const QSSGRenderCamera *camera)
const;
506 void setLightmapTexture(
const QSSGModelContext &modelContext, QRhiTexture *lightmapTexture);
507 [[nodiscard]] QRhiTexture *getLightmapTexture(
const QSSGModelContext &modelContext)
const;
509 void setBonemapTexture(
const QSSGModelContext &modelContext, QRhiTexture *bonemapTexture);
510 [[nodiscard]] QRhiTexture *getBonemapTexture(
const QSSGModelContext &modelContext)
const;
512 [[nodiscard]] QSSGRenderContextInterface *contextInterface()
const;
514 [[nodiscard]]
bool isZPrePassActive()
const {
return zPrePassActive; }
515 void setZPrePassPrepResult(
bool res) { zPrePassActive = res; }
518 [[nodiscard]]
const QSSGShaderDefaultMaterialKeyProperties &getDefaultMaterialPropertyTable()
const
520 return defaultMaterialShaderKeyProperties;
522 [[nodiscard]]
const QSSGShaderParticleMaterialKeyProperties &getParticleMaterialPropertyTable()
const
524 return particleMaterialShaderKeyProperties;
527 struct GlobalRenderProperties
529 bool isYUpInFramebuffer =
true;
530 bool isYUpInNDC =
true;
531 bool isClipDepthZeroToOne =
true;
534 [[nodiscard]]
static GlobalRenderProperties globalRenderProperties(
const QSSGRenderContextInterface &ctx);
538 const QSSGRenderShadowMapPtr &requestShadowMapManager();
539 const QSSGRenderReflectionMapPtr &requestReflectionMapManager();
540 const QSSGRenderSkyMaterialManagerPtr &requestSkyMaterialManager();
541 const QSSGUserRenderPassManagerPtr &requestUserRenderPassManager();
542 const QSSGRenderMotionVectorMapPtr &requestMotionVectorMapManager();
543 const QSSGRenderShadowMapPtr &getShadowMapManager()
const {
return shadowMapManager; }
544 const QSSGRenderReflectionMapPtr &getReflectionMapManager()
const {
return reflectionMapManager; }
545 const QSSGRenderSkyMaterialManagerPtr &getSkyMaterialManager()
const {
return skyMaterialManager; }
546 const QSSGUserRenderPassManagerPtr &getUserRenderPassManager()
const {
return userRenderPassManager; }
547 const QSSGRenderMotionVectorMapPtr &getMotionvectorMapManager()
const {
return motionVectorMapManager; }
549 QSSGOITRenderContext &getOitRenderContext() {
return oitRenderContext; }
550 const QSSGOITRenderContext &getOitRenderContextConst()
const {
return oitRenderContext; }
552 static bool prepareInstancing(QSSGRhiContext *rhiCtx,
553 QSSGSubsetRenderable *renderable,
554 const QVector3D &cameraDirection,
555 const QVector3D &cameraPosition,
559 [[nodiscard]] QSSGRhiRenderableTexture *getRenderResult(QSSGRenderResult::Key id) {
return &renderResults[size_t(id)]; }
560 [[nodiscard]]
const QSSGRhiRenderableTexture *getRenderResult(QSSGRenderResult::Key id)
const {
return &renderResults[size_t(id)]; }
562 QSSGRenderImageTexture skyMaterialTexture;
563 void resolveLayerIblTexture();
565 [[nodiscard]]
static inline const std::unique_ptr<QSSGPerFrameAllocator> &perFrameAllocator(QSSGRenderContextInterface &ctx);
566 [[nodiscard]]
static inline QSSGLayerRenderData *getCurrent(
const QSSGRenderer &renderer) {
return renderer.m_currentLayer; }
567 void saveRenderState(
const QSSGRenderer &renderer);
568 void restoreRenderState(QSSGRenderer &renderer);
570 static void setTonemapFeatures(QSSGShaderFeatures &features, QSSGRenderLayer::TonemapMode tonemapMode)
572 features.set(QSSGShaderFeatures::Feature::LinearTonemapping,
573 tonemapMode == QSSGRenderLayer::TonemapMode::Linear);
574 features.set(QSSGShaderFeatures::Feature::AcesTonemapping,
575 tonemapMode == QSSGRenderLayer::TonemapMode::Aces);
576 features.set(QSSGShaderFeatures::Feature::HejlDawsonTonemapping,
577 tonemapMode == QSSGRenderLayer::TonemapMode::HejlDawson);
578 features.set(QSSGShaderFeatures::Feature::FilmicTonemapping,
579 tonemapMode == QSSGRenderLayer::TonemapMode::Filmic);
580 features.set(QSSGShaderFeatures::Feature::ForceIblExposure,
581 tonemapMode == QSSGRenderLayer::TonemapMode::Custom);
584 QSSGPrepContextId getOrCreateExtensionContext(
const QSSGRenderExtension &ext,
585 QSSGRenderCamera *camera =
nullptr,
589 QSSGRenderablesId createRenderables(QSSGPrepContextId prepId,
const QSSGNodeIdList &nodes, QSSGRenderHelpers::CreateFlags createFlags);
590 void setGlobalTransform(QSSGRenderablesId renderablesId,
const QSSGRenderModel &model,
const QMatrix4x4 &mvp);
591 QMatrix4x4 getGlobalTransform(QSSGPrepContextId prepId,
const QSSGRenderModel &model);
592 void setGlobalOpacity(QSSGRenderablesId renderablesId,
const QSSGRenderModel &model,
float opacity);
593 float getGlobalOpacity(QSSGPrepContextId prepId,
const QSSGRenderModel &model);
594 [[nodiscard]] QMatrix4x4 getModelMvps(QSSGPrepContextId prepId,
const QSSGRenderModel &model)
const;
595 void setModelMaterials(QSSGRenderablesId renderablesId,
const QSSGRenderModel &model,
const QList<QSSGResourceId> &materials);
596 void setModelMaterials(
const QSSGRenderablesId renderablesId,
const QList<QSSGResourceId> &materials);
597 [[nodiscard]] QSSGPrepResultId prepareModelsForRender(QSSGRenderContextInterface &contextInterface,
598 QSSGPrepContextId prepId,
599 QSSGRenderablesId renderablesId,
603 [[nodiscard]] QMatrix4x4 getGlobalTransform(QSSGRenderNodeHandle h,
const QMatrix4x4 &defaultValue)
const
605 return nodeData->getGlobalTransform(h, defaultValue);
607 [[nodiscard]] QMatrix4x4 getGlobalTransform(QSSGRenderNodeHandle h)
const
609 return nodeData->getGlobalTransform(h, QMatrix4x4());
611 [[nodiscard]] QMatrix4x4 getGlobalTransform(
const QSSGRenderNode &node)
const
613 return nodeData->getGlobalTransform(node.h, node.localTransform);
615 [[nodiscard]] QMatrix3x3 getNormalMatrix(QSSGRenderNodeHandle h)
const
617 return modelData->getNormalMatrix(h, QMatrix3x3(Qt::Uninitialized));
619 [[nodiscard]] QMatrix3x3 getNormalMatrix(
const QSSGRenderModel &model)
const
621 return modelData->getNormalMatrix(model);
623 [[nodiscard]] ModelViewProjections getModelMvps(QSSGRenderNodeHandle h)
const
625 return modelData->getModelViewProjection(h);
627 [[nodiscard]] ModelViewProjections getModelMvps(
const QSSGRenderModel &model)
const
629 return modelData->getModelViewProjection(model);
631 [[nodiscard]] InstanceTransforms getInstanceTransforms(QSSGRenderNodeHandle h)
const
633 return nodeData->getInstanceTransforms(h);
635 [[nodiscard]] InstanceTransforms getInstanceTransforms(
const QSSGRenderNode &node)
const
637 return nodeData->getInstanceTransforms(node.h);
639 [[nodiscard]]
float getGlobalOpacity(QSSGRenderNodeHandle h,
float defaultValue = 1.0f)
const
641 return nodeData->getGlobalOpacity(h, defaultValue);
643 [[nodiscard]]
float getGlobalOpacity(
const QSSGRenderNode &node)
const
645 return nodeData->getGlobalOpacity(node.h);
649 [[nodiscard]] QSSGRenderItem2DData::Item2DRenderer getItem2DRenderer(
const QSSGRenderItem2D &item)
const
651 return item2DData->getItem2DRenderer(item);
654 [[nodiscard]] ModelViewProjections getItem2DMvps(QSSGRenderNodeHandle h)
const
656 return item2DData->getModelViewProjection(h);
659 [[nodiscard]] ModelViewProjections getItem2DMvps(
const QSSGRenderItem2D &item)
const
661 return item2DData->getModelViewProjection(item);
666 void prepareRenderables(QSSGRenderContextInterface &ctx,
667 QSSGPrepResultId prepId,
668 QRhiRenderPassDescriptor *renderPassDescriptor,
669 const QSSGRhiGraphicsPipelineState &ps,
670 QSSGRenderablesFilters filter);
671 void renderRenderables(QSSGRenderContextInterface &ctx,
672 QSSGPrepResultId prepId);
674 static bool calculateGlobalVariables(QSSGRenderNode &node,
675 std::vector<QMatrix4x4> &globalTransforms,
676 std::vector<
float> &globalOpacities);
678 QSSGRenderCameraData getCameraDataImpl(
const QSSGRenderCamera *camera)
const;
680 static QSSGNodeIdList filter(
const QSSGGlobalRenderNodeData::LayerNodeView &layerNodes,
684 [[nodiscard]]
static QSSGLayerRenderData *getCurrent(
const QSSGFrameData &data) {
return data.getCurrent(); }
686 QSSGDefaultMaterialPreparationResult prepareDefaultMaterialForRender(QSSGRenderDefaultMaterial &inMaterial,
687 QSSGRenderableObjectFlags &inExistingFlags,
690 bool anyLightHasShadows,
691 QSSGLayerRenderPreparationResultFlags &ioFlags);
693 QSSGDefaultMaterialPreparationResult prepareCustomMaterialForRender(QSSGRenderCustomMaterial &inMaterial,
694 QSSGRenderableObjectFlags &inExistingFlags,
695 float inOpacity,
bool alreadyDirty,
697 bool anyLightHasShadows,
698 QSSGLayerRenderPreparationResultFlags &ioFlags);
700 static void categorizeAndFilterNodes(
const QSSGGlobalRenderNodeData::LayerNodeView &layerNodes,
701 QSSGLayerRenderData::NodeCollection &nodeCollection,
703 void updateFilteredLayerNodes(quint32 layerMask);
705 friend class QSSGRenderer;
706 friend class QSSGRendererPrivate;
707 friend class QSSGFrameData;
708 friend class QSSGModelHelpers;
709 friend class QSSGRenderHelpers;
710 friend class QSSGParticleRenderer;
712 class ExtensionContext
715 explicit ExtensionContext() =
default;
716 explicit ExtensionContext(
const QSSGRenderExtension &ownerExt, QSSGRenderCamera *cam, size_t idx, quint32 slot)
717 : owner(&ownerExt), camera(cam), ps{}, filter{0}, index(idx), slot(slot)
719 const QSSGRenderExtension *owner =
nullptr;
720 QSSGRenderCamera *camera =
nullptr;
721 QSSGRhiGraphicsPipelineState ps[3] {};
722 QSSGRenderablesFilters filter { 0 };
727 std::vector<ExtensionContext> extContexts { ExtensionContext{ } };
728 std::vector<RenderableNodeEntries> renderableModelStore { RenderableNodeEntries{ } };
729 std::vector<TModelContextPtrList> modelContextStore { TModelContextPtrList{ }};
730 std::vector<QSSGRenderableObjectList> renderableObjectStore { QSSGRenderableObjectList{ }};
731 std::vector<QSSGRenderableObjectList> opaqueObjectStore { QSSGRenderableObjectList{ }};
732 std::vector<QSSGRenderableObjectList> transparentObjectStore { QSSGRenderableObjectList{ }};
733 std::vector<QSSGRenderableObjectList> screenTextureObjectStore { QSSGRenderableObjectList{ }};
735 std::shared_ptr<QSSGGlobalRenderNodeData> nodeData;
736 std::unique_ptr<QSSGRenderModelData> modelData;
737 std::unique_ptr<QSSGRenderItem2DData> item2DData;
740 using CameraKey = std::pair<
const QSSGRenderCamera*, uint32_t>;
742 struct CameraKeyHash {
743 std::size_t operator()(
const CameraKey& k)
const noexcept {
745 return std::hash<
const QSSGRenderCamera*>()(k.first) ^
746 (std::hash<uint32_t>()(k.second) << 1);
751 bool operator()(
const CameraKey& a,
const CameraKey& b)
const noexcept {
752 return a.first == b.first && a.second == b.second;
756 using PerCameraCache = std::unordered_map<CameraKey, QSSGRenderableObjectList, CameraKeyHash, CameraKeyEq>;
757 std::vector<PerCameraCache> sortedOpaqueObjectCache { PerCameraCache{ } };
758 std::vector<PerCameraCache> sortedTransparentObjectCache { PerCameraCache{ } };
759 std::vector<PerCameraCache> sortedScreenTextureObjectCache { PerCameraCache{ } };
760 std::vector<PerCameraCache> sortedOpaqueDepthPrepassCache { PerCameraCache{ } };
761 std::vector<PerCameraCache> sortedDepthWriteCache { PerCameraCache{ } };
763 [[nodiscard]]
const QSSGRenderCameraDataList &getCachedCameraDatas();
764 void ensureCachedCameraDatas();
765 void updateSortedDepthObjectsListImp(
const QSSGRenderCamera &camera, size_t index);
767 static void prepareModelMaterials(RenderableNodeEntries &renderableModels,
bool cullUnrenderables);
768 static void prepareModelMaterials(
const RenderableNodeEntries::ConstIterator &begin,
769 const RenderableNodeEntries::ConstIterator &end);
772 QHash<QSSGShaderMapKey, QSSGRhiShaderPipelinePtr> shaderMap;
773 QHash<QSSGParticleShaderMapKey, QSSGRhiShaderPipelinePtr> particleShaderMap;
776 QByteArray generatedShaderString;
779 struct SavedRenderState
786 std::optional<SavedRenderState> savedRenderState;
790 QSSGShaderDefaultMaterialKeyProperties defaultMaterialShaderKeyProperties;
791 QSSGShaderParticleMaterialKeyProperties particleMaterialShaderKeyProperties;
792 QSSGFrameData frameData;
793 QSSGRhiGraphicsPipelineState ps;
794 QSSGShaderFeatures features;
795 QSSGRenderNodeVersionType version = 0;
796 bool particlesEnabled =
true;
797 bool hasDepthWriteObjects =
false;
798 bool zPrePassActive =
false;
802 bool renderablesModifiedByExtension =
false;
803 enum class DepthPrepassObject : quint8
810 using DepthPrepassObjectStateT = std::underlying_type_t<DepthPrepassObject>;
811 DepthPrepassObjectStateT depthPrepassObjectsState { DepthPrepassObjectStateT(DepthPrepassObject::None) };
812 QSSGRenderShadowMapPtr shadowMapManager;
813 QSSGRenderReflectionMapPtr reflectionMapManager;
814 QSSGRenderSkyMaterialManagerPtr skyMaterialManager;
815 QSSGUserRenderPassManagerPtr userRenderPassManager;
816 QSSGRenderMotionVectorMapPtr motionVectorMapManager;
817 QHash<
const QSSGModelContext *, QRhiTexture *> lightmapTextures;
818 QHash<
const QSSGModelContext *, QRhiTexture *> bonemapTextures;
819 QSSGRhiRenderableTexture renderResults[size_t(QSSGRenderResult::Key::RenderResultCount)] {};
820 QSSGOITRenderContext oitRenderContext;