diff --git a/source/anim/AnimatedModel.cpp b/source/anim/AnimatedModel.cpp
index 9c4688f9016f93de1975a3548ae836c842e786c2..2756886052e7fee1187465019ae3b2e7b7f9e431 100644
--- a/source/anim/AnimatedModel.cpp
+++ b/source/anim/AnimatedModel.cpp
@@ -749,6 +749,8 @@ void XMETHODCALLTYPE CAnimatedModel::render(UINT uLod, bool isTransparent)
 		m_isWorldDirty = false;
 	}
 
+	m_pProvider->bindVertexFormat();
+
 	IGXContext *pCtx = m_pDevice->getThreadContext();
 
 	pCtx->setVSConstant(m_pWorldBuffer, 1 /* SCR_OBJECT */);
diff --git a/source/anim/AnimatedModelProvider.cpp b/source/anim/AnimatedModelProvider.cpp
index fabf3e64d8c74f18b19213528e2dcd5fe9c6b88e..b235b7fd1e6c23158b3f114c8a0910dab4aec5c4 100644
--- a/source/anim/AnimatedModelProvider.cpp
+++ b/source/anim/AnimatedModelProvider.cpp
@@ -175,6 +175,11 @@ void CAnimatedModelProvider::sync()
 	}
 }
 
+void CAnimatedModelProvider::bindVertexFormat()
+{
+	m_pMaterialSystem->bindVS(m_pVertexShaderHandler);
+}
+
 void CAnimatedModelProvider::render(CRenderableVisibility *pVisibility)
 {
 	m_pMaterialSystem->bindVS(m_pVertexShaderHandler);
diff --git a/source/anim/AnimatedModelProvider.h b/source/anim/AnimatedModelProvider.h
index d200daf7894c910e9438014e4d8f4f75deaa43c6..ca592c9cc339421c2311adffef1f3c700b1b2114 100644
--- a/source/anim/AnimatedModelProvider.h
+++ b/source/anim/AnimatedModelProvider.h
@@ -35,6 +35,8 @@ public:
 	void scheduleSharedGPUinit(CAnimatedModelShared *pShared);
 	void scheduleModelGPUinit(CAnimatedModel *pModel);
 
+	void bindVertexFormat();
+
 protected:
 	AssotiativeArray<IXResourceModelAnimated*, Array<CAnimatedModelShared*>> m_mModels;
 
diff --git a/source/anim/DynamicModel.cpp b/source/anim/DynamicModel.cpp
index bcd15a29fa848c2ac96f648386f68d1e5c5cc26f..2819bd742be8e74e7ba5ffc44ecb565593b6fe17 100644
--- a/source/anim/DynamicModel.cpp
+++ b/source/anim/DynamicModel.cpp
@@ -220,8 +220,9 @@ void XMETHODCALLTYPE CDynamicModel::render(UINT uLod, bool isTransparent)
 		m_isWorldDirty = false;
 	}
 
-	m_pDevice->getThreadContext()->setVSConstant(m_pWorldBuffer, 1 /* SCR_OBJECT */);
+	m_pProvider->bindVertexFormat();
 
+	m_pDevice->getThreadContext()->setVSConstant(m_pWorldBuffer, 1 /* SCR_OBJECT */);
 	m_pShared->render(m_uSkin, uLod, m_vColor, isTransparent);
 }
 
diff --git a/source/anim/DynamicModelProvider.cpp b/source/anim/DynamicModelProvider.cpp
index ddd014c47c2536d0ed5776522ae2d7dc1387a566..a535262fb278981a478d1938de8cfb7a5e3a4d14 100644
--- a/source/anim/DynamicModelProvider.cpp
+++ b/source/anim/DynamicModelProvider.cpp
@@ -216,9 +216,14 @@ IXMaterialSystem *CDynamicModelProvider::getMaterialSystem()
 	return((IXMaterialSystem*)m_pCore->getPluginManager()->getInterface(IXMATERIALSYSTEM_GUID));
 }
 
-void CDynamicModelProvider::render(bool isTransparent, CRenderableVisibility *pVisibility)
+void CDynamicModelProvider::bindVertexFormat()
 {
 	m_pMaterialSystem->bindVS(m_pVertexShaderHandler);
+}
+
+void CDynamicModelProvider::render(bool isTransparent, CRenderableVisibility *pVisibility)
+{
+	bindVertexFormat();
 	//if(isTransparent/* || m_apModels.size() < 1000*/)
 	//{
 		for(UINT i = 0, l = m_apModels.size(); i < l; ++i)
diff --git a/source/anim/DynamicModelProvider.h b/source/anim/DynamicModelProvider.h
index 0141c30960588dc7dc84a550f4e99532da7ea472..7aab732a199df395d357d98c20c3f8cbe7c6bf0a 100644
--- a/source/anim/DynamicModelProvider.h
+++ b/source/anim/DynamicModelProvider.h
@@ -56,6 +56,7 @@ public:
 
 	void notifyModelChanged(CDynamicModel *pModel, XEventModelChanged::TYPE type);
 
+	void bindVertexFormat();
 protected:
 	void onMaterialTransparencyChanged(const IXMaterial *pMaterial);
 
diff --git a/source/mtrl/IXMaterialSystem.h b/source/mtrl/IXMaterialSystem.h
index 0f26281f1896b6c49db7b45aba9037052fb7a1ef..130d707c2bfb55d1c963d4ca757d9d550bfc45e9 100644
--- a/source/mtrl/IXMaterialSystem.h
+++ b/source/mtrl/IXMaterialSystem.h
@@ -133,7 +133,7 @@ public:
 	// ["GBuffer color(rgb) light(a)", "g_txGBufferC3L1", 0],
 	// ["Scene default", "g_sScene", 0]
 	// ["Base color", "vBaseColor", 'GXDECLTYPE_FLOAT4', "float4(1.0f, 0.0f, 0.0f, 0.5f)"],
-	virtual XRenderPassHandler* XMETHODCALLTYPE registerRenderPass(const char *szName, const char *szShaderFile, XRenderPassTexturesElement *pTextures, XRenderPassSamplersElement *pSamplers, XRenderPassOutputElement *pOutput, XRenderPassVariantElement *pVariants=NULL) = 0;
+	virtual XRenderPassHandler* XMETHODCALLTYPE registerRenderPass(const char *szName, const char *szShaderFile, XRenderPassTexturesElement *pTextures, XRenderPassSamplersElement *pSamplers, XRenderPassOutputElement *pOutput, XRenderPassVariantElement *pVariants = NULL, bool bSkipMaterialShader = false) = 0;
 	virtual XRenderPassHandler* XMETHODCALLTYPE getRenderPass(const char *szName) = 0;
 	virtual void XMETHODCALLTYPE bindRenderPass(XRenderPassHandler *pRenderPass, UINT uVariant = 0) = 0;
 
diff --git a/source/mtrl/MaterialSystem.cpp b/source/mtrl/MaterialSystem.cpp
index 10b0eeccf49d18d18cd17435e6aab4c6f5a8d3ba..c16d6ffd15930f83ccceef4d30098e5f89a93da6 100644
--- a/source/mtrl/MaterialSystem.cpp
+++ b/source/mtrl/MaterialSystem.cpp
@@ -333,6 +333,29 @@ void XMETHODCALLTYPE CMaterialSystem::setWorld(const SMMATRIX &mWorld)
 }
 void XMETHODCALLTYPE CMaterialSystem::bindMaterial(IXMaterial *pMaterial)
 {
+	if(m_pCurrentRP && m_pCurrentRP->bSkipMaterialShader)
+	{
+		if(!m_pCurrentVS)
+		{
+			return;
+		}
+
+		MaterialVariantVS *pVS = &m_pCurrentRP->aPassVariants[m_uCurrentRPvariant].aVertexShaders[m_pCurrentVS->uID];
+		ID idShaderSet = -1;
+		if(m_pCurrentGS)
+		{
+			idShaderSet = pVS->aGeometryShaders[m_pCurrentGS->uID];
+		}
+		else
+		{
+			idShaderSet = pVS->idSet;
+		}
+
+		SGCore_ShaderBind(idShaderSet);
+
+		return;
+	}
+
 	CMaterial *pMat = (CMaterial*)pMaterial;
 	if(pMaterial)
 	{
@@ -668,7 +691,7 @@ void XMETHODCALLTYPE CMaterialSystem::bindGS(XGeometryShaderHandler *pGeometrySh
 	m_pCurrentGS = (GeometryShader*)pGeometryShader;
 }
 
-XRenderPassHandler* XMETHODCALLTYPE CMaterialSystem::registerRenderPass(const char *szName, const char *szShaderFile, XRenderPassTexturesElement *pTextures, XRenderPassSamplersElement *pSamplers, XRenderPassOutputElement *pOutput, XRenderPassVariantElement *pVariants)
+XRenderPassHandler* XMETHODCALLTYPE CMaterialSystem::registerRenderPass(const char *szName, const char *szShaderFile, XRenderPassTexturesElement *pTextures, XRenderPassSamplersElement *pSamplers, XRenderPassOutputElement *pOutput, XRenderPassVariantElement *pVariants, bool bSkipMaterialShader)
 {
 	if(m_mRenderPasses.KeyExists(szName))
 	{
@@ -680,6 +703,8 @@ XRenderPassHandler* XMETHODCALLTYPE CMaterialSystem::registerRenderPass(const ch
 
 	pass.szName = strdup(szName);
 	pass.szShaderFile = strdup(szShaderFile);
+	pass.bSkipMaterialShader = bSkipMaterialShader;
+	assert(!bSkipMaterialShader && "bSkipMaterialShader is not currently supported!");
 
 	while(pTextures && pTextures->szName)
 	{
@@ -1359,6 +1384,71 @@ void CMaterialSystem::updateReferences()
 			}
 		}
 	}
+
+#if 0
+	for(AssotiativeArray<String, RenderPass>::Iterator i = m_mRenderPasses.begin(); i; i++)
+	{
+		RenderPass *pRP = i.second;
+		if(!pRP->bSkipMaterialShader)
+		{
+			continue;
+		}
+
+
+		String sVSOstruct;
+		for(UINT k = 0, kl = pShader->pVertexFormat->aDecl.size(); k < kl; ++k)
+		{
+			XVertexOutputElement *el = &pShader->pVertexFormat->aDecl[k];
+			if(k != 0)
+			{
+				sVSOstruct += "; ";
+			}
+			sVSOstruct += String(getHLSLType(el->type)) + " " + el->szName + ": " + getHLSLSemantic(el->usage);
+		}
+
+
+		Array<GXMacro> aVariantDefines = pRP->aDefines;
+		aVariantDefines.push_back({"XMAT_PS_STRUCT()", sVSOstruct.c_str()});
+		aVariantDefines.push_back({"XMAT_MS_TEXTURES()", ""});
+		aVariantDefines.push_back({"XMAT_MS_SAMPLERS()", ""});
+		aVariantDefines.push_back({"XMATERIAL_OUTPUT_STRUCT()", ""});
+		
+
+		UINT uOldSize = aVariantDefines.size();
+
+		pRP->aPassVariants.clearFast();
+		for(UINT uPassVariant = 0, uPassVariantl = pRP->aVariants.size(); uPassVariant < uPassVariantl; ++uPassVariant)
+		{
+			aVariantDefines.resizeFast(uOldSize);
+
+			auto &aPassVariants = pPass->pRenderPass->aVariants[uPassVariant];
+			for(UINT m = 0, ml = aPassVariants.size(); m < ml; ++m)
+			{
+				aVariantDefines.push_back(aPassVariants[m]);
+			}
+
+			aVariantDefines.push_back({NULL, NULL});
+
+			ID idShader = SGCore_ShaderLoad(SHADER_TYPE_PIXEL, pMetaPass->szShaderFile, NULL, &aVariantDefines[0]);
+			pVariant->aPassVariants[uPassVariant].idShader = idShader;
+
+
+			pVariant->aPassVariants[uPassVariant].aVertexShaders.clearFast();
+			for(UINT j = 0, jl = pShader->pVertexFormat->aVS.size(); j < jl; ++j)
+			{
+				VertexShaderData *pVS = pShader->pVertexFormat->aVS[j];
+				MaterialVariantVS &vs = pVariant->aPassVariants[uPassVariant].aVertexShaders[j];
+				vs.idSet = SGCore_ShaderCreateKit(pVS->idShader, idShader);
+
+				for(UINT k = 0, kl = pShader->pVertexFormat->aGS.size(); k < kl; ++k)
+				{
+					GeometryShaderData *pGS = pShader->pVertexFormat->aGS[k];
+					vs.aGeometryShaders[k] = SGCore_ShaderCreateKit(pVS->idShader, idShader, pGS->idShader);
+				}
+			}
+		}
+	}
+#endif
 }
 
 void CMaterialSystem::cleanData() 
diff --git a/source/mtrl/MaterialSystem.h b/source/mtrl/MaterialSystem.h
index 34eb581e4651cf3a57d6965ab67a35470574322c..b315a3c2b8ac01403790be26fa8294cf8eb31c1a 100644
--- a/source/mtrl/MaterialSystem.h
+++ b/source/mtrl/MaterialSystem.h
@@ -309,7 +309,7 @@ public:
 	XGeometryShaderHandler* XMETHODCALLTYPE registerGeometryShader(const char *szShaderFile, const char **aszRequiredParameters, GXMacro *pDefines = NULL) override;
 	void XMETHODCALLTYPE bindGS(XGeometryShaderHandler *pGeometryShader) override;
 
-	XRenderPassHandler* XMETHODCALLTYPE registerRenderPass(const char *szName, const char *szShaderFile, XRenderPassTexturesElement *pTextures, XRenderPassSamplersElement *pSamplers, XRenderPassOutputElement *pOutput, XRenderPassVariantElement *pVariants = NULL) override;
+	XRenderPassHandler* XMETHODCALLTYPE registerRenderPass(const char *szName, const char *szShaderFile, XRenderPassTexturesElement *pTextures, XRenderPassSamplersElement *pSamplers, XRenderPassOutputElement *pOutput, XRenderPassVariantElement *pVariants = NULL, bool bSkipMaterialShader = false) override;
 	XRenderPassHandler* XMETHODCALLTYPE getRenderPass(const char *szName) override;
 	void XMETHODCALLTYPE bindRenderPass(XRenderPassHandler *pRenderPass, UINT uVariant = 0) override;
 
@@ -395,6 +395,19 @@ protected:
 		Array<GeometryShaderData*> aGS;
 	};
 
+	struct MaterialVariantVS
+	{
+		ID idSet;
+
+		Array<ID> aGeometryShaders;
+	};
+
+	struct MaterialVariantPass
+	{
+		ID idShader;
+		Array<MaterialVariantVS> aVertexShaders;
+	};
+
 	struct RenderPass: public XRenderPassHandler
 	{
 		const char *szName;
@@ -404,6 +417,9 @@ protected:
 		Array<XRenderPassOutputElement> aOutput;
 		Array<GXMacro> aDefines;
 
+		bool bSkipMaterialShader;
+		Array<MaterialVariantPass> aPassVariants;
+
 		Array<Array<GXMacro>> aVariants;
 	};
 
@@ -427,13 +443,6 @@ protected:
 		// XMaterialProperty *pProp;
 	};
 
-	struct MaterialVariantVS
-	{
-		ID idSet;
-
-		Array<ID> aGeometryShaders;
-	};
-
 	struct MaterialShaderConstants
 	{
 		const char *szKey;
@@ -455,12 +464,6 @@ protected:
 		GXTEXTURE_TYPE type;
 	};
 
-	struct MaterialVariantPass
-	{
-		ID idShader;
-		Array<MaterialVariantVS> aVertexShaders;
-	};
-
 	struct MaterialVariant
 	{
 		bool isReady;
diff --git a/source/terrax/terrax.cpp b/source/terrax/terrax.cpp
index f9f5d03ec1086f81fc2184c22a42f70b5d2d7cee..18f840b59f737aec06f4c141c8084517e515b5db 100644
--- a/source/terrax/terrax.cpp
+++ b/source/terrax/terrax.cpp
@@ -215,6 +215,14 @@ public:
 	{
 		pCore->getRenderPipeline(&m_pOldPipeline);
 		pCore->setRenderPipeline(this);
+
+		IPluginManager *pPluginManager = pCore->getPluginManager();
+		m_pMaterialSystem = (IXMaterialSystem*)pPluginManager->getInterface(IXMATERIALSYSTEM_GUID);
+
+		{
+			m_pRenderPassGeometry2D = m_pMaterialSystem->getRenderPass("xGBuffer");
+			// m_pRenderPassGeometry2D = m_pMaterialSystem->registerRenderPass("xEditor2D", "terrax/geom2d.ps", NULL, NULL, NULL, NULL, true);
+		}
 	}
 	~CRenderPipeline()
 	{
@@ -234,6 +242,8 @@ public:
 		IGXContext *pDXDevice = getDevice()->getThreadContext();
 		pDXDevice->setDepthStencilState(NULL);
 
+		m_pMaterialSystem->bindRenderPass(m_pRenderPassGeometry2D);
+
 		XRender3D();
 
 		//#############################################################################
@@ -250,6 +260,7 @@ public:
 
 		XUpdateSelectionBound();
 
+
 		for(int i = 0; i < 3; ++i)
 		{
 			if(!IsWindowVisible(hWnds[i]))
@@ -282,7 +293,7 @@ public:
 
 			XRender2D(views[i], fScales[i], true);
 
-		//	renderEditor2D();
+			renderEditor2D();
 
 			Core_RIntSet(G_RI_INT_RENDERSTATE, RENDER_STATE_MATERIAL);
 			pDXDevice->setVSConstant(g_pCameraConstantBuffer, 4);
@@ -375,6 +386,9 @@ public:
 
 	IXCore *m_pCore;
 	IXRenderPipeline *m_pOldPipeline = NULL;
+	IXMaterialSystem *m_pMaterialSystem = NULL;
+
+	XRenderPassHandler *m_pRenderPassGeometry2D = NULL;
 };
 
 #if defined(_WINDOWS)