From 33832f52eaeb8d3cdadd6188437df8b168827fe4 Mon Sep 17 00:00:00 2001 From: Alfredo de Greef Date: Sat, 21 May 2005 20:49:24 +0000 Subject: Part one of the final yafray commit. 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 | 182 +++++++++++++++++++++++---- 1 file changed, 156 insertions(+), 26 deletions(-) (limited to 'source/blender/yafray/intern/export_File.cpp') diff --git a/source/blender/yafray/intern/export_File.cpp b/source/blender/yafray/intern/export_File.cpp index f259a2b903f..90e05e627c5 100755 --- a/source/blender/yafray/intern/export_File.cpp +++ b/source/blender/yafray/intern/export_File.cpp @@ -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\n"; ostr << "\t\t\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\n"; ostr << "\t\n\n\n"; xmlfile << ostr.str(); break; @@ -412,6 +423,9 @@ void yafrayFileRender_t::writeTextures() ostr << "\t\t\n"; ostr << "\t\tstype) << "\" />\n"; ostr << "\t\t\n"; + ts = "sin"; + if (tex->noisebasis2==1) ts="saw"; else if (tex->noisebasis2==2) ts="tri"; + ostr << "\t\t\n"; ostr << "\t\n\n\n"; xmlfile << ostr.str(); break; @@ -544,6 +558,7 @@ void yafrayFileRender_t::writeTextures() string texpath(ima->name); adjustPath(texpath); ostr << "\t\t\n"; + ostr << "\t\timaflag & TEX_INTERPOL) ? "bilinear" : "none") << "\" />\n"; ostr << "\t\n\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 << "\n"; + ostr << "\t\n\t\n"; + for (int i=0;itot;i++) { + ostr << "\tdata[i].pos << "\" >\n"; + ostr << "\t\tdata[i].r << "\"" << + " g=\"" << cb->data[i].g << "\"" << + " b=\"" << cb->data[i].b << "\"" << + " a=\"" << cb->data[i].a << "\" />\n"; + ostr << "\t\n"; + } + ostr << "\n\n"; + xmlfile << ostr.str(); + } + cb = matr->ramp_spec; + if ((matr->mode & MA_RAMP_SPEC) && (cb!=NULL)) + { + ostr.str(""); + ostr << "\n"; + ostr << "\t\n\t\n"; + for (int i=0;itot;i++) { + ostr << "\tdata[i].pos << "\" >\n"; + ostr << "\t\tdata[i].r << "\"" << + " g=\"" << cb->data[i].g << "\"" << + " b=\"" << cb->data[i].b << "\"" << + " a=\"" << cb->data[i].a << "\" />\n"; + ostr << "\t\n"; + } + ostr << "\n\n"; + xmlfile << ostr.str(); + } + } + ostr.str(""); ostr << "\n"; ostr << "\t\n"; - float diff = matr->alpha; + float diff = 1; //matr->alpha; ostr << "\t\tr*diff << "\" g=\"" << matr->g*diff << "\" b=\"" << matr->b*diff << "\" />\n"; ostr << "\t\tspecr << "\" g=\"" << matr->specg << "\" b=\"" << matr->specb << "\" />\n"; ostr << "\t\tmirr << "\" g=\"" << matr->mirg << "\" b=\"" << matr->mirb << "\" />\n"; ostr << "\t\tref << "\" />\n"; ostr << "\t\tspec << "\" />\n"; - ostr << "\t\thar << "\" />\n"; ostr << "\t\talpha << "\" />\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\tang << "\" />\n"; if (matr->mode & MA_RAYMIRROR) { - float rf = matr->ray_mirror; // blender uses mir color for reflection as well - ostr << "\t\tmirr << "\" g=\"" << matr->mirg << "\" b=\"" << matr->mirb << "\" />\n"; - ostr << "\t\t\n"; - if (matr->ray_depth>maxraydepth) maxraydepth = matr->ray_depth; + //ostr << "\t\tmirr << "\" 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\n"; + ostr << "\t\tray_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\n"; } if (matr->mode & MA_RAYTRANSP) { - float tr=1.0-matr->alpha; - ostr << "\t\tr * tr << "\" g=\"" << matr->g * tr << "\" b=\"" << matr->b * tr << "\" />\n"; + //float tr=1.0-matr->alpha; + //ostr << "\t\tr*tr << "\" g=\"" << matr->g*tr << "\" b=\"" << matr->b*tr << "\" />\n"; + ostr << "\t\t\n"; + ostr << "\t\tfilter << "\" />\n"; // tir on by default ostr << "\t\t\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\n"; + + // diffuse & specular brdf, lambert/cooktorr defaults + // diffuse + if (matr->diff_shader==MA_DIFF_ORENNAYAR) { + ostr << "\t\t\n"; + ostr << "\t\troughness << "\" />\n"; + } + else if (matr->diff_shader==MA_DIFF_TOON) { + ostr << "\t\t\n"; + ostr << "\t\tparam[0] << "\" />\n"; + ostr << "\t\tparam[1] << "\" />\n"; + } + else if (matr->diff_shader==MA_DIFF_MINNAERT) { + ostr << "\t\t\n"; + ostr << "\t\tdarkness << "\" />\n"; + } + else ostr << "\t\t\n"; + // specular + if (matr->spec_shader==MA_SPEC_PHONG) { + ostr << "\t\t\n"; + ostr << "\t\thar << "\" />\n"; + } + else if (matr->spec_shader==MA_SPEC_BLINN) { + ostr << "\t\t\n"; + ostr << "\t\trefrac << "\" />\n"; + ostr << "\t\thar << "\" />\n"; + } + else if (matr->spec_shader==MA_SPEC_TOON) { + ostr << "\t\t\n"; + ostr << "\t\tparam[2] << "\" />\n"; + ostr << "\t\tparam[3] << "\" />\n"; + } + else if (matr->spec_shader==MA_SPEC_WARDISO) { + ostr << "\t\t\n"; + ostr << "\t\trms << "\" />\n"; + ostr << "\t\trms << "\" />\n"; + } + else { + ostr << "\t\t\n"; + ostr << "\t\thar << "\" />\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\n"; + ostr << "\t\trampin_col] << "\" />\n"; + ostr << "\t\trampblend_col] << "\" />\n"; + ostr << "\t\trampfac_col << "\" />\n"; + } + // specular + if ((matr->mode & MA_RAMP_SPEC) && (matr->ramp_spec!=NULL)) { + ostr << "\t\t\n"; + ostr << "\t\trampin_spec] << "\" />\n"; + ostr << "\t\trampblend_spec] << "\" />\n"; + ostr << "\t\trampfac_spec << "\" />\n"; + } + } + ostr << "\t\n"; xmlfile << ostr.str(); @@ -681,12 +807,9 @@ void yafrayFileRender_t::writeShader(const string &shader_name, Material* matr, else ostr << "\t\t\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\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\tblendtype] << "\" />\n"; // texture color (for use with MUL and/or no_rgb etc..) ostr << "\t\tr << "\" 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\n"; - } // emit modulation @@ -759,9 +881,16 @@ void yafrayFileRender_t::writeShader(const string &shader_name, Material* matr, ostr << "\t\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\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 << "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\n"; @@ -1662,11 +1791,12 @@ bool yafrayFileRender_t::writeWorld() adjustPath(wt_path); if (BLI_testextensie(wimg->name, ".hdr")) { ostr.str(""); - ostr << "mtex[i]->tex->bright-1) << "\" mapping=\"probe\" >\n"; + ostr << "exposure_adjust=\"" << wtex->tex->bright-1.f << "\" mapping=\"probe\" >\n"; ostr << "\t\n"; + ostr << "\ttex->imaflag & TEX_INTERPOL) ? "bilinear" : "none") << "\" />\n"; ostr << "\n\n"; xmlfile << ostr.str(); return true; -- cgit v1.2.3