diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index e674da0473379b09ed8fef8037f3a0806fc0c515..18c596f67e45ec1b51fe0bf02f518acca5b3da99 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -212,13 +212,13 @@ typedef struct RenderData {
 	float postmul, postgamma, postadd, postigamma;
 
 	/* yafray: global panel params. TODO: move elsewhere */
-	short GIquality, GIcache, GImethod, GIgradient, GIphotons, GIdirect;
-	short YF_AA, YFexportxml;
+	short GIquality, GIcache, GImethod, GIphotons, GIdirect;
+	short YF_AA, YFexportxml, yfpad1[3];
 	int GIdepth, GIcausdepth, GIpixelspersample;
 	int GIphotoncount, GImixphotons;
 	float GIphotonradius;
 	int YF_numprocs, YF_raydepth, YF_AApasses, YF_AAsamples;
-	float GIshadowquality, GIrefinement, GIpower;
+	float GIshadowquality, GIrefinement, GIpower, GIindirpower;
 	float YF_gamma, YF_exposure, YF_raybias, YF_AApixelsize, YF_AAthreshold;
 
 	char backbuf[160], pic[160], ftype[160];
diff --git a/source/blender/python/api2_2x/sceneRender.c b/source/blender/python/api2_2x/sceneRender.c
index 7d6ba0cb7f7c4cce758ee9ab1f4965f8a8828929..d4a23c9e4644923e0310374d5ae741fc8597a69d 100644
--- a/source/blender/python/api2_2x/sceneRender.c
+++ b/source/blender/python/api2_2x/sceneRender.c
@@ -221,8 +221,6 @@ static PyObject *RenderData_YafrayGIShadowQuality( BPy_RenderData * self,
 						   PyObject * args );
 static PyObject *RenderData_YafrayGIPixelsPerSample( BPy_RenderData * self,
 						     PyObject * args );
-static PyObject *RenderData_EnableYafrayGIGradient( BPy_RenderData * self,
-						    PyObject * args );
 static PyObject *RenderData_YafrayGIRefinement( BPy_RenderData * self,
 						PyObject * args );
 static PyObject *RenderData_YafrayRayBias( BPy_RenderData * self,
@@ -451,9 +449,6 @@ static PyMethodDef BPy_RenderData_methods[] = {
 	{"yafrayGIPixelsPerSample",
 	 ( PyCFunction ) RenderData_YafrayGIPixelsPerSample, METH_VARARGS,
 	 "(int) - get/set maximum number of pixels without samples, the lower the better and slower\n"},
-	{"enableYafrayGIGradient",
-	 ( PyCFunction ) RenderData_EnableYafrayGIGradient, METH_VARARGS,
-	 "(bool) - enable/disable try to smooth lighting using a gradient\n"},
 	{"yafrayGIRefinement", ( PyCFunction ) RenderData_YafrayGIRefinement,
 	 METH_VARARGS,
 	 "(float) - get/setthreshold to refine shadows EXPERIMENTAL. 1 = no refinement\n"},
@@ -1793,20 +1788,6 @@ PyObject *RenderData_YafrayGIPixelsPerSample( BPy_RenderData * self,
 						"YafrayGIMethod must be set to 'FULL' and GICache must be enabled\n" ) );
 }
 
-//------------------------------------RenderData.EnableYafrayGIGradient() 
-PyObject *RenderData_EnableYafrayGIGradient( BPy_RenderData * self,
-					     PyObject * args )
-{
-	if( self->renderContext->GImethod == 2
-	    && self->renderContext->GIcache == 1 ) {
-		return M_Render_BitToggleShort( args, 1,
-						&self->renderContext->
-						GIgradient );;
-	} else
-		return ( EXPP_ReturnPyObjError( PyExc_StandardError,
-						"YafrayGIMethod must be set to 'FULL' and GICache must be enabled" ) );
-}
-
 //------------------------------------RenderData.YafrayGIRefinement() ----
 PyObject *RenderData_YafrayGIRefinement( BPy_RenderData * self,
 					 PyObject * args )
diff --git a/source/blender/renderconverter/intern/convertBlenderScene.c b/source/blender/renderconverter/intern/convertBlenderScene.c
index 28fec81b49190aef268e7203f5c20c4c0034effd..5facd9081ecfa0dc1d09d4fd4ded7b6227d5b087 100644
--- a/source/blender/renderconverter/intern/convertBlenderScene.c
+++ b/source/blender/renderconverter/intern/convertBlenderScene.c
@@ -3016,7 +3016,7 @@ void RE_rotateBlenderScene(void)
 					free_duplilist();
 				}
 				else {
-					/* yafray: if there are linked data objects (except lamps or empties),
+					/* yafray: if there are linked data objects (except lamps, empties or armatures),
 					   yafray only needs to know about one, the rest can be instanciated.
 					   The dupliMtx list is used for this purpose */
 					if (R.r.renderer==R_YAFRAY) {
@@ -3027,7 +3027,7 @@ void RE_rotateBlenderScene(void)
 							else
 								init_render_object(ob);
 						}
-						else if ((ob->type!=OB_EMPTY) && (ob->type!=OB_LAMP) && YAF_objectKnownData(ob))
+						else if ((ob->type!=OB_EMPTY) && (ob->type!=OB_LAMP) && (ob->type!=OB_ARMATURE) && YAF_objectKnownData(ob))
 							printf("Added dupli matrix for linked data object %s\n", ob->id.name);
 						else
 							init_render_object(ob);
diff --git a/source/blender/src/buttons_scene.c b/source/blender/src/buttons_scene.c
index 232b30bffcfb8f0c1a1c98381f5b8dfb5af3060c..a25472bc1203c60015b21ff978d35968540aba8a 100644
--- a/source/blender/src/buttons_scene.c
+++ b/source/blender/src/buttons_scene.c
@@ -1281,10 +1281,9 @@ static void render_panel_yafrayGI()
 			70,150,89,20, &G.scene->r.GIquality, 0, 0, 0, 0, "Global Illumination Quality");
 
 	if (G.scene->r.GImethod>0) {
-		if (G.scene->r.GIpower==0) G.scene->r.GIpower=1;
-		uiDefButF(block, NUM, B_DIFF, "Power:", 5,10,154,20, &G.scene->r.GIpower, 0.01, 100.0, 10, 0, "GI lighting intensity scale, 1 is normal");
+		uiDefButF(block, NUM, B_DIFF, "EmitPwr:", 5,35,154,20, &G.scene->r.GIpower, 0.01, 100.0, 10, 0, "arealight, material emit and background intensity scaling, 1 is normal");
+		if (G.scene->r.GImethod==2) uiDefButF(block, NUM, B_DIFF, "GI Pwr:", 5,10,154,20, &G.scene->r.GIindirpower, 0.01, 100.0, 10, 0, "GI indirect lighting intensity scaling, 1 is normal");
 	}
-        
 
 	if (G.scene->r.GImethod==2) 
 	{
@@ -1300,9 +1299,8 @@ static void render_panel_yafrayGI()
 			uiDefButF(block, NUM, B_DIFF,"ShadQu:", 5,85,154,20,	&(G.scene->r.GIshadowquality), 0.01, 1.0 ,1,0, "Sets the shadow quality, keep it under 0.95 :-) ");
 			if (G.scene->r.GIpixelspersample==0) G.scene->r.GIpixelspersample=10;
 			uiDefButI(block, NUM, B_DIFF, "Prec:",	5,60,75,20, &G.scene->r.GIpixelspersample, 1, 50, 10, 10, "Maximum number of pixels without samples, the lower the better and slower");
-			uiDefButS(block,TOG|BIT|0, B_DIFF, "Gradient", 84,60,75,20, &G.scene->r.GIgradient, 0, 0, 0, 0, "Try to smooth lighting using a gradient");
 			if (G.scene->r.GIrefinement==0) G.scene->r.GIrefinement=1.0;
-			uiDefButF(block, NUM, B_DIFF, "Refinement:", 5,35,154,20, &G.scene->r.GIrefinement, 0.001, 1.0, 1, 0, "Threshold to refine shadows EXPERIMENTAL. 1 = no refinement");
+			uiDefButF(block, NUM, B_DIFF, "Ref:", 80,60,75,20, &G.scene->r.GIrefinement, 0.001, 1.0, 1, 0, "Threshold to refine shadows EXPERIMENTAL. 1 = no refinement");
 		}
 		if (G.scene->r.GIphotons) 
 		{
@@ -1315,7 +1313,7 @@ static void render_panel_yafrayGI()
 					0.00001, 100.0 ,0,0, "Radius to search for photons to mix (blur)");
 			if(G.scene->r.GImixphotons==0) G.scene->r.GImixphotons=100;
 			uiDefButI(block, NUM, B_DIFF, "MixCount:", 170,35,140,20, &G.scene->r.GImixphotons, 
-					0, 1000, 10, 10, "Number of photons to shoot");
+					0, 1000, 10, 10, "Number of photons to mix");
 			uiDefButS(block,TOG|BIT|0, B_REDR, "Tune Photons",170,10,140,20, &G.scene->r.GIdirect, 
 					0, 0, 0, 0, "Show the photonmap directly in the render for tuning");
 		}
@@ -1373,6 +1371,8 @@ void render_panels()
 		if (G.scene->r.YF_raydepth==0) G.scene->r.YF_raydepth=5;
 		if (G.scene->r.YF_AApixelsize==0.0) G.scene->r.YF_AApixelsize=1.5;
 		if (G.scene->r.YF_AAthreshold==0.0) G.scene->r.YF_AAthreshold=0.05;
+		if (G.scene->r.GIpower==0.0) G.scene->r.GIpower=1.0;
+		if (G.scene->r.GIindirpower==0.0) G.scene->r.GIindirpower=1.0;
 		render_panel_yafrayGlobal();
 		render_panel_yafrayGI();
 	}
diff --git a/source/blender/yafray/intern/export_File.cpp b/source/blender/yafray/intern/export_File.cpp
index 5584ac47bd34dd2a8d1cdda4becf418829214669..eca34a65504e5f3470f99afa7b2e7a71f84b3050 100755
--- a/source/blender/yafray/intern/export_File.cpp
+++ b/source/blender/yafray/intern/export_File.cpp
@@ -313,13 +313,47 @@ static void adjustPath(string &path)
 }
 
 
+static string noise2string(short nbtype)
+{
+	switch (nbtype) {
+		case TEX_BLENDER:
+			return "blender";
+		case TEX_STDPERLIN:
+			return "stdperlin";
+		case TEX_VORONOI_F1:
+			return "voronoi_f1";
+		case TEX_VORONOI_F2:
+			return "voronoi_f2";
+		case TEX_VORONOI_F3:
+			return "voronoi_f3";
+		case TEX_VORONOI_F4:
+			return "voronoi_f4";
+		case TEX_VORONOI_F2F1:
+			return "voronoi_f2f1";
+		case TEX_VORONOI_CRACKLE:
+			return "voronoi_crackle";
+		case TEX_CELLNOISE:
+			return "cellnoise";
+		default:
+		case TEX_NEWPERLIN:
+			return "newperlin";
+	}
+}
+
 void yafrayFileRender_t::writeTextures()
 {
-	for (map<string, pair<Material*, MTex*> >::const_iterator blendtex=used_textures.begin();
+	string ts;
+	for (map<string, MTex*>::const_iterator blendtex=used_textures.begin();
 						blendtex!=used_textures.end();++blendtex) {
-		//Material* matr = blendtex->second.first;
-		MTex* mtex = blendtex->second.second;
+		MTex* mtex = blendtex->second;
 		Tex* tex = mtex->tex;
+
+		float nsz = tex->noisesize;
+		if (nsz!=0.f) nsz=1.f/nsz;
+
+		// noisebasis type
+		string ntype = noise2string(tex->noisebasis);
+
 		switch (tex->type) {
 			case TEX_STUCCI:
 				// stucci is clouds as bump, but could be added to yafray to handle both wall in/out as well.
@@ -329,8 +363,9 @@ void yafrayFileRender_t::writeTextures()
 				ostr << "<shader type=\"clouds\" name=\"" << blendtex->first << "\" >\n";
 				ostr << "\t<attributes>\n";
 				ostr << "\t\t<depth value=\"" << tex->noisedepth+1 << "\" />\n";
-				ostr << "\t</attributes>\n";
-				ostr << "</shader >\n\n";
+				ostr << "\t\t<size value=\"" << nsz << "\" />\n";
+				ostr << "\t\t<noise_type value=\"" << ntype << "\" />\n";
+				ostr << "\t</attributes>\n</shader >\n\n";
 				xmlfile << ostr.str();
 				break;
 			}
@@ -342,11 +377,10 @@ void yafrayFileRender_t::writeTextures()
 				ostr << "\t\t<turbulence value=\"" << tex->turbul << "\" />\n";
 				ostr << "\t\t<ringscale_x value=\"" << mtex->size[0] << "\" />\n";
 				ostr << "\t\t<ringscale_y value=\"" << mtex->size[1] << "\" />\n";
-				string ts = "on";
+				ts = "on";
 				if (tex->noisetype==TEX_NOISESOFT) ts = "off";
 				ostr << "\t\t<hard value=\"" << ts << "\" />\n";
-				ostr << "\t</attributes>\n";
-				ostr << "</shader>\n\n";
+				ostr << "\t</attributes>\n</shader>\n\n";
 				xmlfile << ostr.str();
 				break;
 			}
@@ -356,28 +390,115 @@ void yafrayFileRender_t::writeTextures()
 				ostr << "\t<attributes>\n";
 				ostr << "\t\t<depth value=\"" << tex->noisedepth+1 << "\" />\n";
 				ostr << "\t\t<turbulence value=\"" << tex->turbul << "\" />\n";
-				string ts = "on";
+				ts = "on";
 				if (tex->noisetype==TEX_NOISESOFT) ts = "off";
 				ostr << "\t\t<hard value=\"" << ts << "\" />\n";
 				ts = "1";
 				if (tex->stype==1) ts="5"; else if (tex->stype==2) ts="10";
 				ostr << "\t\t<sharpness value=\"" << ts << "\" />\n";
-				ostr << "\t</attributes>\n";
-				ostr << "</shader>\n\n";
+				ostr << "\t</attributes>\n</shader>\n\n";
+				xmlfile << ostr.str();
+				break;
+			}
+			case TEX_VORONOI: {
+				ostr.str("");
+				ostr << "<shader type=\"voronoi\" name=\"" << blendtex->first << "\" >\n";
+				ostr << "\t<attributes>\n";
+				ts = "int";
+				if (tex->vn_coltype==1)
+					ts = "col1";
+				else if (tex->vn_coltype==2)
+					ts = "col2";
+				else if (tex->vn_coltype==3)
+					ts = "col3";
+				ostr << "\t\t<color_type value=\"" << ts << "\" />\n";
+				ostr << "\t\t<weight1 value=\"" << tex->vn_w1 << "\" />\n";
+				ostr << "\t\t<weight2 value=\"" << tex->vn_w2 << "\" />\n";
+				ostr << "\t\t<weight3 value=\"" << tex->vn_w3 << "\" />\n";
+				ostr << "\t\t<weight4 value=\"" << tex->vn_w4 << "\" />\n";
+				ostr << "\t\t<mk_exponent value=\"" << tex->vn_mexp << "\" />\n";
+				ostr << "\t\t<intensity value=\"" << tex->ns_outscale << "\" />\n";
+				ostr << "\t\t<size value=\"" << nsz << "\" />\n";
+				ts = "actual";
+				if (tex->vn_distm==TEX_DISTANCE_SQUARED)
+					ts = "squared";
+				else if (tex->vn_distm==TEX_MANHATTAN)
+					ts = "manhattan";
+				else if (tex->vn_distm==TEX_CHEBYCHEV)
+					ts = "chebychev";
+				else if (tex->vn_distm==TEX_MINKOVSKY_HALF)
+					ts = "minkovsky_half";
+				else if (tex->vn_distm==TEX_MINKOVSKY_FOUR)
+					ts = "minkovsky_four";
+				else if (tex->vn_distm==TEX_MINKOVSKY)
+					ts = "minkovsky";
+				ostr << "\t\t<distance_metric value=\"" << ts << "\" />\n";
+				ostr << "\t</attributes>\n</shader>\n\n";
+				xmlfile << ostr.str();
+				break;
+			}
+			case TEX_MUSGRAVE: {
+				ostr.str("");
+				ostr << "<shader type=\"musgrave\" name=\"" << blendtex->first << "\" >\n";
+				ostr << "\t<attributes>\n";
+				switch (tex->stype) {
+					case TEX_MFRACTAL:
+						ts = "multifractal";
+						break;
+					case TEX_RIDGEDMF:
+						ts = "ridgedmf";
+						break;
+					case TEX_HYBRIDMF:
+						ts = "hybridmf";
+						break;
+					case TEX_HTERRAIN:
+						ts = "heteroterrain";
+						break;
+					default:
+					case TEX_FBM:
+						ts = "fBm";
+				}
+				ostr << "\t\t<musgrave_type value=\"" << ts << "\" />\n";
+				ostr << "\t\t<noise_type value=\"" << ntype << "\" />\n";
+				ostr << "\t\t<H value=\"" << tex->mg_H << "\" />\n";
+				ostr << "\t\t<lacunarity value=\"" << tex->mg_lacunarity << "\" />\n";
+				ostr << "\t\t<octaves value=\"" << tex->mg_octaves << "\" />\n";
+				if ((tex->stype==TEX_HTERRAIN) || (tex->stype==TEX_RIDGEDMF) || (tex->stype==TEX_HYBRIDMF)) {
+					ostr << "\t\t<offset value=\"" << tex->mg_offset << "\" />\n";
+					if ((tex->stype==TEX_RIDGEDMF) || (tex->stype==TEX_HYBRIDMF))
+						ostr << "\t\t<gain value=\"" << tex->mg_gain << "\" />\n";
+				}
+				ostr << "\t\t<size value=\"" << nsz << "\" />\n";
+				ostr << "\t\t<intensity value=\"" << tex->ns_outscale << "\" />\n";
+				ostr << "\t</attributes>\n</shader>\n\n";
+				xmlfile << ostr.str();
+				break;
+			}
+			case TEX_DISTNOISE: {
+				ostr.str("");
+				ostr << "<shader type=\"distorted_noise\" name=\"" << blendtex->first << "\" >\n";
+				ostr << "\t<attributes>\n";
+				ostr << "\t\t<distort value=\"" << tex->dist_amount << "\" />\n";
+				ostr << "\t\t<size value=\"" << nsz << "\" />\n";
+				ostr << "\t\t<noise_type1 value=\"" << ntype << "\" />\n";
+				ostr << "\t\t<noise_type2 value=\"" << noise2string(tex->noisebasis2) << "\" />\n";
+				ostr << "\t</attributes>\n</shader>\n\n";
 				xmlfile << ostr.str();
 				break;
 			}
 			case TEX_IMAGE: {
 				Image* ima = tex->ima;
 				if (ima) {
+					// remove from imagetex list to avoid possible duplicates when TexFace used
+					imagetex.erase(ima);
 					ostr.str("");
-					ostr << "<shader type=\"image\" name=\"" << blendtex->first << "\" >\n";
+					// use image name instead of texname here
+					ostr << "<shader type=\"image\" name=\"" << ima->id.name << "\" >\n";
 					ostr << "\t<attributes>\n";
-					string texpath = ima->name;
+					string texpath(ima->name);
 					adjustPath(texpath);
 					ostr << "\t\t<filename value=\"" << texpath << "\" />\n";
-					ostr << "\t</attributes>\n";
-					ostr << "</shader>\n\n";
+					ostr << "\t</attributes>\n</shader>\n\n";
 					xmlfile << ostr.str();
 				}
 				break;
@@ -409,19 +530,235 @@ void yafrayFileRender_t::writeTextures()
 		}
 
 	}
+	
+	// If used, textures for the material 'TexFace' case
+	if (!imagetex.empty()) {
+		for (map<Image*, Material*>::const_iterator imgtex=imagetex.begin();
+					imgtex!=imagetex.end();++imgtex)
+		{
+			ostr.str("");
+			ostr << "<shader type=\"image\" name=\"" << imgtex->first->id.name << "\" >\n";
+			ostr << "\t<attributes>\n";
+			string texpath(imgtex->first->name);
+			adjustPath(texpath);
+			ostr << "\t\t<filename value=\"" << texpath << "\" />\n";
+			ostr << "\t</attributes>\n</shader>\n\n";
+			xmlfile << ostr.str();
+		}
+	}
+
+}
+
+void yafrayFileRender_t::writeShader(const string &shader_name, Material* matr, const string &facetexname)
+{
+	ostr.str("");
+	ostr << "<shader type=\"blendershader\" name=\"" << shader_name << "\" >\n";
+	ostr << "\t<attributes>\n";
+	float diff = matr->alpha;
+	ostr << "\t\t<color r=\"" << matr->r*diff << "\" g=\"" << matr->g*diff << "\" b=\"" << matr->b*diff << "\" />\n";
+	ostr << "\t\t<specular_color r=\"" << matr->specr << "\" g=\"" << matr->specg << "\" b=\"" << matr->specb << "\" />\n";
+	ostr << "\t\t<mirror_color r=\"" << matr->mirr << "\" g=\"" << matr->mirg << "\" b=\"" << matr->mirb << "\" />\n";
+	ostr << "\t\t<diffuse_reflect value=\"" << matr->ref << "\" />\n";
+	ostr << "\t\t<specular_amount value=\"" << matr->spec << "\" />\n";
+	ostr << "\t\t<hard value=\"" << matr->har << "\" />\n";
+	ostr << "\t\t<alpha value=\"" << matr->alpha << "\" />\n";
+	// if no GI used, the GIpower parameter is not always initialized, so in that case ignore it
+	float bg_mult = (R.r.GImethod==0) ? 1 : R.r.GIpower;
+	ostr << "\t\t<emit value=\"" << (matr->emit * bg_mult) << "\" />\n";
+
+	// reflection/refraction
+	if ( (matr->mode & MA_RAYMIRROR) || (matr->mode & MA_RAYTRANSP) )
+		ostr << "\t\t<IOR value=\"" << matr->ang << "\" />\n";
+	if (matr->mode & MA_RAYMIRROR) {
+		float rf = matr->ray_mirror;
+		// blender uses mir color for reflection as well
+		ostr << "\t\t<reflected r=\"" << matr->mirr << "\" g=\"" << matr->mirg << "\" b=\"" << matr->mirb << "\" />\n";
+		ostr << "\t\t<min_refle value=\""<< rf << "\" />\n";
+		if (matr->ray_depth>maxraydepth) maxraydepth = matr->ray_depth;
+	}
+	if (matr->mode & MA_RAYTRANSP) 
+	{
+		float tr=1.0-matr->alpha;
+		ostr << "\t\t<transmitted r=\"" << matr->r * tr << "\" g=\"" << matr->g * tr << "\" b=\"" << matr->b * tr << "\" />\n";
+		// tir on by default
+		ostr << "\t\t<tir value=\"on\" />\n";
+		if (matr->ray_depth_tra>maxraydepth) maxraydepth = matr->ray_depth_tra;
+	}
+
+	string Mmode = "";
+	if (matr->mode & MA_TRACEBLE) Mmode += "traceable";
+	if (matr->mode & MA_SHADOW) Mmode += " shadow";
+	if (matr->mode & MA_SHLESS) Mmode += " shadeless";
+	if (matr->mode & MA_VERTEXCOL) Mmode += " vcol_light";
+	if (matr->mode & MA_VERTEXCOLP) Mmode += " vcol_paint";
+	if (matr->mode & MA_ZTRA) Mmode += " ztransp";
+	if (matr->mode & MA_ONLYSHADOW) Mmode += " onlyshadow";
+	if (Mmode!="") ostr << "\t\t<matmodes value=\"" << Mmode << "\" />\n";
+	ostr << "\t</attributes>\n";
+	xmlfile << ostr.str();
+	
+	// modulators
+	// first modulator is the texture of the face, if used (TexFace mode)
+	if (facetexname.length()!=0) {
+			ostr.str("");
+			ostr << "\t<modulator>\n";
+			ostr << "\t\t<input value=\"" << facetexname << "\" />\n";
+			ostr << "\t\t<color value=\"1\" />\n";
+			ostr << "\t</modulator>\n";
+			xmlfile << ostr.str();
+	}
+
+	for (int m2=0;m2<8;m2++) {
+
+		if (matr->septex & (1<<m2)) continue;// all active channels
+
+		// ignore null mtex
+		MTex* mtex = matr->mtex[m2];
+		if (mtex==NULL) continue;
+
+		// ignore null tex
+		Tex* tex = mtex->tex;
+		if (tex==NULL) continue;
+
+		map<string, MTex*>::const_iterator mtexL = used_textures.find(string(tex->id.name));
+		if (mtexL!=used_textures.end()) {
+
+			ostr.str("");
+			ostr << "\t<modulator>\n";
+			// when no facetex used, shader_name is created from original material name
+			if (facetexname.length()!=0)
+				ostr << "\t\t<input value=\"" << matr->id.name << "_map" << m2 << "\" />\n";
+			else
+				ostr << "\t\t<input value=\"" << shader_name << "_map" << m2 << "\" />\n";
+
+			// blendtype
+			string ts = "mix";
+			if (mtex->blendtype==MTEX_MUL) ts="mul";
+			else if (mtex->blendtype==MTEX_ADD) ts="add";
+			else if (mtex->blendtype==MTEX_SUB) ts="sub";
+			ostr << "\t\t<mode value=\"" << ts << "\" />\n";
+
+			// texture color (for use with MUL and/or no_rgb etc..)
+			ostr << "\t\t<texcol r=\"" << mtex->r << "\" g=\"" << mtex->g << "\" b=\"" << mtex->b << "\" />\n";
+
+			// texture contrast, brightness & color adjustment
+			ostr << "\t\t<filtercolor r=\"" << tex->rfac << "\" g=\"" << tex->gfac << "\" b=\"" << tex->bfac << "\" />\n";
+			ostr << "\t\t<contrast value=\"" << tex->contrast << "\" />\n";
+			ostr << "\t\t<brightness value=\"" << tex->bright << "\" />\n";
+
+			// all texture flags now are switches, having the value 1 or -1 (negative option)
+			// the negative option only used for the intensity modulation options.
+
+			// material (diffuse) color, amount controlled by colfac (see below)
+			if (mtex->mapto & MAP_COL)
+				ostr << "\t\t<color value=\"1\" />\n";
+
+			// bumpmapping
+			if ((mtex->mapto & MAP_NORM) || (mtex->maptoneg & MAP_NORM)) {
+				// for yafray, bump factor is negated (unless negative option of 'Nor', is not affected by 'Neg')
+				// scaled down quite a bit for yafray
+				float nf = -mtex->norfac;
+				if (mtex->maptoneg & MAP_NORM) nf *= -1.f;
+				ostr << "\t\t<normal value=\"" << (nf/60.f) << "\" />\n";
+
+			}
+
+			// all blender texture modulation as switches, either 1 or -1 (negative state of button)
+			// Csp, specular color modulation
+			if (mtex->mapto & MAP_COLSPEC)
+				ostr << "\t\t<colspec value=\"1\" />\n";
+
+			// CMir, mirror color  modulation
+			if (mtex->mapto & MAP_COLMIR)
+				ostr << "\t\t<colmir value=\"1\" />\n";
+
+			// Ref, diffuse reflection amount  modulation
+			if ((mtex->mapto & MAP_REF) || (mtex->maptoneg & MAP_REF)) {
+				int t = 1;
+				if (mtex->maptoneg & MAP_REF) t = -1;
+				ostr << "\t\t<difref value=\"" << t << "\" />\n";
+			}
+
+			// Spec, specular amount mod
+			if ((mtex->mapto & MAP_SPEC) || (mtex->maptoneg & MAP_SPEC)) {
+				int t = 1;
+				if (mtex->maptoneg & MAP_SPEC) t = -1;
+				ostr << "\t\t<specular value=\"" << t << "\" />\n";
+			}
+
+			// hardness modulation
+			if ((mtex->mapto & MAP_HAR) || (mtex->maptoneg & MAP_HAR)) {
+				int t = 1;
+				if (mtex->maptoneg & MAP_HAR) t = -1;
+				ostr << "\t\t<hard value=\"" << t << "\" />\n";
+			}
+
+			// alpha modulation
+			if ((mtex->mapto & MAP_ALPHA) || (mtex->maptoneg & MAP_ALPHA)) {
+				int t = 1;
+				if (mtex->maptoneg & MAP_ALPHA) t = -1;
+				ostr << "\t\t<alpha value=\"" << t << "\" />\n";
+
+			}
+
+			// emit modulation
+			if ((mtex->mapto & MAP_EMIT) || (mtex->maptoneg & MAP_EMIT)) {
+				int t = 1;
+				if (mtex->maptoneg & MAP_EMIT) t = -1;
+				ostr << "\t\t<emit value=\"" << t << "\" />\n";
+			}
+
+			// texture flag, combination of strings
+			if (mtex->texflag & (MTEX_RGBTOINT | MTEX_STENCIL | MTEX_NEGATIVE)) {
+				ts = "";
+				if (mtex->texflag & MTEX_RGBTOINT) ts += "no_rgb ";
+				if (mtex->texflag & MTEX_STENCIL) ts += "stencil ";
+				if (mtex->texflag & MTEX_NEGATIVE) ts += "negative";
+				ostr << "\t\t<texflag value=\"" << ts << "\" />\n";
+			}
+
+			// colfac, controls amount of color modulation
+			ostr << "\t\t<colfac value=\"" << mtex->colfac << "\" />\n";
+
+			// def_var
+			ostr << "\t\t<def_var value=\"" << mtex->def_var << "\" />\n";
+
+			//varfac
+			ostr << "\t\t<varfac value=\"" << mtex->varfac << "\" />\n";
+
+			if ((tex->imaflag & (TEX_CALCALPHA | TEX_USEALPHA)) || (tex->flag & TEX_NEGALPHA)) {
+				ts = "";
+				if (tex->imaflag & TEX_CALCALPHA) ts += "calc_alpha ";
+				if (tex->imaflag & TEX_USEALPHA) ts += "use_alpha ";
+				if (tex->flag & TEX_NEGALPHA) ts += "neg_alpha";
+				ostr << "\t\t<alpha_flag value=\"" << ts << "\" />\n";
+			}
+
+			ostr << "\t</modulator>\n";
+			xmlfile << ostr.str();
+
+		}
+	}
+	xmlfile << "</shader>\n\n";
+
 }
 
 
 // write all materials & modulators
 void yafrayFileRender_t::writeMaterialsAndModulators()
 {
+	// shaders/mappers for regular texture (or non-texture) mode
+	// In case material has texface mode, and all faces have an image texture,
+	// this shader will not be used, but still be written
 	for (map<string, Material*>::const_iterator blendmat=used_materials.begin();
-		blendmat!=used_materials.end();++blendmat) {
+			blendmat!=used_materials.end();++blendmat)
+	{
 
 		Material* matr = blendmat->second;
 
-		// blendermappers
-		for (int m=0;m<8;m++) {
+		// mapper(s)
+		for (int m=0;m<8;m++)
+		{
 
 			if (matr->septex & (1<<m)) continue;// all active channels
 
@@ -432,8 +769,7 @@ void yafrayFileRender_t::writeMaterialsAndModulators()
 			Tex* tex = mtex->tex;
 			if (tex==NULL) continue;
 
-			// now included the full name
-			map<string, pair<Material*, MTex*> >::const_iterator mtexL = used_textures.find(string(tex->id.name));
+			map<string, MTex*>::const_iterator mtexL = used_textures.find(string(tex->id.name));
 			if (mtexL!=used_textures.end()) {
 				ostr.str("");
 				ostr << "<shader type=\"blendermapper\" name=\"" << blendmat->first + "_map" << m <<"\"";
@@ -448,34 +784,30 @@ void yafrayFileRender_t::writeMaterialsAndModulators()
 					else	// also for refl. map
 						MTC_Mat4CpyMat4(texmat, maincam_obj->obmat);
 					MTC_Mat4Invert(itexmat, texmat);
-					ostr << "\n           m00=\"" << itexmat[0][0] << "\" m01=\"" << itexmat[1][0]
-							 <<           "\" m02=\"" << itexmat[2][0] << "\" m03=\"" << itexmat[3][0] << "\"\n\t";
-					ostr <<   "           m10=\"" << itexmat[0][1] << "\" m11=\"" << itexmat[1][1]
-							 <<           "\" m12=\"" << itexmat[2][1] << "\" m13=\"" << itexmat[3][1] << "\"\n\t";
-					ostr <<   "           m20=\"" << itexmat[0][2] << "\" m21=\"" << itexmat[1][2]
-							 <<           "\" m22=\"" << itexmat[2][2] << "\" m23=\"" << itexmat[3][2] << "\"\n\t";
-					ostr <<   "           m30=\"" << itexmat[0][3] << "\" m31=\"" << itexmat[1][3]
-							 <<           "\" m32=\"" << itexmat[2][3] << "\" m33=\"" << itexmat[3][3] << "\">\n";
+					ostr << "\n\t\tm00=\"" << itexmat[0][0] << "\" m01=\"" << itexmat[1][0]
+							<< "\" m02=\"" << itexmat[2][0] << "\" m03=\"" << itexmat[3][0] << "\"\n";
+					ostr << "\t\tm10=\"" << itexmat[0][1] << "\" m11=\"" << itexmat[1][1]
+							<< "\" m12=\"" << itexmat[2][1] << "\" m13=\"" << itexmat[3][1] << "\"\n";
+					ostr << "\t\tm20=\"" << itexmat[0][2] << "\" m21=\"" << itexmat[1][2]
+							<< "\" m22=\"" << itexmat[2][2] << "\" m23=\"" << itexmat[3][2] << "\"\n";
+					ostr << "\t\tm30=\"" << itexmat[0][3] << "\" m31=\"" << itexmat[1][3]
+							<< "\" m32=\"" << itexmat[2][3] << "\" m33=\"" << itexmat[3][3] << "\">\n";
 				}
 				else ostr << ">\n";
 				ostr << "\t<attributes>\n";
 
-				if ((tex->flag & TEX_COLORBAND) & (tex->coba!=NULL))
+				// use image name instead of texname when texture is image
+				if ((tex->type==TEX_IMAGE) && tex->ima)
+					ostr << "\t\t<input value=\"" << tex->ima->id.name << "\" />\n";
+				else if ((tex->flag & TEX_COLORBAND) & (tex->coba!=NULL))
 					ostr << "\t\t<input value=\"" << mtexL->first + "_coba" << "\" />\n";
 				else
 					ostr << "\t\t<input value=\"" << mtexL->first << "\" />\n";
 
-				// size, if the texturetype is clouds/marble/wood, also take noisesize into account
-				float sc = 1;
-				if ((tex->type==TEX_CLOUDS) || (tex->type==TEX_MARBLE) || (tex->type==TEX_WOOD)) {
-					sc = tex->noisesize;
-					if (sc!=0) sc = 1.f/sc;
-
-				}
 				// texture size
-				ostr << "\t\t<sizex value=\"" << mtex->size[0]*sc << "\" />\n";
-				ostr << "\t\t<sizey value=\"" << mtex->size[1]*sc << "\" />\n";
-				ostr << "\t\t<sizez value=\"" << mtex->size[2]*sc << "\" />\n";
+				ostr << "\t\t<sizex value=\"" << mtex->size[0] << "\" />\n";
+				ostr << "\t\t<sizey value=\"" << mtex->size[1] << "\" />\n";
+				ostr << "\t\t<sizez value=\"" << mtex->size[2] << "\" />\n";
 
 				// texture offset
 				ostr << "\t\t<ofsx value=\"" << mtex->ofs[0] << "\" />\n";
@@ -483,7 +815,7 @@ void yafrayFileRender_t::writeMaterialsAndModulators()
 				ostr << "\t\t<ofsz value=\"" << mtex->ofs[2] << "\" />\n";
 
 				// texture coordinates, have to disable 'sticky' in Blender
-				if ((mtex->texco & TEXCO_UV) || (matr->mode & MA_FACETEXTURE))
+				if (mtex->texco & TEXCO_UV)
 					ostr << "\t\t<texco value=\"uv\" />\n";
 				else if ((mtex->texco & TEXCO_GLOB) || (mtex->texco & TEXCO_OBJECT))
 					// object mode is also set as global, but the object matrix was specified above with <modulator..>
@@ -497,6 +829,12 @@ void yafrayFileRender_t::writeMaterialsAndModulators()
 				else if (mtex->texco & TEXCO_REFL)
 					ostr << "\t\t<texco value=\"reflect\" />\n";
 
+				// texture projection axes, both image & procedural
+				string proj = "nxyz";		// 'n' for 'none'
+				ostr << "\t\t<proj_x value=\"" << proj[mtex->projx] << "\" />\n";
+				ostr << "\t\t<proj_y value=\"" << proj[mtex->projy] << "\" />\n";
+				ostr << "\t\t<proj_z value=\"" << proj[mtex->projz] << "\" />\n";
+
 				// texture mapping parameters only relevant to image type
 				if (tex->type==TEX_IMAGE) {
 					if (mtex->mapping==MTEX_FLAT)
@@ -508,12 +846,6 @@ void yafrayFileRender_t::writeMaterialsAndModulators()
 					else if (mtex->mapping==MTEX_SPHERE)
 						ostr << "\t\t<mapping value=\"sphere\" />\n";
 
-					// texture projection axes
-					string proj = "nxyz";		// 'n' for 'none'
-					ostr << "\t\t<proj_x value=\"" << proj[mtex->projx] << "\" />\n";
-					ostr << "\t\t<proj_y value=\"" << proj[mtex->projy] << "\" />\n";
-					ostr << "\t\t<proj_z value=\"" << proj[mtex->projz] << "\" />\n";
-
 					// repeat
 					ostr << "\t\t<xrepeat value=\"" << tex->xrepeat << "\" />\n";
 					ostr << "\t\t<yrepeat value=\"" << tex->yrepeat << "\" />\n";
@@ -547,185 +879,45 @@ void yafrayFileRender_t::writeMaterialsAndModulators()
 			}
 		}
 
-		// blendershaders + modulators
-		ostr.str("");
-		ostr << "<shader type=\"blendershader\" name=\"" << blendmat->first << "\" >\n";
-		ostr << "\t<attributes>\n";
-		float diff=matr->alpha;
-		ostr << "\t\t<color r=\"" << matr->r*diff << "\" g=\"" << matr->g*diff << "\" b=\"" << matr->b*diff << "\" />\n";
-		ostr << "\t\t<specular_color r=\"" << matr->specr << "\" g=\"" << matr->specg << "\" b=\"" << matr->specb<< "\" />\n";
-		ostr << "\t\t<mirror_color r=\"" << matr->mirr << "\" g=\"" << matr->mirg << "\" b=\"" << matr->mirb << "\" />\n";
-		ostr << "\t\t<diffuse_reflect value=\"" << matr->ref << "\" />\n";
-		ostr << "\t\t<specular_amount value=\"" << matr->spec << "\" />\n";
-		ostr << "\t\t<hard value=\"" << matr->har << "\" />\n";
-		ostr << "\t\t<alpha value=\"" << matr->alpha << "\" />\n";
-		// if no GI used, the GIpower parameter is not always initialized, so in that case ignore it
-		float bg_mult;
-		if (R.r.GImethod==0) bg_mult=1; else bg_mult=R.r.GIpower;
-		ostr << "\t\t<emit value=\"" << (matr->emit * bg_mult) << "\" />\n";
-
-		// reflection/refraction
-		if ( (matr->mode & MA_RAYMIRROR) || (matr->mode & MA_RAYTRANSP) )
-			ostr << "\t\t<IOR value=\"" << matr->ang << "\" />\n";
-		if (matr->mode & MA_RAYMIRROR) {
-			float rf = matr->ray_mirror;
-			// blender uses mir color for reflection as well
-			ostr << "\t\t<reflected r=\"" << matr->mirr << "\" g=\"" << matr->mirg << "\" b=\"" << matr->mirb << "\" />\n";
-			ostr << "\t\t<min_refle value=\""<< rf << "\" />\n";
-			if (matr->ray_depth>maxraydepth) maxraydepth = matr->ray_depth;
-		}
-		if (matr->mode & MA_RAYTRANSP) 
-		{
-			float tr=1.0-matr->alpha;
-			ostr << "\t\t<transmitted r=\"" << matr->r * tr << "\" g=\"" << matr->g * tr << "\" b=\"" << matr->b * tr << "\" />\n";
-			// tir on by default
-			ostr << "\t\t<tir value=\"on\" />\n";
-			if (matr->ray_depth_tra>maxraydepth) maxraydepth = matr->ray_depth_tra;
-		}
-
-		string Mmode = "";
-		if (matr->mode & MA_TRACEBLE) Mmode += "traceable";
-		if (matr->mode & MA_SHADOW) Mmode += " shadow";
-		if (matr->mode & MA_SHLESS) Mmode += " shadeless";
-		if (matr->mode & MA_VERTEXCOL) Mmode += " vcol_light";
-		if (matr->mode & MA_VERTEXCOLP) Mmode += " vcol_paint";
-		if (matr->mode & MA_ZTRA) Mmode += " ztransp";
-		if (matr->mode & MA_ONLYSHADOW) Mmode += " onlyshadow";
-		if (Mmode!="") ostr << "\t\t<matmodes value=\"" << Mmode << "\" />\n";
-		ostr << "\t</attributes>\n";
-		xmlfile << ostr.str();
-
-		// modulators
-		for (int m2=0;m2<8;m2++) {
-
-			if (matr->septex & (1<<m2)) continue;// all active channels
-
-			// ignore null mtex
-			MTex* mtex = matr->mtex[m2];
-			if (mtex==NULL) continue;
-
-			// ignore null tex
-			Tex* tex = mtex->tex;
-			if (tex==NULL) continue;
-
-			map<string, pair<Material*, MTex*> >::const_iterator mtexL = used_textures.find(string(tex->id.name));
-			if (mtexL!=used_textures.end()) {
-
-				ostr.str("");
-				ostr << "\t<modulator>\n";
-				ostr << "\t\t<input value=\"" << blendmat->first + "_map" << m2 << "\" />\n";
-
-				// blendtype
-				string ts = "mix";
-				if (mtex->blendtype==MTEX_MUL) ts="mul";
-				else if (mtex->blendtype==MTEX_ADD) ts="add";
-				else if (mtex->blendtype==MTEX_SUB) ts="sub";
-				ostr << "\t\t<mode value=\"" << ts << "\" />\n";
-
-				// texture color (for use with MUL and/or no_rgb etc..)
-				ostr << "\t\t<texcol r=\"" << mtex->r << "\" g=\"" << mtex->g << "\" b=\"" << mtex->b << "\" />\n";
-
-				// texture contrast, brightness & color adjustment
-				ostr << "\t\t<filtercolor r=\"" << tex->rfac << "\" g=\"" << tex->gfac << "\" b=\"" << tex->bfac << "\" />\n";
-				ostr << "\t\t<contrast value=\"" << tex->contrast << "\" />\n";
-				ostr << "\t\t<brightness value=\"" << tex->bright << "\" />\n";
-
-				// all texture flags now are switches, having the value 1 or -1 (negative option)
-				// the negative option only used for the intensity modulation options.
-
-				// material (diffuse) color, amount controlled by colfac (see below)
-				if (mtex->mapto & MAP_COL)
-					ostr << "\t\t<color value=\"1\" />\n";
-
-				// bumpmapping
-				if ((mtex->mapto & MAP_NORM) || (mtex->maptoneg & MAP_NORM)) {
-					// for yafray, bump factor is negated (unless negative option of 'Nor', is not affected by 'Neg')
-					// scaled down quite a bit for yafray
-					float nf = -mtex->norfac;
-					if (mtex->maptoneg & MAP_NORM) nf *= -1.f;
-					if (tex->type==TEX_IMAGE) nf/=60.f; else nf/=30.f;
-					ostr << "\t\t<normal value=\"" << nf << "\" />\n";
-
-				}
+		// shader + modulators
+		writeShader(blendmat->first, matr);
 
-				// all blender texture modulation as switches, either 1 or -1 (negative state of button)
-				// Csp, specular color modulation
-				if (mtex->mapto & MAP_COLSPEC)
-					ostr << "\t\t<colspec value=\"1\" />\n";
-
-				// CMir, mirror color  modulation
-				if (mtex->mapto & MAP_COLMIR)
-					ostr << "\t\t<colmir value=\"1\" />\n";
-
-				// Ref, diffuse reflection amount  modulation
-				if ((mtex->mapto & MAP_REF) || (mtex->maptoneg & MAP_REF)) {
-					int t = 1;
-					if (mtex->maptoneg & MAP_REF) t = -1;
-					ostr << "\t\t<difref value=\"" << t << "\" />\n";
-				}
-
-				// Spec, specular amount mod
-				if ((mtex->mapto & MAP_SPEC) || (mtex->maptoneg & MAP_SPEC)) {
-					int t = 1;
-					if (mtex->maptoneg & MAP_SPEC) t = -1;
-					ostr << "\t\t<specular value=\"" << t << "\" />\n";
-				}
-
-				// hardness modulation
-				if ((mtex->mapto & MAP_HAR) || (mtex->maptoneg & MAP_HAR)) {
-					int t = 1;
-					if (mtex->maptoneg & MAP_HAR) t = -1;
-					ostr << "\t\t<hard value=\"" << t << "\" />\n";
-				}
- 
-				// alpha modulation
-				if ((mtex->mapto & MAP_ALPHA) || (mtex->maptoneg & MAP_ALPHA)) {
-					int t = 1;
-					if (mtex->maptoneg & MAP_ALPHA) t = -1;
-					ostr << "\t\t<alpha value=\"" << t << "\" />\n";
-
-				}
-
-				// emit modulation
-				if ((mtex->mapto & MAP_EMIT) || (mtex->maptoneg & MAP_EMIT)) {
-					int t = 1;
-					if (mtex->maptoneg & MAP_EMIT) t = -1;
-					ostr << "\t\t<emit value=\"" << t << "\" />\n";
-				}
-
-				// texture flag, combination of strings
-				if (mtex->texflag & (MTEX_RGBTOINT | MTEX_STENCIL | MTEX_NEGATIVE)) {
-					ts = "";
-					if (mtex->texflag & MTEX_RGBTOINT) ts += "no_rgb ";
-					if (mtex->texflag & MTEX_STENCIL) ts += "stencil ";
-					if (mtex->texflag & MTEX_NEGATIVE) ts += "negative";
-					ostr << "\t\t<texflag value=\"" << ts << "\" />\n";
-				}
-
-				// colfac, controls amount of color modulation
-				ostr << "\t\t<colfac value=\"" << mtex->colfac << "\" />\n";
+	}
 
-				// def_var
-				ostr << "\t\t<def_var value=\"" << mtex->def_var << "\" />\n";
+	// write the mappers & shaders for the TexFace case
+	if (!imagetex.empty()) {
+		// Yafray doesn't have per-face-textures, only per-face-shaders,
+		// so create as many mappers/shaders as the images used by the object
+		int snum = 0;
+		for (map<Image*, Material*>::const_iterator imgtex=imagetex.begin();
+				imgtex!=imagetex.end();++imgtex)
+		{
+			Material* matr = imgtex->second;
 
-				//varfac
-				ostr << "\t\t<varfac value=\"" << mtex->varfac << "\" />\n";
+			// mapper
+			ostr.str("");
+			ostr << "<shader type=\"blendermapper\" name=\"" << string(matr->id.name) + "_ftex_mp" << snum << "\" >\n";
+			ostr << "\t<attributes>\n";
+			ostr << "\t\t<input value=\"" << imgtex->first->id.name << "\" />\n";
+			// all yafray default settings, except for texco, so no need to set others
+			ostr << "\t\t<texco value=\"uv\" />\n";
+			ostr << "\t</attributes>\n";
+			ostr << "</shader>\n\n";
+			xmlfile << ostr.str();
 
-				if ((tex->imaflag & (TEX_CALCALPHA | TEX_USEALPHA)) || (tex->flag & TEX_NEGALPHA)) {
-					ts = "";
-					if (tex->imaflag & TEX_CALCALPHA) ts += "calc_alpha ";
-					if (tex->imaflag & TEX_USEALPHA) ts += "use_alpha ";
-					if (tex->flag & TEX_NEGALPHA) ts += "neg_alpha";
-					ostr << "\t\t<alpha_flag value=\"" << ts << "\" />\n";
-				}
+			// shader, remember name, used later when writing per-face-shaders
+			ostr.str("");
+			ostr << matr->id.name <<  "_ftex_sh" << snum;
+			string shader_name = ostr.str();
+			imgtex_shader[imgtex->first] = shader_name;
 
-				ostr << "\t</modulator>\n";
-				xmlfile << ostr.str();
+			ostr.str("");
+			ostr << matr->id.name << "_ftex_mp" << snum++;
+			writeShader(shader_name, matr, ostr.str());
 
-			}
 		}
-		xmlfile << "</shader>\n\n";
 	}
+
 }
 
 
@@ -744,35 +936,45 @@ void yafrayFileRender_t::writeObject(Object* obj, const vector<VlakRen*> &VLR_li
 	xmlfile << ostr.str();
 
 	ostr.str("");
-	ostr << "<object name=\"" << obj->id.name+2 << "\"";
-	// yafray still needs default shader name in object def.,
-	// since we write a shader with every face, simply use the material of the first face
-	// if this is an empty string, assume default mat
-	char* matname = VLR_list[0]->mat->id.name;
-	bool shadow=VLR_list[0]->mat->mode & MA_TRACEBLE;
-	ostr <<" shadow=\""<< (shadow ? "on" : "off" )<<"\" ";
-	bool caus = (((VLR_list[0]->mat->mode & MA_RAYTRANSP) | (VLR_list[0]->mat->mode & MA_RAYMIRROR))!=0);
-	if (caus) ostr << "caus_IOR=\"" << VLR_list[0]->mat->ang << "\"";
-	if (strlen(matname)==0) matname = "blender_default"; 
+	ostr << "<object name=\"" << obj->id.name << "\"";
+	// Yafray still needs default shader name in object def.,
+	// since we write a shader with every face, simply use the material of the first face.
+	// If this is an empty string, assume default material.
+	VlakRen* face0 = VLR_list[0];
+	Material* face0mat = face0->mat;
+	string matname(face0mat->id.name);
+	// use name in imgtex_shader list if 'TexFace' enabled for this material
+	if (face0mat->mode & MA_FACETEXTURE) {
+		TFace* tface = face0->tface;
+		if (tface) {
+			Image* fimg = (Image*)tface->tpage;
+			if (fimg) matname = imgtex_shader[fimg];
+		}
+	}
+	bool shadow = face0mat->mode & MA_TRACEBLE;
+	ostr <<" shadow=\""<< (shadow ? "on" : "off" ) << "\" ";
+	bool caus = (((face0mat->mode & MA_RAYTRANSP) | (face0->mat->mode & MA_RAYMIRROR))!=0);
+	if (caus) ostr << "caus_IOR=\"" << face0mat->ang << "\"";
+	if (matname.length()==0) matname = "blender_default";
 	ostr << " shader_name=\"" << matname << "\" >\n";
 	ostr << "\t<attributes>\n";
 	if (caus)
 	{
-			float tr = 1.0-VLR_list[0]->mat->alpha;
-			ostr << "\t\t<caus_tcolor r=\"" << VLR_list[0]->mat->r*tr
-					 << "\" g=\"" << VLR_list[0]->mat->g*tr
-					 << "\" b=\"" << VLR_list[0]->mat->b*tr << "\" />\n";
-			tr = VLR_list[0]->mat->ray_mirror;
-			ostr << "\t\t<caus_rcolor r=\"" << VLR_list[0]->mat->mirr*tr
-					 << "\" g=\"" << VLR_list[0]->mat->mirg*tr
-					 << "\" b=\"" << VLR_list[0]->mat->mirb*tr << "\" />\n";
+			float tr = 1.0-face0mat->alpha;
+			ostr << "\t\t<caus_tcolor r=\"" << face0mat->r*tr
+					 << "\" g=\"" << face0mat->g*tr
+					 << "\" b=\"" << face0mat->b*tr << "\" />\n";
+			tr = face0mat->ray_mirror;
+			ostr << "\t\t<caus_rcolor r=\"" << face0mat->mirr*tr
+					 << "\" g=\"" << face0mat->mirg*tr
+					 << "\" b=\"" << face0mat->mirb*tr << "\" />\n";
 	}
 	ostr << "\t</attributes>\n";
 	xmlfile << ostr.str();
 
 	// if any face in the Blender mesh uses an orco texture, every face has orco coords,
 	// so only need to check the first facevtx.orco in the list if they need to be exported
-	bool EXPORT_ORCO = (VLR_list[0]->v1->orco!=NULL);
+	bool EXPORT_ORCO = (face0->v1->orco!=NULL);
 
 	string has_orco = "off";
 	if (EXPORT_ORCO) has_orco = "on";
@@ -793,7 +995,7 @@ void yafrayFileRender_t::writeObject(Object* obj, const vector<VlakRen*> &VLR_li
 		// If AutoSmooth not used, since yafray currently cannot specify if a face is smooth
 		// or flat shaded, the smooth flag of the first face is used to determine
 		// the shading for the whole mesh
-		if (VLR_list[0]->flag & ME_SMOOTH)
+		if (face0->flag & ME_SMOOTH)
 			xmlfile << "\t<mesh autosmooth=\"90\" has_orco=\"" << has_orco << "\" >\n";
 		else
 			xmlfile << "\t<mesh autosmooth=\"0.1\" has_orco=\"" << has_orco << "\" >\n";	//0 shows artefacts
@@ -885,33 +1087,38 @@ void yafrayFileRender_t::writeObject(Object* obj, const vector<VlakRen*> &VLR_li
 		VlakRen* vlr = *fci2;
 		Material* fmat = vlr->mat;
 		bool EXPORT_VCOL = ((fmat->mode & (MA_VERTEXCOL|MA_VERTEXCOLP))!=0);
-		char* fmatname = fmat->id.name;
-		if (strlen(fmatname)==0) fmatname = "blender_default"; 
-		TFace* uvc = vlr->tface;	// possible uvcoords (v upside down)
-		int idx1, idx2, idx3;
-
-		idx1 = vert_idx.find(vlr->v1)->second;
-		idx2 = vert_idx.find(vlr->v2)->second;
-		idx3 = vert_idx.find(vlr->v3)->second;
-
+		string fmatname(fmat->id.name);
+		// use name in imgtex_shader list if 'TexFace' enabled for this face material
+		if (fmat->mode & MA_FACETEXTURE) {
+			TFace* tface = vlr->tface;
+			if (tface) {
+				Image* fimg = (Image*)tface->tpage;
+				if (fimg) fmatname = imgtex_shader[fimg];
+			}
+		}
+		else if (fmatname.length()==0) fmatname = "blender_default";
+	
+		int idx1 = vert_idx.find(vlr->v1)->second;
+		int idx2 = vert_idx.find(vlr->v2)->second;
+		int idx3 = vert_idx.find(vlr->v3)->second;
 		// make sure the indices point to the vertices when orco coords exported
 		if (EXPORT_ORCO) { idx1*=2;  idx2*=2;  idx3*=2; }
 
 		ostr.str("");
 		ostr << "\t\t\t<f a=\"" << idx1 << "\" b=\"" << idx2 << "\" c=\"" << idx3 << "\"";
 
+		TFace* uvc = vlr->tface;	// possible uvcoords (v upside down)
 		if (uvc) {
 			// use correct uv coords for this triangle
-			if (vlr->flag & R_FACE_SPLIT) {
-				ostr << " u_a=\"" << uvc->uv[0][0] << "\" v_a=\"" << 1-uvc->uv[0][1] << "\""
-						 << " u_b=\"" << uvc->uv[2][0] << "\" v_b=\"" << 1-uvc->uv[2][1] << "\""
-						 << " u_c=\"" << uvc->uv[3][0] << "\" v_c=\"" << 1-uvc->uv[3][1] << "\"";
-			}
-			else {
-				ostr << " u_a=\"" << uvc->uv[0][0] << "\" v_a=\"" << 1-uvc->uv[0][1] << "\""
-						 << " u_b=\"" << uvc->uv[1][0] << "\" v_b=\"" << 1-uvc->uv[1][1] << "\""
-						 << " u_c=\"" << uvc->uv[2][0] << "\" v_c=\"" << 1-uvc->uv[2][1] << "\"";
+			int ui1=0, ui2=1, ui3=2;
+			if (vlr->flag & R_DIVIDE_24) {
+				ui3++;
+				if (vlr->flag & R_FACE_SPLIT) { ui1++;  ui2++; }
 			}
+			else if (vlr->flag & R_FACE_SPLIT) { ui2++;  ui3++; }
+			ostr << " u_a=\"" << uvc->uv[ui1][0] << "\" v_a=\"" << 1-uvc->uv[ui1][1] << "\""
+					 << " u_b=\"" << uvc->uv[ui2][0] << "\" v_b=\"" << 1-uvc->uv[ui2][1] << "\""
+					 << " u_c=\"" << uvc->uv[ui3][0] << "\" v_c=\"" << 1-uvc->uv[ui3][1] << "\"";
 		}
 
 		// since Blender seems to need vcols when uvs are used, for yafray only export when the material actually uses vcols
@@ -982,7 +1189,7 @@ void yafrayFileRender_t::writeAllObjects()
 	for (map<Object*, vector<VlakRen*> >::const_iterator obi=all_objects.begin();
 			obi!=all_objects.end(); ++obi)
 	{
-	  // skip main duplivert object if in dupliMtx_list, written later
+		// skip main duplivert object if in dupliMtx_list, written later
 		Object* obj = obi->first;
 		if (dupliMtx_list.find(string(obj->id.name))!=dupliMtx_list.end()) continue;
 		writeObject(obj, obi->second, obj->obmat);
@@ -1031,7 +1238,7 @@ void yafrayFileRender_t::writeAllObjects()
 
 			// new name from original
 			ostr.str("");
-			ostr << "<object name=\"" << obj->id.name+2 << "_dup" << (curmtx>>4) << "\" original=\"" << obj->id.name+2 << "\" >\n";
+			ostr << "<object name=\"" << obj->id.name << "_dup" << (curmtx>>4) << "\" original=\"" << obj->id.name << "\" >\n";
 			xmlfile << ostr.str();
 			xmlfile << "\t<attributes>\n\t</attributes>\n\t<null/>\n</object>\n</transform>\n\n";
 
@@ -1150,11 +1357,16 @@ void yafrayFileRender_t::writeLamps()
 		// cast_shadows flag not used with softlight, spherelight or photonlight
 		if ((!is_softL) && (!is_sphereL) && (lamp->type!=LA_YF_PHOTON)) {
 			string lpmode="off";
-			// shadows only when Blender has shadow button enabled, only spots use LA_SHAD flag
-			if (R.r.mode & R_SHADOW)
-				if (((lamp->type==LA_SPOT) && (lamp->mode & LA_SHAD)) || (lamp->mode & LA_SHAD_RAY)) lpmode="on";
+			// Shadows only when Blender has shadow button enabled, only spots use LA_SHAD flag.
+			// Also blender hemilights exported as sunlights which might have shadow flag set
+			// should have cast_shadows set to off (reported by varuag)
+			if (lamp->type!=LA_HEMI) {
+				if (R.r.mode & R_SHADOW)
+					if (((lamp->type==LA_SPOT) && (lamp->mode & LA_SHAD)) || (lamp->mode & LA_SHAD_RAY)) lpmode="on";
+			}
 			ostr << " cast_shadows=\"" << lpmode << "\"";
 		}
+
 		
 		// spot specific stuff
 		bool has_halo = ((lamp->type==LA_SPOT) && (lamp->mode & LA_HALO) && (lamp->haint>0.0));
@@ -1287,7 +1499,7 @@ void yafrayFileRender_t::writeCamera()
 void yafrayFileRender_t::writeHemilight()
 {
 	ostr.str("");
-	ostr << "<light type=\"hemilight\" name=\"hemi_LT\" power=\"1.0\" ";
+	ostr << "<light type=\"hemilight\" name=\"hemi_LT\" power=\"" << R.r.GIpower << "\"";
 	switch (R.r.GIquality)
 	{
 		case 1 :
@@ -1311,7 +1523,7 @@ void yafrayFileRender_t::writePathlight()
 				 << "\" caus_depth=\""<<R.r.GIcausdepth<< "\" search=\""<< R.r.GImixphotons<<"\" >"<<endl;
 		ostr << "</light>"<<endl;
 	}
-	ostr << "<light type=\"pathlight\" name=\"path_LT\" power=\"1.0\" ";
+	ostr << "<light type=\"pathlight\" name=\"path_LT\" power=\"" << R.r.GIindirpower << "\"";
 	ostr << " depth=\"" << ((R.r.GIphotons) ? 1 : R.r.GIdepth) << "\" caus_depth=\"" << R.r.GIcausdepth <<"\"\n";
 	if(R.r.GIdirect && R.r.GIphotons) ostr << "direct=\"on\"" << endl;
 	if (R.r.GIcache && ! (R.r.GIdirect && R.r.GIphotons))
@@ -1327,12 +1539,10 @@ void yafrayFileRender_t::writePathlight()
 		}
 		float aspect = 1;
 		if (R.r.xsch < R.r.ysch) aspect = float(R.r.xsch)/float(R.r.ysch);
-		//float sbase = 2.0*atan(0.5/(mainCamLens/(aspect*32.0)))/float(R.r.xsch);
 		float sbase = 2.0/float(R.r.xsch);
 		ostr << " cache=\"on\" use_QMC=\"on\" threshold=\"" <<R.r.GIrefinement<<"\""<<endl;
 		ostr << " cache_size=\"" << sbase*R.r.GIpixelspersample << "\" shadow_threshold=\"" <<
-			1.0 - R.r.GIshadowquality << "\" grid=\"82\" search=\"35\" gradient=\"" <<
-			((R.r.GIgradient)? "on" : "off") << "\" >\n";
+			1.0 - R.r.GIshadowquality << "\" grid=\"82\" search=\"35\" >\n";
 	}
 	else
 	{
@@ -1404,8 +1614,7 @@ bool yafrayFileRender_t::writeWorld()
 	ostr << "<background type=\"constant\" name=\"world_background\" >\n";
 	// if no GI used, the GIpower parameter is not always initialized, so in that case ignore it
 	// (have to change method to init yafray vars in Blender)
-	float bg_mult;
-	if (R.r.GImethod==0) bg_mult=1; else bg_mult=R.r.GIpower;
+	float bg_mult = (R.r.GImethod==0) ? 1 : R.r.GIpower;
 	ostr << "\t<color r=\"" << (world->horr * bg_mult) << 
 								"\" g=\"" << (world->horg * bg_mult) << 
 								"\" b=\"" << (world->horb * bg_mult) << "\" />\n";
diff --git a/source/blender/yafray/intern/export_File.h b/source/blender/yafray/intern/export_File.h
index c9d650f578f18e10876ec12442a23c15f204efb0..5d2e0c53a21d7ecc2a94c23cc4ab0d11005a8997 100755
--- a/source/blender/yafray/intern/export_File.h
+++ b/source/blender/yafray/intern/export_File.h
@@ -16,11 +16,11 @@ class yafrayFileRender_t : public yafrayRender_t
 		void displayImage();
 		bool executeYafray(const std::string &xmlpath);
 		virtual void writeTextures();
+		virtual void writeShader(const std::string &shader_name, Material* matr, const std::string &facetexname="");
 		virtual void writeMaterialsAndModulators();
-		virtual void writeObject(Object* obj, 
-				const std::vector<VlakRen*> &VLR_list, const float obmat[4][4]);
+		virtual void writeObject(Object* obj, const std::vector<VlakRen*> &VLR_list, const float obmat[4][4]);
 		virtual void writeAllObjects();
-		void writeAreaLamp(LampRen* lamp, int num, float iview[4][4]);
+		virtual void writeAreaLamp(LampRen* lamp, int num, float iview[4][4]);
 		virtual void writeLamps();
 		virtual void writeCamera();
 		virtual void writeHemilight();
diff --git a/source/blender/yafray/intern/export_Plugin.cpp b/source/blender/yafray/intern/export_Plugin.cpp
index 960e65c13c217a3b1c069fa15ebf22e136ef114a..40e87d3856fbf568de3031ba5af0fd49735e7f5b 100644
--- a/source/blender/yafray/intern/export_Plugin.cpp
+++ b/source/blender/yafray/intern/export_Plugin.cpp
@@ -317,34 +317,74 @@ static void adjustPath(string &path)
 }
 
 
+static string noise2string(short nbtype)
+{
+	switch (nbtype) {
+		case TEX_BLENDER:
+			return "blender";
+		case TEX_STDPERLIN:
+			return "stdperlin";
+		case TEX_VORONOI_F1:
+			return "voronoi_f1";
+		case TEX_VORONOI_F2:
+			return "voronoi_f2";
+		case TEX_VORONOI_F3:
+			return "voronoi_f3";
+		case TEX_VORONOI_F4:
+			return "voronoi_f4";
+		case TEX_VORONOI_F2F1:
+			return "voronoi_f2f1";
+		case TEX_VORONOI_CRACKLE:
+			return "voronoi_crackle";
+		case TEX_CELLNOISE:
+			return "cellnoise";
+		default:
+		case TEX_NEWPERLIN:
+			return "newperlin";
+	}
+}
+
 void yafrayPluginRender_t::writeTextures()
 {
-	for (map<string, pair<Material*, MTex*> >::const_iterator blendtex=used_textures.begin();
+	string ts;
+	yafray::paramMap_t params;
+	list<yafray::paramMap_t> lparams;
+	for (map<string, MTex*>::const_iterator blendtex=used_textures.begin();
 						blendtex!=used_textures.end();++blendtex) 
 	{
-		yafray::paramMap_t params;
-		list<yafray::paramMap_t> lparams;
-		MTex* mtex = blendtex->second.second;
+		MTex* mtex = blendtex->second;
 		Tex* tex = mtex->tex;
-		params["name"]=yafray::parameter_t(blendtex->first);
+		// name is image name instead of texture name when type is image (see TEX_IMAGE case below)
+		// (done because of possible combinations of 'TexFace' images and regular image textures, to avoid duplicates)
+		if (tex->type!=TEX_IMAGE) params["name"] = yafray::parameter_t(blendtex->first);
+
+		float nsz = tex->noisesize;
+		if (nsz!=0.f) nsz=1.f/nsz;
+
+		// noisebasis type
+		string ntype = noise2string(tex->noisebasis);
+
 		switch (tex->type) {
 			case TEX_STUCCI:
 				// stucci is clouds as bump, but could be added to yafray to handle both wall in/out as well.
 				// noisedepth must be at least 1 in yafray
-			case TEX_CLOUDS: 
-				params["type"]=yafray::parameter_t("clouds");
-				params["depth"]=yafray::parameter_t(tex->noisedepth+1);
+			case TEX_CLOUDS: {
+				params["type"] = yafray::parameter_t("clouds");
+				params["depth"] = yafray::parameter_t(tex->noisedepth+1);
+				params["size"] = yafray::parameter_t(nsz);
+				params["noise_type"] = ntype;
 				break;
+			}
 			case TEX_WOOD:
 			{
-				params["type"]=yafray::parameter_t("wood");
-				params["depth"]=yafray::parameter_t(tex->noisedepth+1);
-				params["turbulence"]=yafray::parameter_t(tex->turbul);
-				params["ringscale_x"]=yafray::parameter_t(mtex->size[0]);
-				params["ringscale_y"]=yafray::parameter_t(mtex->size[1]);
-				string ts = "on";
+				params["type"] = yafray::parameter_t("wood");
+				params["depth"] = yafray::parameter_t(tex->noisedepth+1);
+				params["turbulence"] = yafray::parameter_t(tex->turbul);
+				params["ringscale_x"] = yafray::parameter_t(mtex->size[0]);
+				params["ringscale_y"] = yafray::parameter_t(mtex->size[1]);
+				ts = "on";
 				if (tex->noisetype==TEX_NOISESOFT) ts = "off";
-				params["hard"]=yafray::parameter_t(ts);
+				params["hard"] = yafray::parameter_t(ts);
 				break;
 			}
 			case TEX_MARBLE: 
@@ -352,7 +392,7 @@ void yafrayPluginRender_t::writeTextures()
 				params["type"]=yafray::parameter_t("marble");
 				params["depth"]=yafray::parameter_t(tex->noisedepth+1);
 				params["turbulence"]=yafray::parameter_t(tex->turbul);
-				string ts = "on";
+				ts = "on";
 				if (tex->noisetype==TEX_NOISESOFT) ts = "off";
 				params["hard"]=yafray::parameter_t(ts);
 				if (tex->stype==1)
@@ -367,17 +407,97 @@ void yafrayPluginRender_t::writeTextures()
 			{
 				Image* ima = tex->ima;
 				if (ima) {
-					params["type"]=yafray::parameter_t("image");
+					// remove from imagetex list to avoid possible duplicates when TexFace used
+					imagetex.erase(ima);
+					params["type"] = yafray::parameter_t("image");
+					params["name"] = yafray::parameter_t(ima->id.name);
 					string texpath = ima->name;
 					adjustPath(texpath);
 					params["filename"] = yafray::parameter_t(texpath);
 				}
 				break;
 			}
+			case TEX_VORONOI:
+			{
+				params["type"] = yafray::parameter_t("voronoi");
+				ts = "int";
+				if (tex->vn_coltype==1)
+					ts = "col1";
+				else if (tex->vn_coltype==2)
+					ts = "col2";
+				else if (tex->vn_coltype==3)
+					ts = "col3";
+				params["color_type"] = yafray::parameter_t(ts);
+				params["weight1"] = yafray::parameter_t(tex->vn_w1);
+				params["weight2"] = yafray::parameter_t(tex->vn_w2);
+				params["weight3"] = yafray::parameter_t(tex->vn_w3);
+				params["weight4"] = yafray::parameter_t(tex->vn_w4);
+				params["mk_exponent"] = yafray::parameter_t(tex->vn_mexp);
+				params["intensity"] = yafray::parameter_t(tex->ns_outscale);
+				params["size"] = yafray::parameter_t(nsz);
+				ts = "actual";
+				if (tex->vn_distm==TEX_DISTANCE_SQUARED)
+					ts = "squared";
+				else if (tex->vn_distm==TEX_MANHATTAN)
+					ts = "manhattan";
+				else if (tex->vn_distm==TEX_CHEBYCHEV)
+					ts = "chebychev";
+				else if (tex->vn_distm==TEX_MINKOVSKY_HALF)
+					ts = "minkovsky_half";
+				else if (tex->vn_distm==TEX_MINKOVSKY_FOUR)
+					ts = "minkovsky_four";
+				else if (tex->vn_distm==TEX_MINKOVSKY)
+					ts = "minkovsky";
+				params["distance_metric"] = yafray::parameter_t(ts);
+				break;
+			}
+			case TEX_MUSGRAVE:
+			{
+				params["type"] = yafray::parameter_t("musgrave");
+				switch (tex->stype) {
+					case TEX_MFRACTAL:
+						ts = "multifractal";
+						break;
+					case TEX_RIDGEDMF:
+						ts = "ridgedmf";
+						break;
+					case TEX_HYBRIDMF:
+						ts = "hybridmf";
+						break;
+					case TEX_HTERRAIN:
+						ts = "heteroterrain";
+						break;
+					default:
+					case TEX_FBM:
+						ts = "fBm";
+				}
+				params["musgrave_type"] = yafray::parameter_t(ts);
+				params["noise_type"] = yafray::parameter_t(ntype);
+				params["H"] = yafray::parameter_t(tex->mg_H);
+				params["lacunarity"] = yafray::parameter_t(tex->mg_lacunarity);
+				params["octaves"] = yafray::parameter_t(tex->mg_octaves);
+				if ((tex->stype==TEX_HTERRAIN) || (tex->stype==TEX_RIDGEDMF) || (tex->stype==TEX_HYBRIDMF)) {
+					params["offset"] = yafray::parameter_t(tex->mg_offset);
+					if ((tex->stype==TEX_RIDGEDMF) || (tex->stype==TEX_HYBRIDMF))
+						params["gain"] = yafray::parameter_t(tex->mg_gain);
+				}
+				params["size"] = yafray::parameter_t(nsz);
+				params["intensity"] = yafray::parameter_t(tex->ns_outscale);
+				break;
+			}
+			case TEX_DISTNOISE:
+			{
+				params["type"] = yafray::parameter_t("distorted_noise");
+				params["distort"] = yafray::parameter_t(tex->dist_amount);
+				params["size"] = yafray::parameter_t(nsz);
+				params["noise_type1"] = yafray::parameter_t(ntype);
+				params["noise_type2"] = yafray::parameter_t(noise2string(tex->noisebasis2));
+			}
 			default:
 				cout << "Unsupported texture type\n";
 		}
-		yafrayGate->addShader(params,lparams);
+		yafrayGate->addShader(params, lparams);
+
 		// colorbands
 		if (tex->flag & TEX_COLORBAND) 
 		{
@@ -398,23 +518,231 @@ void yafrayPluginRender_t::writeTextures()
 																																cb->data[i].a));
 					lparams.push_back(mparams);
 				}
-				yafrayGate->addShader(params,lparams);
+				yafrayGate->addShader(params, lparams);
 			}
 		}
 
 	}
+
+	// If used, textures for the material 'TexFace' case
+	if (!imagetex.empty()) {
+		for (map<Image*, Material*>::const_iterator imgtex=imagetex.begin();
+					imgtex!=imagetex.end();++imgtex)
+		{
+			params.clear();
+			params["name"] = yafray::parameter_t(imgtex->first->id.name);
+			params["type"] = yafray::parameter_t("image");
+			string texpath(imgtex->first->name);
+			adjustPath(texpath);
+			params["filename"] = yafray::parameter_t(texpath);
+			yafrayGate->addShader(params, lparams);
+		}
+	}
+
 }
 
 
+void yafrayPluginRender_t::writeShader(const string &shader_name, Material* matr, const string &facetexname)
+{
+	yafray::paramMap_t params;
+	params["type"] = yafray::parameter_t("blendershader");
+	params["name"] = yafray::parameter_t(shader_name);
+	float diff = matr->alpha;
+	params["color"] = yafray::parameter_t(yafray::color_t(matr->r*diff, matr->g*diff, matr->b*diff));
+	params["specular_color"] = yafray::parameter_t(yafray::color_t(matr->specr, matr->specg, matr->specb));
+	params["mirror_color"] = yafray::parameter_t(yafray::color_t(matr->mirr, matr->mirg, matr->mirb));
+	params["diffuse_reflect"] = yafray::parameter_t(matr->ref);
+	params["specular_amount"] = yafray::parameter_t(matr->spec);
+	params["hard"] = yafray::parameter_t(matr->har);
+	params["alpha"] = yafray::parameter_t(matr->alpha);
+	
+	// if no GI used, the GIpower parameter is not always initialized, so in that case ignore it
+	float bg_mult = (R.r.GImethod==0) ? 1 : R.r.GIpower;
+	params["emit"]=yafray::parameter_t(matr->emit*bg_mult);
+
+	// reflection/refraction
+	if ( (matr->mode & MA_RAYMIRROR) || (matr->mode & MA_RAYTRANSP) )
+		params["IOR"] = yafray::parameter_t(matr->ang);
+	if (matr->mode & MA_RAYMIRROR) 
+	{
+		float rf = matr->ray_mirror;
+		// blender uses mir color for reflection as well
+		params["reflected"] = yafray::parameter_t(yafray::color_t(matr->mirr, matr->mirg, matr->mirb));
+		params["min_refle"] = yafray::parameter_t(rf);
+		if (matr->ray_depth>maxraydepth) maxraydepth = matr->ray_depth;
+	}
+	if (matr->mode & MA_RAYTRANSP) 
+	{
+		float tr = 1.0-matr->alpha;
+		params["transmitted"]=yafray::parameter_t(yafray::color_t(matr->r*tr, matr->g*tr, matr->b*tr));
+		// tir on by default
+		params["tir"] = yafray::parameter_t("on");
+		if (matr->ray_depth_tra>maxraydepth) maxraydepth = matr->ray_depth_tra;
+	}
+
+	string Mmode = "";
+	if (matr->mode & MA_TRACEBLE) Mmode += "traceable";
+	if (matr->mode & MA_SHADOW) Mmode += " shadow";
+	if (matr->mode & MA_SHLESS) Mmode += " shadeless";
+	if (matr->mode & MA_VERTEXCOL) Mmode += " vcol_light";
+	if (matr->mode & MA_VERTEXCOLP) Mmode += " vcol_paint";
+	if (matr->mode & MA_ZTRA) Mmode += " ztransp";
+	if (matr->mode & MA_ONLYSHADOW) Mmode += " onlyshadow";
+	if (Mmode!="") params["matmodes"] = yafray::parameter_t(Mmode);
+
+	// modulators
+	list<yafray::paramMap_t> lparams;
+
+	// first modulator is the texture of the face, if used (TexFace mode)
+	if (facetexname.length()!=0) {
+			yafray::paramMap_t mparams;
+			mparams["input"] = yafray::parameter_t(facetexname);
+			mparams["color"] = yafray::parameter_t(1);
+			lparams.push_back(mparams);
+	}
+	
+	for (int m2=0;m2<8;m2++)
+	{
+		if (matr->septex & (1<<m2)) continue;// all active channels
+		// ignore null mtex
+		MTex* mtex = matr->mtex[m2];
+		if (mtex==NULL) continue;
+		// ignore null tex
+		Tex* tex = mtex->tex;
+		if (tex==NULL) continue;
+
+		map<string, MTex*>::const_iterator mtexL = used_textures.find(string(tex->id.name));
+		if (mtexL!=used_textures.end()) 
+		{
+			yafray::paramMap_t mparams;
+			// when no facetex used, shader_name is created from original material name
+			char temp[32];
+			sprintf(temp,"_map%d", m2);
+			if (facetexname.length()!=0)
+				mparams["input"] = yafray::parameter_t(string(matr->id.name) + string(temp));
+			else
+				mparams["input"] = yafray::parameter_t(shader_name + temp);
+			// blendtype
+			string ts = "mix";
+			if (mtex->blendtype==MTEX_MUL) ts="mul";
+			else if (mtex->blendtype==MTEX_ADD) ts="add";
+			else if (mtex->blendtype==MTEX_SUB) ts="sub";
+			mparams["mode"]=yafray::parameter_t(ts);
+
+			// texture color (for use with MUL and/or no_rgb etc..)
+			mparams["texcol"]=yafray::parameter_t(yafray::color_t(mtex->r,mtex->g,mtex->b));
+			// texture contrast, brightness & color adjustment
+			mparams["filtercolor"]=yafray::parameter_t(yafray::color_t(tex->rfac,tex->gfac,tex->bfac));
+			mparams["contrast"]=yafray::parameter_t(tex->contrast);
+			mparams["brightness"]=yafray::parameter_t(tex->bright);
+			// all texture flags now are switches, having the value 1 or -1 (negative option)
+			// the negative option only used for the intensity modulation options.
+
+			// material (diffuse) color, amount controlled by colfac (see below)
+			if (mtex->mapto & MAP_COL)
+				mparams["color"]=yafray::parameter_t(1.0);
+			// bumpmapping
+			if ((mtex->mapto & MAP_NORM) || (mtex->maptoneg & MAP_NORM)) 
+			{
+				// for yafray, bump factor is negated (unless negative option of 'Nor', 
+				// is not affected by 'Neg')
+				// scaled down quite a bit for yafray
+				float nf = -mtex->norfac;
+				if (mtex->maptoneg & MAP_NORM) nf *= -1.f;
+				mparams["normal"] = yafray::parameter_t(nf/60.f);
+			}
+
+			// all blender texture modulation as switches, either 1 or -1 (negative state of button)
+			// Csp, specular color modulation
+			if (mtex->mapto & MAP_COLSPEC)
+				mparams["colspec"]=yafray::parameter_t(1.0);
+			// CMir, mirror color  modulation
+			if (mtex->mapto & MAP_COLMIR)
+				mparams["colmir"]=yafray::parameter_t(1.0);
+
+			// Ref, diffuse reflection amount  modulation
+			if ((mtex->mapto & MAP_REF) || (mtex->maptoneg & MAP_REF)) 
+			{
+				int t = 1;
+				if (mtex->maptoneg & MAP_REF) t = -1;
+				mparams["difref"]=yafray::parameter_t(t);
+			}
+
+			// Spec, specular amount mod
+			if ((mtex->mapto & MAP_SPEC) || (mtex->maptoneg & MAP_SPEC)) 
+			{
+				int t = 1;
+				if (mtex->maptoneg & MAP_SPEC) t = -1;
+				mparams["specular"]=yafray::parameter_t(t);
+			}
+
+			// hardness modulation
+			if ((mtex->mapto & MAP_HAR) || (mtex->maptoneg & MAP_HAR)) 
+			{
+				int t = 1;
+				if (mtex->maptoneg & MAP_HAR) t = -1;
+				mparams["hard"]=yafray::parameter_t(t);
+			}
+
+			// alpha modulation
+			if ((mtex->mapto & MAP_ALPHA) || (mtex->maptoneg & MAP_ALPHA)) 
+			{
+				int t = 1;
+				if (mtex->maptoneg & MAP_ALPHA) t = -1;
+				mparams["alpha"]=yafray::parameter_t(t);
+			}
+
+			// emit modulation
+			if ((mtex->mapto & MAP_EMIT) || (mtex->maptoneg & MAP_EMIT)) {
+				int t = 1;
+				if (mtex->maptoneg & MAP_EMIT) t = -1;
+				mparams["emit"]=yafray::parameter_t(t);
+			}
+
+			// texture flag, combination of strings
+			if (mtex->texflag & (MTEX_RGBTOINT | MTEX_STENCIL | MTEX_NEGATIVE)) {
+				ts = "";
+				if (mtex->texflag & MTEX_RGBTOINT) ts += "no_rgb ";
+				if (mtex->texflag & MTEX_STENCIL) ts += "stencil ";
+				if (mtex->texflag & MTEX_NEGATIVE) ts += "negative";
+				mparams["texflag"]=yafray::parameter_t(ts);
+			}
+
+			// colfac, controls amount of color modulation
+			mparams["colfac"]=yafray::parameter_t(mtex->colfac);
+			// def_var
+			mparams["def_var"]=yafray::parameter_t(mtex->def_var);
+			//varfac
+			mparams["varfac"]=yafray::parameter_t(mtex->varfac);
+
+			if ((tex->imaflag & (TEX_CALCALPHA | TEX_USEALPHA)) || (tex->flag & TEX_NEGALPHA)) 
+			{
+				ts = "";
+				if (tex->imaflag & TEX_CALCALPHA) ts += "calc_alpha ";
+				if (tex->imaflag & TEX_USEALPHA) ts += "use_alpha ";
+				if (tex->flag & TEX_NEGALPHA) ts += "neg_alpha";
+				mparams["alpha_flag"]=yafray::parameter_t(ts);
+			}
+			lparams.push_back(mparams);
+		}
+	}
+	yafrayGate->addShader(params,lparams);
+
+}
+
 // write all materials & modulators
 void yafrayPluginRender_t::writeMaterialsAndModulators()
 {
-	  
+	// shaders/mappers for regular texture (or non-texture) mode
+	// In case material has texface mode, and all faces have an image texture,
+	// this shader will not be used, but still be written
+	yafray::paramMap_t params;
+	list<yafray::paramMap_t> lparams;
 	for (map<string, Material*>::const_iterator blendmat=used_materials.begin();
 		blendmat!=used_materials.end();++blendmat) 
 	{
 		Material* matr = blendmat->second;
-		// blendermappers
+		// mapper(s)
 		for (int m=0;m<8;m++) 
 		{
 			if (matr->septex & (1<<m)) continue;// all active channels
@@ -425,18 +753,13 @@ void yafrayPluginRender_t::writeMaterialsAndModulators()
 			Tex* tex = mtex->tex;
 			if (tex==NULL) continue;
 
-			// now included the full name
-			map<string, pair<Material*, MTex*> >::const_iterator mtexL = used_textures.find(string(tex->id.name));
+			map<string, MTex*>::const_iterator mtexL = used_textures.find(string(tex->id.name));
 			if (mtexL!=used_textures.end()) 
 			{
-				yafray::paramMap_t params;
-				list<yafray::paramMap_t> lparams;
-				//params.clear();
-				//lparams.clear();
-				char temp[16];
-				sprintf(temp,"%d",m);
-				params["type"]=yafray::parameter_t("blendermapper");
-				params["name"]=yafray::parameter_t(blendmat->first + "_map"+temp);
+				char temp[32];
+				sprintf(temp, "_map%d", m);
+				params["type"] = yafray::parameter_t("blendermapper");
+				params["name"] = yafray::parameter_t(blendmat->first + string(temp));
 				if ((mtex->texco & TEXCO_OBJECT) || (mtex->texco & TEXCO_REFL))
 				{
 					// For object & reflection mapping, add the object matrix to the modulator,
@@ -449,327 +772,171 @@ void yafrayPluginRender_t::writeMaterialsAndModulators()
 						MTC_Mat4CpyMat4(texmat, maincam_obj->obmat);
 					MTC_Mat4Invert(itexmat, texmat);
 #define flp yafray::parameter_t
-					params["m00"]=flp(itexmat[0][0]);params["m01"]=flp(itexmat[1][0]);
-					params["m02"]=flp(itexmat[2][0]);params["m03"]=flp(itexmat[3][0]);
-					params["m10"]=flp(itexmat[0][1]);params["m11"]=flp(itexmat[1][1]);
-					params["m12"]=flp(itexmat[2][1]);params["m13"]=flp(itexmat[3][1]);
-					params["m20"]=flp(itexmat[0][2]);params["m21"]=flp(itexmat[1][2]);
-					params["m22"]=flp(itexmat[2][2]);params["m23"]=flp(itexmat[3][2]);
-					params["m30"]=flp(itexmat[0][3]);params["m31"]=flp(itexmat[1][3]);
-					params["m32"]=flp(itexmat[2][3]);params["m33"]=flp(itexmat[3][3]);
+					params["m00"]=flp(itexmat[0][0]);  params["m01"]=flp(itexmat[1][0]);
+					params["m02"]=flp(itexmat[2][0]);  params["m03"]=flp(itexmat[3][0]);
+					params["m10"]=flp(itexmat[0][1]);  params["m11"]=flp(itexmat[1][1]);
+					params["m12"]=flp(itexmat[2][1]);  params["m13"]=flp(itexmat[3][1]);
+					params["m20"]=flp(itexmat[0][2]);  params["m21"]=flp(itexmat[1][2]);
+					params["m22"]=flp(itexmat[2][2]);  params["m23"]=flp(itexmat[3][2]);
+					params["m30"]=flp(itexmat[0][3]);  params["m31"]=flp(itexmat[1][3]);
+					params["m32"]=flp(itexmat[2][3]);  params["m33"]=flp(itexmat[3][3]);
 #undef flp
 				}
-				if ((tex->flag & TEX_COLORBAND) & (tex->coba!=NULL))
-					params["input"]=yafray::parameter_t(mtexL->first + "_coba");
+				// use image name instead of texname when texture is image
+				if ((tex->type==TEX_IMAGE) && tex->ima)
+					params["input"] = yafray::parameter_t(tex->ima->id.name);
+				else if ((tex->flag & TEX_COLORBAND) & (tex->coba!=NULL))
+					params["input"] = yafray::parameter_t(mtexL->first + "_coba");
 				else
-					params["input"]=yafray::parameter_t(mtexL->first);
+					params["input"] = yafray::parameter_t(mtexL->first);
 
-				// size, if the texturetype is clouds/marble/wood, also take noisesize into account
-				float sc = 1;
-				if ((tex->type==TEX_CLOUDS) || (tex->type==TEX_MARBLE) || (tex->type==TEX_WOOD)) 
-				{
-					sc = tex->noisesize;
-					if (sc!=0) sc = 1.f/sc;
-				}
 				// texture size
-				params["sizex"]=yafray::parameter_t(mtex->size[0]*sc);
-				params["sizey"]=yafray::parameter_t(mtex->size[1]*sc);
-				params["sizez"]=yafray::parameter_t(mtex->size[2]*sc);
+				params["sizex"] = yafray::parameter_t(mtex->size[0]);
+				params["sizey"] = yafray::parameter_t(mtex->size[1]);
+				params["sizez"] = yafray::parameter_t(mtex->size[2]);
 
 				// texture offset
-				params["ofsx"]=yafray::parameter_t(mtex->ofs[0]*sc);
-				params["ofsy"]=yafray::parameter_t(mtex->ofs[1]*sc);
-				params["ofsz"]=yafray::parameter_t(mtex->ofs[2]*sc);
+				params["ofsx"] = yafray::parameter_t(mtex->ofs[0]);
+				params["ofsy"] = yafray::parameter_t(mtex->ofs[1]);
+				params["ofsz"] = yafray::parameter_t(mtex->ofs[2]);
 
 				// texture coordinates, have to disable 'sticky' in Blender
-				if ((mtex->texco & TEXCO_UV) || (matr->mode & MA_FACETEXTURE))
-					params["texco"]=yafray::parameter_t("uv");
+				if (mtex->texco & TEXCO_UV)
+					params["texco"] = yafray::parameter_t("uv");
 				else if ((mtex->texco & TEXCO_GLOB) || (mtex->texco & TEXCO_OBJECT))
 					// object mode is also set as global, but the object matrix 
 					// was specified above with <modulator..>
-					params["texco"]=yafray::parameter_t("global");
+					params["texco"] = yafray::parameter_t("global");
 				else if (mtex->texco & TEXCO_ORCO)
-					params["texco"]=yafray::parameter_t("orco");
+					params["texco"] = yafray::parameter_t("orco");
 				else if (mtex->texco & TEXCO_WINDOW)
-					params["texco"]=yafray::parameter_t("window");
+					params["texco"] = yafray::parameter_t("window");
 				else if (mtex->texco & TEXCO_NORM)
-					params["texco"]=yafray::parameter_t("normal");
+					params["texco"] = yafray::parameter_t("normal");
 				else if (mtex->texco & TEXCO_REFL)
-					params["texco"]=yafray::parameter_t("reflect");
+					params["texco"] = yafray::parameter_t("reflect");
+
+				// texture projection axes, both image & procedural
+				string proj = "nxyz";		// 'n' for 'none'
+				params["proj_x"] = yafray::parameter_t(string(1,proj[mtex->projx]));
+				params["proj_y"] = yafray::parameter_t(string(1,proj[mtex->projy]));
+				params["proj_z"] = yafray::parameter_t(string(1,proj[mtex->projz]));
 
 				// texture mapping parameters only relevant to image type
 				if (tex->type==TEX_IMAGE) 
 				{
 					if (mtex->mapping==MTEX_FLAT)
-						params["mapping"]=yafray::parameter_t("flat");
+						params["mapping"] = yafray::parameter_t("flat");
 					else if (mtex->mapping==MTEX_CUBE)
-						params["mapping"]=yafray::parameter_t("cube");
+						params["mapping"] = yafray::parameter_t("cube");
 					else if (mtex->mapping==MTEX_TUBE)
-						params["mapping"]=yafray::parameter_t("tube");
+						params["mapping"] = yafray::parameter_t("tube");
 					else if (mtex->mapping==MTEX_SPHERE)
-						params["mapping"]=yafray::parameter_t("sphere");
-
-					// texture projection axes
-					string proj = "nxyz";		// 'n' for 'none'
-					params["proj_x"]=yafray::parameter_t(string(1,proj[mtex->projx]));
-					params["proj_y"]=yafray::parameter_t(string(1,proj[mtex->projy]));
-					params["proj_z"]=yafray::parameter_t(string(1,proj[mtex->projz]));
+						params["mapping"] = yafray::parameter_t("sphere");
 
 					// repeat
-					params["xrepeat"]=yafray::parameter_t(tex->xrepeat);
-					params["yrepeat"]=yafray::parameter_t(tex->yrepeat);
+					params["xrepeat"] = yafray::parameter_t(tex->xrepeat);
+					params["yrepeat"] = yafray::parameter_t(tex->yrepeat);
 
 					// clipping
 					if (tex->extend==TEX_EXTEND)
-						params["clipping"]=yafray::parameter_t("extend");
+						params["clipping"] = yafray::parameter_t("extend");
 					else if (tex->extend==TEX_CLIP)
-						params["clipping"]=yafray::parameter_t("clip");
+						params["clipping"] = yafray::parameter_t("clip");
 					else if (tex->extend==TEX_CLIPCUBE)
-						params["clipping"]=yafray::parameter_t("clipcube");
+						params["clipping"] = yafray::parameter_t("clipcube");
 					else
-						params["clipping"]=yafray::parameter_t("repeat");
+						params["clipping"] = yafray::parameter_t("repeat");
 
 					// crop min/max
-					params["cropmin_x"]=yafray::parameter_t(tex->cropxmin);
-					params["cropmin_y"]=yafray::parameter_t(tex->cropymin);
-					params["cropmax_x"]=yafray::parameter_t(tex->cropxmax);
-					params["cropmax_y"]=yafray::parameter_t(tex->cropymax);
+					params["cropmin_x"] = yafray::parameter_t(tex->cropxmin);
+					params["cropmin_y"] = yafray::parameter_t(tex->cropymin);
+					params["cropmax_x"] = yafray::parameter_t(tex->cropxmax);
+					params["cropmax_y"] = yafray::parameter_t(tex->cropymax);
 
 					// rot90 flag
 					if (tex->imaflag & TEX_IMAROT) 
-						params["rot90"]=yafray::parameter_t("on");
+						params["rot90"] = yafray::parameter_t("on");
 					else
-						params["rot90"]=yafray::parameter_t("off");
+						params["rot90"] = yafray::parameter_t("off");
 				}
-				yafrayGate->addShader(params,lparams);
+				yafrayGate->addShader(params, lparams);
 			}
 		}
-		yafray::paramMap_t params;
-		// blendershaders + modulators
-		params["type"]=yafray::parameter_t("blendershader");
-		params["name"]=yafray::parameter_t(blendmat->first);
-		float diff=matr->alpha;
-
-		params["color"]=yafray::parameter_t(yafray::color_t(matr->r*diff,matr->g*diff,matr->b*diff));
-
-		params["specular_color"]=yafray::parameter_t(yafray::color_t(matr->specr,
-																																 matr->specg,
-																																 matr->specb));
-		params["mirror_color"]=yafray::parameter_t(yafray::color_t(matr->mirr, matr->mirg,matr->mirb));
-		params["diffuse_reflect"]=yafray::parameter_t(matr->ref);
-		params["specular_amount"]=yafray::parameter_t(matr->spec);
-		params["hard"]=yafray::parameter_t(matr->har);
-		params["alpha"]=yafray::parameter_t(matr->alpha);
-		// if no GI used, the GIpower parameter is not always initialized, so in that case ignore it
-		float bg_mult;
-		if (R.r.GImethod==0) bg_mult=1; else bg_mult=R.r.GIpower;
-		params["emit"]=yafray::parameter_t(matr->emit * bg_mult);
-
-		// reflection/refraction
-		if ( (matr->mode & MA_RAYMIRROR) || (matr->mode & MA_RAYTRANSP) )
-			params["IOR"]=yafray::parameter_t(matr->ang);
-		if (matr->mode & MA_RAYMIRROR) 
-		{
-			float rf = matr->ray_mirror;
-			// blender uses mir color for reflection as well
-			params["reflected"]=yafray::parameter_t(yafray::color_t(matr->mirr, matr->mirg,matr->mirb));
-			params["min_refle"]=yafray::parameter_t(rf);
-			if (matr->ray_depth>maxraydepth) maxraydepth = matr->ray_depth;
-		}
-		if (matr->mode & MA_RAYTRANSP) 
-		{
-			float tr=1.0-matr->alpha;
-			params["transmitted"]=yafray::parameter_t(yafray::color_t(matr->r*tr,matr->g*tr,matr->b*tr));
-			// tir on by default
-			params["tir"]=yafray::parameter_t("on");
-			if (matr->ray_depth_tra>maxraydepth) maxraydepth = matr->ray_depth_tra;
-		}
 
-		string Mmode = "";
-		if (matr->mode & MA_TRACEBLE) Mmode += "traceable";
-		if (matr->mode & MA_SHADOW) Mmode += " shadow";
-		if (matr->mode & MA_SHLESS) Mmode += " shadeless";
-		if (matr->mode & MA_VERTEXCOL) Mmode += " vcol_light";
-		if (matr->mode & MA_VERTEXCOLP) Mmode += " vcol_paint";
-		if (matr->mode & MA_ZTRA) Mmode += " ztransp";
-		if (matr->mode & MA_ONLYSHADOW) Mmode += " onlyshadow";
-		if (Mmode!="") params["matmodes"]=yafray::parameter_t(Mmode);
-
-		// modulators
-		list<yafray::paramMap_t> lparams;
-		for (int m2=0;m2<8;m2++) 
-		{
-			if (matr->septex & (1<<m2)) continue;// all active channels
-			// ignore null mtex
-			MTex* mtex = matr->mtex[m2];
-			if (mtex==NULL) continue;
-			// ignore null tex
-			Tex* tex = mtex->tex;
-			if (tex==NULL) continue;
+		// shader + modulators
+		writeShader(blendmat->first, matr);
 
-			map<string, pair<Material*, MTex*> >::const_iterator mtexL = used_textures.find(string(tex->id.name));
-			if (mtexL!=used_textures.end()) 
-			{
-				yafray::paramMap_t mparams;
-				char temp[16];
-				sprintf(temp,"%d",m2);
-				mparams["input"]=yafray::parameter_t(blendmat->first + "_map" + temp);
-				// blendtype
-				string ts = "mix";
-				if (mtex->blendtype==MTEX_MUL) ts="mul";
-				else if (mtex->blendtype==MTEX_ADD) ts="add";
-				else if (mtex->blendtype==MTEX_SUB) ts="sub";
-				mparams["mode"]=yafray::parameter_t(ts);
-
-				// texture color (for use with MUL and/or no_rgb etc..)
-				mparams["texcol"]=yafray::parameter_t(yafray::color_t(mtex->r,mtex->g,mtex->b));
-				// texture contrast, brightness & color adjustment
-				mparams["filtercolor"]=yafray::parameter_t(yafray::color_t(tex->rfac,tex->gfac,tex->bfac));
-				mparams["contrast"]=yafray::parameter_t(tex->contrast);
-				mparams["brightness"]=yafray::parameter_t(tex->bright);
-				// all texture flags now are switches, having the value 1 or -1 (negative option)
-				// the negative option only used for the intensity modulation options.
-
-				// material (diffuse) color, amount controlled by colfac (see below)
-				if (mtex->mapto & MAP_COL)
-					mparams["color"]=yafray::parameter_t(1.0);
-				// bumpmapping
-				if ((mtex->mapto & MAP_NORM) || (mtex->maptoneg & MAP_NORM)) 
-				{
-					// for yafray, bump factor is negated (unless negative option of 'Nor', 
-					// is not affected by 'Neg')
-					// scaled down quite a bit for yafray
-					float nf = -mtex->norfac;
-					if (mtex->maptoneg & MAP_NORM) nf *= -1.f;
-					if (tex->type==TEX_IMAGE) nf/=60.f; else nf/=30.f;
-					mparams["normal"]=yafray::parameter_t(nf);
-				}
-
-				// all blender texture modulation as switches, either 1 or -1 (negative state of button)
-				// Csp, specular color modulation
-				if (mtex->mapto & MAP_COLSPEC)
-					mparams["colspec"]=yafray::parameter_t(1.0);
-				// CMir, mirror color  modulation
-				if (mtex->mapto & MAP_COLMIR)
-					mparams["colmir"]=yafray::parameter_t(1.0);
-
-				// Ref, diffuse reflection amount  modulation
-				if ((mtex->mapto & MAP_REF) || (mtex->maptoneg & MAP_REF)) 
-				{
-					int t = 1;
-					if (mtex->maptoneg & MAP_REF) t = -1;
-					mparams["difref"]=yafray::parameter_t(t);
-				}
-
-				// Spec, specular amount mod
-				if ((mtex->mapto & MAP_SPEC) || (mtex->maptoneg & MAP_SPEC)) 
-				{
-					int t = 1;
-					if (mtex->maptoneg & MAP_SPEC) t = -1;
-					mparams["specular"]=yafray::parameter_t(t);
-				}
-
-				// hardness modulation
-				if ((mtex->mapto & MAP_HAR) || (mtex->maptoneg & MAP_HAR)) 
-				{
-					int t = 1;
-					if (mtex->maptoneg & MAP_HAR) t = -1;
-					mparams["hard"]=yafray::parameter_t(t);
-				}
- 
-				// alpha modulation
-				if ((mtex->mapto & MAP_ALPHA) || (mtex->maptoneg & MAP_ALPHA)) 
-				{
-					int t = 1;
-					if (mtex->maptoneg & MAP_ALPHA) t = -1;
-					mparams["alpha"]=yafray::parameter_t(t);
-				}
-
-				// emit modulation
-				if ((mtex->mapto & MAP_EMIT) || (mtex->maptoneg & MAP_EMIT)) {
-					int t = 1;
-					if (mtex->maptoneg & MAP_EMIT) t = -1;
-					mparams["emit"]=yafray::parameter_t(t);
-				}
-
-				// texture flag, combination of strings
-				if (mtex->texflag & (MTEX_RGBTOINT | MTEX_STENCIL | MTEX_NEGATIVE)) {
-					ts = "";
-					if (mtex->texflag & MTEX_RGBTOINT) ts += "no_rgb ";
-					if (mtex->texflag & MTEX_STENCIL) ts += "stencil ";
-					if (mtex->texflag & MTEX_NEGATIVE) ts += "negative";
-					mparams["texflag"]=yafray::parameter_t(ts);
-				}
+	}
 
-				// colfac, controls amount of color modulation
-				mparams["colfac"]=yafray::parameter_t(mtex->colfac);
-				// def_var
-				mparams["def_var"]=yafray::parameter_t(mtex->def_var);
-				//varfac
-				mparams["varfac"]=yafray::parameter_t(mtex->varfac);
+		// write the mappers & shaders for the TexFace case
+	if (!imagetex.empty()) {
+		// Yafray doesn't have per-face-textures, only per-face-shaders,
+		// so create as many mappers/shaders as the images used by the object
+		params.clear();
+		lparams.clear();
+		int snum = 0;
+		for (map<Image*, Material*>::const_iterator imgtex=imagetex.begin();
+				imgtex!=imagetex.end();++imgtex)
+		{
+			Material* matr = imgtex->second;
+
+			// mapper
+			params["type"] = yafray::parameter_t("blendermapper");
+			char temp[32];
+			sprintf(temp, "_ftex_mp%d", snum);
+			params["name"] = yafray::parameter_t(string(matr->id.name) + string(temp));
+			params["input"] = yafray::parameter_t(imgtex->first->id.name);
+			// all yafray default settings, except for texco, so no need to set others
+			params["texco"] = yafray::parameter_t("uv");
+			yafrayGate->addShader(params, lparams);
+
+			// shader, remember name, used later when writing per-face-shaders
+			sprintf(temp, "_ftex_sh%d", snum);
+			string shader_name = string(matr->id.name) + string(temp);
+			imgtex_shader[imgtex->first] = shader_name;
+
+			sprintf(temp, "_ftex_mp%d", snum++);
+			string facetexname = string(matr->id.name) + string(temp);
+			writeShader(shader_name, matr, facetexname);
 
-				if ((tex->imaflag & (TEX_CALCALPHA | TEX_USEALPHA)) || (tex->flag & TEX_NEGALPHA)) 
-				{
-					ts = "";
-					if (tex->imaflag & TEX_CALCALPHA) ts += "calc_alpha ";
-					if (tex->imaflag & TEX_USEALPHA) ts += "use_alpha ";
-					if (tex->flag & TEX_NEGALPHA) ts += "neg_alpha";
-					mparams["alpha_flag"]=yafray::parameter_t(ts);
-				}
-				lparams.push_back(mparams);
-			}
 		}
-		yafrayGate->addShader(params,lparams);
 	}
+
 }
 
-void yafrayPluginRender_t::genUVcoords(vector<yafray::GFLOAT> &uvcoords,VlakRen *vlr,TFace* uvc)
+void yafrayPluginRender_t::genUVcoords(vector<yafray::GFLOAT> &uvcoords, VlakRen *vlr, TFace* uvc, bool comple)
 {
 	if (uvc) 
 	{
-	// use correct uv coords for this triangle
-		if (vlr->flag & R_FACE_SPLIT) 
-		{
-			uvcoords.push_back(uvc->uv[0][0]);uvcoords.push_back(1-uvc->uv[0][1]);
-			uvcoords.push_back(uvc->uv[2][0]);uvcoords.push_back(1-uvc->uv[2][1]);
-			uvcoords.push_back(uvc->uv[3][0]);uvcoords.push_back(1-uvc->uv[3][1]);
+		// use correct uv coords for this triangle
+		int ui1=0, ui2=1, ui3=2;
+		if (vlr->flag & R_DIVIDE_24) {
+			ui3++;
+			if (vlr->flag & R_FACE_SPLIT) { ui1++;  ui2++; }
 		}
-		else 
-		{
-			uvcoords.push_back(uvc->uv[0][0]);uvcoords.push_back(1-uvc->uv[0][1]);
-			uvcoords.push_back(uvc->uv[1][0]);uvcoords.push_back(1-uvc->uv[1][1]);
-			uvcoords.push_back(uvc->uv[2][0]);uvcoords.push_back(1-uvc->uv[2][1]);
+		else if (vlr->flag & R_FACE_SPLIT) { ui2++;  ui3++; }
+		if (comple) {
+			ui1 = (ui1+2) & 3;
+			ui2 = (ui2+2) & 3;
+			ui3 = (ui3+2) & 3;
 		}
+		uvcoords.push_back(uvc->uv[ui1][0]);  uvcoords.push_back(1-uvc->uv[ui1][1]);
+		uvcoords.push_back(uvc->uv[ui2][0]);  uvcoords.push_back(1-uvc->uv[ui2][1]);
+		uvcoords.push_back(uvc->uv[ui3][0]);  uvcoords.push_back(1-uvc->uv[ui3][1]);
 	}
 	else
 	{
-		uvcoords.push_back(0);uvcoords.push_back(0);
-		uvcoords.push_back(0);uvcoords.push_back(0);
-		uvcoords.push_back(0);uvcoords.push_back(0);
-	}
-}
-
-void yafrayPluginRender_t::genCompleUVcoords(vector<yafray::GFLOAT> &uvcoords,/*VlakRen *vlr,*/TFace* uvc)
-{
-	if (uvc) 
-	{
-	// use correct uv coords for this triangle
-		uvcoords.push_back(uvc->uv[2][0]);uvcoords.push_back(1-uvc->uv[2][1]);
-		uvcoords.push_back(uvc->uv[3][0]);uvcoords.push_back(1-uvc->uv[3][1]);
-		uvcoords.push_back(uvc->uv[0][0]);uvcoords.push_back(1-uvc->uv[0][1]);
-	}
-	else
-	{
-		uvcoords.push_back(0);uvcoords.push_back(0);
-		uvcoords.push_back(0);uvcoords.push_back(0);
-		uvcoords.push_back(0);uvcoords.push_back(0);
+		uvcoords.push_back(0);  uvcoords.push_back(0);
+		uvcoords.push_back(0);  uvcoords.push_back(0);
+		uvcoords.push_back(0);  uvcoords.push_back(0);
 	}
 }
 
 void yafrayPluginRender_t::genVcol(vector<yafray::CFLOAT> &vcol,VlakRen *vlr,
-																		int p1,int p2,int p3,bool EXPORT_VCOL)
+																		int p1,int p2,int p3)
 {
-	if ((EXPORT_VCOL) && (vlr->vcol)) 
+	if (vlr->vcol)
 	{
 		// vertex colors
 		float vr, vg, vb;
@@ -797,12 +964,20 @@ void yafrayPluginRender_t::genVcol(vector<yafray::CFLOAT> &vcol,VlakRen *vlr,
 void yafrayPluginRender_t::genFace(vector<int> &faces,vector<string> &shaders,vector<int> &faceshader,
 														vector<yafray::GFLOAT> &uvcoords,vector<yafray::CFLOAT> &vcol,
 														map<VertRen*, int> &vert_idx,VlakRen *vlr,
-														bool has_orco,bool has_uv, bool has_vcol)
+														bool has_orco,bool has_uv)
 {
 	Material* fmat = vlr->mat;
 	bool EXPORT_VCOL = ((fmat->mode & (MA_VERTEXCOL|MA_VERTEXCOLP))!=0);
-	string fmatname = fmat->id.name;
-	if (fmatname=="") fmatname = "blender_default";
+	string fmatname(fmat->id.name);
+	// use name in imgtex_shader list if 'TexFace' enabled for this face material
+	if (fmat->mode & MA_FACETEXTURE) {
+		TFace* tface = vlr->tface;
+		if (tface) {
+			Image* fimg = (Image*)tface->tpage;
+			if (fimg) fmatname = imgtex_shader[fimg];
+		}
+	}
+	else if (fmatname.length()==0) fmatname = "blender_default";
 	bool newmat=true;
 	for(unsigned int i=0;i<shaders.size();++i)
 		if(shaders[i]==fmatname)
@@ -826,18 +1001,18 @@ void yafrayPluginRender_t::genFace(vector<int> &faces,vector<string> &shaders,ve
 	// make sure the indices point to the vertices when orco coords exported
 	if (has_orco) { idx1*=2;  idx2*=2;  idx3*=2; }
 
-	faces.push_back(idx1);faces.push_back(idx2);faces.push_back(idx3);
+	faces.push_back(idx1);  faces.push_back(idx2);  faces.push_back(idx3);
 
 	if(has_uv) genUVcoords(uvcoords,vlr,uvc);
 
 	// since Blender seems to need vcols when uvs are used, for yafray only export when the material actually uses vcols
-	if (has_vcol) genVcol(vcol,vlr,0,1,2,EXPORT_VCOL);
+	if (EXPORT_VCOL) genVcol(vcol, vlr, 0, 1, 2);
 }
 
 void yafrayPluginRender_t::genCompleFace(vector<int> &faces,/*vector<string> &shaders,*/vector<int> &faceshader,
 														vector<yafray::GFLOAT> &uvcoords,vector<yafray::CFLOAT> &vcol,
 														map<VertRen*, int> &vert_idx,VlakRen *vlr,
-														bool has_orco,bool has_uv, bool has_vcol)
+														bool has_orco,bool has_uv)
 {
 	Material* fmat = vlr->mat;
 	bool EXPORT_VCOL = ((fmat->mode & (MA_VERTEXCOL|MA_VERTEXCOLP))!=0);
@@ -852,10 +1027,10 @@ void yafrayPluginRender_t::genCompleFace(vector<int> &faces,/*vector<string> &sh
 	// make sure the indices point to the vertices when orco coords exported
 	if (has_orco) { idx1*=2;  idx2*=2;  idx3*=2; }
 
-	faces.push_back(idx1);faces.push_back(idx2);faces.push_back(idx3);
+	faces.push_back(idx1);  faces.push_back(idx2);  faces.push_back(idx3);
 
-	if(has_uv) genCompleUVcoords(uvcoords,/*vlr,*/uvc);
-	if (has_vcol) genVcol(vcol,vlr,2,3,0,EXPORT_VCOL);
+	if (has_uv) genUVcoords(uvcoords, vlr, uvc, true);
+	if (EXPORT_VCOL) genVcol(vcol, vlr, 2, 3, 0);
 }
 
 void yafrayPluginRender_t::genVertices(vector<yafray::point3d_t> &verts, int &vidx,
@@ -913,19 +1088,22 @@ void yafrayPluginRender_t::writeObject(Object* obj, const vector<VlakRen*> &VLR_
 	mtr[2*4+0]=obmat[0][2];  mtr[2*4+1]=obmat[1][2];  mtr[2*4+2]=obmat[2][2];  mtr[2*4+3]=obmat[3][2];
 	mtr[3*4+0]=obmat[0][3];  mtr[3*4+1]=obmat[1][3];  mtr[3*4+2]=obmat[2][3];  mtr[3*4+3]=obmat[3][3];
 	yafrayGate->transformPush(mtr);
-	string name=string(obj->id.name+2);
-	bool castShadows=VLR_list[0]->mat->mode & MA_TRACEBLE;
+	
+	VlakRen* face0 = VLR_list[0];
+	Material* face0mat = face0->mat;
+	
+	bool castShadows = face0mat->mode & MA_TRACEBLE;
 	float caus_IOR=1.0;
-	yafray::color_t caus_tcolor(0.0,0.0,0.0),caus_rcolor(0.0,0.0,0.0);
-	bool caus = (((VLR_list[0]->mat->mode & MA_RAYTRANSP) | (VLR_list[0]->mat->mode & MA_RAYMIRROR))!=0);
+	yafray::color_t caus_tcolor(0.0, 0.0, 0.0), caus_rcolor(0.0, 0.0, 0.0);
+	bool caus = (((face0->mat->mode & MA_RAYTRANSP) | (face0->mat->mode & MA_RAYMIRROR))!=0);
 	if (caus) {
-		caus_IOR = VLR_list[0]->mat->ang;
-		float tr = 1.0-VLR_list[0]->mat->alpha;
-		caus_tcolor.set(VLR_list[0]->mat->r*tr, VLR_list[0]->mat->g*tr, VLR_list[0]->mat->b*tr);
-		tr = VLR_list[0]->mat->ray_mirror;
-		caus_rcolor.set(VLR_list[0]->mat->mirr*tr, VLR_list[0]->mat->mirg*tr, VLR_list[0]->mat->mirb*tr);
+		caus_IOR = face0mat->ang;
+		float tr = 1.0-face0mat->alpha;
+		caus_tcolor.set(face0mat->r*tr, face0mat->g*tr, face0mat->b*tr);
+		tr = face0mat->ray_mirror;
+		caus_rcolor.set(face0mat->mirr*tr, face0mat->mirg*tr, face0mat->mirb*tr);
 	}
-	bool has_orco = (VLR_list[0]->v1->orco!=NULL);
+	bool has_orco = (face0->v1->orco!=NULL);
 	bool no_auto = true;	//in case non-mesh, or mesh has no autosmooth
 	float sm_angle = 0.1f;
 	if (obj->type==OB_MESH) 
@@ -940,12 +1118,8 @@ void yafrayPluginRender_t::writeObject(Object* obj, const vector<VlakRen*> &VLR_
 	if (no_auto) {
 		// no per face smooth flag in yafray, if AutoSmooth not used, 
 		// use smooth flag of the first face instead
-		if (VLR_list[0]->flag & ME_SMOOTH) sm_angle=90;
+		if (face0->flag & ME_SMOOTH) sm_angle=90;
 	}
-	// Guess if we need to set vertex colors Could be faster? sure
-	bool has_vcol=false;
-	if ((obj->type==OB_MESH) && (obj->data!=NULL))
-		has_vcol = (((Mesh*)obj->data)->mcol!=NULL);
 	vector<yafray::point3d_t> verts;
 	vector<yafray::CFLOAT> vcol;
 	// now all vertices
@@ -968,14 +1142,14 @@ void yafrayPluginRender_t::writeObject(Object* obj, const vector<VlakRen*> &VLR_
 				fci2!=VLR_list.end();++fci2)
 	{
 		VlakRen* vlr = *fci2;
-		genFace(faces, shaders, faceshader, uvcoords, vcol, vert_idx, vlr, has_orco, has_uv, has_vcol);
+		genFace(faces, shaders, faceshader, uvcoords, vcol, vert_idx, vlr, has_orco, has_uv);
 		if (vlr->v4) 
-			genCompleFace(faces, /*shaders,*/ faceshader, uvcoords, vcol, vert_idx, vlr, has_orco, has_uv, has_vcol);
+			genCompleFace(faces, faceshader, uvcoords, vcol, vert_idx, vlr, has_orco, has_uv);
 	}
 
-	yafrayGate->addObject_trimesh(name,verts,faces,uvcoords,vcol,
-			shaders,faceshader,sm_angle,castShadows,true,true,caus,has_orco,
-			caus_rcolor,caus_tcolor,caus_IOR);
+	yafrayGate->addObject_trimesh(string(obj->id.name), verts, faces, uvcoords, vcol,
+			shaders, faceshader, sm_angle, castShadows, true, true, caus, has_orco,
+			caus_rcolor, caus_tcolor, caus_IOR);
 	yafrayGate->transformPop();
 }
 
@@ -1029,11 +1203,11 @@ void yafrayPluginRender_t::writeAllObjects()
 			yafrayGate->transformPush(mtr);
 
 			// new name from original
-			string name=(obj->id.name+2);
+			string name=(obj->id.name);
 			char temp[16];
 			sprintf(temp,"_dup%d",(curmtx>>4));
 			name+=temp;
-			yafrayGate->addObject_reference(name,obj->id.name+2);
+			yafrayGate->addObject_reference(name,obj->id.name);
 			yafrayGate->transformPop();
 		}
 
@@ -1159,9 +1333,13 @@ void yafrayPluginRender_t::writeLamps()
 		// cast_shadows flag not used with softlight, spherelight or photonlight
 		if ((!is_softL) && (!is_sphereL) && (lamp->type!=LA_YF_PHOTON)) {
 			string lpmode="off";
-			// shadows only when Blender has shadow button enabled, only spots use LA_SHAD flag
-			if (R.r.mode & R_SHADOW)
-				if (((lamp->type==LA_SPOT) && (lamp->mode & LA_SHAD)) || (lamp->mode & LA_SHAD_RAY)) lpmode="on";
+			// Shadows only when Blender has shadow button enabled, only spots use LA_SHAD flag.
+			// Also blender hemilights exported as sunlights which might have shadow flag set
+			// should have cast_shadows set to off (reported by varuag)
+			if (lamp->type!=LA_HEMI) {
+				if (R.r.mode & R_SHADOW)
+					if (((lamp->type==LA_SPOT) && (lamp->mode & LA_SHAD)) || (lamp->mode & LA_SHAD_RAY)) lpmode="on";
+			}
 			params["cast_shadows"] = yafray::parameter_t(lpmode);
 		}
 		
@@ -1289,9 +1467,9 @@ void yafrayPluginRender_t::writeCamera()
 void yafrayPluginRender_t::writeHemilight()
 {
 	yafray::paramMap_t params;
-	params["type"]=yafray::parameter_t("hemilight");
-	params["name"]=yafray::parameter_t("hemi_LT");
-	params["power"]=yafray::parameter_t(1.0);
+	params["type"] = yafray::parameter_t("hemilight");
+	params["name"] = yafray::parameter_t("hemi_LT");
+	params["power"] = yafray::parameter_t(R.r.GIpower);
 	switch (R.r.GIquality)
 	{
 		case 1 :
@@ -1321,7 +1499,7 @@ void yafrayPluginRender_t::writePathlight()
 	yafray::paramMap_t params;
 	params["type"]=yafray::parameter_t("pathlight");
 	params["name"]=yafray::parameter_t("path_LT");
-	params["power"]=yafray::parameter_t(1.0);
+	params["power"]=yafray::parameter_t(R.r.GIindirpower);
 	params["depth"]=yafray::parameter_t(((R.r.GIphotons) ? 1 : R.r.GIdepth));
 	params["caus_depth"]=yafray::parameter_t(R.r.GIcausdepth);
 	if(R.r.GIdirect && R.r.GIphotons) params["direct"]=yafray::parameter_t("on");
@@ -1338,7 +1516,6 @@ void yafrayPluginRender_t::writePathlight()
 		}
 		float aspect = 1;
 		if (R.r.xsch < R.r.ysch) aspect = float(R.r.xsch)/float(R.r.ysch);
-		//float sbase = 2.0*atan(0.5/(mainCamLens/(aspect*32.0)))/float(R.r.xsch);
 		float sbase = 2.0/float(R.r.xsch);
 		params["cache"]=yafray::parameter_t("on");
 		params["use_QMC"]=yafray::parameter_t("on");
@@ -1347,7 +1524,6 @@ void yafrayPluginRender_t::writePathlight()
 		params["shadow_threshold"]=yafray::parameter_t(1.0 - R.r.GIshadowquality);
 		params["grid"]=yafray::parameter_t(82);
 		params["search"]=yafray::parameter_t(35);
-		//params["gradient"]=yafray::parameter_t("off");
 	}
 	else
 	{
@@ -1418,8 +1594,7 @@ bool yafrayPluginRender_t::writeWorld()
 	params["name"] = yafray::parameter_t("world_background");
 	// if no GI used, the GIpower parameter is not always initialized, so in that case ignore it
 	// (have to change method to init yafray vars in Blender)
-	float bg_mult;
-	if (R.r.GImethod==0) bg_mult=1; else bg_mult=R.r.GIpower;
+	float bg_mult = (R.r.GImethod==0) ? 1 : R.r.GIpower;
 	params["color"]=yafray::parameter_t(yafray::color_t(world->horr * bg_mult,
 																											world->horg * bg_mult,
 																											world->horb * bg_mult));
diff --git a/source/blender/yafray/intern/export_Plugin.h b/source/blender/yafray/intern/export_Plugin.h
index c7adab723a608d481c3936e5b0a188dd03783a03..d2d9128d824bee19622d548b85283c40b63aff79 100644
--- a/source/blender/yafray/intern/export_Plugin.h
+++ b/source/blender/yafray/intern/export_Plugin.h
@@ -31,11 +31,12 @@ class yafrayPluginRender_t : public yafrayRender_t
 
 		void displayImage();
 		virtual void writeTextures();
+		virtual void writeShader(const std::string &shader_name, Material* matr, const std::string &facetexname="");
 		virtual void writeMaterialsAndModulators();
 		virtual void writeObject(Object* obj, 
 				const std::vector<VlakRen*> &VLR_list, const float obmat[4][4]);
 		virtual void writeAllObjects();
-		void writeAreaLamp(LampRen* lamp, int num, float iview[4][4]);
+		virtual void writeAreaLamp(LampRen* lamp, int num, float iview[4][4]);
 		virtual void writeLamps();
 		virtual void writeCamera();
 		virtual void writeHemilight();
@@ -45,18 +46,17 @@ class yafrayPluginRender_t : public yafrayRender_t
 		virtual bool initExport();
 		virtual bool finishExport();
 
-		void genUVcoords(std::vector<yafray::GFLOAT> &uvcoords,VlakRen *vlr,TFace* uvc);
-		void genCompleUVcoords(std::vector<yafray::GFLOAT> &uvcoords,/*VlakRen *vlr,*/TFace* uvc);
+		void genUVcoords(std::vector<yafray::GFLOAT> &uvcoords,VlakRen *vlr,TFace* uvc, bool comple=false);
 		void genVcol(std::vector<yafray::CFLOAT> &vcol,VlakRen *vlr,
-								int p1,int p2,int p3,bool EXPORT_VCOL);
+								int p1,int p2,int p3);
 		void genFace(std::vector<int> &faces,std::vector<std::string> &shaders,std::vector<int> &faceshader,
 				std::vector<yafray::GFLOAT> &uvcoords,std::vector<yafray::CFLOAT> &vcol,
 				std::map<VertRen*, int> &vert_idx,VlakRen *vlr,
-				bool has_orco,bool has_uv, bool has_vcol);
+				bool has_orco,bool has_uv);
 		void genCompleFace(std::vector<int> &faces,/*std::vector<std::string> &shaders,*/std::vector<int> &faceshader,
 				std::vector<yafray::GFLOAT> &uvcoords,std::vector<yafray::CFLOAT> &vcol,
 				std::map<VertRen*, int> &vert_idx,VlakRen *vlr,
-				bool has_orco,bool has_uv, bool has_vcol);
+				bool has_orco,bool has_uv);
 		void genVertices(std::vector<yafray::point3d_t> &verts, int &vidx,
 										 std::map<VertRen*, int> &vert_idx, VlakRen* vlr, bool has_orco, Object* obj);
 };
diff --git a/source/blender/yafray/intern/yafray_Render.cpp b/source/blender/yafray/intern/yafray_Render.cpp
index 461e5d5dfe51363d29cea779d27e2cf27817ad76..bbb5855b9640a40e8fef5536416db06545a1de31 100644
--- a/source/blender/yafray/intern/yafray_Render.cpp
+++ b/source/blender/yafray/intern/yafray_Render.cpp
@@ -18,6 +18,8 @@ void yafrayRender_t::clearAll()
 	dupliMtx_list.clear();
 	dup_srcob.clear();
 	objectData.clear();
+	imagetex.clear();
+	imgtex_shader.clear();
 }
 
 bool yafrayRender_t::exportScene()
@@ -102,8 +104,7 @@ bool yafrayRender_t::getAllMatTexObs()
 			if (strlen(matr->id.name)==0)
 				used_materials["blender_default"] = matr;
 			else
-				used_materials[matr->id.name] = matr; // <-- full name to avoid name collision in yafray
-				//used_materials[matr->id.name+2] = matr;	// skip 'MA' id
+				used_materials[matr->id.name] = matr;
 			// textures, all active channels
 			for (int m=0;m<8;m++) {
 				if (matr->septex & (1<<m)) continue;	// only active channels
@@ -115,26 +116,36 @@ bool yafrayRender_t::getAllMatTexObs()
 				if (tx==NULL) continue;
 				short txtp = tx->type;
 				// if texture type not available in yafray, ignore
-				if ((txtp!=TEX_STUCCI) &&
-						(txtp!=TEX_CLOUDS) &&
-						(txtp!=TEX_WOOD) &&
-						(txtp!=TEX_MARBLE) &&
-						(txtp!=TEX_IMAGE)) continue;
-				// in the case of an image texture, check that there is an actual image, otherwise ignore
-				if ((txtp & TEX_IMAGE) && (!tx->ima)) continue;
-				used_textures[tx->id.name] = make_pair(matr, mx); // <-- full name to avoid name collision in yafray
-				//used_textures[tx->id.name+2] = make_pair(matr, mx);
+				if ((txtp==0) ||
+						(txtp==TEX_MAGIC) ||
+						(txtp==TEX_BLEND) ||
+						(txtp==TEX_NOISE) ||
+						(txtp==TEX_PLUGIN) ||
+						(txtp==TEX_ENVMAP)) continue;
+				// In the case of an image texture, check that there is an actual image, otherwise ignore.
+				// Stupid error was here (...if (txtp & TEX_IMAGE)...),
+				// which happened to work sofar, but not anymore with the extended texture support..
+				if ((txtp==TEX_IMAGE) && (!tx->ima)) continue;
+				used_textures[tx->id.name] = mx;
 			}
 		}
 
-		// make list of faces per object, ignore <3 vert faces, duplicate vertex sorting done later
-		// make sure null object pointers are ignored
+		// Make list of faces per object, ignore <3 vert faces, duplicate vertex sorting done later.
+		// ignore null object pointers.
+		// Also make list of facetexture images (material 'TexFace').
 		if (vlr->ob) {
 			int nv = 0;	// number of vertices
 			if (vlr->v4) nv=4; else if (vlr->v3) nv=3;
 			if (nv) all_objects[vlr->ob].push_back(vlr);
+			if (vlr->tface) {
+				Image* fc_img = (Image*)vlr->tface->tpage;
+				if (fc_img) {
+					Material* fmat = vlr->mat;
+					// only save if TexFace enabled
+					if (fmat && (fmat->mode & MA_FACETEXTURE)) imagetex[fc_img] = fmat;
+				}
+			}
 		}
-		//else cout << "WARNING: VlakRen struct with null obj.ptr!\n";
 
 	}
 
@@ -167,7 +178,7 @@ void yafrayRender_t::addDupliMtx(Object* obj)
 {
 	for (int i=0;i<4;i++)
 		for (int j=0;j<4;j++)
-			dupliMtx_list[string(obj->id.name)].push_back(obj->obmat[i][j]);
+			dupliMtx_list[obj->id.name].push_back(obj->obmat[i][j]);
 }
 
 
@@ -184,7 +195,7 @@ bool yafrayRender_t::objectKnownData(Object* obj)
 		// then save matrix of linked object in dupliMtx_list, using name of ORIGINAL object
 		for (int i=0;i<4;i++)
 			for (int j=0;j<4;j++)
-				dupliMtx_list[string(orgob->id.name)].push_back(obj->obmat[i][j]);
+				dupliMtx_list[orgob->id.name].push_back(obj->obmat[i][j]);
 		return true;
 	}
 	// object not known yet
diff --git a/source/blender/yafray/intern/yafray_Render.h b/source/blender/yafray/intern/yafray_Render.h
index c65dab58615145d501b7895bda16c6f6836fe76c..e5c710c465d07736a2675165696566ee4200ba77 100644
--- a/source/blender/yafray/intern/yafray_Render.h
+++ b/source/blender/yafray/intern/yafray_Render.h
@@ -88,20 +88,24 @@ class yafrayRender_t
 
 		std::map<Object*, std::vector<VlakRen*> > all_objects;
 		std::map<std::string, Material*> used_materials;
-		std::map<std::string, std::pair<Material*, MTex*> > used_textures;
+		std::map<std::string, MTex*> used_textures;
 		std::map<std::string, std::vector<float> > dupliMtx_list;
 		std::map<std::string, Object*> dup_srcob;
 		std::map<void*, Object*> objectData;
+		std::map<Image*, Material*> imagetex;
+		std::map<Image*, std::string> imgtex_shader;
 
 		Object* findObject(const char* name);
 		bool getAllMatTexObs();
 
 		virtual void writeTextures()=0;
+		virtual void writeShader(const std::string &shader_name, Material* matr, const std::string &facetexname)=0;
 		virtual void writeMaterialsAndModulators()=0;
 		virtual void writeObject(Object* obj, const std::vector<VlakRen*> &VLR_list, const float obmat[4][4])=0;
 		virtual void writeAllObjects()=0;
 		virtual void writeLamps()=0;
 		virtual void writeCamera()=0;
+		virtual void writeAreaLamp(LampRen* lamp, int num, float iview[4][4])=0;
 		virtual void writeHemilight()=0;
 		virtual void writePathlight()=0;
 		virtual bool writeWorld()=0;