diff --git a/source/anim/DynamicModelProvider.cpp b/source/anim/DynamicModelProvider.cpp
index 98c6715f262f65fe0468807e7d3b54d154622fea..cc06aaed5d550f1b81c80d82e8cdb5accb95aacd 100644
--- a/source/anim/DynamicModelProvider.cpp
+++ b/source/anim/DynamicModelProvider.cpp
@@ -539,16 +539,16 @@ void CDynamicModelProvider::renderEmissive(CRenderableVisibility *pVisibility)
 	render(pVisibility->getSelfillumList(), MF_SELFILLUM);
 }
 
-void CDynamicModelProvider::computeVisibility(const IXFrustum *pFrustum, CRenderableVisibility *pVisibility, CRenderableVisibility *pReference)
+void CDynamicModelProvider::computeVisibility(const IXFrustum *pFrustum, const float3 &vHintDir, CRenderableVisibility *pVisibility, CRenderableVisibility *pReference)
 {
 	void **ppData;
-	UINT uCount = m_pOpaqueQuery->execute(pFrustum, &ppData);
+	UINT uCount = m_pOpaqueQuery->execute(pFrustum, vHintDir, &ppData);
 	pVisibility->setRenderList(ppData, uCount);
 
-	uCount = m_pSelfillumQuery->execute(pFrustum, &ppData);
+	uCount = m_pSelfillumQuery->execute(pFrustum, vHintDir, &ppData);
 	pVisibility->setSelfillumList(ppData, uCount);
 
-	uCount = m_pTransparentQuery->execute(pFrustum, &ppData);
+	uCount = m_pTransparentQuery->execute(pFrustum, vHintDir, &ppData);
 	pVisibility->setTransparentList(ppData, uCount);
 
 	{
diff --git a/source/anim/DynamicModelProvider.h b/source/anim/DynamicModelProvider.h
index 957cfb47d596f4218b835c1e3f9c3c2c1529c17d..97488fa5291039a49e31ab51db0f740e66a69e8d 100644
--- a/source/anim/DynamicModelProvider.h
+++ b/source/anim/DynamicModelProvider.h
@@ -45,7 +45,7 @@ public:
 
 	void render(bool isTransparent, CRenderableVisibility *pVisibility = NULL);
 	void renderEmissive(CRenderableVisibility *pVisibility);
-	void computeVisibility(const IXFrustum *pFrustum, CRenderableVisibility *pVisibility, CRenderableVisibility *pReference=NULL);
+	void computeVisibility(const IXFrustum *pFrustum, const float3 &vHintDir, CRenderableVisibility *pVisibility, CRenderableVisibility *pReference=NULL);
 
 	void render(Array<CDynamicModel*> &aRenderList, XMODEL_FEATURE bmWhat);
 
diff --git a/source/anim/RenderableVisibility.cpp b/source/anim/RenderableVisibility.cpp
index 6f9b472157f3a0047cfa26f670ce91ed95a5ced2..90f1d2caa1207747b8d42c3e1888d37ee5a3e265 100644
--- a/source/anim/RenderableVisibility.cpp
+++ b/source/anim/RenderableVisibility.cpp
@@ -22,8 +22,16 @@ void CRenderableVisibility::setOcclusionCuller(IXOcclusionCuller *pOcclusionCull
 
 void CRenderableVisibility::updateForCamera(ICamera *pCamera, const IXRenderableVisibility *pReference)
 {
+	CRenderableVisibility *pRef = NULL;
+	if(pReference)
+	{
+		assert(((IXRenderableVisibility*)pReference)->getPluginId() == getPluginId());
+		pRef = (CRenderableVisibility*)pReference;
+	}
+
 	IXFrustum *pFrustum = pCamera->getFrustum();
-	updateForFrustum(pFrustum, pReference);
+	m_pProviderAnimated->computeVisibility(pFrustum, this, pRef);
+	m_pProviderDynamic->computeVisibility(pFrustum, pCamera->getLook(), this, pRef);
 	mem_release(pFrustum);
 }
 
@@ -37,7 +45,7 @@ void CRenderableVisibility::updateForFrustum(const IXFrustum *pFrustum, const IX
 	}
 
 	m_pProviderAnimated->computeVisibility(pFrustum, this, pRef);
-	m_pProviderDynamic->computeVisibility(pFrustum, this, pRef);
+	m_pProviderDynamic->computeVisibility(pFrustum, float3(), this, pRef);
 }
 
 static void SortRenderList(Array<CDynamicModel*> &aList)
diff --git a/source/render/Scene.cpp b/source/render/Scene.cpp
index eda1ea18254017749d4e0193c8802307cd6d607d..667f057cd01690f3806b2ad9a3ce4b3fc2bb920a 100644
--- a/source/render/Scene.cpp
+++ b/source/render/Scene.cpp
@@ -86,6 +86,25 @@ void XMETHODCALLTYPE CSceneObject::setFeatures(IXSceneFeature **ppFeatures)
 
 //##########################################################################
 
+static const UINT gcs_puOrders[][BVH_CHILD_COUNT] = {
+	// +x +y +z
+	{13, 4, 10, 12, 1, 3, 9, 14, 16, 22, 0, 5, 7, 11, 15, 19, 21, 2, 6, 17, 18, 23, 25, 8, 20, 24, 26},
+	// +x +y -z
+	{22, 4, 19, 21, 1, 3, 13, 18, 23, 25, 0, 5, 7, 10, 12, 20, 24, 2, 6, 9, 14, 16, 26, 8, 11, 15, 17},
+	// +x -y +z
+	{16, 7, 10, 15, 1, 6, 9, 13, 17, 25, 0, 4, 8, 11, 12, 19, 24, 2, 3, 14, 18, 22, 26, 5, 20, 21, 23},
+	// +x -y -z
+	{25, 7, 19, 24, 1, 6, 16, 18, 22, 26, 0, 4, 8, 10, 15, 20, 21, 2, 3, 9, 13, 17, 23, 5, 11, 12, 14},
+	// -x +y +z
+	{14, 5, 11, 12, 2, 3, 9, 13, 17, 23, 0, 4, 8, 10, 15, 20, 21, 1, 6, 16, 18, 22, 26, 7, 19, 24, 25},
+	// -x +y -z
+	{23, 5, 20, 21, 2, 3, 14, 18, 22, 26, 0, 4, 8, 11 ,12, 19, 24, 1, 6, 9, 13, 17, 25, 7, 10, 15, 16},
+	// -x -y +z
+	{17, 8, 11, 15, 2, 6, 9, 14, 16, 26, 0, 5, 7, 10, 12, 20, 24, 1, 3, 13, 18, 23, 25, 4, 19, 21, 22},
+	// -x -y -z
+	{26, 8, 20, 24, 2, 6, 17, 18, 23, 25, 0, 5, 7, 11, 15, 19, 21, 1, 3, 9, 14, 16, 22, 4, 10, 12, 13}
+};
+
 CSceneQuery::CSceneQuery(CScene *pScene, CSceneObjectType *pObjectType):
 	m_pScene(pScene),
 	m_bmType(pObjectType->getType())
@@ -95,8 +114,19 @@ CSceneQuery::~CSceneQuery()
 {
 }
 
+UINT XMETHODCALLTYPE CSceneQuery::execute(const IXFrustum *pFrustum, const float3 &vDir, void ***pppObjects, IXOcclusionCuller *pOcclusionCuller)
+{
+	pOrder = gcs_puOrders[(vDir.x < 0.0f ? 4 : 0) + (vDir.y < 0.0f ? 2 : 0) + (vDir.z < 0.0f ? 1 : 0)];
+
+	return(execute(pFrustum, pppObjects, pOcclusionCuller));
+}
+
 UINT XMETHODCALLTYPE CSceneQuery::execute(const IXFrustum *pFrustum, void ***pppObjects, IXOcclusionCuller *pOcclusionCuller)
 {
+	if(!pOrder)
+	{
+		pOrder = gcs_puOrders[0];
+	}
 	m_aQueryResponse.clearFast();
 
 	queryObjectsInternal(m_pScene->m_pRootNode, pFrustum);
@@ -140,7 +170,7 @@ void CSceneQuery::queryObjectsInternal(CSceneNode *pNode, const IXFrustum *pFrus
 
 	for(UINT i = 0; i < BVH_CHILD_COUNT; ++i)
 	{
-		queryObjectsInternal(pNode->getChild(i, false), pFrustum, isFullyVisible);
+		queryObjectsInternal(pNode->getChild(pOrder[i], false), pFrustum, isFullyVisible);
 	}
 
 	auto &aObjects = pNode->getObjects();
diff --git a/source/render/Scene.h b/source/render/Scene.h
index 1e3ac2249065a23ba13cf72149f44b2a485d9d00..abd4d5848f3f75d132a7e2406367f8a3f42e3d8f 100644
--- a/source/render/Scene.h
+++ b/source/render/Scene.h
@@ -88,6 +88,7 @@ public:
 	~CSceneQuery();
 
 	UINT XMETHODCALLTYPE execute(const IXFrustum *pFrustum, void ***pppObjects, IXOcclusionCuller *pOcclusionCuller = NULL) override;
+	UINT XMETHODCALLTYPE execute(const IXFrustum *pFrustum, const float3 &vDir, void ***pppObjects, IXOcclusionCuller *pOcclusionCuller = NULL) override;
 
 	void XMETHODCALLTYPE setOP(XSCENE_QUERY_OP op) override;
 
@@ -102,6 +103,8 @@ private:
 	NodeFeature m_bmSet = 0;
 	NodeFeature m_bmUnset = 0;
 
+	const UINT *pOrder = NULL;
+
 	void queryObjectsInternal(CSceneNode *pNode, const IXFrustum *pFrustum, bool isFullyVisible = false, IXOcclusionCuller *pOcclusionCuller = NULL);
 	bool testFeatures(NodeFeature bmFeatures, bool isStrict = true);
 };
diff --git a/source/xcommon/IXScene.h b/source/xcommon/IXScene.h
index 14e50abf1199a6902176db222a95bb267d3c198d..a424ebe7879c5bdae23c2e1ff90c56d63b9c1a80 100644
--- a/source/xcommon/IXScene.h
+++ b/source/xcommon/IXScene.h
@@ -66,6 +66,14 @@ public:
 	*/
 	virtual UINT XMETHODCALLTYPE execute(const IXFrustum *pFrustum, void ***pppObjects, IXOcclusionCuller *pOcclusionCuller = NULL) = 0;
 
+	/*!
+		Выполняет запрос, возвращает количество найденных объектов,
+		в pppObjects записывается указатель на массив пользовательских указателей найденных объектов
+		в vDir задается предпочтительное направление обхода (данное направление лишь подсказка, но не руководство к действию)
+		@threadsafe sync
+	*/
+	virtual UINT XMETHODCALLTYPE execute(const IXFrustum *pFrustum, const float3 &vDir, void ***pppObjects, IXOcclusionCuller *pOcclusionCuller = NULL) = 0;
+
 	/*!
 		Устанавливает операцию выборки
 		@threadsafe none