diff --git a/src/quick3d/qquick3ddefaultmaterial.cpp b/src/quick3d/qquick3ddefaultmaterial.cpp
index bdda20f2e7cef2ecd7e196a8966b244ee00b0cee..62018320ce65bf4318f835b45d21644f59c04c13 100644
--- a/src/quick3d/qquick3ddefaultmaterial.cpp
+++ b/src/quick3d/qquick3ddefaultmaterial.cpp
@@ -1000,19 +1000,19 @@ void QQuick3DDefaultMaterial::itemChange(QQuick3DObject::ItemChange change, cons
         updateSceneManager(value.sceneManager);
 }
 
-void QQuick3DDefaultMaterial::updateSceneManager(const QSharedPointer<QQuick3DSceneManager> &sceneManager)
+void QQuick3DDefaultMaterial::updateSceneManager(QQuick3DSceneManager *sceneManager)
 {
     // Check all the resource value's windows, and update as necessary
     if (sceneManager) {
-        QQuick3DObjectPrivate::refSceneManager(m_diffuseMap, sceneManager);
-        QQuick3DObjectPrivate::refSceneManager(m_emissiveMap, sceneManager);
-        QQuick3DObjectPrivate::refSceneManager(m_specularReflectionMap, sceneManager);
-        QQuick3DObjectPrivate::refSceneManager(m_specularMap, sceneManager);
-        QQuick3DObjectPrivate::refSceneManager(m_roughnessMap, sceneManager);
-        QQuick3DObjectPrivate::refSceneManager(m_opacityMap, sceneManager);
-        QQuick3DObjectPrivate::refSceneManager(m_bumpMap, sceneManager);
-        QQuick3DObjectPrivate::refSceneManager(m_normalMap, sceneManager);
-        QQuick3DObjectPrivate::refSceneManager(m_translucencyMap, sceneManager);
+        QQuick3DObjectPrivate::refSceneManager(m_diffuseMap, *sceneManager);
+        QQuick3DObjectPrivate::refSceneManager(m_emissiveMap, *sceneManager);
+        QQuick3DObjectPrivate::refSceneManager(m_specularReflectionMap, *sceneManager);
+        QQuick3DObjectPrivate::refSceneManager(m_specularMap, *sceneManager);
+        QQuick3DObjectPrivate::refSceneManager(m_roughnessMap, *sceneManager);
+        QQuick3DObjectPrivate::refSceneManager(m_opacityMap, *sceneManager);
+        QQuick3DObjectPrivate::refSceneManager(m_bumpMap, *sceneManager);
+        QQuick3DObjectPrivate::refSceneManager(m_normalMap, *sceneManager);
+        QQuick3DObjectPrivate::refSceneManager(m_translucencyMap, *sceneManager);
     } else {
         QQuick3DObjectPrivate::derefSceneManager(m_diffuseMap);
         QQuick3DObjectPrivate::derefSceneManager(m_emissiveMap);
diff --git a/src/quick3d/qquick3ddefaultmaterial_p.h b/src/quick3d/qquick3ddefaultmaterial_p.h
index 0d8cd056a459d96fb9495a9032139edcd44c925f..f3617e40a56e5787349088d536127d7669f1408e 100644
--- a/src/quick3d/qquick3ddefaultmaterial_p.h
+++ b/src/quick3d/qquick3ddefaultmaterial_p.h
@@ -232,7 +232,7 @@ private:
         LineWidthDirty = 0x00000800
     };
 
-    void updateSceneManager(const QSharedPointer<QQuick3DSceneManager> &sceneManager);
+    void updateSceneManager(QQuick3DSceneManager *sceneManager);
     Lighting m_lighting = FragmentLighting;
     BlendMode m_blendMode = SourceOver;
     QColor m_diffuseColor;
diff --git a/src/quick3d/qquick3deffect.cpp b/src/quick3d/qquick3deffect.cpp
index b3a942d139ef62ee757ad0d2ec4fc9ed04d4c1e5..829432e23cdc4db448be7e193e10b724821837b8 100644
--- a/src/quick3d/qquick3deffect.cpp
+++ b/src/quick3d/qquick3deffect.cpp
@@ -1040,11 +1040,11 @@ void QQuick3DEffect::markDirty(QQuick3DEffect::Dirty type)
     }
 }
 
-void QQuick3DEffect::updateSceneManager(const QSharedPointer<QQuick3DSceneManager> &sceneManager)
+void QQuick3DEffect::updateSceneManager(QQuick3DSceneManager *sceneManager)
 {
     if (sceneManager) {
         for (auto it : m_dynamicTextureMaps)
-            QQuick3DObjectPrivate::refSceneManager(it, sceneManager);
+            QQuick3DObjectPrivate::refSceneManager(it, *sceneManager);
     } else {
         for (auto it : m_dynamicTextureMaps)
             QQuick3DObjectPrivate::derefSceneManager(it);
diff --git a/src/quick3d/qquick3deffect_p.h b/src/quick3d/qquick3deffect_p.h
index f35c1da1786b2ae3a7e65f049cc9bd53e6970e6b..d81da180aac0ca22ab58bf2bfe6d89636d436aa1 100644
--- a/src/quick3d/qquick3deffect_p.h
+++ b/src/quick3d/qquick3deffect_p.h
@@ -91,7 +91,7 @@ private:
 
     quint32 m_dirtyAttributes = 0xffffffff;
 
-    void updateSceneManager(const QSharedPointer<QQuick3DSceneManager> &sceneManager);
+    void updateSceneManager(QQuick3DSceneManager *sceneManager);
 
     friend class QQuick3DSceneRenderer;
     QVector<QQuick3DShaderUtilsRenderPass *> m_passes;
diff --git a/src/quick3d/qquick3dmaterial.cpp b/src/quick3d/qquick3dmaterial.cpp
index 332522485840c166b90bc9fc5bbda0d7104c63c3..7ac2f5ae0e828fb4c0bd383605cf767d09ff3637 100644
--- a/src/quick3d/qquick3dmaterial.cpp
+++ b/src/quick3d/qquick3dmaterial.cpp
@@ -287,15 +287,15 @@ void QQuick3DMaterial::setDynamicTextureMap(QQuick3DTexture *textureMap, const Q
     update();
 }
 
-void QQuick3DMaterial::updateSceneManager(const QSharedPointer<QQuick3DSceneManager> &sceneManager)
+void QQuick3DMaterial::updateSceneManager(QQuick3DSceneManager *sceneManager)
 {
     if (sceneManager) {
-        QQuick3DObjectPrivate::refSceneManager(m_lightmapIndirect, sceneManager);
-        QQuick3DObjectPrivate::refSceneManager(m_lightmapRadiosity, sceneManager);
-        QQuick3DObjectPrivate::refSceneManager(m_lightmapShadow, sceneManager);
-        QQuick3DObjectPrivate::refSceneManager(m_iblProbe, sceneManager);
+        QQuick3DObjectPrivate::refSceneManager(m_lightmapIndirect, *sceneManager);
+        QQuick3DObjectPrivate::refSceneManager(m_lightmapRadiosity, *sceneManager);
+        QQuick3DObjectPrivate::refSceneManager(m_lightmapShadow, *sceneManager);
+        QQuick3DObjectPrivate::refSceneManager(m_iblProbe, *sceneManager);
         for (auto it : m_dynamicTextureMaps)
-            QQuick3DObjectPrivate::refSceneManager(it, sceneManager);
+            QQuick3DObjectPrivate::refSceneManager(it, *sceneManager);
     } else {
        QQuick3DObjectPrivate::derefSceneManager(m_lightmapIndirect);
        QQuick3DObjectPrivate::derefSceneManager(m_lightmapRadiosity);
diff --git a/src/quick3d/qquick3dmaterial_p.h b/src/quick3d/qquick3dmaterial_p.h
index 68047bc24f0c44e3ef853b00d7a22b4532fe5362..4b499dd46db921e63336fb3126abda326a1fd5fa 100644
--- a/src/quick3d/qquick3dmaterial_p.h
+++ b/src/quick3d/qquick3dmaterial_p.h
@@ -110,7 +110,7 @@ protected:
 public:
     void setDynamicTextureMap(QQuick3DTexture *textureMap, const QByteArray &name);
 private:
-    void updateSceneManager(const QSharedPointer<QQuick3DSceneManager> &sceneManager);
+    void updateSceneManager(QQuick3DSceneManager *sceneManager);
     QQuick3DTexture *m_lightmapIndirect = nullptr;
     QQuick3DTexture *m_lightmapRadiosity = nullptr;
     QQuick3DTexture *m_lightmapShadow = nullptr;
diff --git a/src/quick3d/qquick3dmodel.cpp b/src/quick3d/qquick3dmodel.cpp
index cfb2d9049df72981458cce8b8f6f823cfe6207b1..f5e75c87d6f77e6cae49383c5da0a66fb48ed2c1 100644
--- a/src/quick3d/qquick3dmodel.cpp
+++ b/src/quick3d/qquick3dmodel.cpp
@@ -501,16 +501,16 @@ void QQuick3DModel::markDirty(QQuick3DModel::QSSGModelDirtyType type)
     }
 }
 
-void QQuick3DModel::updateSceneManager(const QSharedPointer<QQuick3DSceneManager> &sceneManager)
+void QQuick3DModel::updateSceneManager(QQuick3DSceneManager *sceneManager)
 {
     if (sceneManager) {
         sceneManager->dirtyBoundingBoxList.append(this);
-        QQuick3DObjectPrivate::refSceneManager(m_skeleton, sceneManager);
-        QQuick3DObjectPrivate::refSceneManager(m_geometry, sceneManager);
+        QQuick3DObjectPrivate::refSceneManager(m_skeleton, *sceneManager);
+        QQuick3DObjectPrivate::refSceneManager(m_geometry, *sceneManager);
         for (Material &mat : m_materials) {
             if (!mat.material->parentItem() && !QQuick3DObjectPrivate::get(mat.material)->sceneManager) {
                 if (!mat.refed) {
-                    QQuick3DObjectPrivate::refSceneManager(mat.material, sceneManager);
+                    QQuick3DObjectPrivate::refSceneManager(mat.material, *sceneManager);
                     mat.refed = true;
                 }
             }
@@ -557,7 +557,7 @@ void QQuick3DModel::qmlAppendMaterial(QQmlListProperty<QQuick3DMaterial> *list,
         } else { // If no valid parent was found, make sure the material refs our scene manager
             const auto &sceneManager = QQuick3DObjectPrivate::get(self)->sceneManager;
             if (sceneManager) {
-                QQuick3DObjectPrivate::get(material)->refSceneManager(sceneManager);
+                QQuick3DObjectPrivate::get(material)->refSceneManager(*sceneManager);
                 // Have to keep track if we called refSceneManager because we
                 // can end up in double deref attempts when a model is going
                 // away, due to updateSceneManager() being called on
diff --git a/src/quick3d/qquick3dmodel_p.h b/src/quick3d/qquick3dmodel_p.h
index 75b2a9f4dce126c455dfeeac3f8c3a5f6c395f61..7fb7c9af3c1bd3f4f4b23b36c3b22c9996ae9cf3 100644
--- a/src/quick3d/qquick3dmodel_p.h
+++ b/src/quick3d/qquick3dmodel_p.h
@@ -165,7 +165,7 @@ private:
 
     quint32 m_dirtyAttributes = 0xffffffff; // all dirty by default
     void markDirty(QSSGModelDirtyType type);
-    void updateSceneManager(const QSharedPointer<QQuick3DSceneManager> &sceneManager);
+    void updateSceneManager(QQuick3DSceneManager *sceneManager);
 
     static void qmlAppendMaterial(QQmlListProperty<QQuick3DMaterial> *list, QQuick3DMaterial *material);
     static QQuick3DMaterial *qmlMaterialAt(QQmlListProperty<QQuick3DMaterial> *list, int index);
diff --git a/src/quick3d/qquick3dobject.cpp b/src/quick3d/qquick3dobject.cpp
index 0eb571b4f5720df9af8cceac72463d1df471d358..5158d175814f1077324a3405c02e3b1f45b1e750 100644
--- a/src/quick3d/qquick3dobject.cpp
+++ b/src/quick3d/qquick3dobject.cpp
@@ -104,13 +104,6 @@ QQuick3DObject::QQuick3DObject(QQuick3DObject *parent)
 QQuick3DObject::~QQuick3DObject()
 {
     Q_D(QQuick3DObject);
-    if (d->windowRefCount > 1)
-        d->windowRefCount = 1; // Make sure window is set to null in next call to derefWindow().
-    if (d->parentItem)
-        setParentItem(nullptr);
-    else if (d->sceneManager)
-        QQuick3DObjectPrivate::derefSceneManager(this);
-
     // XXX todo - optimize
     while (!d->childItems.isEmpty())
         d->childItems.constFirst()->setParentItem(nullptr);
@@ -119,6 +112,17 @@ QQuick3DObject::~QQuick3DObject()
     d->_stateGroup = nullptr;
     delete d->contentItem2d;
     d->contentItem2d = nullptr;
+
+    if (d->parentItem)
+        setParentItem(nullptr);
+
+    if (d->sceneRefCount > 1) {
+        qWarning("Unexpected ref. count %d\n", d->sceneRefCount);
+        d->sceneRefCount = 1; // Make sure the scene is set to null in next call to derefSceneManager().
+    }
+
+    if (!d->parentItem && d->sceneManager)
+        QQuick3DObjectPrivate::derefSceneManager(this);
 }
 
 void QQuick3DObject::update()
@@ -192,7 +196,7 @@ void QQuick3DObject::setParentItem(QQuick3DObject *parentItem)
             QQuick3DObjectPrivate::derefSceneManager(this);
         d->parentItem = parentItem;
         if (parentSceneManager)
-            QQuick3DObjectPrivate::refSceneManager(this, parentSceneManager);
+            QQuick3DObjectPrivate::refSceneManager(this, *parentSceneManager);
     }
 
     d->dirty(QQuick3DObjectPrivate::ParentChanged);
@@ -279,14 +283,14 @@ void QQuick3DObject::preSync()
 
 void QQuick3DObjectPrivate::updatePropertyListener(QQuick3DObject *newO,
                                                    QQuick3DObject *oldO,
-                                                   const QSharedPointer<QQuick3DSceneManager> &window,
+                                                   QQuick3DSceneManager *sceneManager,
                                                    const QByteArray &propertyKey,
                                                    ConnectionMap &connections,
                                                    const std::function<void(QQuick3DObject *)> &callFn)
 {
     // disconnect previous destruction listener
     if (oldO) {
-        if (window)
+        if (sceneManager)
             QQuick3DObjectPrivate::derefSceneManager(oldO);
 
         auto connection = connections.find(propertyKey);
@@ -298,8 +302,8 @@ void QQuick3DObjectPrivate::updatePropertyListener(QQuick3DObject *newO,
 
     // listen for new map's destruction
     if (newO) {
-        if (window)
-            QQuick3DObjectPrivate::refSceneManager(newO, window);
+        if (sceneManager)
+            QQuick3DObjectPrivate::refSceneManager(newO, *sceneManager);
         auto connection = QObject::connect(newO, &QObject::destroyed, [callFn](){
             callFn(nullptr);
         });
@@ -313,7 +317,7 @@ QQuick3DObjectPrivate::QQuick3DObjectPrivate(QQuick3DObjectPrivate::Type t)
     , nextDirtyItem(nullptr)
     , prevDirtyItem(nullptr)
     , sceneManager(nullptr)
-    , windowRefCount(0)
+    , sceneRefCount(0)
     , parentItem(nullptr)
     , sortedChildItems(&childItems)
     , subFocusItem(nullptr)
@@ -978,28 +982,27 @@ void QQuick3DObjectPrivate::markSortedChildrenDirty(QQuick3DObject *child)
     Q_UNUSED(child);
 }
 
-void QQuick3DObjectPrivate::refSceneManager(const QSharedPointer<QQuick3DSceneManager> &c)
+void QQuick3DObjectPrivate::refSceneManager(QQuick3DSceneManager &c)
 {
-    // An item needs a window if it is referenced by another item which has a window.
+    // An item needs a scene manager if it is referenced by another item which has a scene manager.
     // Typically the item is referenced by a parent, but can also be referenced by a
-    // ShaderEffect or ShaderEffectSource. 'windowRefCount' counts how many items with
-    // a window is referencing this item. When the reference count goes from zero to one,
-    // or one to zero, the window of this item is updated and propagated to the children.
-    // As long as the reference count stays above zero, the window is unchanged.
-    // refWindow() increments the reference count.
-    // derefWindow() decrements the reference count.
+    // ShaderEffect or ShaderEffectSource. 'sceneRefCount' counts how many items with
+    // a scene manager is referencing this item. When the reference count goes from zero to one,
+    // or one to zero, the scene manager of this item is updated and propagated to the children.
+    // As long as the reference count stays above zero, the scene manager is unchanged.
+    // refSceneManager() increments the reference count.
+    // derefSceneManager() decrements the reference count.
 
     Q_Q(QQuick3DObject);
-    Q_ASSERT((sceneManager != nullptr) == (windowRefCount > 0));
-    Q_ASSERT(c);
-    if (++windowRefCount > 1) {
-        if (c != sceneManager)
+    Q_ASSERT((sceneManager != nullptr) == (sceneRefCount > 0));
+    if (++sceneRefCount > 1) {
+        if (&c != sceneManager)
             qWarning("QSSGObject: Cannot use same item on different windows at the same time.");
         return; // Window already set.
     }
 
     Q_ASSERT(sceneManager == nullptr);
-    sceneManager = c;
+    sceneManager = &c;
 
     //    if (polishScheduled)
     //        QSSGWindowPrivate::get(window)->itemsToPolish.append(q);
@@ -1014,7 +1017,7 @@ void QQuick3DObjectPrivate::refSceneManager(const QSharedPointer<QQuick3DSceneMa
 
     dirty(Window);
 
-    itemChange(QQuick3DObject::ItemSceneChange, c);
+    itemChange(QQuick3DObject::ItemSceneChange, &c);
 }
 
 void QQuick3DObjectPrivate::derefSceneManager()
@@ -1024,8 +1027,8 @@ void QQuick3DObjectPrivate::derefSceneManager()
     if (!sceneManager)
         return; // This can happen when destroying recursive shader effect sources.
 
-    if (--windowRefCount > 0)
-        return; // There are still other references, so don't set window to null yet.
+    if (--sceneRefCount > 0)
+        return; // There are still other references, so don't set the scene manager to null yet.
 
     removeFromDirtyList();
     if (sceneManager) {
@@ -1038,8 +1041,6 @@ void QQuick3DObjectPrivate::derefSceneManager()
     if (!parentItem)
         sceneManager->parentlessItems.remove(q);
 
-    sceneManager.reset();
-
     spatialNode = nullptr;
 
     for (int ii = 0; ii < childItems.count(); ++ii) {
@@ -1047,6 +1048,8 @@ void QQuick3DObjectPrivate::derefSceneManager()
         QQuick3DObjectPrivate::derefSceneManager(child);
     }
 
+    sceneManager = nullptr;
+
     dirty(Window);
 
     itemChange(QQuick3DObject::ItemSceneChange, sceneManager);
diff --git a/src/quick3d/qquick3dobject.h b/src/quick3d/qquick3dobject.h
index c19b3d5e96b0031a056f4bd00232cd6abfc04f36..759d43627fb42922d8b8318c1a8258ede7cfce54 100644
--- a/src/quick3d/qquick3dobject.h
+++ b/src/quick3d/qquick3dobject.h
@@ -82,19 +82,16 @@ public:
         ItemEnabledHasChanged // value.boolValue
     };
 
-    struct ItemChangeData {
+    union ItemChangeData {
         ItemChangeData(QQuick3DObject *v) : item(v) {}
-        ItemChangeData(const QSharedPointer<QQuick3DSceneManager> &v) : sceneManager(v) {}
+        ItemChangeData(QQuick3DSceneManager *v) : sceneManager(v) {}
         ItemChangeData(qreal v) : realValue(v) {}
         ItemChangeData(bool v) : boolValue(v) {}
-        ~ItemChangeData() {}
-
-        QSharedPointer<QQuick3DSceneManager> sceneManager;
-        union {
-            QQuick3DObject *item;
-            qreal realValue;
-            bool boolValue;
-        };
+
+        QQuick3DObject *item;
+        QQuick3DSceneManager *sceneManager;
+        qreal realValue;
+        bool boolValue;
     };
 
     explicit QQuick3DObject(QQuick3DObject *parent = nullptr);
diff --git a/src/quick3d/qquick3dobject_p.h b/src/quick3d/qquick3dobject_p.h
index 542a5708c25e703a2d3a9c10a28f6df14e4b929c..d86e9afc638e2b80381aa4864a1a5117b7d81761 100644
--- a/src/quick3d/qquick3dobject_p.h
+++ b/src/quick3d/qquick3dobject_p.h
@@ -94,7 +94,7 @@ public:
 
     static void updatePropertyListener(QQuick3DObject *newO,
                                        QQuick3DObject *oldO,
-                                       const QSharedPointer<QQuick3DSceneManager> &window,
+                                       QQuick3DSceneManager *sceneManager,
                                        const QByteArray &propertyKey,
                                        ConnectionMap &connections,
                                        const std::function<void(QQuick3DObject *o)> &callFn);
@@ -233,8 +233,8 @@ public:
 
     void setCulled(bool);
 
-    QSharedPointer<QQuick3DSceneManager> sceneManager;
-    int windowRefCount;
+    QQuick3DSceneManager *sceneManager = nullptr;
+    int sceneRefCount;
 
     QQuick3DObject *parentItem;
 
@@ -247,10 +247,10 @@ public:
 
     void markSortedChildrenDirty(QQuick3DObject *child);
 
-    void refSceneManager(const QSharedPointer<QQuick3DSceneManager> &);
+    void refSceneManager(QQuick3DSceneManager &);
     void derefSceneManager();
 
-    static void refSceneManager(QQuick3DObject *obj,const QSharedPointer<QQuick3DSceneManager> &mgr)
+    static void refSceneManager(QQuick3DObject *obj, QQuick3DSceneManager &mgr)
     {
         if (obj)
             QQuick3DObjectPrivate::get(obj)->refSceneManager(mgr);
diff --git a/src/quick3d/qquick3dprincipledmaterial.cpp b/src/quick3d/qquick3dprincipledmaterial.cpp
index a75cbfc31ffe87382552d652ca74efc78eb4bd87..bf4bea46d6bcc95fdd543233066211b1813852d2 100644
--- a/src/quick3d/qquick3dprincipledmaterial.cpp
+++ b/src/quick3d/qquick3dprincipledmaterial.cpp
@@ -1007,19 +1007,19 @@ void QQuick3DPrincipledMaterial::itemChange(QQuick3DObject::ItemChange change, c
         updateSceneManager(value.sceneManager);
 }
 
-void QQuick3DPrincipledMaterial::updateSceneManager(const QSharedPointer<QQuick3DSceneManager> &window)
+void QQuick3DPrincipledMaterial::updateSceneManager(QQuick3DSceneManager *sceneManager)
 {
-    // Check all the resource value's windows, and update as necessary
-    if (window) {
-        QQuick3DObjectPrivate::refSceneManager(m_baseColorMap, window);
-        QQuick3DObjectPrivate::refSceneManager(m_emissiveMap, window);
-        QQuick3DObjectPrivate::refSceneManager(m_specularReflectionMap, window);
-        QQuick3DObjectPrivate::refSceneManager(m_specularMap, window);
-        QQuick3DObjectPrivate::refSceneManager(m_roughnessMap, window);
-        QQuick3DObjectPrivate::refSceneManager(m_opacityMap, window);
-        QQuick3DObjectPrivate::refSceneManager(m_normalMap, window);
-        QQuick3DObjectPrivate::refSceneManager(m_metalnessMap, window);
-        QQuick3DObjectPrivate::refSceneManager(m_occlusionMap, window);
+    // Check all the resource value's scene manager, and update as necessary.
+    if (sceneManager) {
+        QQuick3DObjectPrivate::refSceneManager(m_baseColorMap, *sceneManager);
+        QQuick3DObjectPrivate::refSceneManager(m_emissiveMap, *sceneManager);
+        QQuick3DObjectPrivate::refSceneManager(m_specularReflectionMap, *sceneManager);
+        QQuick3DObjectPrivate::refSceneManager(m_specularMap, *sceneManager);
+        QQuick3DObjectPrivate::refSceneManager(m_roughnessMap, *sceneManager);
+        QQuick3DObjectPrivate::refSceneManager(m_opacityMap, *sceneManager);
+        QQuick3DObjectPrivate::refSceneManager(m_normalMap, *sceneManager);
+        QQuick3DObjectPrivate::refSceneManager(m_metalnessMap, *sceneManager);
+        QQuick3DObjectPrivate::refSceneManager(m_occlusionMap, *sceneManager);
     } else {
         QQuick3DObjectPrivate::derefSceneManager(m_baseColorMap);
         QQuick3DObjectPrivate::derefSceneManager(m_emissiveMap);
diff --git a/src/quick3d/qquick3dprincipledmaterial_p.h b/src/quick3d/qquick3dprincipledmaterial_p.h
index b9aa518f7529160b2385b384152c525e5abefa0b..da9870fb241ae854f3f9ae7125bd09821cde9c42 100644
--- a/src/quick3d/qquick3dprincipledmaterial_p.h
+++ b/src/quick3d/qquick3dprincipledmaterial_p.h
@@ -231,7 +231,7 @@ private:
         LineWidthDirty = 0x00001000
     };
 
-    void updateSceneManager(const QSharedPointer<QQuick3DSceneManager> &window);
+    void updateSceneManager(QQuick3DSceneManager *window);
 
     // Note: The default values for properties that are also present in
     // QSSGShaderCustomMaterialAdapter must match the values there, because a
diff --git a/src/quick3d/qquick3dsceneenvironment.cpp b/src/quick3d/qquick3dsceneenvironment.cpp
index 92106b2d1e453bec7bd1edf51d28802ea01fd3d8..b1c654158d048a80a0d0d66e7e562074da2e50dd 100644
--- a/src/quick3d/qquick3dsceneenvironment.cpp
+++ b/src/quick3d/qquick3dsceneenvironment.cpp
@@ -680,10 +680,10 @@ void QQuick3DSceneEnvironment::itemChange(QQuick3DObject::ItemChange change, con
         updateSceneManager(value.sceneManager);
 }
 
-void QQuick3DSceneEnvironment::updateSceneManager(const QSharedPointer<QQuick3DSceneManager> &manager)
+void QQuick3DSceneEnvironment::updateSceneManager(QQuick3DSceneManager *manager)
 {
     if (manager)
-        QQuick3DObjectPrivate::refSceneManager(m_lightProbe, manager);
+        QQuick3DObjectPrivate::refSceneManager(m_lightProbe, *manager);
     else
         QQuick3DObjectPrivate::derefSceneManager(m_lightProbe);
 }
diff --git a/src/quick3d/qquick3dsceneenvironment_p.h b/src/quick3d/qquick3dsceneenvironment_p.h
index 61a7757089d39ee16019d7b1389c52f873562bc7..cb12019fa6bb4c38d288814f0eb2efe19da35db3 100644
--- a/src/quick3d/qquick3dsceneenvironment_p.h
+++ b/src/quick3d/qquick3dsceneenvironment_p.h
@@ -218,7 +218,7 @@ private:
     static int qmlEffectsCount(QQmlListProperty<QQuick3DEffect> *list);
     static void qmlClearEffects(QQmlListProperty<QQuick3DEffect> *list);
 
-    void updateSceneManager(const QSharedPointer<QQuick3DSceneManager> &manager);
+    void updateSceneManager(QQuick3DSceneManager *manager);
 
     QQuick3DEnvironmentAAModeValues m_antialiasingMode = NoAA;
     QQuick3DEnvironmentAAQualityValues m_antialiasingQuality = High;
diff --git a/src/quick3d/qquick3dscenerenderer.cpp b/src/quick3d/qquick3dscenerenderer.cpp
index fe3058ec5486db07abc98a4e30583d3cd37c7b47..ab6f03d0381d3dc9d36a8405dbda772f32fb81c1 100644
--- a/src/quick3d/qquick3dscenerenderer.cpp
+++ b/src/quick3d/qquick3dscenerenderer.cpp
@@ -565,7 +565,7 @@ void QQuick3DSceneRenderer::synchronize(QQuick3DViewport *item, const QSize &siz
         m_importSceneManager->updateBoundingBoxes(m_sgContext->bufferManager());
         m_importSceneManager->updateDirtyNodes();
     } else {
-        m_importSceneManager.clear();
+        m_importSceneManager = nullptr;
     }
 
     // Generate layer node
diff --git a/src/quick3d/qquick3dscenerenderer_p.h b/src/quick3d/qquick3dscenerenderer_p.h
index 89396cd9ab27866b874df4b297c2bc05650a2656..92659b646a1515f7f3ec2ffd470011b622d21b63 100644
--- a/src/quick3d/qquick3dscenerenderer_p.h
+++ b/src/quick3d/qquick3dscenerenderer_p.h
@@ -86,8 +86,8 @@ private:
     void addNodeToLayer(QSSGRenderNode *node);
     void removeNodeFromLayer(QSSGRenderNode *node);
     QSSGRef<QSSGRenderContextInterface> m_sgContext;
-    QSharedPointer<QQuick3DSceneManager> m_sceneManager;
-    QSharedPointer<QQuick3DSceneManager> m_importSceneManager;
+    QQuick3DSceneManager *m_sceneManager = nullptr;
+    QQuick3DSceneManager *m_importSceneManager = nullptr;
     QSSGRenderLayer *m_layer = nullptr;
     QSize m_surfaceSize;
     void *data = nullptr;
diff --git a/src/quick3d/qquick3dtexture.cpp b/src/quick3d/qquick3dtexture.cpp
index 172101ce191dbd4a61ed1f2961a54100568d0fe0..24fb76bf98f86d3b5cb8244e448b6d41379e6b78 100644
--- a/src/quick3d/qquick3dtexture.cpp
+++ b/src/quick3d/qquick3dtexture.cpp
@@ -983,7 +983,7 @@ void QQuick3DTexture::itemChange(QQuick3DObject::ItemChange change, const QQuick
         if (m_textureData) {
             const auto &sceneManager = value.sceneManager;
             if (sceneManager)
-                QQuick3DObjectPrivate::refSceneManager(m_textureData, sceneManager);
+                QQuick3DObjectPrivate::refSceneManager(m_textureData, *sceneManager);
             else
                 QQuick3DObjectPrivate::derefSceneManager(m_textureData);
         }
@@ -1037,7 +1037,7 @@ void QQuick3DTexture::createLayerTexture()
     connect(
             layer,
             &QObject::destroyed,
-            manager.data(),
+            manager,
             [manager, layer]() {
                 // this is on the render thread so all borked threading-wise (all data here is gui thread stuff...) but will survive
                 manager->qsgDynamicTextures.removeAll(layer);
diff --git a/src/quick3d/qquick3dtexture_p.h b/src/quick3d/qquick3dtexture_p.h
index 15ca5274cf657b8611e240e13dae33962e99fce2..f7c342bb714fe2b78f7c8d6536c8604e3cec8506 100644
--- a/src/quick3d/qquick3dtexture_p.h
+++ b/src/quick3d/qquick3dtexture_p.h
@@ -221,7 +221,7 @@ private:
                               | DirtyFlags(DirtyFlag::TextureDataDirty);
     QMetaObject::Connection m_textureProviderConnection;
     QMetaObject::Connection m_textureUpdateConnection;
-    QSharedPointer<QQuick3DSceneManager> m_sceneManagerForLayer;
+    QQuick3DSceneManager *m_sceneManagerForLayer = nullptr;
     QQuickItem *m_initializedSourceItem = nullptr;
     void trySetSourceParent();
     QHash<QByteArray, QMetaObject::Connection> m_connections;
diff --git a/src/quick3d/qquick3dviewport.cpp b/src/quick3d/qquick3dviewport.cpp
index 58db81e6ba3e1b43c34726273e0485de55ffa226..a3ddf3ab33467eb56e8c9035aaf700223291ae2a 100644
--- a/src/quick3d/qquick3dviewport.cpp
+++ b/src/quick3d/qquick3dviewport.cpp
@@ -100,9 +100,10 @@ QQuick3DViewport::QQuick3DViewport(QQuickItem *parent)
     m_sceneRoot = new QQuick3DSceneRootNode(this);
     m_environment = new QQuick3DSceneEnvironment(m_sceneRoot);
     m_renderStats = new QQuick3DRenderStats(m_sceneRoot);
-    QSharedPointer<QQuick3DSceneManager> sceneManager(new QQuick3DSceneManager(m_sceneRoot));
-    QQuick3DObjectPrivate::get(m_sceneRoot)->refSceneManager(sceneManager);
-    connect(QQuick3DObjectPrivate::get(m_sceneRoot)->sceneManager.data(), &QQuick3DSceneManager::needsUpdate,
+    QQuick3DSceneManager *sceneManager = new QQuick3DSceneManager(m_sceneRoot);
+    QQuick3DObjectPrivate::get(m_sceneRoot)->refSceneManager(*sceneManager);
+    Q_ASSERT(sceneManager == QQuick3DObjectPrivate::get(m_sceneRoot)->sceneManager);
+    connect(sceneManager, &QQuick3DSceneManager::needsUpdate,
             this, &QQuickItem::update);
 }
 
@@ -110,11 +111,14 @@ QQuick3DViewport::~QQuick3DViewport()
 {
     for (const auto &connection : qAsConst(m_connections))
         disconnect(connection);
-    // Do not delete scenemanager along with sceneroot
-    auto &sceneManager = QQuick3DObjectPrivate::get(m_sceneRoot)->sceneManager;
+    auto sceneManager = QQuick3DObjectPrivate::get(m_sceneRoot)->sceneManager;
     if (sceneManager)
         sceneManager->setParent(nullptr);
+
     delete m_sceneRoot;
+    m_sceneRoot = nullptr;
+
+    delete sceneManager;
 
     // m_directRenderer must be destroyed on the render thread at the proper time, not here.
     // That's handled in releaseResources() + upon sceneGraphInvalidated
@@ -501,15 +505,17 @@ void QQuick3DViewport::setImportScene(QQuick3DNode *inScene)
 
     m_importScene = inScene;
     if (m_importScene) {
-        // If the referenced scene doesn't have a manager, add one (scenes defined outside of an view3d)
+        // If the referenced scene doesn't have a manager use the one from the sceen root (scenes defined outside of an view3d)
         auto privateObject = QQuick3DObjectPrivate::get(m_importScene);
         if (!privateObject->sceneManager) {
-            QSharedPointer<QQuick3DSceneManager> manager(new QQuick3DSceneManager);
-            manager->setWindow(window());
-            privateObject->refSceneManager(manager);
+            if (QQuick3DSceneManager *manager = QQuick3DObjectPrivate::get(m_sceneRoot)->sceneManager) {
+                manager->setWindow(window());
+                privateObject->refSceneManager(*manager);
+            }
+            Q_ASSERT(privateObject->sceneManager);
         }
 
-        connect(privateObject->sceneManager.data(), &QQuick3DSceneManager::needsUpdate,
+        connect(privateObject->sceneManager, &QQuick3DSceneManager::needsUpdate,
                 this, &QQuickItem::update);
 
         QQuick3DNode *scene = inScene;
@@ -518,7 +524,7 @@ void QQuick3DViewport::setImportScene(QQuick3DNode *inScene)
             scene = rn ? rn->view3D()->importScene() : nullptr;
 
             if (scene) {
-                connect(QQuick3DObjectPrivate::get(scene)->sceneManager.data(),
+                connect(QQuick3DObjectPrivate::get(scene)->sceneManager,
                         &QQuick3DSceneManager::needsUpdate,
                         this, &QQuickItem::update);
             }
diff --git a/tools/shadergen/genshaders.cpp b/tools/shadergen/genshaders.cpp
index b5df490ba37e4e3cae4bdcbb2b548f83fbb519b1..c8d985cd7a1142e7cbe9fb36cbacf0a64b6c45aa 100644
--- a/tools/shadergen/genshaders.cpp
+++ b/tools/shadergen/genshaders.cpp
@@ -77,7 +77,7 @@ static QQsbShaderFeatureSet toQsbShaderFeatureSet(const ShaderFeatureSetList &fe
 
 GenShaders::GenShaders(const QString &sourceDir)
 {
-    sceneManager.reset(new QQuick3DSceneManager);
+    sceneManager = new QQuick3DSceneManager;
 
     rhi = QRhi::create(QRhi::Null, nullptr);
     QRhiCommandBuffer *cb;
diff --git a/tools/shadergen/genshaders.h b/tools/shadergen/genshaders.h
index 6ec249c0ca72afcb564395c8fdf8baac837e43a4..ec458f15270304177f2170bc85f435b559f1bcfb 100644
--- a/tools/shadergen/genshaders.h
+++ b/tools/shadergen/genshaders.h
@@ -56,7 +56,7 @@ struct GenShaders
     QRhi *rhi = nullptr;
     QSSGRef<QSSGRenderContextInterface> renderContext;
 
-    QSharedPointer<QQuick3DSceneManager> sceneManager;
+    QQuick3DSceneManager *sceneManager = nullptr;
 
     static void processFoo(const QSSGRef<QSSGRenderContextInterface> &renderContext, const MaterialParser::SceneData &sceneData);
 };