void QuickRefreshEditorShader()
{
	const char *nameLast = NULL;
	for ( MaterialHandle_t curMatHandle = g_pMaterialSystem->FirstMaterial();
		curMatHandle != g_pMaterialSystem->InvalidMaterial();
		curMatHandle = g_pMaterialSystem->NextMaterial( curMatHandle ) )
	{
		IMaterial *pMat = g_pMaterialSystem->GetMaterial( curMatHandle );
		if ( IsErrorMaterial( pMat ) )
			continue;

		//bool bSanityTest = false;
		//IMaterialVar *pVarBaseTexture = pMat->FindVar( "$basetexture", &bSanityTest, false );
		//if ( !pVarBaseTexture || !bSanityTest )
		//	continue;
		if ( !pMat->ShaderParamCount() )
			continue;

		const char *n = pMat->GetName();

		if ( !n || (nameLast && !Q_strcmp( nameLast, n )) )
			continue;
		nameLast = n;

		const char *shaderName = pMat->GetShaderName();
		if ( !shaderName )
			continue;

		if ( !Q_stricmp( shaderName, "EDITOR_SHADER" ) )
		{
			pMat->Refresh();
			pMat->RecomputeStateSnapshots();
		}
	}
}
void ReloadGameShaders( GenericShaderData *data, char **pszMaterialList, int iNumMaterials )
{
	const bool bIsOverriding = !!data;
	char *CanvasName = NULL;

	if ( bIsOverriding )
	{
		const char *ShaderName = data->name;

		int SwapIndex = ::gProcShaderCTRL->FindPreloadShader( ShaderName );
		if ( SwapIndex < 0 )
		{
			const char *pszSearch = Q_stristr( data->name, "_" );
			if ( pszSearch )
			{
				const char *ShaderName_Small = pszSearch + 1;
				SwapIndex = ::gProcShaderCTRL->FindPreloadShader( ShaderName_Small );
			}
		}

		CanvasName = new char[ Q_strlen( ShaderName ) + 1 ];
		Q_strcpy( CanvasName, ShaderName );

		BasicShaderCfg_t *SwapData = new BasicShaderCfg_t( *data->shader );
		Assert( !SwapData->CanvasName );
		SwapData->CanvasName = CanvasName;

		// build shader names
		static unsigned int _HackyIndexIncrement = 0;
		{
			int len = Q_strlen( SwapData->ProcPSName ) + 2 + 7;
			char *uniquifyShader = new char[len];
			Q_snprintf( uniquifyShader, len, "%06X_%s", _HackyIndexIncrement, SwapData->ProcPSName );
			delete [] SwapData->ProcPSName;
			SwapData->ProcPSName = uniquifyShader;
		}
		{
			int len = Q_strlen( SwapData->ProcVSName ) + 2 + 7;
			char *uniquifyShader = new char[len];
			Q_snprintf( uniquifyShader, len, "%06X_%s", _HackyIndexIncrement, SwapData->ProcVSName );
			delete [] SwapData->ProcVSName;
			SwapData->ProcVSName = uniquifyShader;
		}

		char *OldName = data->name;
		char targetname[MAX_PATH];
		Q_snprintf( targetname, MAX_PATH, "%06X_%s", _HackyIndexIncrement, OldName );

		// copy vcs files
		char __path_compiler[MAX_PATH];
		char __path_engine[MAX_PATH];
		ComposeShaderPath_Compiled( data, false, true, __path_compiler, MAX_PATH );
		data->name = targetname;
		ComposeShaderPath_CompiledEngine( data, false, true, __path_engine, MAX_PATH );
		EngineCopy( __path_compiler, __path_engine );

		data->name = OldName;
		ComposeShaderPath_Compiled( data, true, true, __path_compiler, MAX_PATH );
		data->name = targetname;
		ComposeShaderPath_CompiledEngine( data, true, true, __path_engine, MAX_PATH );
		EngineCopy( __path_compiler, __path_engine );


		data->name = OldName;
		_HackyIndexIncrement++;

		if ( SwapIndex >= 0 )
		{
			// swap shader data
			BasicShaderCfg_t *trash = (BasicShaderCfg_t*)gProcShaderCTRL->SwapPreloadShader( SwapIndex, SwapData );
			delete trash;
		}
		else
			gProcShaderCTRL->AddPreloadShader( SwapData );
	}

	// reload materials
	if ( pszMaterialList && iNumMaterials )
	{
		for ( int i = 0; i < iNumMaterials; i++ )
		{
			IMaterial *pMat = materials->FindMaterial( pszMaterialList[i], TEXTURE_GROUP_MODEL );
			if ( IsErrorMaterial( pMat ) )
				continue;

			KeyValues *pKV = new KeyValues( "" );
			char tmppath[ MAX_PATH ];
			Q_snprintf( tmppath, MAX_PATH, "materials/%s.vmt", pszMaterialList[i] );
			if ( !pKV->LoadFromFile( g_pFullFileSystem, tmppath ) )
			{
				pKV->deleteThis();
				continue;
			}

			if ( bIsOverriding )
			{
				pKV->SetName( "EDITOR_SHADER" );
				pKV->SetString( "$SHADERNAME", CanvasName );
			
				const char *curEnvmap = pKV->GetString( "$envmap" );
				if ( !curEnvmap || !*curEnvmap )
					pKV->SetString( "$envmap", "env_cubemap" );
			}
			else
				UnpackMaterial( pKV );

			pMat->SetShaderAndParams( pKV );

			pMat->Refresh();
			pMat->RecomputeStateSnapshots();

			pKV->deleteThis();
		}
		return;
	}

	if ( !bIsOverriding )
		return;

	QuickRefreshEditorShader();
}