320 MAX_TEMPORAL_AA_LEVELS = 2,
323 using InstanceTransforms = QSSGGlobalRenderNodeData::InstanceTransforms;
324 using ModelViewProjections = QSSGRenderModelData::ModelViewProjections;
326 using QSSGModelsView = QSSGDataView<QSSGRenderModel *>;
327 using QSSGParticlesView = QSSGDataView<QSSGRenderParticles *>;
328 using QSSGItem2DsView = QSSGDataView<QSSGRenderItem2D *>;
329 using QSSGCamerasView = QSSGDataView<QSSGRenderCamera *>;
330 using QSSGLightsView = QSSGDataView<QSSGRenderLight *>;
331 using QSSGReflectionProbesView = QSSGDataView<QSSGRenderReflectionProbe *>;
332 using QSSGNonCategorizedView = QSSGDataView<QSSGRenderNode *>;
334 using RenderableFilter = std::function<
bool(QSSGModelContext *)>;
336 QSSGLayerRenderData(QSSGRenderLayer &inLayer, QSSGRenderer &inRenderer);
337 ~QSSGLayerRenderData();
339 typedef QVector<QSSGModelContext *> TModelContextPtrList;
340 using RenderableNodeEntries = QVector<QSSGRenderableNodeEntry>;
341 using RenderableItem2DEntries = QVector<QSSGRenderItem2D *>;
343 void prepareImageForRender(QSSGRenderImage &inImage,
344 QSSGRenderableImage::Type inMapType,
345 QSSGRenderableImage *&ioFirstImage,
346 QSSGRenderableImage *&ioNextImage,
347 QSSGRenderableObjectFlags &ioFlags,
348 QSSGShaderDefaultMaterialKey &ioGeneratedShaderKey,
349 quint32 inImageIndex, QSSGRenderDefaultMaterial *inMaterial =
nullptr);
351 void setVertexInputPresence(
const QSSGRenderableObjectFlags &renderableFlags,
352 QSSGShaderDefaultMaterialKey &key);
354 static void prepareModelBoneTextures(
const QSSGRenderContextInterface &contextInterface,
355 const RenderableNodeEntries &renderableModels);
359 bool prepareModelsForRender(QSSGRenderContextInterface &ctx,
360 const RenderableNodeEntries &renderableModels,
361 QSSGLayerRenderPreparationResultFlags &ioFlags,
362 const QSSGRenderCameraList &allCameras,
363 const QSSGRenderCameraDataList &allCameraData,
364 TModelContextPtrList &modelContexts,
365 QSSGRenderableObjectList &opaqueObjects,
366 QSSGRenderableObjectList &transparentObjects,
367 QSSGRenderableObjectList &screenTextureObjects,
368 float lodThreshold = 0.0f);
369 bool prepareParticlesForRender(
const RenderableNodeEntries &renderableParticles,
const QSSGRenderCameraData &cameraData, QSSGLayerRenderPreparationResultFlags &ioFlags);
371 void prepareResourceLoaders();
373 void prepareForRender();
375 void prepareReflectionProbesForRender();
377 [[nodiscard]]
static qsizetype frustumCullingInline(
const QSSGClippingFrustum &clipFrustum, QSSGRenderableObjectList &renderables);
379 [[nodiscard]]
static qsizetype filterLayerMaskInline(quint32 layerMask, QSSGRenderableObjectList &renderables);
383 const QSSGRenderableObjectList &getSortedOpaqueRenderableObjects(
const QSSGRenderCamera &camera, size_t index = 0, quint32 layerMask = 0xFFFFFFFF);
385 const QSSGRenderableObjectList &getSortedTransparentRenderableObjects(
const QSSGRenderCamera &camera, size_t index = 0, quint32 layerMask = 0xFFFFFFFF);
386 const QSSGRenderableObjectList &getSortedScreenTextureRenderableObjects(
const QSSGRenderCamera &camera, size_t index = 0);
387 const QVector<QSSGBakedLightingModel> &getSortedBakedLightingModels();
388 const RenderableItem2DEntries &getRenderableItem2Ds();
389 const QSSGRenderableObjectList &getSortedRenderedDepthWriteObjects(
const QSSGRenderCamera &camera, size_t index = 0);
390 const QSSGRenderableObjectList &getSortedrenderedOpaqueDepthPrepassObjects(
const QSSGRenderCamera &camera, size_t index = 0);
391 void getShadowCastingObjects(
const QSSGRenderCamera &camera,
392 QSSGRenderableObjectList &outObjects,
393 QSSGBounds3 &outBoundsCasting,
394 QSSGBounds3 &outBoundsReceiving);
396 void resetForFrame();
398 QSSGFrameData &getFrameData();
400 ShadowMapPass shadowMapPass;
401 ReflectionMapPass reflectionMapPass;
402 ZPrePassPass zPrePassPass;
403 SSAOMapPass ssaoMapPass;
404 DepthMapPass depthMapPass;
405 DepthMapPass depthMapPassMS;
406 SkyMaterialPass skyMaterialPass;
407 ScreenMapPass screenMapPass;
408 ScreenReflectionPass reflectionPass;
409 Item2DPass item2DPass;
410 SkyboxPass skyboxPass;
411 SkyboxCubeMapPass skyboxCubeMapPass;
412 UserRenderPass userRenderPasses;
413 static constexpr size_t USERPASSES = 3;
414 UserExtensionPass userPasses[USERPASSES];
415 OpaquePass opaquePass;
416 TransparentPass transparentPass;
417 OITRenderPass oitRenderPass;
418 OITCompositePass oitCompositePass;
419 InfiniteGridPass infiniteGridPass;
420 DebugDrawPass debugDrawPass;
421 NormalPass normalPass;
422 MotionVectorMapPass motionVectorMapPass;
425 QVarLengthArray<QSSGRenderPass *, 16> activePasses;
427 QSSGRenderLayer &layer;
428 QSSGRenderer *renderer =
nullptr;
432 using LayerNodes = std::vector<QSSGRenderNode *>;
433 QSSGGlobalRenderNodeData::LayerNodeView layerNodes;
436 RenderableNodeEntries renderableModels;
437 RenderableNodeEntries renderableParticles;
442 Q_DISABLE_COPY(NodeCollection)
444 NodeCollection() =
default;
446 QSSGModelsView modelsView;
447 QSSGParticlesView particlesView;
448 QSSGItem2DsView item2DsView;
449 QSSGCamerasView camerasView;
450 QSSGLightsView lightsView;
451 QSSGReflectionProbesView reflectionProbesView;
452 QSSGNonCategorizedView nonCategorizedView;
453 LayerNodes layerNodesCategorized;
455 NodeCollection nodeCollection;
457 QSSGModelsView &modelsView = nodeCollection.modelsView;
458 QSSGParticlesView &particlesView = nodeCollection.particlesView;
459 QSSGItem2DsView &item2DsView = nodeCollection.item2DsView;
460 QSSGCamerasView &camerasView = nodeCollection.camerasView;
461 QSSGLightsView &lightsView = nodeCollection.lightsView;
462 QSSGReflectionProbesView &reflectionProbesView = nodeCollection.reflectionProbesView;
463 QSSGNonCategorizedView &nonCategorizedView = nodeCollection.nonCategorizedView;
466 QSSGRenderCameraList renderedCameras;
467 QSSGShaderLightList globalLights;
469 QVector<QSSGBakedLightingModel> bakedLightingModels;
472 QVector<QSSGBakedLightingModel> renderedBakedLightingModels;
473 RenderableItem2DEntries renderedItem2Ds;
475 QSSGLayerRenderPreparationResult layerPrepResult;
476 std::optional<QSSGRenderCameraDataList> renderedCameraData;
478 TModelContextPtrList modelContexts;
480 QQsbCollection::EntryMap m_particleShaderEntries;
482 bool nonExplicitCameraWithLayerMaskWarningShown =
false;
483 bool tooManyLightsWarningShown =
false;
484 bool tooManyDirectionalLightsWarningShown =
false;
485 bool oitWarningUnsupportedShown =
false;
486 bool oitWarningInvalidBlendModeShown =
false;
487 bool orderIndependentTransparencyEnabled =
false;
488 bool disableMainPasses =
true;
490 std::unique_ptr<QSSGLightmapBaker> lightmapBaker =
nullptr;
492 QSSGShaderFeatures getShaderFeatures()
const {
return features; }
493 QSSGRhiGraphicsPipelineState getPipelineState()
const {
return ps; }
495 void initializeLightmapBaking(QSSGLightmapBaker::Context &ctx);
496 void maybeProcessLightmapBaking();
498 [[nodiscard]] QSSGRenderGraphObject *getCamera(QSSGCameraId id)
const;
499 [[nodiscard]] QSSGRenderCamera *activeCamera()
const {
return !renderedCameras.isEmpty() ? renderedCameras[0] :
nullptr; }
501 [[nodiscard]] QSSGRenderCameraData getCameraRenderData(
const QSSGRenderCamera *camera);
502 [[nodiscard]] QSSGRenderCameraData getCameraRenderData(
const QSSGRenderCamera *camera)
const;
504 void setLightmapTexture(
const QSSGModelContext &modelContext, QRhiTexture *lightmapTexture);
505 [[nodiscard]] QRhiTexture *getLightmapTexture(
const QSSGModelContext &modelContext)
const;
507 void setBonemapTexture(
const QSSGModelContext &modelContext, QRhiTexture *bonemapTexture);
508 [[nodiscard]] QRhiTexture *getBonemapTexture(
const QSSGModelContext &modelContext)
const;
510 [[nodiscard]] QSSGRenderContextInterface *contextInterface()
const;
512 [[nodiscard]]
bool isZPrePassActive()
const {
return zPrePassActive; }
513 void setZPrePassPrepResult(
bool res) { zPrePassActive = res; }
516 [[nodiscard]]
const QSSGShaderDefaultMaterialKeyProperties &getDefaultMaterialPropertyTable()
const
518 return defaultMaterialShaderKeyProperties;
520 [[nodiscard]]
const QSSGShaderParticleMaterialKeyProperties &getParticleMaterialPropertyTable()
const
522 return particleMaterialShaderKeyProperties;
525 struct GlobalRenderProperties
527 bool isYUpInFramebuffer =
true;
528 bool isYUpInNDC =
true;
529 bool isClipDepthZeroToOne =
true;
532 [[nodiscard]]
static GlobalRenderProperties globalRenderProperties(
const QSSGRenderContextInterface &ctx);
536 const QSSGRenderShadowMapPtr &requestShadowMapManager();
537 const QSSGRenderReflectionMapPtr &requestReflectionMapManager();
538 const QSSGRenderSkyMaterialManagerPtr &requestSkyMaterialManager();
539 const QSSGUserRenderPassManagerPtr &requestUserRenderPassManager();
540 const QSSGRenderMotionVectorMapPtr &requestMotionVectorMapManager();
541 const QSSGRenderShadowMapPtr &getShadowMapManager()
const {
return shadowMapManager; }
542 const QSSGRenderReflectionMapPtr &getReflectionMapManager()
const {
return reflectionMapManager; }
543 const QSSGRenderSkyMaterialManagerPtr &getSkyMaterialManager()
const {
return skyMaterialManager; }
544 const QSSGUserRenderPassManagerPtr &getUserRenderPassManager()
const {
return userRenderPassManager; }
545 const QSSGRenderMotionVectorMapPtr &getMotionvectorMapManager()
const {
return motionVectorMapManager; }
547 QSSGOITRenderContext &getOitRenderContext() {
return oitRenderContext; }
548 const QSSGOITRenderContext &getOitRenderContextConst()
const {
return oitRenderContext; }
550 static bool prepareInstancing(QSSGRhiContext *rhiCtx,
551 QSSGSubsetRenderable *renderable,
552 const QVector3D &cameraDirection,
553 const QVector3D &cameraPosition,
557 [[nodiscard]] QSSGRhiRenderableTexture *getRenderResult(QSSGRenderResult::Key id) {
return &renderResults[size_t(id)]; }
558 [[nodiscard]]
const QSSGRhiRenderableTexture *getRenderResult(QSSGRenderResult::Key id)
const {
return &renderResults[size_t(id)]; }
560 QSSGRenderImageTexture skyMaterialTexture;
561 void resolveLayerIblTexture();
563 [[nodiscard]]
static inline const std::unique_ptr<QSSGPerFrameAllocator> &perFrameAllocator(QSSGRenderContextInterface &ctx);
564 [[nodiscard]]
static inline QSSGLayerRenderData *getCurrent(
const QSSGRenderer &renderer) {
return renderer.m_currentLayer; }
565 void saveRenderState(
const QSSGRenderer &renderer);
566 void restoreRenderState(QSSGRenderer &renderer);
568 static void setTonemapFeatures(QSSGShaderFeatures &features, QSSGRenderLayer::TonemapMode tonemapMode)
570 features.set(QSSGShaderFeatures::Feature::LinearTonemapping,
571 tonemapMode == QSSGRenderLayer::TonemapMode::Linear);
572 features.set(QSSGShaderFeatures::Feature::AcesTonemapping,
573 tonemapMode == QSSGRenderLayer::TonemapMode::Aces);
574 features.set(QSSGShaderFeatures::Feature::HejlDawsonTonemapping,
575 tonemapMode == QSSGRenderLayer::TonemapMode::HejlDawson);
576 features.set(QSSGShaderFeatures::Feature::FilmicTonemapping,
577 tonemapMode == QSSGRenderLayer::TonemapMode::Filmic);
578 features.set(QSSGShaderFeatures::Feature::ForceIblExposure,
579 tonemapMode == QSSGRenderLayer::TonemapMode::Custom);
582 QSSGPrepContextId getOrCreateExtensionContext(
const QSSGRenderExtension &ext,
583 QSSGRenderCamera *camera =
nullptr,
587 QSSGRenderablesId createRenderables(QSSGPrepContextId prepId,
const QSSGNodeIdList &nodes, QSSGRenderHelpers::CreateFlags createFlags);
588 void setGlobalTransform(QSSGRenderablesId renderablesId,
const QSSGRenderModel &model,
const QMatrix4x4 &mvp);
589 QMatrix4x4 getGlobalTransform(QSSGPrepContextId prepId,
const QSSGRenderModel &model);
590 void setGlobalOpacity(QSSGRenderablesId renderablesId,
const QSSGRenderModel &model,
float opacity);
591 float getGlobalOpacity(QSSGPrepContextId prepId,
const QSSGRenderModel &model);
592 [[nodiscard]] QMatrix4x4 getModelMvps(QSSGPrepContextId prepId,
const QSSGRenderModel &model)
const;
593 void setModelMaterials(QSSGRenderablesId renderablesId,
const QSSGRenderModel &model,
const QList<QSSGResourceId> &materials);
594 void setModelMaterials(
const QSSGRenderablesId renderablesId,
const QList<QSSGResourceId> &materials);
595 [[nodiscard]] QSSGPrepResultId prepareModelsForRender(QSSGRenderContextInterface &contextInterface,
596 QSSGPrepContextId prepId,
597 QSSGRenderablesId renderablesId,
601 [[nodiscard]] QMatrix4x4 getGlobalTransform(QSSGRenderNodeHandle h,
const QMatrix4x4 &defaultValue)
const
603 return nodeData->getGlobalTransform(h, defaultValue);
605 [[nodiscard]] QMatrix4x4 getGlobalTransform(QSSGRenderNodeHandle h)
const
607 return nodeData->getGlobalTransform(h, QMatrix4x4());
609 [[nodiscard]] QMatrix4x4 getGlobalTransform(
const QSSGRenderNode &node)
const
611 return nodeData->getGlobalTransform(node.h, node.localTransform);
613 [[nodiscard]] QMatrix3x3 getNormalMatrix(QSSGRenderNodeHandle h)
const
615 return modelData->getNormalMatrix(h, QMatrix3x3(Qt::Uninitialized));
617 [[nodiscard]] QMatrix3x3 getNormalMatrix(
const QSSGRenderModel &model)
const
619 return modelData->getNormalMatrix(model);
621 [[nodiscard]] ModelViewProjections getModelMvps(QSSGRenderNodeHandle h)
const
623 return modelData->getModelViewProjection(h);
625 [[nodiscard]] ModelViewProjections getModelMvps(
const QSSGRenderModel &model)
const
627 return modelData->getModelViewProjection(model);
629 [[nodiscard]] InstanceTransforms getInstanceTransforms(QSSGRenderNodeHandle h)
const
631 return nodeData->getInstanceTransforms(h);
633 [[nodiscard]] InstanceTransforms getInstanceTransforms(
const QSSGRenderNode &node)
const
635 return nodeData->getInstanceTransforms(node.h);
637 [[nodiscard]]
float getGlobalOpacity(QSSGRenderNodeHandle h,
float defaultValue = 1.0f)
const
639 return nodeData->getGlobalOpacity(h, defaultValue);
641 [[nodiscard]]
float getGlobalOpacity(
const QSSGRenderNode &node)
const
643 return nodeData->getGlobalOpacity(node.h);
647 [[nodiscard]] QSSGRenderItem2DData::Item2DRenderer getItem2DRenderer(
const QSSGRenderItem2D &item)
const
649 return item2DData->getItem2DRenderer(item);
652 [[nodiscard]] ModelViewProjections getItem2DMvps(QSSGRenderNodeHandle h)
const
654 return item2DData->getModelViewProjection(h);
657 [[nodiscard]] ModelViewProjections getItem2DMvps(
const QSSGRenderItem2D &item)
const
659 return item2DData->getModelViewProjection(item);
664 void prepareRenderables(QSSGRenderContextInterface &ctx,
665 QSSGPrepResultId prepId,
666 QRhiRenderPassDescriptor *renderPassDescriptor,
667 const QSSGRhiGraphicsPipelineState &ps,
668 QSSGRenderablesFilters filter);
669 void renderRenderables(QSSGRenderContextInterface &ctx,
670 QSSGPrepResultId prepId);
672 static bool calculateGlobalVariables(QSSGRenderNode &node,
673 std::vector<QMatrix4x4> &globalTransforms,
674 std::vector<
float> &globalOpacities);
676 QSSGRenderCameraData getCameraDataImpl(
const QSSGRenderCamera *camera)
const;
678 static QSSGNodeIdList filter(
const QSSGGlobalRenderNodeData::LayerNodeView &layerNodes,
682 [[nodiscard]]
static QSSGLayerRenderData *getCurrent(
const QSSGFrameData &data) {
return data.getCurrent(); }
684 QSSGDefaultMaterialPreparationResult prepareDefaultMaterialForRender(QSSGRenderDefaultMaterial &inMaterial,
685 QSSGRenderableObjectFlags &inExistingFlags,
688 bool anyLightHasShadows,
689 QSSGLayerRenderPreparationResultFlags &ioFlags);
691 QSSGDefaultMaterialPreparationResult prepareCustomMaterialForRender(QSSGRenderCustomMaterial &inMaterial,
692 QSSGRenderableObjectFlags &inExistingFlags,
693 float inOpacity,
bool alreadyDirty,
695 bool anyLightHasShadows,
696 QSSGLayerRenderPreparationResultFlags &ioFlags);
698 static void categorizeAndFilterNodes(
const QSSGGlobalRenderNodeData::LayerNodeView &layerNodes,
699 QSSGLayerRenderData::NodeCollection &nodeCollection,
701 void updateFilteredLayerNodes(quint32 layerMask);
703 friend class QSSGRenderer;
704 friend class QSSGRendererPrivate;
705 friend class QSSGFrameData;
706 friend class QSSGModelHelpers;
707 friend class QSSGRenderHelpers;
708 friend class QSSGParticleRenderer;
710 class ExtensionContext
713 explicit ExtensionContext() =
default;
714 explicit ExtensionContext(
const QSSGRenderExtension &ownerExt, QSSGRenderCamera *cam, size_t idx, quint32 slot)
715 : owner(&ownerExt), camera(cam), ps{}, filter{0}, index(idx), slot(slot)
717 const QSSGRenderExtension *owner =
nullptr;
718 QSSGRenderCamera *camera =
nullptr;
719 QSSGRhiGraphicsPipelineState ps[3] {};
720 QSSGRenderablesFilters filter { 0 };
725 std::vector<ExtensionContext> extContexts { ExtensionContext{ } };
726 std::vector<RenderableNodeEntries> renderableModelStore { RenderableNodeEntries{ } };
727 std::vector<TModelContextPtrList> modelContextStore { TModelContextPtrList{ }};
728 std::vector<QSSGRenderableObjectList> renderableObjectStore { QSSGRenderableObjectList{ }};
729 std::vector<QSSGRenderableObjectList> opaqueObjectStore { QSSGRenderableObjectList{ }};
730 std::vector<QSSGRenderableObjectList> transparentObjectStore { QSSGRenderableObjectList{ }};
731 std::vector<QSSGRenderableObjectList> screenTextureObjectStore { QSSGRenderableObjectList{ }};
733 std::shared_ptr<QSSGGlobalRenderNodeData> nodeData;
734 std::unique_ptr<QSSGRenderModelData> modelData;
735 std::unique_ptr<QSSGRenderItem2DData> item2DData;
738 using CameraKey = std::pair<
const QSSGRenderCamera*, uint32_t>;
740 struct CameraKeyHash {
741 std::size_t operator()(
const CameraKey& k)
const noexcept {
743 return std::hash<
const QSSGRenderCamera*>()(k.first) ^
744 (std::hash<uint32_t>()(k.second) << 1);
749 bool operator()(
const CameraKey& a,
const CameraKey& b)
const noexcept {
750 return a.first == b.first && a.second == b.second;
754 using PerCameraCache = std::unordered_map<CameraKey, QSSGRenderableObjectList, CameraKeyHash, CameraKeyEq>;
755 std::vector<PerCameraCache> sortedOpaqueObjectCache { PerCameraCache{ } };
756 std::vector<PerCameraCache> sortedTransparentObjectCache { PerCameraCache{ } };
757 std::vector<PerCameraCache> sortedScreenTextureObjectCache { PerCameraCache{ } };
758 std::vector<PerCameraCache> sortedOpaqueDepthPrepassCache { PerCameraCache{ } };
759 std::vector<PerCameraCache> sortedDepthWriteCache { PerCameraCache{ } };
761 [[nodiscard]]
const QSSGRenderCameraDataList &getCachedCameraDatas();
762 void ensureCachedCameraDatas();
763 void updateSortedDepthObjectsListImp(
const QSSGRenderCamera &camera, size_t index);
765 static void prepareModelMaterials(RenderableNodeEntries &renderableModels,
bool cullUnrenderables);
766 static void prepareModelMaterials(
const RenderableNodeEntries::ConstIterator &begin,
767 const RenderableNodeEntries::ConstIterator &end);
770 QHash<QSSGShaderMapKey, QSSGRhiShaderPipelinePtr> shaderMap;
771 QHash<QSSGParticleShaderMapKey, QSSGRhiShaderPipelinePtr> particleShaderMap;
774 QByteArray generatedShaderString;
777 struct SavedRenderState
784 std::optional<SavedRenderState> savedRenderState;
788 QSSGShaderDefaultMaterialKeyProperties defaultMaterialShaderKeyProperties;
789 QSSGShaderParticleMaterialKeyProperties particleMaterialShaderKeyProperties;
790 QSSGFrameData frameData;
791 QSSGRhiGraphicsPipelineState ps;
792 QSSGShaderFeatures features;
793 QSSGRenderNodeVersionType version = 0;
794 bool particlesEnabled =
true;
795 bool hasDepthWriteObjects =
false;
796 bool zPrePassActive =
false;
800 bool renderablesModifiedByExtension =
false;
801 enum class DepthPrepassObject : quint8
808 using DepthPrepassObjectStateT = std::underlying_type_t<DepthPrepassObject>;
809 DepthPrepassObjectStateT depthPrepassObjectsState { DepthPrepassObjectStateT(DepthPrepassObject::None) };
810 QSSGRenderShadowMapPtr shadowMapManager;
811 QSSGRenderReflectionMapPtr reflectionMapManager;
812 QSSGRenderSkyMaterialManagerPtr skyMaterialManager;
813 QSSGUserRenderPassManagerPtr userRenderPassManager;
814 QSSGRenderMotionVectorMapPtr motionVectorMapManager;
815 QHash<
const QSSGModelContext *, QRhiTexture *> lightmapTextures;
816 QHash<
const QSSGModelContext *, QRhiTexture *> bonemapTextures;
817 QSSGRhiRenderableTexture renderResults[size_t(QSSGRenderResult::Key::RenderResultCount)] {};
818 QSSGOITRenderContext oitRenderContext;