Part one of the final yafray commit.
authorAlfredo de Greef <eeshlo@yahoo.com>
Sat, 21 May 2005 20:49:24 +0000 (20:49 +0000)
committerAlfredo de Greef <eeshlo@yahoo.com>
Sat, 21 May 2005 20:49:24 +0000 (20:49 +0000)
Totally updated blender shader in yafray, hopefully better matches blender
results. Though ramps are now partially supported, they cannot work in all
cases properly in yafray, and in fact are a bit useless probably as far as
yafray is concerned. In fact the 'Result' ramp input mode is not supported
at all, because it works on the total lighting result, and in a yafray
shader this is not possible since it works per light.
Also, since Blender and Yafray have totally different lighting models,
the 'Energy' ramp input mode also won't generally give the same results
as in Blender, since it works with light energy and in yafray this is
different from Blender. Even worse, the only ramp shader that will work
properly when used with GI is the 'Normal' ramp input mode.
As contradictory as this might seem, at various stages of the GI process,
lighting is not known, so properly getting light (ramp 'energy' mode)
or shader information (ramp 'shader' mode, which depends on lighting)
is not possible. Which all means that when the ramp is in 'energy' or
'shader' mode and using it with GI enabled, yafray can only 'see' the
underlying material color, not the ramps, which results in a mix of the
ramp colors (from direct light) with the material color (from indirect light).
There is currently nothing that can be done about that.

The supported texture mapping modes now includes raymir as well, transparency
as far as texturing is concerned now works similar to Blender, with the
exception that you still have to set alpha to a low value to get any
transparency effect at all in yafray. So the Blender 'filter' parameter
now also will affect yafray.
All texture blending modes are now supported (same for ramps).
'Translu' and 'Amb' texture modulation are not supported.
Texture interpolation can be switched off ('InterPol' switch in blender
image texture button section).

All Blender brdf models (aka 'shaders' for the Blender users) are now supported,
and again, you won't necessarily get the same results as in Blender.
The reason for that is partially of course the lighting differences, but also,
not all Blender 'shader' implementations are  actually correct, and copying
those errors just for the sake of matching Blender results doesn't really
seem like a good idea...
Though this really is only the case for WardIso, less so for Minnaert and
Blinn, which in yafray are more or less (but not totally) a copy of
the Blender code.
In any case, in practice those differences might not be
too noticable at all (I hope).

Continue to the next part...

source/blender/yafray/intern/export_File.cpp
source/blender/yafray/intern/export_Plugin.cpp
source/blender/yafray/intern/yafray_Render.cpp
source/blender/yafray/intern/yafray_Render.h

index f259a2b903f1c25bdda928aab19da7dcade713cb..90e05e627c594bd8426a88094ebc3f4dde5009d2 100755 (executable)
@@ -224,7 +224,14 @@ bool yafrayFileRender_t::writeRender()
                ostr << "\tAA_pixelwidth=\"1.5\" AA_threshold=\"0.05\" bias=\"" << R.r.YF_raybias << "\"\n";
        }
 
-       if (hasworld) ostr << "\tbackground_name=\"world_background\"\n";
+       if (hasworld) {
+               World *world = G.scene->world;
+               if (world->mode & WO_MIST) {
+                       ostr << "\tfog_density=\"" << world->mistdist << "\" ";
+                       ostr << "fog_color r=\"" << world->horr << "\" g=\"" << world->horg << "\" b=\"" << world->horb << "\"\n";
+               }
+               ostr << "\tbackground_name=\"world_background\"\n";
+       }
  
        // alpha channel render when RGBA button enabled
        if (R.r.planes==R_PLANES32) ostr << "\n\tsave_alpha=\"on\"";
@@ -398,6 +405,10 @@ void yafrayFileRender_t::writeTextures()
                                ts = (tex->stype & 1) ? "rings" : "bands";      //stype 1&3 ringtype
                                ostr << "\t\t<wood_type value=\"" << ts << "\" />\n";
                                ostr << "\t\t<noise_type value=\"" << ntype << "\" />\n";
+                               // shape parameter, for some reason noisebasis2 is used...
+                               ts = "sin";
+                               if (tex->noisebasis2==1) ts="saw"; else if (tex->noisebasis2==2) ts="tri";
+                               ostr << "\t\t<shape value=\"" << ts << "\" />\n";
                                ostr << "\t</attributes>\n</shader>\n\n";
                                xmlfile << ostr.str();
                                break;
@@ -412,6 +423,9 @@ void yafrayFileRender_t::writeTextures()
                                ostr << "\t\t<hard value=\"" << hardnoise << "\" />\n";
                                ostr << "\t\t<sharpness value=\"" << (float)(1<<tex->stype) << "\" />\n";
                                ostr << "\t\t<noise_type value=\"" << ntype << "\" />\n";
+                               ts = "sin";
+                               if (tex->noisebasis2==1) ts="saw"; else if (tex->noisebasis2==2) ts="tri";
+                               ostr << "\t\t<shape value=\"" << ts << "\" />\n";
                                ostr << "\t</attributes>\n</shader>\n\n";
                                xmlfile << ostr.str();
                                break;
@@ -544,6 +558,7 @@ void yafrayFileRender_t::writeTextures()
                                        string texpath(ima->name);
                                        adjustPath(texpath);
                                        ostr << "\t\t<filename value=\"" << texpath << "\" />\n";
+                                       ostr << "\t\t<interpolate value=\"" << ((tex->imaflag & TEX_INTERPOL) ? "bilinear" : "none") << "\" />\n";
                                        ostr << "\t</attributes>\n</shader>\n\n";
                                        xmlfile << ostr.str();
                                }
@@ -601,16 +616,55 @@ void yafrayFileRender_t::writeTextures()
 
 void yafrayFileRender_t::writeShader(const string &shader_name, Material* matr, const string &facetexname)
 {
+       // if material has ramps, export colorbands first
+       if (matr->mode & (MA_RAMP_COL|MA_RAMP_SPEC))
+       {
+               // both colorbands without input shader
+               ColorBand* cb = matr->ramp_col;
+               if ((matr->mode & MA_RAMP_COL) && (cb!=NULL))
+               {
+                       ostr.str("");
+                       ostr << "<shader type=\"colorband\" name=\"" << shader_name+"_difframp" << "\" >\n";
+                       ostr << "\t<attributes>\n\t</attributes>\n";
+                       for (int i=0;i<cb->tot;i++) {
+                               ostr << "\t<modulator value=\"" << cb->data[i].pos << "\" >\n";
+                               ostr << "\t\t<color r=\"" << cb->data[i].r << "\"" <<
+                                                                                                       " g=\"" << cb->data[i].g << "\"" <<
+                                                                                                       " b=\"" << cb->data[i].b << "\"" <<
+                                                                                                       " a=\"" << cb->data[i].a << "\" />\n";
+                               ostr << "\t</modulator>\n";
+                       }
+                       ostr << "</shader>\n\n";
+                       xmlfile << ostr.str();
+               }
+               cb = matr->ramp_spec;
+               if ((matr->mode & MA_RAMP_SPEC) && (cb!=NULL))
+               {
+                       ostr.str("");
+                       ostr << "<shader type=\"colorband\" name=\"" << shader_name+"_specramp" << "\" >\n";
+                       ostr << "\t<attributes>\n\t</attributes>\n";
+                       for (int i=0;i<cb->tot;i++) {
+                               ostr << "\t<modulator value=\"" << cb->data[i].pos << "\" >\n";
+                               ostr << "\t\t<color r=\"" << cb->data[i].r << "\"" <<
+                                                                                                       " g=\"" << cb->data[i].g << "\"" <<
+                                                                                                       " b=\"" << cb->data[i].b << "\"" <<
+                                                                                                       " a=\"" << cb->data[i].a << "\" />\n";
+                               ostr << "\t</modulator>\n";
+                       }
+                       ostr << "</shader>\n\n";
+                       xmlfile << ostr.str();
+               }
+       }
+
        ostr.str("");
        ostr << "<shader type=\"blendershader\" name=\"" << shader_name << "\" >\n";
        ostr << "\t<attributes>\n";
-       float diff = matr->alpha;
+       float diff = 1; //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;
@@ -620,19 +674,27 @@ void yafrayFileRender_t::writeShader(const string &shader_name, Material* matr,
        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;
+               //ostr << "\t\t<reflected r=\"" << matr->mirr << "\" g=\"" << matr->mirg << "\" b=\"" << matr->mirb << "\" />\n";
+               // Sofar yafray's min_refle parameter (which misleadingly actually controls fresnel reflection offset)
+               // has been mapped to Blender's ray_mirror parameter.
+               // This causes it be be misinterpreted and misused as a reflection amount control however.
+               // Besides that, it also causes extra complications for the yafray Blendershader.
+               // So added an actual amount of reflection parameter instead, and another
+               // extra parameter 'frsOfs' to actually control fresnel offset (re-uses Blender fresnel_mir_i param).
+               ostr << "\t\t<reflect value=\"on\" />\n";
+               ostr << "\t\t<reflect_amount value=\""<< matr->ray_mirror << "\" />\n";
+               float fo = 1.f-(matr->fresnel_mir_i-1.f)*0.25f; // blender param range [1,5], also here reversed (1 in Blender -> no fresnel)
+               ostr << "\t\t<fresnel_offset value=\""<< fo << "\" />\n";
        }
        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";
+               //float tr=1.0-matr->alpha;
+               //ostr << "\t\t<transmitted r=\"" << matr->r*tr << "\" g=\"" << matr->g*tr << "\" b=\"" << matr->b*tr << "\" />\n";
+               ostr << "\t\t<refract value=\"on\" />\n";
+               ostr << "\t\t<transmit_filter value=\"" << matr->filter << "\" />\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 = "";
@@ -644,6 +706,70 @@ void yafrayFileRender_t::writeShader(const string &shader_name, Material* matr,
        if (matr->mode & MA_ZTRA) Mmode += " ztransp";
        if (matr->mode & MA_ONLYSHADOW) Mmode += " onlyshadow";
        if (Mmode!="") ostr << "\t\t<matmodes value=\"" << Mmode << "\" />\n";
+
+       // diffuse & specular brdf, lambert/cooktorr defaults
+       // diffuse
+       if (matr->diff_shader==MA_DIFF_ORENNAYAR) {
+               ostr << "\t\t<diffuse_brdf value=\"oren_nayar\" />\n";
+               ostr << "\t\t<roughness value=\"" << matr->roughness << "\" />\n";
+       }
+       else if (matr->diff_shader==MA_DIFF_TOON) {
+               ostr << "\t\t<diffuse_brdf value=\"toon\" />\n";
+               ostr << "\t\t<toondiffuse_size value=\"" << matr->param[0] << "\" />\n";
+               ostr << "\t\t<toondiffuse_smooth value=\"" << matr->param[1] << "\" />\n";
+       }
+       else if (matr->diff_shader==MA_DIFF_MINNAERT) {
+               ostr << "\t\t<diffuse_brdf value=\"minnaert\" />\n";
+               ostr << "\t\t<darkening value=\"" << matr->darkness << "\" />\n";
+       }
+       else ostr << "\t\t<diffuse_brdf value=\"lambert\" />\n";
+       // specular
+       if (matr->spec_shader==MA_SPEC_PHONG) {
+               ostr << "\t\t<specular_brdf value=\"phong\" />\n";
+               ostr << "\t\t<hard value=\"" << matr->har << "\" />\n";
+       }
+       else if (matr->spec_shader==MA_SPEC_BLINN) {
+               ostr << "\t\t<specular_brdf value=\"blinn\" />\n";
+               ostr << "\t\t<blinn_ior value=\"" << matr->refrac << "\" />\n";
+               ostr << "\t\t<hard value=\"" << matr->har << "\" />\n";
+       }
+       else if (matr->spec_shader==MA_SPEC_TOON) {
+               ostr << "\t\t<specular_brdf value=\"toon\" />\n";
+               ostr << "\t\t<toonspecular_size value=\"" << matr->param[2] << "\" />\n";
+               ostr << "\t\t<toonspecular_smooth value=\"" << matr->param[3] << "\" />\n";
+       }
+       else if (matr->spec_shader==MA_SPEC_WARDISO) {
+               ostr << "\t\t<specular_brdf value=\"ward\" />\n";
+               ostr << "\t\t<u_roughness value=\"" << matr->rms << "\" />\n";
+               ostr << "\t\t<v_roughness value=\"" << matr->rms << "\" />\n";
+       }
+       else {
+               ostr << "\t\t<specular_brdf value=\"blender_cooktorr\" />\n";
+               ostr << "\t\t<hard value=\"" << matr->har << "\" />\n";
+       }
+
+       // ramps, if used
+       if (matr->mode & (MA_RAMP_COL|MA_RAMP_SPEC))
+       {
+               const string rm_blend[9] = {"mix", "add", "mul", "sub", "screen", "divide", "difference", "darken", "lighten"};
+               const string rm_mode[4] = {"shader", "energy", "normal", "result"};
+               // diffuse
+               if ((matr->mode & MA_RAMP_COL) && (matr->ramp_col!=NULL))
+               {
+                       ostr << "\t\t<diffuse_ramp value=\"" << shader_name+"_difframp" << "\" />\n";
+                       ostr << "\t\t<diffuse_ramp_mode value=\"" << rm_mode[(int)matr->rampin_col] << "\" />\n";
+                       ostr << "\t\t<diffuse_ramp_blend value=\"" << rm_blend[(int)matr->rampblend_col] << "\" />\n";
+                       ostr << "\t\t<diffuse_ramp_factor value=\"" << matr->rampfac_col << "\" />\n";
+               }
+               // specular
+               if ((matr->mode & MA_RAMP_SPEC) && (matr->ramp_spec!=NULL)) {
+                       ostr << "\t\t<specular_ramp value=\"" << shader_name+"_specramp" << "\" />\n";
+                       ostr << "\t\t<specular_ramp_mode value=\"" << rm_mode[(int)matr->rampin_spec] << "\" />\n";
+                       ostr << "\t\t<specular_ramp_blend value=\"" << rm_blend[(int)matr->rampblend_spec] << "\" />\n";
+                       ostr << "\t\t<specular_ramp_factor value=\"" << matr->rampfac_spec << "\" />\n";
+               }
+       }
+
        ostr << "\t</attributes>\n";
        xmlfile << ostr.str();
        
@@ -681,12 +807,9 @@ void yafrayFileRender_t::writeShader(const string &shader_name, Material* matr,
                        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";
+                       // blendtype, would have been nice if the order would have been the same as for ramps...
+                       const string blendtype[9] = {"mix", "mul", "add", "sub", "divide", "darken", "difference", "lighten", "screen"};
+                       ostr << "\t\t<mode value=\"" << blendtype[(int)mtex->blendtype] << "\" />\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";
@@ -749,7 +872,6 @@ void yafrayFileRender_t::writeShader(const string &shader_name, Material* matr,
                                int t = 1;
                                if (mtex->maptoneg & MAP_ALPHA) t = -1;
                                ostr << "\t\t<alpha value=\"" << t << "\" />\n";
-
                        }
 
                        // emit modulation
@@ -759,9 +881,16 @@ void yafrayFileRender_t::writeShader(const string &shader_name, Material* matr,
                                ostr << "\t\t<emit value=\"" << t << "\" />\n";
                        }
 
+                       // raymir modulation
+                       if ((mtex->mapto & MAP_RAYMIRR) || (mtex->maptoneg & MAP_RAYMIRR)) {
+                               int t = 1;
+                               if (mtex->maptoneg & MAP_RAYMIRR) t = -1;
+                               ostr << "\t\t<raymir value=\"" << t << "\" />\n";
+                       }
+
                        // texture flag, combination of strings
+                       string ts = "";
                        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";
@@ -827,9 +956,9 @@ void yafrayFileRender_t::writeMaterialsAndModulators()
                        if (mtexL!=used_textures.end()) {
                                ostr.str("");
                                ostr << "<shader type=\"blendermapper\" name=\"" << blendmat->first + "_map" << m <<"\"";
-                               if ((mtex->texco & TEXCO_OBJECT) || (mtex->texco & TEXCO_REFL))
+                               if ((mtex->texco & TEXCO_OBJECT) || (mtex->texco & TEXCO_REFL) || (mtex->texco & TEXCO_NORM))
                                {
-                                       // For object & reflection mapping, add the object matrix to the modulator,
+                                       // For object, reflection & normal mapping, add the object matrix to the modulator,
                                        // as in LF script, use camera matrix if no object specified.
                                        // In this case this means the inverse of that matrix
                                        float texmat[4][4], itexmat[4][4];
@@ -839,13 +968,13 @@ void yafrayFileRender_t::writeMaterialsAndModulators()
                                                MTC_Mat4CpyMat4(texmat, maincam_obj->obmat);
                                        MTC_Mat4Invert(itexmat, texmat);
                                        ostr << "\n\t\tm00=\"" << itexmat[0][0] << "\" m01=\"" << itexmat[1][0]
-                                                       << "\" m02=\"" << itexmat[2][0] << "\" m03=\"" << itexmat[3][0] << "\"\n";
+                                                        << "\" 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";
+                                                        << "\" 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";
+                                                        << "\" 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";
+                                                        << "\" m32=\"" << itexmat[2][3] << "\" m33=\"" << itexmat[3][3] << "\">\n";
                                }
                                else ostr << ">\n";
                                ostr << "\t<attributes>\n";
@@ -1662,11 +1791,12 @@ bool yafrayFileRender_t::writeWorld()
                        adjustPath(wt_path);
                        if (BLI_testextensie(wimg->name, ".hdr")) {
                                ostr.str("");
-                               ostr << "<background type=\"HDRI\" name=\"world_background\" ";
+                               ostr << "<background type=\"image\" name=\"world_background\" ";
                                // since exposure adjust is an integer, using the texbri slider isn't actually very useful here (result either -1/0/1)
                                // GIpower could be used, but is only active for GI
-                               ostr << "exposure_adjust=\"" << int(world->mtex[i]->tex->bright-1) << "\" mapping=\"probe\" >\n";
+                               ostr << "exposure_adjust=\"" << wtex->tex->bright-1.f << "\" mapping=\"probe\" >\n";
                                ostr << "\t<filename value=\"" << wt_path << "\" />\n";
+                               ostr << "\t<interpolate value=\"" << ((wtex->tex->imaflag & TEX_INTERPOL) ? "bilinear" : "none") << "\" />\n";
                                ostr << "</background>\n\n";
                                xmlfile << ostr.str();
                                return true;
index 9de22ffc12cf36c56210209806754ece545a137f..63a02ffe087ad1d2c7517a3401365a3d5a6337f3 100644 (file)
@@ -222,30 +222,37 @@ bool yafrayPluginRender_t::writeRender()
        {
                if ((R.r.GImethod!=0) && (R.r.GIquality>1) && (!R.r.GIcache))
                {
-                       params["AA_passes"]=yafray::parameter_t(5);
-                       params["AA_minsamples"]=yafray::parameter_t(5);
+                       params["AA_passes"] = yafray::parameter_t(5);
+                       params["AA_minsamples"] = yafray::parameter_t(5);
                }
                else if ((R.r.mode & R_OSA) && (R.r.osa)) 
                {
-                       params["AA_passes"]=yafray::parameter_t((R.r.osa%4)==0 ? R.r.osa/4 : 1);
-                       params["AA_minsamples"]=yafray::parameter_t((R.r.osa%4)==0 ? 4 : R.r.osa);
+                       params["AA_passes"] = yafray::parameter_t((R.r.osa%4)==0 ? R.r.osa/4 : 1);
+                       params["AA_minsamples"] = yafray::parameter_t((R.r.osa%4)==0 ? 4 : R.r.osa);
                }
                else 
                {
-                       params["AA_passes"]=yafray::parameter_t(0);
-                       params["AA_minsamples"]=yafray::parameter_t(1);
+                       params["AA_passes"] = yafray::parameter_t(0);
+                       params["AA_minsamples"] = yafray::parameter_t(1);
                }
-               params["AA_pixelwidth"]=yafray::parameter_t(1.5);
-               params["AA_threshold"]=yafray::parameter_t(0.05f);
+               params["AA_pixelwidth"] = yafray::parameter_t(1.5);
+               params["AA_threshold"] = yafray::parameter_t(0.05f);
        }
        if(R.r.mode & R_BORDER) 
        {
-               params["border_xmin"]=yafray::parameter_t( R.r.border.xmin*2.0-1.0 );
-               params["border_xmax"]=yafray::parameter_t( R.r.border.xmax*2.0-1.0 );
-               params["border_ymin"]=yafray::parameter_t( R.r.border.ymin*2.0-1.0 );
-               params["border_ymax"]=yafray::parameter_t( R.r.border.ymax*2.0-1.0 );
+               params["border_xmin"] = yafray::parameter_t( R.r.border.xmin*2.0-1.0 );
+               params["border_xmax"] = yafray::parameter_t( R.r.border.xmax*2.0-1.0 );
+               params["border_ymin"] = yafray::parameter_t( R.r.border.ymin*2.0-1.0 );
+               params["border_ymax"] = yafray::parameter_t( R.r.border.ymax*2.0-1.0 );
+       }
+       if (hasworld) {
+               World *world = G.scene->world;
+               if (world->mode & WO_MIST) {
+                       params["fog_density"] = yafray::parameter_t(world->mistdist);
+                       params["fog_color"] = yafray::parameter_t(yafray::color_t(world->horr, world->horg, world->horb));
+               }
+               params["background_name"] = yafray::parameter_t("world_background");
        }
-       if (hasworld) params["background_name"]=yafray::parameter_t("world_background");
        params["bias"]=yafray::parameter_t(R.r.YF_raybias);
        //params["outfile"]=yafray::parameter_t(imgout);
        blenderYafrayOutput_t output;
@@ -413,6 +420,10 @@ void yafrayPluginRender_t::writeTextures()
                                ts = (tex->stype & 1) ? "rings" : "bands";      //stype 1&3 ringtype
                                params["wood_type"] = yafray::parameter_t(ts);
                                params["noise_type"] = yafray::parameter_t(ntype);
+                               // shape parameter, for some reason noisebasis2 is used...
+                               ts = "sin";
+                               if (tex->noisebasis2==1) ts="saw"; else if (tex->noisebasis2==2) ts="tri";
+                               params["shape"] = yafray::parameter_t(ts);
                                break;
                        }
                        case TEX_MARBLE: 
@@ -424,6 +435,9 @@ void yafrayPluginRender_t::writeTextures()
                                params["hard"] = yafray::parameter_t(hardnoise);
                                params["sharpness"] = yafray::parameter_t((float)(1<<tex->stype));
                                params["noise_type"] = yafray::parameter_t(ntype);
+                               ts = "sin";
+                               if (tex->noisebasis2==1) ts="saw"; else if (tex->noisebasis2==2) ts="tri";
+                               params["shape"] = yafray::parameter_t(ts);
                                break;
                        }
                        case TEX_VORONOI:
@@ -538,6 +552,7 @@ void yafrayPluginRender_t::writeTextures()
                                        string texpath = ima->name;
                                        adjustPath(texpath);
                                        params["filename"] = yafray::parameter_t(texpath);
+                                       params["interpolate"] = yafray::parameter_t((tex->imaflag & TEX_INTERPOL) ? "bilinear" : "none");
                                }
                                break;
                        }
@@ -554,14 +569,14 @@ void yafrayPluginRender_t::writeTextures()
                        {
                                lparams.clear();
                                params.clear();
-                               params["type"]=yafray::parameter_t("colorband");
-                               params["name"]=yafray::parameter_t(blendtex->first + "_coba");
-                               params["input"]=yafray::parameter_t(blendtex->first);
+                               params["type"] = yafray::parameter_t("colorband");
+                               params["name"] = yafray::parameter_t(blendtex->first + "_coba");
+                               params["input"] = yafray::parameter_t(blendtex->first);
                                for (int i=0;i<cb->tot;i++) 
                                {
                                        yafray::paramMap_t mparams;
-                                       mparams["value"]=yafray::parameter_t(cb->data[i].pos);
-                                       mparams["color"]=yafray::parameter_t(yafray::colorA_t(cb->data[i].r,
+                                       mparams["value"] = yafray::parameter_t(cb->data[i].pos);
+                                       mparams["color"] = yafray::parameter_t(yafray::colorA_t(cb->data[i].r,
                                                                                                                                                                                                                                                                cb->data[i].g,
                                                                                                                                                                                                                                                                cb->data[i].b,
                                                                                                                                                                                                                                                                cb->data[i].a));
@@ -580,6 +595,7 @@ void yafrayPluginRender_t::writeTextures()
                {
                        // skip if already written above
                        if (dupimg.find(imgtex->first)==dupimg.end()) {
+                               lparams.clear();
                                params.clear();
                                params["name"] = yafray::parameter_t(imgtex->first->id.name);
                                params["type"] = yafray::parameter_t("image");
@@ -597,15 +613,52 @@ void yafrayPluginRender_t::writeTextures()
 void yafrayPluginRender_t::writeShader(const string &shader_name, Material* matr, const string &facetexname)
 {
        yafray::paramMap_t params;
+       list<yafray::paramMap_t> lparams;
+
+       // if material has ramps, export colorbands first
+       if (matr->mode & (MA_RAMP_COL|MA_RAMP_SPEC))
+       {
+               // both colorbands without input shader
+               ColorBand* cb = matr->ramp_col;
+               if ((matr->mode & MA_RAMP_COL) && (cb!=NULL))
+               {
+                       params["type"] = yafray::parameter_t("colorband");
+                       params["name"] = yafray::parameter_t(shader_name+"_difframp");
+                       for (int i=0;i<cb->tot;i++) {
+                               yafray::paramMap_t mparams;
+                               mparams["value"] = yafray::parameter_t(cb->data[i].pos);
+                               mparams["color"] = yafray::parameter_t(yafray::colorA_t(cb->data[i].r, cb->data[i].g, cb->data[i].b, cb->data[i].a));
+                               lparams.push_back(mparams);
+                       }
+                       yafrayGate->addShader(params, lparams);
+               }
+               cb = matr->ramp_spec;
+               if ((matr->mode & MA_RAMP_SPEC) && (cb!=NULL))
+               {
+                       lparams.clear();
+                       params.clear();
+                       params["type"] = yafray::parameter_t("colorband");
+                       params["name"] = yafray::parameter_t(shader_name+"_specramp");
+                       for (int i=0;i<cb->tot;i++) {
+                               yafray::paramMap_t mparams;
+                               mparams["value"] = yafray::parameter_t(cb->data[i].pos);
+                               mparams["color"] = yafray::parameter_t(yafray::colorA_t(cb->data[i].r, cb->data[i].g, cb->data[i].b, cb->data[i].a));
+                               lparams.push_back(mparams);
+                       }
+                       yafrayGate->addShader(params, lparams);
+               }
+               lparams.clear();
+               params.clear();
+       }
+
        params["type"] = yafray::parameter_t("blendershader");
        params["name"] = yafray::parameter_t(shader_name);
-       float diff = matr->alpha;
+       float diff = 1; //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
@@ -615,21 +668,30 @@ void yafrayPluginRender_t::writeShader(const string &shader_name, Material* matr
        // reflection/refraction
        if ( (matr->mode & MA_RAYMIRROR) || (matr->mode & MA_RAYTRANSP) )
                params["IOR"] = yafray::parameter_t(matr->ang);
-       if (matr->mode & MA_RAYMIRROR) 
+       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;
+               //params["reflected"] = yafray::parameter_t(yafray::color_t(matr->mirr, matr->mirg, matr->mirb));
+               // Sofar yafray's min_refle parameter (which misleadingly actually controls fresnel reflection offset)
+               // has been mapped to Blender's ray_mirror parameter.
+               // This causes it be be misinterpreted and misused as a reflection amount control however.
+               // Besides that, it also causes extra complications for the yafray Blendershader.
+               // So added an actual amount of reflection parameter instead, and another
+               // extra parameter to actually control fresnel offset (re-uses Blender fresnel_mir_i param)
+               // Hopefully that clears things up a bit...
+               params["reflect"] = yafray::parameter_t("on");
+               params["reflect_amount"] = yafray::parameter_t(matr->ray_mirror);
+               float fo = 1.f-(matr->fresnel_mir_i-1.f)*0.25f; // blender param range [1,5], also here reversed (1 in Blender -> no fresnel)
+               params["fresnel_offset"] = yafray::parameter_t(fo);
        }
        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));
+               //float tr = 1.0-matr->alpha;
+               //params["transmitted"]=yafray::parameter_t(yafray::color_t(matr->r*tr, matr->g*tr, matr->b*tr));
+               params["refract"] = yafray::parameter_t("on");
+               params["transmit_filter"] = yafray::parameter_t(matr->filter);
                // tir on by default
                params["tir"] = yafray::parameter_t("on");
-               if (matr->ray_depth_tra>maxraydepth) maxraydepth = matr->ray_depth_tra;
        }
 
        string Mmode = "";
@@ -642,9 +704,70 @@ void yafrayPluginRender_t::writeShader(const string &shader_name, Material* matr
        if (matr->mode & MA_ONLYSHADOW) Mmode += " onlyshadow";
        if (Mmode!="") params["matmodes"] = yafray::parameter_t(Mmode);
 
-       // modulators
-       list<yafray::paramMap_t> lparams;
+       // diffuse & specular brdf, lambert/cooktorr defaults
+       // diffuse
+       if (matr->diff_shader==MA_DIFF_ORENNAYAR) {
+               params["diffuse_brdf"] = yafray::parameter_t("oren_nayar");
+               params["roughness"] = yafray::parameter_t(matr->roughness);
+       }
+       else if (matr->diff_shader==MA_DIFF_TOON) {
+               params["diffuse_brdf"] = yafray::parameter_t("toon");
+               params["toondiffuse_size"] = yafray::parameter_t(matr->param[0]);
+               params["toondiffuse_smooth"] = yafray::parameter_t(matr->param[1]);
+       }
+       else if (matr->diff_shader==MA_DIFF_MINNAERT) {
+               params["diffuse_brdf"] = yafray::parameter_t("minnaert");
+               params["darkening"] = yafray::parameter_t(matr->darkness);
+       }
+       else params["diffuse_brdf"] = yafray::parameter_t("lambert");
+       // specular
+       if (matr->spec_shader==MA_SPEC_PHONG) {
+               params["specular_brdf"] = yafray::parameter_t("phong");
+               params["hard"] = yafray::parameter_t(matr->har);
+       }
+       else if (matr->spec_shader==MA_SPEC_BLINN) {
+               params["specular_brdf"] = yafray::parameter_t("blinn");
+               params["blinn_ior"] = yafray::parameter_t(matr->refrac);
+               params["hard"] = yafray::parameter_t(matr->har);
+       }
+       else if (matr->spec_shader==MA_SPEC_TOON) {
+               params["specular_brdf"] = yafray::parameter_t("toon");
+               params["toonspecular_size"] = yafray::parameter_t(matr->param[2]);
+               params["toonspecular_smooth"] = yafray::parameter_t(matr->param[3]);
+       }
+       else if (matr->spec_shader==MA_SPEC_WARDISO) {
+               params["specular_brdf"] = yafray::parameter_t("ward");
+               params["u_roughness"] = yafray::parameter_t(matr->rms);
+               params["v_roughness"] = yafray::parameter_t(matr->rms);
+       }
+       else {
+               params["specular_brdf"] = yafray::parameter_t("blender_cooktorr");
+               params["hard"] = yafray::parameter_t(matr->har);
+       }
 
+       // ramps, if used
+       if (matr->mode & (MA_RAMP_COL|MA_RAMP_SPEC))
+       {
+               const string rm_blend[9] = {"mix", "add", "mul", "sub", "screen", "divide", "difference", "darken", "lighten"};
+               const string rm_mode[4] = {"shader", "energy", "normal", "result"};
+               // diffuse
+               if ((matr->mode & MA_RAMP_COL) && (matr->ramp_col!=NULL))
+               {
+                       params["diffuse_ramp"] = yafray::parameter_t(shader_name+"_difframp");
+                       params["diffuse_ramp_mode"] = yafray::parameter_t(rm_mode[(int)matr->rampin_col]);
+                       params["diffuse_ramp_blend"] = yafray::parameter_t(rm_blend[(int)matr->rampblend_col]);
+                       params["diffuse_ramp_factor"] = yafray::parameter_t(matr->rampfac_col);
+               }
+               // specular
+               if ((matr->mode & MA_RAMP_SPEC) && (matr->ramp_spec!=NULL)) {
+                       params["specular_ramp"] = yafray::parameter_t(shader_name+"_specramp");
+                       params["specular_ramp_mode"] = yafray::parameter_t(rm_mode[(int)matr->rampin_spec]);
+                       params["specular_ramp_blend"] = yafray::parameter_t(rm_blend[(int)matr->rampblend_spec]);
+                       params["specular_ramp_factor"] = yafray::parameter_t(matr->rampfac_spec);
+               }
+       }
+
+       // modulators
        // first modulator is the texture of the face, if used (TexFace mode)
        if (facetexname.length()!=0) {
                        yafray::paramMap_t mparams;
@@ -679,7 +802,12 @@ void yafrayPluginRender_t::writeShader(const string &shader_name, Material* matr
                        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);
+                       else if (mtex->blendtype==MTEX_DIV) ts="divide";
+                       else if (mtex->blendtype==MTEX_DARK) ts="darken";
+                       else if (mtex->blendtype==MTEX_DIFF) ts="difference";
+                       else if (mtex->blendtype==MTEX_LIGHT) ts="lighten";
+                       else if (mtex->blendtype==MTEX_SCREEN) ts="screen";
+                       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));
@@ -707,17 +835,17 @@ void yafrayPluginRender_t::writeShader(const string &shader_name, Material* matr
                        // 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);
+                               mparams["colspec"] = yafray::parameter_t(1.0);
                        // CMir, mirror color  modulation
                        if (mtex->mapto & MAP_COLMIR)
-                               mparams["colmir"]=yafray::parameter_t(1.0);
+                               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);
+                               mparams["difref"] = yafray::parameter_t(t);
                        }
 
                        // Spec, specular amount mod
@@ -725,7 +853,7 @@ void yafrayPluginRender_t::writeShader(const string &shader_name, Material* matr
                        {
                                int t = 1;
                                if (mtex->maptoneg & MAP_SPEC) t = -1;
-                               mparams["specular"]=yafray::parameter_t(t);
+                               mparams["specular"] = yafray::parameter_t(t);
                        }
 
                        // hardness modulation
@@ -733,7 +861,7 @@ void yafrayPluginRender_t::writeShader(const string &shader_name, Material* matr
                        {
                                int t = 1;
                                if (mtex->maptoneg & MAP_HAR) t = -1;
-                               mparams["hard"]=yafray::parameter_t(t);
+                               mparams["hard"] = yafray::parameter_t(t);
                        }
 
                        // alpha modulation
@@ -741,14 +869,21 @@ void yafrayPluginRender_t::writeShader(const string &shader_name, Material* matr
                        {
                                int t = 1;
                                if (mtex->maptoneg & MAP_ALPHA) t = -1;
-                               mparams["alpha"]=yafray::parameter_t(t);
+                               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);
+                               mparams["emit"] = yafray::parameter_t(t);
+                       }
+
+                       // raymir modulation
+                       if ((mtex->mapto & MAP_RAYMIRR) || (mtex->maptoneg & MAP_RAYMIRR)) {
+                               int t = 1;
+                               if (mtex->maptoneg & MAP_RAYMIRR) t = -1;
+                               mparams["raymir"] = yafray::parameter_t(t);
                        }
 
                        // texture flag, combination of strings
@@ -782,7 +917,7 @@ void yafrayPluginRender_t::writeShader(const string &shader_name, Material* matr
                        lparams.push_back(mparams);
                }
        }
-       yafrayGate->addShader(params,lparams);
+       yafrayGate->addShader(params, lparams);
 
 }
 
@@ -818,9 +953,9 @@ void yafrayPluginRender_t::writeMaterialsAndModulators()
                                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))
+                               if ((mtex->texco & TEXCO_OBJECT) || (mtex->texco & TEXCO_REFL) || (mtex->texco & TEXCO_NORM))
                                {
-                                       // For object & reflection mapping, add the object matrix to the modulator,
+                                       // For object, reflection & normal mapping, add the object matrix to the modulator,
                                        // as in LF script, use camera matrix if no object specified.
                                        // In this case this means the inverse of that matrix
                                        float texmat[4][4], itexmat[4][4];
@@ -1380,8 +1515,9 @@ void yafrayPluginRender_t::writeLamps()
                char temp[16];
                sprintf(temp,"LAMP%d",i+1);
                params["name"] = yafray::parameter_t(temp);
+
                // color already premultiplied by energy, so only need distance here
-               float pwr = 1;  // default for sun/hemi, distance irrelevant
+               float pwr = 1;
                if ((lamp->type!=LA_SUN) && (lamp->type!=LA_HEMI)) {
                        if (lamp->mode & LA_SPHERE) {
                                // best approx. as used in LFexport script (LF d.f.m. 4pi?)
@@ -1562,6 +1698,19 @@ void yafrayPluginRender_t::writeCamera()
 
 void yafrayPluginRender_t::writeHemilight()
 {
+       // updated to use Blender AO params
+       World *world = G.scene->world;
+       if (world==NULL) return;
+       yafray::paramMap_t params;
+       params["type"] = yafray::parameter_t("hemilight");
+       params["name"] = yafray::parameter_t("hemi_LT");
+       params["power"] = yafray::parameter_t(R.r.GIpower);
+       params["samples"] = yafray::parameter_t(world->aosamp*world->aosamp);
+       params["maxdistance"] = yafray::parameter_t(world->aodist);
+       params["use_QMC"] = yafray::parameter_t((world->aomode & WO_AORNDSMP) ? "off" : "on");
+       yafrayGate->addLight(params);
+
+       /*
        yafray::paramMap_t params;
        params["type"] = yafray::parameter_t("hemilight");
        params["name"] = yafray::parameter_t("hemi_LT");
@@ -1576,6 +1725,7 @@ void yafrayPluginRender_t::writeHemilight()
                default: params["samples"]=yafray::parameter_t(25);
        }
        yafrayGate->addLight(params);
+       */
 }
 
 void yafrayPluginRender_t::writePathlight()
@@ -1658,12 +1808,13 @@ bool yafrayPluginRender_t::writeWorld()
                        string wt_path = wimg->name;
                        adjustPath(wt_path);
                        if (BLI_testextensie(wimg->name, ".hdr")) {
-                               params["type"] = yafray::parameter_t("HDRI");
+                               params["type"] = yafray::parameter_t("image");
                                params["name"] = yafray::parameter_t("world_background");
                                // since exposure adjust is an integer, using the texbri slider isn't actually very useful here (result either -1/0/1)
-                               params["exposure_adjust"] = yafray::parameter_t(int(world->mtex[i]->tex->bright-1));
+                               params["exposure_adjust"] = yafray::parameter_t(wtex->tex->bright-1.f);
                                params["mapping"] = yafray::parameter_t("probe");
                                params["filename"] = yafray::parameter_t(wt_path);
+                               params["interpolate"] = yafray::parameter_t((wtex->tex->imaflag & TEX_INTERPOL) ? "bilinear" : "none");
                                yafrayGate->addBackground(params);
                                return true;
                        }
@@ -1737,12 +1888,12 @@ bool blenderYafrayOutput_t::putPixel(int x, int y, const yafray::color_t &c,
        zbuf[x] = (int)(depth*mz);
 
        out++;
-       if(out==4096)
+       if (out==4096)
        {
                RE_local_render_display(0,R.recty-1, R.rectx, R.recty, R.rectot);
-               out=0;
+               out = 0;
        }
-       if(RE_local_test_break())
+       if (RE_local_test_break())
                return false;
        return true;
 }
index 1ab2ca29c7f24664c76d001315a6f89a42045f35..00798c17a6aa570a1efde5867781c036ccd9e634 100644 (file)
@@ -32,8 +32,6 @@ bool yafrayRender_t::exportScene()
        mainCamLens = 35.0;
        if (maincam_obj->type==OB_CAMERA) mainCamLens=((Camera*)maincam_obj->data)->lens;
 
-       maxraydepth = 5;        // will be set to maximum depth used in blender materials
-
        // recreate the scene as object data, as well as sorting the material & textures, ignoring duplicates
        if (!getAllMatTexObs())
        {
index 8acd0ee5078ee0941011fe9fbeade36a3432d8c9..92125ec6bd259ecfc081db3b24442b8676c1676c 100644 (file)
@@ -82,7 +82,6 @@ class yafrayRender_t
                Object* maincam_obj;
                float mainCamLens;
 
-               int maxraydepth;
                bool hasworld;
 
                std::map<Object*, std::vector<VlakRen*> > all_objects;