308 MAX_TEMPORAL_AA_LEVELS = 2,
311 using InstanceTransforms = QSSGGlobalRenderNodeData::InstanceTransforms;
312 using ModelViewProjections = QSSGRenderModelData::ModelViewProjections;
314 using QSSGModelsView = QSSGDataView<QSSGRenderModel *>;
315 using QSSGParticlesView = QSSGDataView<QSSGRenderParticles *>;
316 using QSSGItem2DsView = QSSGDataView<QSSGRenderItem2D *>;
317 using QSSGCamerasView = QSSGDataView<QSSGRenderCamera *>;
318 using QSSGLightsView = QSSGDataView<QSSGRenderLight *>;
319 using QSSGReflectionProbesView = QSSGDataView<QSSGRenderReflectionProbe *>;
320 using QSSGNonCategorizedView = QSSGDataView<QSSGRenderNode *>;
322 using RenderableFilter = std::function<
bool(QSSGModelContext *)>;
324 QSSGLayerRenderData(QSSGRenderLayer &inLayer, QSSGRenderer &inRenderer);
325 ~QSSGLayerRenderData();
327 typedef QVector<QSSGModelContext *> TModelContextPtrList;
328 using RenderableNodeEntries = QVector<QSSGRenderableNodeEntry>;
329 using RenderableItem2DEntries = QVector<QSSGRenderItem2D *>;
331 void prepareImageForRender(QSSGRenderImage &inImage,
332 QSSGRenderableImage::Type inMapType,
333 QSSGRenderableImage *&ioFirstImage,
334 QSSGRenderableImage *&ioNextImage,
335 QSSGRenderableObjectFlags &ioFlags,
336 QSSGShaderDefaultMaterialKey &ioGeneratedShaderKey,
337 quint32 inImageIndex, QSSGRenderDefaultMaterial *inMaterial =
nullptr);
339 void setVertexInputPresence(
const QSSGRenderableObjectFlags &renderableFlags,
340 QSSGShaderDefaultMaterialKey &key);
342 static void prepareModelBoneTextures(
const QSSGRenderContextInterface &contextInterface,
343 const RenderableNodeEntries &renderableModels);
347 bool prepareModelsForRender(QSSGRenderContextInterface &ctx,
348 const RenderableNodeEntries &renderableModels,
349 QSSGLayerRenderPreparationResultFlags &ioFlags,
350 const QSSGRenderCameraList &allCameras,
351 const QSSGRenderCameraDataList &allCameraData,
352 TModelContextPtrList &modelContexts,
353 QSSGRenderableObjectList &opaqueObjects,
354 QSSGRenderableObjectList &transparentObjects,
355 QSSGRenderableObjectList &screenTextureObjects,
356 float lodThreshold = 0.0f);
357 bool prepareParticlesForRender(
const RenderableNodeEntries &renderableParticles,
const QSSGRenderCameraData &cameraData, QSSGLayerRenderPreparationResultFlags &ioFlags);
359 void prepareResourceLoaders();
361 void prepareForRender();
363 void prepareReflectionProbesForRender();
365 [[nodiscard]]
static qsizetype frustumCullingInline(
const QSSGClippingFrustum &clipFrustum, QSSGRenderableObjectList &renderables);
367 [[nodiscard]]
static qsizetype filterLayerMaskInline(quint32 layerMask, QSSGRenderableObjectList &renderables);
371 const QSSGRenderableObjectList &getSortedOpaqueRenderableObjects(
const QSSGRenderCamera &camera, size_t index = 0, quint32 layerMask = 0xFFFFFFFF);
373 const QSSGRenderableObjectList &getSortedTransparentRenderableObjects(
const QSSGRenderCamera &camera, size_t index = 0, quint32 layerMask = 0xFFFFFFFF);
374 const QSSGRenderableObjectList &getSortedScreenTextureRenderableObjects(
const QSSGRenderCamera &camera, size_t index = 0);
375 const QVector<QSSGBakedLightingModel> &getSortedBakedLightingModels();
376 const RenderableItem2DEntries &getRenderableItem2Ds();
377 const QSSGRenderableObjectList &getSortedRenderedDepthWriteObjects(
const QSSGRenderCamera &camera, size_t index = 0);
378 const QSSGRenderableObjectList &getSortedrenderedOpaqueDepthPrepassObjects(
const QSSGRenderCamera &camera, size_t index = 0);
380 void resetForFrame();
382 QSSGFrameData &getFrameData();
384 ShadowMapPass shadowMapPass;
385 ReflectionMapPass reflectionMapPass;
386 ZPrePassPass zPrePassPass;
387 SSAOMapPass ssaoMapPass;
388 DepthMapPass depthMapPass;
389 DepthMapPass depthMapPassMS;
390 ScreenMapPass screenMapPass;
391 ScreenReflectionPass reflectionPass;
392 Item2DPass item2DPass;
393 SkyboxPass skyboxPass;
394 SkyboxCubeMapPass skyboxCubeMapPass;
395 UserRenderPass userRenderPasses;
396 static constexpr size_t USERPASSES = 3;
397 UserExtensionPass userPasses[USERPASSES];
398 OpaquePass opaquePass;
399 TransparentPass transparentPass;
400 OITRenderPass oitRenderPass;
401 OITCompositePass oitCompositePass;
402 InfiniteGridPass infiniteGridPass;
403 DebugDrawPass debugDrawPass;
404 NormalPass normalPass;
405 MotionVectorMapPass motionVectorMapPass;
408 QVarLengthArray<QSSGRenderPass *, 16> activePasses;
410 QSSGRenderLayer &layer;
411 QSSGRenderer *renderer =
nullptr;
415 using LayerNodes = std::vector<QSSGRenderNode *>;
416 QSSGGlobalRenderNodeData::LayerNodeView layerNodes;
419 RenderableNodeEntries renderableModels;
420 RenderableNodeEntries renderableParticles;
425 Q_DISABLE_COPY(NodeCollection)
427 NodeCollection() =
default;
429 QSSGModelsView modelsView;
430 QSSGParticlesView particlesView;
431 QSSGItem2DsView item2DsView;
432 QSSGCamerasView camerasView;
433 QSSGLightsView lightsView;
434 QSSGReflectionProbesView reflectionProbesView;
435 QSSGNonCategorizedView nonCategorizedView;
436 LayerNodes layerNodesCategorized;
438 NodeCollection nodeCollection;
440 QSSGModelsView &modelsView = nodeCollection.modelsView;
441 QSSGParticlesView &particlesView = nodeCollection.particlesView;
442 QSSGItem2DsView &item2DsView = nodeCollection.item2DsView;
443 QSSGCamerasView &camerasView = nodeCollection.camerasView;
444 QSSGLightsView &lightsView = nodeCollection.lightsView;
445 QSSGReflectionProbesView &reflectionProbesView = nodeCollection.reflectionProbesView;
446 QSSGNonCategorizedView &nonCategorizedView = nodeCollection.nonCategorizedView;
449 QSSGRenderCameraList renderedCameras;
450 QSSGShaderLightList globalLights;
452 QVector<QSSGBakedLightingModel> bakedLightingModels;
455 QVector<QSSGBakedLightingModel> renderedBakedLightingModels;
456 RenderableItem2DEntries renderedItem2Ds;
458 QSSGLayerRenderPreparationResult layerPrepResult;
459 std::optional<QSSGRenderCameraDataList> renderedCameraData;
461 TModelContextPtrList modelContexts;
463 QQsbCollection::EntryMap m_particleShaderEntries;
465 bool nonExplicitCameraWithLayerMaskWarningShown =
false;
466 bool tooManyLightsWarningShown =
false;
467 bool tooManyDirectionalLightsWarningShown =
false;
468 bool oitWarningUnsupportedShown =
false;
469 bool oitWarningInvalidBlendModeShown =
false;
470 bool orderIndependentTransparencyEnabled =
false;
471 bool disableMainPasses =
true;
473 std::unique_ptr<QSSGLightmapBaker> lightmapBaker =
nullptr;
475 QSSGShaderFeatures getShaderFeatures()
const {
return features; }
476 QSSGRhiGraphicsPipelineState getPipelineState()
const {
return ps; }
478 void initializeLightmapBaking(QSSGLightmapBaker::Context &ctx);
479 void maybeProcessLightmapBaking();
481 [[nodiscard]] QSSGRenderGraphObject *getCamera(QSSGCameraId id)
const;
482 [[nodiscard]] QSSGRenderCamera *activeCamera()
const {
return !renderedCameras.isEmpty() ? renderedCameras[0] :
nullptr; }
484 [[nodiscard]] QSSGRenderCameraData getCameraRenderData(
const QSSGRenderCamera *camera);
485 [[nodiscard]] QSSGRenderCameraData getCameraRenderData(
const QSSGRenderCamera *camera)
const;
487 void setLightmapTexture(
const QSSGModelContext &modelContext, QRhiTexture *lightmapTexture);
488 [[nodiscard]] QRhiTexture *getLightmapTexture(
const QSSGModelContext &modelContext)
const;
490 void setBonemapTexture(
const QSSGModelContext &modelContext, QRhiTexture *bonemapTexture);
491 [[nodiscard]] QRhiTexture *getBonemapTexture(
const QSSGModelContext &modelContext)
const;
493 [[nodiscard]] QSSGRenderContextInterface *contextInterface()
const;
495 [[nodiscard]]
bool isZPrePassActive()
const {
return zPrePassActive; }
496 void setZPrePassPrepResult(
bool res) { zPrePassActive = res; }
499 [[nodiscard]]
const QSSGShaderDefaultMaterialKeyProperties &getDefaultMaterialPropertyTable()
const
501 return defaultMaterialShaderKeyProperties;
503 [[nodiscard]]
const QSSGShaderParticleMaterialKeyProperties &getParticleMaterialPropertyTable()
const
505 return particleMaterialShaderKeyProperties;
508 struct GlobalRenderProperties
510 bool isYUpInFramebuffer =
true;
511 bool isYUpInNDC =
true;
512 bool isClipDepthZeroToOne =
true;
515 [[nodiscard]]
static GlobalRenderProperties globalRenderProperties(
const QSSGRenderContextInterface &ctx);
519 const QSSGRenderShadowMapPtr &requestShadowMapManager();
520 const QSSGRenderReflectionMapPtr &requestReflectionMapManager();
521 const QSSGUserRenderPassManagerPtr &requestUserRenderPassManager();
522 const QSSGRenderMotionVectorMapPtr &requestMotionVectorMapManager();
523 const QSSGRenderShadowMapPtr &getShadowMapManager()
const {
return shadowMapManager; }
524 const QSSGRenderReflectionMapPtr &getReflectionMapManager()
const {
return reflectionMapManager; }
525 const QSSGUserRenderPassManagerPtr &getUserRenderPassManager()
const {
return userRenderPassManager; }
526 const QSSGRenderMotionVectorMapPtr &getMotionvectorMapManager()
const {
return motionVectorMapManager; }
528 QSSGOITRenderContext &getOitRenderContext() {
return oitRenderContext; }
529 const QSSGOITRenderContext &getOitRenderContextConst()
const {
return oitRenderContext; }
531 static bool prepareInstancing(QSSGRhiContext *rhiCtx,
532 QSSGSubsetRenderable *renderable,
533 const QVector3D &cameraDirection,
534 const QVector3D &cameraPosition,
538 [[nodiscard]] QSSGRhiRenderableTexture *getRenderResult(QSSGRenderResult::Key id) {
return &renderResults[size_t(id)]; }
539 [[nodiscard]]
const QSSGRhiRenderableTexture *getRenderResult(QSSGRenderResult::Key id)
const {
return &renderResults[size_t(id)]; }
540 [[nodiscard]]
static inline const std::unique_ptr<QSSGPerFrameAllocator> &perFrameAllocator(QSSGRenderContextInterface &ctx);
541 [[nodiscard]]
static inline QSSGLayerRenderData *getCurrent(
const QSSGRenderer &renderer) {
return renderer.m_currentLayer; }
542 void saveRenderState(
const QSSGRenderer &renderer);
543 void restoreRenderState(QSSGRenderer &renderer);
545 static void setTonemapFeatures(QSSGShaderFeatures &features, QSSGRenderLayer::TonemapMode tonemapMode)
547 features.set(QSSGShaderFeatures::Feature::LinearTonemapping,
548 tonemapMode == QSSGRenderLayer::TonemapMode::Linear);
549 features.set(QSSGShaderFeatures::Feature::AcesTonemapping,
550 tonemapMode == QSSGRenderLayer::TonemapMode::Aces);
551 features.set(QSSGShaderFeatures::Feature::HejlDawsonTonemapping,
552 tonemapMode == QSSGRenderLayer::TonemapMode::HejlDawson);
553 features.set(QSSGShaderFeatures::Feature::FilmicTonemapping,
554 tonemapMode == QSSGRenderLayer::TonemapMode::Filmic);
555 features.set(QSSGShaderFeatures::Feature::ForceIblExposure,
556 tonemapMode == QSSGRenderLayer::TonemapMode::Custom);
559 QSSGPrepContextId getOrCreateExtensionContext(
const QSSGRenderExtension &ext,
560 QSSGRenderCamera *camera =
nullptr,
564 QSSGRenderablesId createRenderables(QSSGPrepContextId prepId,
const QSSGNodeIdList &nodes, QSSGRenderHelpers::CreateFlags createFlags);
565 void setGlobalTransform(QSSGRenderablesId renderablesId,
const QSSGRenderModel &model,
const QMatrix4x4 &mvp);
566 QMatrix4x4 getGlobalTransform(QSSGPrepContextId prepId,
const QSSGRenderModel &model);
567 void setGlobalOpacity(QSSGRenderablesId renderablesId,
const QSSGRenderModel &model,
float opacity);
568 float getGlobalOpacity(QSSGPrepContextId prepId,
const QSSGRenderModel &model);
569 [[nodiscard]] QMatrix4x4 getModelMvps(QSSGPrepContextId prepId,
const QSSGRenderModel &model)
const;
570 void setModelMaterials(QSSGRenderablesId renderablesId,
const QSSGRenderModel &model,
const QList<QSSGResourceId> &materials);
571 void setModelMaterials(
const QSSGRenderablesId renderablesId,
const QList<QSSGResourceId> &materials);
572 [[nodiscard]] QSSGPrepResultId prepareModelsForRender(QSSGRenderContextInterface &contextInterface,
573 QSSGPrepContextId prepId,
574 QSSGRenderablesId renderablesId,
578 [[nodiscard]] QMatrix4x4 getGlobalTransform(QSSGRenderNodeHandle h, QMatrix4x4 defaultValue)
const
580 return nodeData->getGlobalTransform(h, defaultValue);
582 [[nodiscard]] QMatrix4x4 getGlobalTransform(QSSGRenderNodeHandle h)
const
584 return nodeData->getGlobalTransform(h, QMatrix4x4());
586 [[nodiscard]] QMatrix4x4 getGlobalTransform(
const QSSGRenderNode &node)
const
588 return nodeData->getGlobalTransform(node.h, node.localTransform);
590 [[nodiscard]] QMatrix3x3 getNormalMatrix(QSSGRenderModelHandle h)
const
592 return modelData->getNormalMatrix(h, QMatrix3x3(Qt::Uninitialized));
594 [[nodiscard]] QMatrix3x3 getNormalMatrix(
const QSSGRenderModel &model)
const
596 return modelData->getNormalMatrix(model);
598 [[nodiscard]] ModelViewProjections getModelMvps(QSSGRenderModelHandle h)
const
600 return modelData->getModelViewProjection(h);
602 [[nodiscard]] ModelViewProjections getModelMvps(
const QSSGRenderModel &model)
const
604 return modelData->getModelViewProjection(model);
606 [[nodiscard]] InstanceTransforms getInstanceTransforms(QSSGRenderNodeHandle h)
const
608 return nodeData->getInstanceTransforms(h);
610 [[nodiscard]] InstanceTransforms getInstanceTransforms(
const QSSGRenderNode &node)
const
612 return nodeData->getInstanceTransforms(node.h);
614 [[nodiscard]]
float getGlobalOpacity(QSSGRenderNodeHandle h,
float defaultValue = 1.0f)
const
616 return nodeData->getGlobalOpacity(h, defaultValue);
618 [[nodiscard]]
float getGlobalOpacity(
const QSSGRenderNode &node)
const
620 return nodeData->getGlobalOpacity(node.h);
624 [[nodiscard]] QSSGRenderItem2DData::Item2DRenderer getItem2DRenderer(
const QSSGRenderItem2D &item)
const
626 return item2DData->getItem2DRenderer(item);
629 [[nodiscard]] ModelViewProjections getItem2DMvps(QSSGRenderItem2DHandle h)
const
631 return item2DData->getModelViewProjection(h);
634 [[nodiscard]] ModelViewProjections getItem2DMvps(
const QSSGRenderItem2D &item)
const
636 return item2DData->getModelViewProjection(item);
641 void prepareRenderables(QSSGRenderContextInterface &ctx,
642 QSSGPrepResultId prepId,
643 QRhiRenderPassDescriptor *renderPassDescriptor,
644 const QSSGRhiGraphicsPipelineState &ps,
645 QSSGRenderablesFilters filter);
646 void renderRenderables(QSSGRenderContextInterface &ctx,
647 QSSGPrepResultId prepId);
649 static bool calculateGlobalVariables(QSSGRenderNode &node,
650 std::vector<QMatrix4x4> &globalTransforms,
651 std::vector<
float> &globalOpacities);
653 QSSGRenderCameraData getCameraDataImpl(
const QSSGRenderCamera *camera)
const;
655 static QSSGNodeIdList filter(
const QSSGGlobalRenderNodeData::LayerNodeView &layerNodes,
659 [[nodiscard]]
static QSSGLayerRenderData *getCurrent(
const QSSGFrameData &data) {
return data.getCurrent(); }
661 QSSGDefaultMaterialPreparationResult prepareDefaultMaterialForRender(QSSGRenderDefaultMaterial &inMaterial,
662 QSSGRenderableObjectFlags &inExistingFlags,
665 bool anyLightHasShadows,
666 QSSGLayerRenderPreparationResultFlags &ioFlags);
668 QSSGDefaultMaterialPreparationResult prepareCustomMaterialForRender(QSSGRenderCustomMaterial &inMaterial,
669 QSSGRenderableObjectFlags &inExistingFlags,
670 float inOpacity,
bool alreadyDirty,
672 bool anyLightHasShadows,
673 QSSGLayerRenderPreparationResultFlags &ioFlags);
675 static void categorizeAndFilterNodes(
const QSSGGlobalRenderNodeData::LayerNodeView &layerNodes,
676 QSSGLayerRenderData::NodeCollection &nodeCollection,
678 void updateFilteredLayerNodes(quint32 layerMask);
680 friend class QSSGRenderer;
681 friend class QSSGRendererPrivate;
682 friend class QSSGFrameData;
683 friend class QSSGModelHelpers;
684 friend class QSSGRenderHelpers;
685 friend class QSSGParticleRenderer;
687 class ExtensionContext
690 explicit ExtensionContext() =
default;
691 explicit ExtensionContext(
const QSSGRenderExtension &ownerExt, QSSGRenderCamera *cam, size_t idx, quint32 slot)
692 : owner(&ownerExt), camera(cam), ps{}, filter{0}, index(idx), slot(slot)
694 const QSSGRenderExtension *owner =
nullptr;
695 QSSGRenderCamera *camera =
nullptr;
696 QSSGRhiGraphicsPipelineState ps[3] {};
697 QSSGRenderablesFilters filter { 0 };
702 std::vector<ExtensionContext> extContexts { ExtensionContext{ } };
703 std::vector<RenderableNodeEntries> renderableModelStore { RenderableNodeEntries{ } };
704 std::vector<TModelContextPtrList> modelContextStore { TModelContextPtrList{ }};
705 std::vector<QSSGRenderableObjectList> renderableObjectStore { QSSGRenderableObjectList{ }};
706 std::vector<QSSGRenderableObjectList> opaqueObjectStore { QSSGRenderableObjectList{ }};
707 std::vector<QSSGRenderableObjectList> transparentObjectStore { QSSGRenderableObjectList{ }};
708 std::vector<QSSGRenderableObjectList> screenTextureObjectStore { QSSGRenderableObjectList{ }};
710 std::shared_ptr<QSSGGlobalRenderNodeData> nodeData;
711 std::unique_ptr<QSSGRenderModelData> modelData;
712 std::unique_ptr<QSSGRenderItem2DData> item2DData;
715 using CameraKey = std::pair<
const QSSGRenderCamera*, uint32_t>;
717 struct CameraKeyHash {
718 std::size_t operator()(
const CameraKey& k)
const noexcept {
720 return std::hash<
const QSSGRenderCamera*>()(k.first) ^
721 (std::hash<uint32_t>()(k.second) << 1);
726 bool operator()(
const CameraKey& a,
const CameraKey& b)
const noexcept {
727 return a.first == b.first && a.second == b.second;
731 using PerCameraCache = std::unordered_map<CameraKey, QSSGRenderableObjectList, CameraKeyHash, CameraKeyEq>;
732 std::vector<PerCameraCache> sortedOpaqueObjectCache { PerCameraCache{ } };
733 std::vector<PerCameraCache> sortedTransparentObjectCache { PerCameraCache{ } };
734 std::vector<PerCameraCache> sortedScreenTextureObjectCache { PerCameraCache{ } };
735 std::vector<PerCameraCache> sortedOpaqueDepthPrepassCache { PerCameraCache{ } };
736 std::vector<PerCameraCache> sortedDepthWriteCache { PerCameraCache{ } };
738 [[nodiscard]]
const QSSGRenderCameraDataList &getCachedCameraDatas();
739 void ensureCachedCameraDatas();
740 void updateSortedDepthObjectsListImp(
const QSSGRenderCamera &camera, size_t index);
742 static void prepareModelMaterials(RenderableNodeEntries &renderableModels,
bool cullUnrenderables);
743 static void prepareModelMaterials(
const RenderableNodeEntries::ConstIterator &begin,
744 const RenderableNodeEntries::ConstIterator &end);
747 QHash<QSSGShaderMapKey, QSSGRhiShaderPipelinePtr> shaderMap;
748 QHash<QSSGParticleShaderMapKey, QSSGRhiShaderPipelinePtr> particleShaderMap;
751 QByteArray generatedShaderString;
754 struct SavedRenderState
761 std::optional<SavedRenderState> savedRenderState;
765 QSSGShaderDefaultMaterialKeyProperties defaultMaterialShaderKeyProperties;
766 QSSGShaderParticleMaterialKeyProperties particleMaterialShaderKeyProperties;
767 QSSGFrameData frameData;
768 QSSGRhiGraphicsPipelineState ps;
769 QSSGShaderFeatures features;
771 bool particlesEnabled =
true;
772 bool hasDepthWriteObjects =
false;
773 bool zPrePassActive =
false;
777 bool renderablesModifiedByExtension =
false;
778 enum class DepthPrepassObject : quint8
785 using DepthPrepassObjectStateT = std::underlying_type_t<DepthPrepassObject>;
786 DepthPrepassObjectStateT depthPrepassObjectsState { DepthPrepassObjectStateT(DepthPrepassObject::None) };
787 QSSGRenderShadowMapPtr shadowMapManager;
788 QSSGRenderReflectionMapPtr reflectionMapManager;
789 QSSGUserRenderPassManagerPtr userRenderPassManager;
790 QSSGRenderMotionVectorMapPtr motionVectorMapManager;
791 QHash<
const QSSGModelContext *, QRhiTexture *> lightmapTextures;
792 QHash<
const QSSGModelContext *, QRhiTexture *> bonemapTextures;
793 QSSGRhiRenderableTexture renderResults[size_t(QSSGRenderResult::Key::RenderResultCount)] {};
794 QSSGOITRenderContext oitRenderContext;