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);
379 void getShadowCastingObjects(
const QSSGRenderCamera &camera,
380 QSSGRenderableObjectList &outObjects,
381 QSSGBounds3 &outBoundsCasting,
382 QSSGBounds3 &outBoundsReceiving);
384 void resetForFrame();
386 QSSGFrameData &getFrameData();
388 ShadowMapPass shadowMapPass;
389 ReflectionMapPass reflectionMapPass;
390 ZPrePassPass zPrePassPass;
391 SSAOMapPass ssaoMapPass;
392 DepthMapPass depthMapPass;
393 DepthMapPass depthMapPassMS;
394 ScreenMapPass screenMapPass;
395 ScreenReflectionPass reflectionPass;
396 Item2DPass item2DPass;
397 SkyboxPass skyboxPass;
398 SkyboxCubeMapPass skyboxCubeMapPass;
399 UserRenderPass userRenderPasses;
400 static constexpr size_t USERPASSES = 3;
401 UserExtensionPass userPasses[USERPASSES];
402 OpaquePass opaquePass;
403 TransparentPass transparentPass;
404 OITRenderPass oitRenderPass;
405 OITCompositePass oitCompositePass;
406 InfiniteGridPass infiniteGridPass;
407 DebugDrawPass debugDrawPass;
408 NormalPass normalPass;
409 MotionVectorMapPass motionVectorMapPass;
412 QVarLengthArray<QSSGRenderPass *, 16> activePasses;
414 QSSGRenderLayer &layer;
415 QSSGRenderer *renderer =
nullptr;
419 using LayerNodes = std::vector<QSSGRenderNode *>;
420 QSSGGlobalRenderNodeData::LayerNodeView layerNodes;
423 RenderableNodeEntries renderableModels;
424 RenderableNodeEntries renderableParticles;
429 Q_DISABLE_COPY(NodeCollection)
431 NodeCollection() =
default;
433 QSSGModelsView modelsView;
434 QSSGParticlesView particlesView;
435 QSSGItem2DsView item2DsView;
436 QSSGCamerasView camerasView;
437 QSSGLightsView lightsView;
438 QSSGReflectionProbesView reflectionProbesView;
439 QSSGNonCategorizedView nonCategorizedView;
440 LayerNodes layerNodesCategorized;
442 NodeCollection nodeCollection;
444 QSSGModelsView &modelsView = nodeCollection.modelsView;
445 QSSGParticlesView &particlesView = nodeCollection.particlesView;
446 QSSGItem2DsView &item2DsView = nodeCollection.item2DsView;
447 QSSGCamerasView &camerasView = nodeCollection.camerasView;
448 QSSGLightsView &lightsView = nodeCollection.lightsView;
449 QSSGReflectionProbesView &reflectionProbesView = nodeCollection.reflectionProbesView;
450 QSSGNonCategorizedView &nonCategorizedView = nodeCollection.nonCategorizedView;
453 QSSGRenderCameraList renderedCameras;
454 QSSGShaderLightList globalLights;
456 QVector<QSSGBakedLightingModel> bakedLightingModels;
459 QVector<QSSGBakedLightingModel> renderedBakedLightingModels;
460 RenderableItem2DEntries renderedItem2Ds;
462 QSSGLayerRenderPreparationResult layerPrepResult;
463 std::optional<QSSGRenderCameraDataList> renderedCameraData;
465 TModelContextPtrList modelContexts;
467 QQsbCollection::EntryMap m_particleShaderEntries;
469 bool nonExplicitCameraWithLayerMaskWarningShown =
false;
470 bool tooManyLightsWarningShown =
false;
471 bool tooManyDirectionalLightsWarningShown =
false;
472 bool oitWarningUnsupportedShown =
false;
473 bool oitWarningInvalidBlendModeShown =
false;
474 bool orderIndependentTransparencyEnabled =
false;
475 bool disableMainPasses =
true;
477 std::unique_ptr<QSSGLightmapBaker> lightmapBaker =
nullptr;
479 QSSGShaderFeatures getShaderFeatures()
const {
return features; }
480 QSSGRhiGraphicsPipelineState getPipelineState()
const {
return ps; }
482 void initializeLightmapBaking(QSSGLightmapBaker::Context &ctx);
483 void maybeProcessLightmapBaking();
485 [[nodiscard]] QSSGRenderGraphObject *getCamera(QSSGCameraId id)
const;
486 [[nodiscard]] QSSGRenderCamera *activeCamera()
const {
return !renderedCameras.isEmpty() ? renderedCameras[0] :
nullptr; }
488 [[nodiscard]] QSSGRenderCameraData getCameraRenderData(
const QSSGRenderCamera *camera);
489 [[nodiscard]] QSSGRenderCameraData getCameraRenderData(
const QSSGRenderCamera *camera)
const;
491 void setLightmapTexture(
const QSSGModelContext &modelContext, QRhiTexture *lightmapTexture);
492 [[nodiscard]] QRhiTexture *getLightmapTexture(
const QSSGModelContext &modelContext)
const;
494 void setBonemapTexture(
const QSSGModelContext &modelContext, QRhiTexture *bonemapTexture);
495 [[nodiscard]] QRhiTexture *getBonemapTexture(
const QSSGModelContext &modelContext)
const;
497 [[nodiscard]] QSSGRenderContextInterface *contextInterface()
const;
499 [[nodiscard]]
bool isZPrePassActive()
const {
return zPrePassActive; }
500 void setZPrePassPrepResult(
bool res) { zPrePassActive = res; }
503 [[nodiscard]]
const QSSGShaderDefaultMaterialKeyProperties &getDefaultMaterialPropertyTable()
const
505 return defaultMaterialShaderKeyProperties;
507 [[nodiscard]]
const QSSGShaderParticleMaterialKeyProperties &getParticleMaterialPropertyTable()
const
509 return particleMaterialShaderKeyProperties;
512 struct GlobalRenderProperties
514 bool isYUpInFramebuffer =
true;
515 bool isYUpInNDC =
true;
516 bool isClipDepthZeroToOne =
true;
519 [[nodiscard]]
static GlobalRenderProperties globalRenderProperties(
const QSSGRenderContextInterface &ctx);
523 const QSSGRenderShadowMapPtr &requestShadowMapManager();
524 const QSSGRenderReflectionMapPtr &requestReflectionMapManager();
525 const QSSGUserRenderPassManagerPtr &requestUserRenderPassManager();
526 const QSSGRenderMotionVectorMapPtr &requestMotionVectorMapManager();
527 const QSSGRenderShadowMapPtr &getShadowMapManager()
const {
return shadowMapManager; }
528 const QSSGRenderReflectionMapPtr &getReflectionMapManager()
const {
return reflectionMapManager; }
529 const QSSGUserRenderPassManagerPtr &getUserRenderPassManager()
const {
return userRenderPassManager; }
530 const QSSGRenderMotionVectorMapPtr &getMotionvectorMapManager()
const {
return motionVectorMapManager; }
532 QSSGOITRenderContext &getOitRenderContext() {
return oitRenderContext; }
533 const QSSGOITRenderContext &getOitRenderContextConst()
const {
return oitRenderContext; }
535 static bool prepareInstancing(QSSGRhiContext *rhiCtx,
536 QSSGSubsetRenderable *renderable,
537 const QVector3D &cameraDirection,
538 const QVector3D &cameraPosition,
542 [[nodiscard]] QSSGRhiRenderableTexture *getRenderResult(QSSGRenderResult::Key id) {
return &renderResults[size_t(id)]; }
543 [[nodiscard]]
const QSSGRhiRenderableTexture *getRenderResult(QSSGRenderResult::Key id)
const {
return &renderResults[size_t(id)]; }
544 [[nodiscard]]
static inline const std::unique_ptr<QSSGPerFrameAllocator> &perFrameAllocator(QSSGRenderContextInterface &ctx);
545 [[nodiscard]]
static inline QSSGLayerRenderData *getCurrent(
const QSSGRenderer &renderer) {
return renderer.m_currentLayer; }
546 void saveRenderState(
const QSSGRenderer &renderer);
547 void restoreRenderState(QSSGRenderer &renderer);
549 static void setTonemapFeatures(QSSGShaderFeatures &features, QSSGRenderLayer::TonemapMode tonemapMode)
551 features.set(QSSGShaderFeatures::Feature::LinearTonemapping,
552 tonemapMode == QSSGRenderLayer::TonemapMode::Linear);
553 features.set(QSSGShaderFeatures::Feature::AcesTonemapping,
554 tonemapMode == QSSGRenderLayer::TonemapMode::Aces);
555 features.set(QSSGShaderFeatures::Feature::HejlDawsonTonemapping,
556 tonemapMode == QSSGRenderLayer::TonemapMode::HejlDawson);
557 features.set(QSSGShaderFeatures::Feature::FilmicTonemapping,
558 tonemapMode == QSSGRenderLayer::TonemapMode::Filmic);
559 features.set(QSSGShaderFeatures::Feature::ForceIblExposure,
560 tonemapMode == QSSGRenderLayer::TonemapMode::Custom);
563 QSSGPrepContextId getOrCreateExtensionContext(
const QSSGRenderExtension &ext,
564 QSSGRenderCamera *camera =
nullptr,
568 QSSGRenderablesId createRenderables(QSSGPrepContextId prepId,
const QSSGNodeIdList &nodes, QSSGRenderHelpers::CreateFlags createFlags);
569 void setGlobalTransform(QSSGRenderablesId renderablesId,
const QSSGRenderModel &model,
const QMatrix4x4 &mvp);
570 QMatrix4x4 getGlobalTransform(QSSGPrepContextId prepId,
const QSSGRenderModel &model);
571 void setGlobalOpacity(QSSGRenderablesId renderablesId,
const QSSGRenderModel &model,
float opacity);
572 float getGlobalOpacity(QSSGPrepContextId prepId,
const QSSGRenderModel &model);
573 [[nodiscard]] QMatrix4x4 getModelMvps(QSSGPrepContextId prepId,
const QSSGRenderModel &model)
const;
574 void setModelMaterials(QSSGRenderablesId renderablesId,
const QSSGRenderModel &model,
const QList<QSSGResourceId> &materials);
575 void setModelMaterials(
const QSSGRenderablesId renderablesId,
const QList<QSSGResourceId> &materials);
576 [[nodiscard]] QSSGPrepResultId prepareModelsForRender(QSSGRenderContextInterface &contextInterface,
577 QSSGPrepContextId prepId,
578 QSSGRenderablesId renderablesId,
582 [[nodiscard]] QMatrix4x4 getGlobalTransform(QSSGRenderNodeHandle h, QMatrix4x4 defaultValue)
const
584 return nodeData->getGlobalTransform(h, defaultValue);
586 [[nodiscard]] QMatrix4x4 getGlobalTransform(QSSGRenderNodeHandle h)
const
588 return nodeData->getGlobalTransform(h, QMatrix4x4());
590 [[nodiscard]] QMatrix4x4 getGlobalTransform(
const QSSGRenderNode &node)
const
592 return nodeData->getGlobalTransform(node.h, node.localTransform);
594 [[nodiscard]] QMatrix3x3 getNormalMatrix(QSSGRenderModelHandle h)
const
596 return modelData->getNormalMatrix(h, QMatrix3x3(Qt::Uninitialized));
598 [[nodiscard]] QMatrix3x3 getNormalMatrix(
const QSSGRenderModel &model)
const
600 return modelData->getNormalMatrix(model);
602 [[nodiscard]] ModelViewProjections getModelMvps(QSSGRenderModelHandle h)
const
604 return modelData->getModelViewProjection(h);
606 [[nodiscard]] ModelViewProjections getModelMvps(
const QSSGRenderModel &model)
const
608 return modelData->getModelViewProjection(model);
610 [[nodiscard]] InstanceTransforms getInstanceTransforms(QSSGRenderNodeHandle h)
const
612 return nodeData->getInstanceTransforms(h);
614 [[nodiscard]] InstanceTransforms getInstanceTransforms(
const QSSGRenderNode &node)
const
616 return nodeData->getInstanceTransforms(node.h);
618 [[nodiscard]]
float getGlobalOpacity(QSSGRenderNodeHandle h,
float defaultValue = 1.0f)
const
620 return nodeData->getGlobalOpacity(h, defaultValue);
622 [[nodiscard]]
float getGlobalOpacity(
const QSSGRenderNode &node)
const
624 return nodeData->getGlobalOpacity(node.h);
628 [[nodiscard]] QSSGRenderItem2DData::Item2DRenderer getItem2DRenderer(
const QSSGRenderItem2D &item)
const
630 return item2DData->getItem2DRenderer(item);
633 [[nodiscard]] ModelViewProjections getItem2DMvps(QSSGRenderItem2DHandle h)
const
635 return item2DData->getModelViewProjection(h);
638 [[nodiscard]] ModelViewProjections getItem2DMvps(
const QSSGRenderItem2D &item)
const
640 return item2DData->getModelViewProjection(item);
645 void prepareRenderables(QSSGRenderContextInterface &ctx,
646 QSSGPrepResultId prepId,
647 QRhiRenderPassDescriptor *renderPassDescriptor,
648 const QSSGRhiGraphicsPipelineState &ps,
649 QSSGRenderablesFilters filter);
650 void renderRenderables(QSSGRenderContextInterface &ctx,
651 QSSGPrepResultId prepId);
653 static bool calculateGlobalVariables(QSSGRenderNode &node,
654 std::vector<QMatrix4x4> &globalTransforms,
655 std::vector<
float> &globalOpacities);
657 QSSGRenderCameraData getCameraDataImpl(
const QSSGRenderCamera *camera)
const;
659 static QSSGNodeIdList filter(
const QSSGGlobalRenderNodeData::LayerNodeView &layerNodes,
663 [[nodiscard]]
static QSSGLayerRenderData *getCurrent(
const QSSGFrameData &data) {
return data.getCurrent(); }
665 QSSGDefaultMaterialPreparationResult prepareDefaultMaterialForRender(QSSGRenderDefaultMaterial &inMaterial,
666 QSSGRenderableObjectFlags &inExistingFlags,
669 bool anyLightHasShadows,
670 QSSGLayerRenderPreparationResultFlags &ioFlags);
672 QSSGDefaultMaterialPreparationResult prepareCustomMaterialForRender(QSSGRenderCustomMaterial &inMaterial,
673 QSSGRenderableObjectFlags &inExistingFlags,
674 float inOpacity,
bool alreadyDirty,
676 bool anyLightHasShadows,
677 QSSGLayerRenderPreparationResultFlags &ioFlags);
679 static void categorizeAndFilterNodes(
const QSSGGlobalRenderNodeData::LayerNodeView &layerNodes,
680 QSSGLayerRenderData::NodeCollection &nodeCollection,
682 void updateFilteredLayerNodes(quint32 layerMask);
684 friend class QSSGRenderer;
685 friend class QSSGRendererPrivate;
686 friend class QSSGFrameData;
687 friend class QSSGModelHelpers;
688 friend class QSSGRenderHelpers;
689 friend class QSSGParticleRenderer;
691 class ExtensionContext
694 explicit ExtensionContext() =
default;
695 explicit ExtensionContext(
const QSSGRenderExtension &ownerExt, QSSGRenderCamera *cam, size_t idx, quint32 slot)
696 : owner(&ownerExt), camera(cam), ps{}, filter{0}, index(idx), slot(slot)
698 const QSSGRenderExtension *owner =
nullptr;
699 QSSGRenderCamera *camera =
nullptr;
700 QSSGRhiGraphicsPipelineState ps[3] {};
701 QSSGRenderablesFilters filter { 0 };
706 std::vector<ExtensionContext> extContexts { ExtensionContext{ } };
707 std::vector<RenderableNodeEntries> renderableModelStore { RenderableNodeEntries{ } };
708 std::vector<TModelContextPtrList> modelContextStore { TModelContextPtrList{ }};
709 std::vector<QSSGRenderableObjectList> renderableObjectStore { QSSGRenderableObjectList{ }};
710 std::vector<QSSGRenderableObjectList> opaqueObjectStore { QSSGRenderableObjectList{ }};
711 std::vector<QSSGRenderableObjectList> transparentObjectStore { QSSGRenderableObjectList{ }};
712 std::vector<QSSGRenderableObjectList> screenTextureObjectStore { QSSGRenderableObjectList{ }};
714 std::shared_ptr<QSSGGlobalRenderNodeData> nodeData;
715 std::unique_ptr<QSSGRenderModelData> modelData;
716 std::unique_ptr<QSSGRenderItem2DData> item2DData;
719 using CameraKey = std::pair<
const QSSGRenderCamera*, uint32_t>;
721 struct CameraKeyHash {
722 std::size_t operator()(
const CameraKey& k)
const noexcept {
724 return std::hash<
const QSSGRenderCamera*>()(k.first) ^
725 (std::hash<uint32_t>()(k.second) << 1);
730 bool operator()(
const CameraKey& a,
const CameraKey& b)
const noexcept {
731 return a.first == b.first && a.second == b.second;
735 using PerCameraCache = std::unordered_map<CameraKey, QSSGRenderableObjectList, CameraKeyHash, CameraKeyEq>;
736 std::vector<PerCameraCache> sortedOpaqueObjectCache { PerCameraCache{ } };
737 std::vector<PerCameraCache> sortedTransparentObjectCache { PerCameraCache{ } };
738 std::vector<PerCameraCache> sortedScreenTextureObjectCache { PerCameraCache{ } };
739 std::vector<PerCameraCache> sortedOpaqueDepthPrepassCache { PerCameraCache{ } };
740 std::vector<PerCameraCache> sortedDepthWriteCache { PerCameraCache{ } };
742 [[nodiscard]]
const QSSGRenderCameraDataList &getCachedCameraDatas();
743 void ensureCachedCameraDatas();
744 void updateSortedDepthObjectsListImp(
const QSSGRenderCamera &camera, size_t index);
746 static void prepareModelMaterials(RenderableNodeEntries &renderableModels,
bool cullUnrenderables);
747 static void prepareModelMaterials(
const RenderableNodeEntries::ConstIterator &begin,
748 const RenderableNodeEntries::ConstIterator &end);
751 QHash<QSSGShaderMapKey, QSSGRhiShaderPipelinePtr> shaderMap;
752 QHash<QSSGParticleShaderMapKey, QSSGRhiShaderPipelinePtr> particleShaderMap;
755 QByteArray generatedShaderString;
758 struct SavedRenderState
765 std::optional<SavedRenderState> savedRenderState;
769 QSSGShaderDefaultMaterialKeyProperties defaultMaterialShaderKeyProperties;
770 QSSGShaderParticleMaterialKeyProperties particleMaterialShaderKeyProperties;
771 QSSGFrameData frameData;
772 QSSGRhiGraphicsPipelineState ps;
773 QSSGShaderFeatures features;
774 QSSGRenderNodeVersionType version = 0;
775 bool particlesEnabled =
true;
776 bool hasDepthWriteObjects =
false;
777 bool zPrePassActive =
false;
781 bool renderablesModifiedByExtension =
false;
782 enum class DepthPrepassObject : quint8
789 using DepthPrepassObjectStateT = std::underlying_type_t<DepthPrepassObject>;
790 DepthPrepassObjectStateT depthPrepassObjectsState { DepthPrepassObjectStateT(DepthPrepassObject::None) };
791 QSSGRenderShadowMapPtr shadowMapManager;
792 QSSGRenderReflectionMapPtr reflectionMapManager;
793 QSSGUserRenderPassManagerPtr userRenderPassManager;
794 QSSGRenderMotionVectorMapPtr motionVectorMapManager;
795 QHash<
const QSSGModelContext *, QRhiTexture *> lightmapTextures;
796 QHash<
const QSSGModelContext *, QRhiTexture *> bonemapTextures;
797 QSSGRhiRenderableTexture renderResults[size_t(QSSGRenderResult::Key::RenderResultCount)] {};
798 QSSGOITRenderContext oitRenderContext;