336 MAX_TEMPORAL_AA_LEVELS = 2,
339 using InstanceTransforms = QSSGGlobalRenderNodeData::InstanceTransforms;
340 using ModelViewProjections = QSSGRenderModelData::ModelViewProjections;
342 using QSSGModelsView = QSSGDataView<QSSGRenderModel *>;
343 using QSSGParticlesView = QSSGDataView<QSSGRenderParticles *>;
344 using QSSGItem2DsView = QSSGDataView<QSSGRenderItem2D *>;
345 using QSSGCamerasView = QSSGDataView<QSSGRenderCamera *>;
346 using QSSGLightsView = QSSGDataView<QSSGRenderLight *>;
347 using QSSGReflectionProbesView = QSSGDataView<QSSGRenderReflectionProbe *>;
348 using QSSGNonCategorizedView = QSSGDataView<QSSGRenderNode *>;
350 using RenderableFilter = std::function<
bool(QSSGModelContext *)>;
352 QSSGLayerRenderData(QSSGRenderLayer &inLayer, QSSGRenderer &inRenderer);
353 ~QSSGLayerRenderData();
355 typedef QVector<QSSGModelContext *> TModelContextPtrList;
356 using RenderableNodeEntries = QVector<QSSGRenderableNodeEntry>;
357 using RenderableItem2DEntries = QVector<QSSGRenderItem2D *>;
359 void prepareImageForRender(QSSGRenderImage &inImage,
360 QSSGRenderableImage::Type inMapType,
361 QSSGRenderableImage *&ioFirstImage,
362 QSSGRenderableImage *&ioNextImage,
363 QSSGRenderableObjectFlags &ioFlags,
364 QSSGShaderDefaultMaterialKey &ioGeneratedShaderKey,
365 quint32 inImageIndex, QSSGRenderDefaultMaterial *inMaterial =
nullptr);
367 void setVertexInputPresence(
const QSSGRenderableObjectFlags &renderableFlags,
368 QSSGShaderDefaultMaterialKey &key);
370 static void prepareModelBoneTextures(
const QSSGRenderContextInterface &contextInterface,
371 const RenderableNodeEntries &renderableModels);
375 bool prepareModelsForRender(QSSGRenderContextInterface &ctx,
376 const RenderableNodeEntries &renderableModels,
377 QSSGLayerRenderPreparationResultFlags &ioFlags,
378 const QSSGRenderCameraList &allCameras,
379 const QSSGRenderCameraDataList &allCameraData,
380 TModelContextPtrList &modelContexts,
381 QSSGRenderableObjectList &opaqueObjects,
382 QSSGRenderableObjectList &transparentObjects,
383 QSSGRenderableObjectList &screenTextureObjects,
384 float lodThreshold = 0.0f);
385 bool prepareParticlesForRender(
const RenderableNodeEntries &renderableParticles,
const QSSGRenderCameraData &cameraData, QSSGLayerRenderPreparationResultFlags &ioFlags);
387 void prepareResourceLoaders();
389 void prepareForRender();
391 void prepareReflectionProbesForRender();
393 [[nodiscard]]
static qsizetype frustumCullingInline(
const QSSGClippingFrustum &clipFrustum, QSSGRenderableObjectList &renderables);
395 [[nodiscard]]
static qsizetype filterLayerMaskInline(quint32 layerMask, QSSGRenderableObjectList &renderables);
399 const QSSGRenderableObjectList &getSortedOpaqueRenderableObjects(
const QSSGRenderCamera &camera, size_t index = 0, quint32 layerMask = 0xFFFFFFFF);
401 const QSSGRenderableObjectList &getSortedTransparentRenderableObjects(
const QSSGRenderCamera &camera, size_t index = 0, quint32 layerMask = 0xFFFFFFFF);
402 const QSSGRenderableObjectList &getSortedScreenTextureRenderableObjects(
const QSSGRenderCamera &camera, size_t index = 0);
403 const QVector<QSSGBakedLightingModel> &getSortedBakedLightingModels();
404 const RenderableItem2DEntries &getRenderableItem2Ds();
405 const QSSGRenderableObjectList &getSortedRenderedDepthWriteObjects(
const QSSGRenderCamera &camera, size_t index = 0);
406 const QSSGRenderableObjectList &getSortedrenderedOpaqueDepthPrepassObjects(
const QSSGRenderCamera &camera, size_t index = 0);
407 void getShadowCastingObjects(
const QSSGRenderCamera &camera,
408 QSSGRenderableObjectList &outObjects,
409 QSSGBounds3 &outBoundsCasting,
410 QSSGBounds3 &outBoundsReceiving);
412 void resetForFrame();
414 QSSGFrameData &getFrameData();
416 ShadowMapPass shadowMapPass;
417 ReflectionMapPass reflectionMapPass;
418 ZPrePassPass zPrePassPass;
419 SSAOMapPass ssaoMapPass;
420 DepthMapPass depthMapPass;
421 DepthMapPass depthMapPassMS;
422 SkyMaterialPass skyMaterialPass;
423 ScreenMapPass screenMapPass;
424 ScreenReflectionPass reflectionPass;
425 Item2DPass item2DPass;
426 SkyboxPass skyboxPass;
427 SkyMaterialBackgroundPass skyMaterialBackgroundPass;
428 SkyboxCubeMapPass skyboxCubeMapPass;
429 UserRenderPass userRenderPasses;
430 static constexpr size_t USERPASSES = 3;
431 UserExtensionPass userPasses[USERPASSES];
432 OpaquePass opaquePass;
433 TransparentPass transparentPass;
434 OITRenderPass oitRenderPass;
435 OITCompositePass oitCompositePass;
436 InfiniteGridPass infiniteGridPass;
437 DebugDrawPass debugDrawPass;
438 NormalPass normalPass;
439 MotionVectorMapPass motionVectorMapPass;
442 QVarLengthArray<QSSGRenderPass *, 16> activePasses;
444 QSSGRenderLayer &layer;
445 QSSGRenderer *renderer =
nullptr;
449 using LayerNodes = std::vector<QSSGRenderNode *>;
450 QSSGGlobalRenderNodeData::LayerNodeView layerNodes;
453 RenderableNodeEntries renderableModels;
454 RenderableNodeEntries renderableParticles;
459 Q_DISABLE_COPY(NodeCollection)
461 NodeCollection() =
default;
463 QSSGModelsView modelsView;
464 QSSGParticlesView particlesView;
465 QSSGItem2DsView item2DsView;
466 QSSGCamerasView camerasView;
467 QSSGLightsView lightsView;
468 QSSGReflectionProbesView reflectionProbesView;
469 QSSGNonCategorizedView nonCategorizedView;
470 LayerNodes layerNodesCategorized;
472 NodeCollection nodeCollection;
474 QSSGModelsView &modelsView = nodeCollection.modelsView;
475 QSSGParticlesView &particlesView = nodeCollection.particlesView;
476 QSSGItem2DsView &item2DsView = nodeCollection.item2DsView;
477 QSSGCamerasView &camerasView = nodeCollection.camerasView;
478 QSSGLightsView &lightsView = nodeCollection.lightsView;
479 QSSGReflectionProbesView &reflectionProbesView = nodeCollection.reflectionProbesView;
480 QSSGNonCategorizedView &nonCategorizedView = nodeCollection.nonCategorizedView;
483 QSSGRenderCameraList renderedCameras;
484 QSSGShaderLightList globalLights;
486 QVector<QSSGBakedLightingModel> bakedLightingModels;
489 QVector<QSSGBakedLightingModel> renderedBakedLightingModels;
490 RenderableItem2DEntries renderedItem2Ds;
492 QSSGLayerRenderPreparationResult layerPrepResult;
493 std::optional<QSSGRenderCameraDataList> renderedCameraData;
495 TModelContextPtrList modelContexts;
497 QQsbCollection::EntryMap m_particleShaderEntries;
499 bool nonExplicitCameraWithLayerMaskWarningShown =
false;
500 bool tooManyLightsWarningShown =
false;
501 bool tooManyDirectionalLightsWarningShown =
false;
502 bool oitWarningUnsupportedShown =
false;
503 bool oitWarningInvalidBlendModeShown =
false;
504 bool orderIndependentTransparencyEnabled =
false;
505 bool disableMainPasses =
true;
507 std::unique_ptr<QSSGLightmapBaker> lightmapBaker =
nullptr;
509 QSSGShaderFeatures getShaderFeatures()
const {
return features; }
510 QSSGRhiGraphicsPipelineState getPipelineState()
const {
return ps; }
512 void initializeLightmapBaking(QSSGLightmapBaker::Context &ctx);
513 void maybeProcessLightmapBaking();
515 [[nodiscard]] QSSGRenderGraphObject *getCamera(QSSGCameraId id)
const;
516 [[nodiscard]] QSSGRenderCamera *activeCamera()
const {
return !renderedCameras.isEmpty() ? renderedCameras[0] :
nullptr; }
518 [[nodiscard]] QSSGRenderCameraData getCameraRenderData(
const QSSGRenderCamera *camera);
519 [[nodiscard]] QSSGRenderCameraData getCameraRenderData(
const QSSGRenderCamera *camera)
const;
521 void setLightmapTexture(
const QSSGModelContext &modelContext, QRhiTexture *lightmapTexture);
522 [[nodiscard]] QRhiTexture *getLightmapTexture(
const QSSGModelContext &modelContext)
const;
524 void setBonemapTexture(
const QSSGModelContext &modelContext, QRhiTexture *bonemapTexture);
525 [[nodiscard]] QRhiTexture *getBonemapTexture(
const QSSGModelContext &modelContext)
const;
527 [[nodiscard]] QSSGRenderContextInterface *contextInterface()
const;
529 [[nodiscard]]
bool isZPrePassActive()
const {
return zPrePassActive; }
530 void setZPrePassPrepResult(
bool res) { zPrePassActive = res; }
533 [[nodiscard]]
const QSSGShaderDefaultMaterialKeyProperties &getDefaultMaterialPropertyTable()
const
535 return defaultMaterialShaderKeyProperties;
537 [[nodiscard]]
const QSSGShaderParticleMaterialKeyProperties &getParticleMaterialPropertyTable()
const
539 return particleMaterialShaderKeyProperties;
542 struct GlobalRenderProperties
544 bool isYUpInFramebuffer =
true;
545 bool isYUpInNDC =
true;
546 bool isClipDepthZeroToOne =
true;
549 [[nodiscard]]
static GlobalRenderProperties globalRenderProperties(
const QSSGRenderContextInterface &ctx);
553 const QSSGRenderShadowMapPtr &requestShadowMapManager();
554 const QSSGRenderReflectionMapPtr &requestReflectionMapManager();
555 const QSSGRenderSkyMaterialManagerPtr &requestSkyMaterialManager();
556 const QSSGUserRenderPassManagerPtr &requestUserRenderPassManager();
557 const QSSGRenderMotionVectorMapPtr &requestMotionVectorMapManager();
558 const QSSGRenderShadowMapPtr &getShadowMapManager()
const {
return shadowMapManager; }
559 const QSSGRenderReflectionMapPtr &getReflectionMapManager()
const {
return reflectionMapManager; }
560 const QSSGRenderSkyMaterialManagerPtr &getSkyMaterialManager()
const {
return skyMaterialManager; }
561 const QSSGUserRenderPassManagerPtr &getUserRenderPassManager()
const {
return userRenderPassManager; }
562 const QSSGRenderMotionVectorMapPtr &getMotionvectorMapManager()
const {
return motionVectorMapManager; }
564 QSSGOITRenderContext &getOitRenderContext() {
return oitRenderContext; }
565 const QSSGOITRenderContext &getOitRenderContextConst()
const {
return oitRenderContext; }
567 static bool prepareInstancing(QSSGRhiContext *rhiCtx,
568 QSSGSubsetRenderable *renderable,
569 const QVector3D &cameraDirection,
570 const QVector3D &cameraPosition,
574 [[nodiscard]] QSSGRhiRenderableTexture *getRenderResult(QSSGRenderResult::Key id) {
return &renderResults[size_t(id)]; }
575 [[nodiscard]]
const QSSGRhiRenderableTexture *getRenderResult(QSSGRenderResult::Key id)
const {
return &renderResults[size_t(id)]; }
577 QSSGRenderImageTexture skyMaterialTexture;
578 void resolveLayerIblTexture(QSSGPassKey passKey);
580 [[nodiscard]]
static inline const std::unique_ptr<QSSGPerFrameAllocator> &perFrameAllocator(QSSGRenderContextInterface &ctx);
581 [[nodiscard]]
static inline QSSGLayerRenderData *getCurrent(
const QSSGRenderer &renderer) {
return renderer.m_currentLayer; }
582 void saveRenderState(
const QSSGRenderer &renderer);
583 void restoreRenderState(QSSGRenderer &renderer);
585 static void setTonemapFeatures(QSSGShaderFeatures &features, QSSGRenderLayer::TonemapMode tonemapMode)
587 features.set(QSSGShaderFeatures::Feature::LinearTonemapping,
588 tonemapMode == QSSGRenderLayer::TonemapMode::Linear);
589 features.set(QSSGShaderFeatures::Feature::AcesTonemapping,
590 tonemapMode == QSSGRenderLayer::TonemapMode::Aces);
591 features.set(QSSGShaderFeatures::Feature::HejlDawsonTonemapping,
592 tonemapMode == QSSGRenderLayer::TonemapMode::HejlDawson);
593 features.set(QSSGShaderFeatures::Feature::FilmicTonemapping,
594 tonemapMode == QSSGRenderLayer::TonemapMode::Filmic);
595 features.set(QSSGShaderFeatures::Feature::ForceIblExposure,
596 tonemapMode == QSSGRenderLayer::TonemapMode::Custom);
599 QSSGPrepContextId getOrCreateExtensionContext(
const QSSGRenderExtension &ext,
600 QSSGRenderCamera *camera =
nullptr,
604 QSSGRenderablesId createRenderables(QSSGPrepContextId prepId,
const QSSGNodeIdList &nodes, QSSGRenderHelpers::CreateFlags createFlags);
605 void setGlobalTransform(QSSGRenderablesId renderablesId,
const QSSGRenderModel &model,
const QMatrix4x4 &mvp);
606 QMatrix4x4 getGlobalTransform(QSSGPrepContextId prepId,
const QSSGRenderModel &model);
607 void setGlobalOpacity(QSSGRenderablesId renderablesId,
const QSSGRenderModel &model,
float opacity);
608 float getGlobalOpacity(QSSGPrepContextId prepId,
const QSSGRenderModel &model);
609 [[nodiscard]] QMatrix4x4 getModelMvps(QSSGPrepContextId prepId,
const QSSGRenderModel &model)
const;
610 void setModelMaterials(QSSGRenderablesId renderablesId,
const QSSGRenderModel &model,
const QList<QSSGResourceId> &materials);
611 void setModelMaterials(
const QSSGRenderablesId renderablesId,
const QList<QSSGResourceId> &materials);
612 [[nodiscard]] QSSGPrepResultId prepareModelsForRender(QSSGRenderContextInterface &contextInterface,
613 QSSGPrepContextId prepId,
614 QSSGRenderablesId renderablesId,
618 [[nodiscard]] QMatrix4x4 getGlobalTransform(QSSGRenderNodeHandle h,
const QMatrix4x4 &defaultValue)
const
620 return nodeData->getGlobalTransform(h, defaultValue);
622 [[nodiscard]] QMatrix4x4 getGlobalTransform(QSSGRenderNodeHandle h)
const
624 return nodeData->getGlobalTransform(h, QMatrix4x4());
626 [[nodiscard]] QMatrix4x4 getGlobalTransform(
const QSSGRenderNode &node)
const
628 return nodeData->getGlobalTransform(node.h, node.localTransform);
630 [[nodiscard]] QMatrix3x3 getNormalMatrix(QSSGRenderNodeHandle h)
const
632 return modelData->getNormalMatrix(h, QMatrix3x3(Qt::Uninitialized));
634 [[nodiscard]] QMatrix3x3 getNormalMatrix(
const QSSGRenderModel &model)
const
636 return modelData->getNormalMatrix(model);
638 [[nodiscard]] ModelViewProjections getModelMvps(QSSGRenderNodeHandle h)
const
640 return modelData->getModelViewProjection(h);
642 [[nodiscard]] ModelViewProjections getModelMvps(
const QSSGRenderModel &model)
const
644 return modelData->getModelViewProjection(model);
646 [[nodiscard]] InstanceTransforms getInstanceTransforms(QSSGRenderNodeHandle h)
const
648 return nodeData->getInstanceTransforms(h);
650 [[nodiscard]] InstanceTransforms getInstanceTransforms(
const QSSGRenderNode &node)
const
652 return nodeData->getInstanceTransforms(node.h);
654 [[nodiscard]]
float getGlobalOpacity(QSSGRenderNodeHandle h,
float defaultValue = 1.0f)
const
656 return nodeData->getGlobalOpacity(h, defaultValue);
658 [[nodiscard]]
float getGlobalOpacity(
const QSSGRenderNode &node)
const
660 return nodeData->getGlobalOpacity(node.h);
664 [[nodiscard]] QSSGRenderItem2DData::Item2DRenderer getItem2DRenderer(
const QSSGRenderItem2D &item)
const
666 return item2DData->getItem2DRenderer(item);
669 [[nodiscard]] ModelViewProjections getItem2DMvps(QSSGRenderNodeHandle h)
const
671 return item2DData->getModelViewProjection(h);
674 [[nodiscard]] ModelViewProjections getItem2DMvps(
const QSSGRenderItem2D &item)
const
676 return item2DData->getModelViewProjection(item);
681 void prepareRenderables(QSSGRenderContextInterface &ctx,
682 QSSGPrepResultId prepId,
683 QRhiRenderPassDescriptor *renderPassDescriptor,
684 const QSSGRhiGraphicsPipelineState &ps,
685 QSSGRenderablesFilters filter);
686 void renderRenderables(QSSGRenderContextInterface &ctx,
687 QSSGPrepResultId prepId);
689 static bool calculateGlobalVariables(QSSGRenderNode &node,
690 std::vector<QMatrix4x4> &globalTransforms,
691 std::vector<
float> &globalOpacities);
693 QSSGRenderCameraData getCameraDataImpl(
const QSSGRenderCamera *camera)
const;
695 static QSSGNodeIdList filter(
const QSSGGlobalRenderNodeData::LayerNodeView &layerNodes,
699 [[nodiscard]]
static QSSGLayerRenderData *getCurrent(
const QSSGFrameData &data) {
return data.getCurrent(); }
701 QSSGDefaultMaterialPreparationResult prepareDefaultMaterialForRender(QSSGRenderDefaultMaterial &inMaterial,
702 QSSGRenderableObjectFlags &inExistingFlags,
705 bool anyLightHasShadows,
706 QSSGLayerRenderPreparationResultFlags &ioFlags);
708 QSSGDefaultMaterialPreparationResult prepareCustomMaterialForRender(QSSGRenderCustomMaterial &inMaterial,
709 QSSGRenderableObjectFlags &inExistingFlags,
710 float inOpacity,
bool alreadyDirty,
712 bool anyLightHasShadows,
713 QSSGLayerRenderPreparationResultFlags &ioFlags);
715 static void categorizeAndFilterNodes(
const QSSGGlobalRenderNodeData::LayerNodeView &layerNodes,
716 QSSGLayerRenderData::NodeCollection &nodeCollection,
718 void updateFilteredLayerNodes(quint32 layerMask);
720 friend class QSSGRenderer;
721 friend class QSSGRendererPrivate;
722 friend class QSSGFrameData;
723 friend class QSSGModelHelpers;
724 friend class QSSGRenderHelpers;
725 friend class QSSGParticleRenderer;
727 class ExtensionContext
730 explicit ExtensionContext() =
default;
731 explicit ExtensionContext(
const QSSGRenderExtension &ownerExt, QSSGRenderCamera *cam, size_t idx, quint32 slot)
732 : owner(&ownerExt), camera(cam), ps{}, filter{0}, index(idx), slot(slot)
734 const QSSGRenderExtension *owner =
nullptr;
735 QSSGRenderCamera *camera =
nullptr;
736 QSSGRhiGraphicsPipelineState ps[3] {};
737 QSSGRenderablesFilters filter { 0 };
742 std::vector<ExtensionContext> extContexts { ExtensionContext{ } };
743 std::vector<RenderableNodeEntries> renderableModelStore { RenderableNodeEntries{ } };
744 std::vector<TModelContextPtrList> modelContextStore { TModelContextPtrList{ }};
745 std::vector<QSSGRenderableObjectList> renderableObjectStore { QSSGRenderableObjectList{ }};
746 std::vector<QSSGRenderableObjectList> opaqueObjectStore { QSSGRenderableObjectList{ }};
747 std::vector<QSSGRenderableObjectList> transparentObjectStore { QSSGRenderableObjectList{ }};
748 std::vector<QSSGRenderableObjectList> screenTextureObjectStore { QSSGRenderableObjectList{ }};
750 std::shared_ptr<QSSGGlobalRenderNodeData> nodeData;
751 std::unique_ptr<QSSGRenderModelData> modelData;
752 std::unique_ptr<QSSGRenderItem2DData> item2DData;
755 using CameraKey = std::pair<
const QSSGRenderCamera*, uint32_t>;
757 struct CameraKeyHash {
758 std::size_t operator()(
const CameraKey& k)
const noexcept {
760 return std::hash<
const QSSGRenderCamera*>()(k.first) ^
761 (std::hash<uint32_t>()(k.second) << 1);
766 bool operator()(
const CameraKey& a,
const CameraKey& b)
const noexcept {
767 return a.first == b.first && a.second == b.second;
771 using PerCameraCache = std::unordered_map<CameraKey, QSSGRenderableObjectList, CameraKeyHash, CameraKeyEq>;
772 std::vector<PerCameraCache> sortedOpaqueObjectCache { PerCameraCache{ } };
773 std::vector<PerCameraCache> sortedTransparentObjectCache { PerCameraCache{ } };
774 std::vector<PerCameraCache> sortedScreenTextureObjectCache { PerCameraCache{ } };
775 std::vector<PerCameraCache> sortedOpaqueDepthPrepassCache { PerCameraCache{ } };
776 std::vector<PerCameraCache> sortedDepthWriteCache { PerCameraCache{ } };
778 [[nodiscard]]
const QSSGRenderCameraDataList &getCachedCameraDatas();
779 void ensureCachedCameraDatas();
780 void updateSortedDepthObjectsListImp(
const QSSGRenderCamera &camera, size_t index);
782 static void prepareModelMaterials(RenderableNodeEntries &renderableModels,
bool cullUnrenderables);
783 static void prepareModelMaterials(
const RenderableNodeEntries::ConstIterator &begin,
784 const RenderableNodeEntries::ConstIterator &end);
787 QHash<QSSGShaderMapKey, QSSGRhiShaderPipelinePtr> shaderMap;
788 QHash<QSSGParticleShaderMapKey, QSSGRhiShaderPipelinePtr> particleShaderMap;
791 QByteArray generatedShaderString;
794 struct SavedRenderState
804 QRhiRenderPassDescriptor *mainRenderPassDescriptor =
nullptr;
805 QRhiRenderTarget *renderTarget =
nullptr;
806 QRhiCommandBuffer *commandBuffer =
nullptr;
807 int mainPassSampleCount = 1;
808 int mainPassViewCount = 1;
811 std::optional<SavedRenderState> savedRenderState;
815 QSSGShaderDefaultMaterialKeyProperties defaultMaterialShaderKeyProperties;
816 QSSGShaderParticleMaterialKeyProperties particleMaterialShaderKeyProperties;
817 QSSGFrameData frameData;
818 QSSGRhiGraphicsPipelineState ps;
819 QSSGShaderFeatures features;
820 QSSGRenderNodeVersionType version = 0;
821 QSSGRenderNodeVersionType stateGeneration = 0;
822 bool particlesEnabled =
true;
823 bool hasDepthWriteObjects =
false;
824 bool zPrePassActive =
false;
828 bool renderablesModifiedByExtension =
false;
829 enum class DepthPrepassObject : quint8
836 using DepthPrepassObjectStateT = std::underlying_type_t<DepthPrepassObject>;
837 DepthPrepassObjectStateT depthPrepassObjectsState { DepthPrepassObjectStateT(DepthPrepassObject::None) };
838 QSSGRenderShadowMapPtr shadowMapManager;
839 QSSGRenderReflectionMapPtr reflectionMapManager;
840 QSSGRenderSkyMaterialManagerPtr skyMaterialManager;
841 QSSGUserRenderPassManagerPtr userRenderPassManager;
842 QSSGRenderMotionVectorMapPtr motionVectorMapManager;
843 QHash<
const QSSGModelContext *, QRhiTexture *> lightmapTextures;
844 QHash<
const QSSGModelContext *, QRhiTexture *> bonemapTextures;
845 QSSGRhiRenderableTexture renderResults[size_t(QSSGRenderResult::Key::RenderResultCount)] {};
846 QSSGOITRenderContext oitRenderContext;