diff options
author | Alfredo de Greef <eeshlo@yahoo.com> | 2004-07-29 02:37:12 +0400 |
---|---|---|
committer | Alfredo de Greef <eeshlo@yahoo.com> | 2004-07-29 02:37:12 +0400 |
commit | e9b0238d0c86258abc7e020a87a798434d220d5e (patch) | |
tree | 022a91af0032b41a6efd505bd9adfead317db357 /source/blender/yafray | |
parent | fcd19e73df47dec183f82da376a5e1b5492c9dac (diff) |
Major update, all implemented a bit in a hurry, and probably will need bugfixes at some point.
Extended the range of the depth and cdepth parameters as reqested by leope.
Bumpmapping should now be a bit more similar to the Blender render.
Added support for all remaining lightsources in yafray, tried to make use of
as much of the existing Blender parameters as possible.
Blender Lamp: added switch to enable rendering with shadowbuffer ('softlight' in yafray).
All other parameters are similar to the Blender settings, for yafray both the
bias parameter and the shadowbuffer size can be lower than equivalent Blender
settings, since the yafray buffer is floating point. Remember that 6 shadowmaps
are created in this case, so can use quite a bit of memory with large
buffer settings.
When 'ray shadow' is enabled for this lamp type, it is possible to set a light
radius to create a spherical arealight source ('spherelight' in yafray),
when this is 0, it is exported as a pointlight instead.
Blender Spot: as in Blender now supports 'halo' rendering.
Halo spots always use shadowbuffers, so when enabled the buttons for shadowmap
settings will appear. The 'ray shadow' button can still be used to disable
shadows cast onto other objects, independent of halo shadows.
One thing to remember, halo's don't work with empty backgrounds, something must
be behind the spotlight for it to be visible.
And finally, the photonlight:
probably the most confusing (as more things related to yafray), the photonlight
is not a real lightsource, it is only used as a source to shoot photons from.
Since indirect lighting is already supported (and looks better as well)
only caustics mode is supported.
So to be able to use this properly other lightsources must be used with it.
For the photonlighting to be 'correct' similar lightsettings as for the 'source'
light are needed.
Probably the best way to do this, when you are happy with the lighting setup
you have, and want to add caustics, copy the light you want to enable for
caustics (shift-D) and leave everything as is, then change the mode to
'Photon'.
To not waiste any photons, the photonlight behaves similar to the spotlight,
you can set the width of the beam with the 'angle' parameter. Make sure
that any object that needs to cast caustics is within that beam, make
the beam width as small as possible to tightly fit the object.
The following other parameters can be set:
-photons: the number of photons to shoot.
-search: the number of photons to search when rendering, the higher,
the blurrier the caustics.
-depth: the amount of photon bounces allowed, since the primary use is for
caustics, you probably best set this to the same level as the 'ray depth'
parameter.
-Blur: this controls the amount of caustics blur (in addition to the search
parameter), very low values will cause very sharp caustics, which when used
with a low photonnumber, probably lead to only some noisy specks being rendered.
-Use QMC: Use quasi monte carlo sampling, can lead to cleaner results, but also
can sometimes cause patterns.
Since the photonlight has no meaning to Blender, when using photonlights and
switching back to the internal render, the light doesn't do anything, and no
type button will be selected. The lightsource can still be selected, but unless
switching to yafray, no parameters can set.
Apologies to Anexus, I had no time to really do something with your code,
I'll still look at it later, to see if I can improve anything in my implementation.
Diffstat (limited to 'source/blender/yafray')
-rwxr-xr-x | source/blender/yafray/intern/export_File.cpp | 114 | ||||
-rw-r--r-- | source/blender/yafray/intern/export_Plugin.cpp | 138 |
2 files changed, 187 insertions, 65 deletions
diff --git a/source/blender/yafray/intern/export_File.cpp b/source/blender/yafray/intern/export_File.cpp index 92a253edd15..98b81c62c18 100755 --- a/source/blender/yafray/intern/export_File.cpp +++ b/source/blender/yafray/intern/export_File.cpp @@ -640,10 +640,10 @@ void yafrayFileRender_t::writeMaterialsAndModulators() // 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 when image type, otherwise used directly + // 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 *= 2e-3f; + if (tex->type==TEX_IMAGE) nf/=60.f; else nf/=30.f; ostr << "\t\t<normal value=\"" << nf << "\" />\n"; } @@ -1050,7 +1050,7 @@ void yafrayFileRender_t::writeAreaLamp(LampRen* lamp, int num, float iview[4][4] ostr << "<light type=\"arealight\" name=\"LAMP" << num+1 << "\" dummy=\""<< md << "\" power=\"" << power << "\" "; if (!R.r.GIphotons) { int psm=0, sm = lamp->ray_totsamp; - if (sm>=64) psm = sm/4; + if (sm>=25) psm = sm/5; ostr << "samples=\"" << sm << "\" psamples=\"" << psm << "\" "; } ostr << ">\n"; @@ -1088,49 +1088,107 @@ void yafrayFileRender_t::writeLamps() { ostr.str(""); LampRen* lamp = R.la[i]; + if (lamp->type==LA_AREA) { writeAreaLamp(lamp, i, iview); continue; } + // TODO: add decay setting in yafray ostr << "<light type=\""; - if (lamp->type==LA_LOCAL) - ostr << "pointlight"; + bool is_softL=false, is_sphereL=false; + if (lamp->type==LA_LOCAL) { + if (lamp->mode & LA_YF_SOFT) { + // shadowmapped omnidirectional light + ostr << "softlight"; + is_softL = true; + } + else if ((lamp->mode & LA_SHAD_RAY) && (lamp->YF_ltradius>0.0)) { + // area sphere, only when ray shadows enabled and radius>0.0 + ostr << "spherelight"; + is_sphereL = true; + } + else ostr << "pointlight"; + } else if (lamp->type==LA_SPOT) ostr << "spotlight"; - else if ((lamp->type==LA_SUN) || (lamp->type==LA_HEMI)) // for now, hemi same as sun + else if ((lamp->type==LA_SUN) || (lamp->type==LA_HEMI)) // hemi exported as sun ostr << "sunlight"; + else if (lamp->type==LA_YF_PHOTON) + ostr << "photonlight"; else { // possibly unknown type, ignore cout << "Unknown Blender lamp type: " << lamp->type << endl; continue; } - ostr << "\" name=\"LAMP" << i+1; //no name available here, create one + + //no name available here, create one + ostr << "\" name=\"LAMP" << i+1; // color already premultiplied by energy, so only need distance here - float pwr; - if (lamp->mode & LA_SPHERE) { - // best approx. as used in LFexport script (LF d.f.m. 4pi?) - pwr = lamp->dist*(lamp->dist+1)*(0.25/M_PI); - //decay = 2; - } - else { - if ((lamp->type==LA_LOCAL) || (lamp->type==LA_SPOT)) { + float pwr = 1; // default for sun/hemi, distance irrelevant + 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?) + pwr = lamp->dist*(lamp->dist+1)*(0.25/M_PI); + //decay = 2; + } + else { pwr = lamp->dist; //decay = 1; } - else pwr = 1; // sun/hemi distance irrelevant } - ostr << "\" power=\"" << pwr; - 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"; - ostr << "\" cast_shadows=\"" << lpmode << "\""; + ostr << "\" power=\"" << pwr << "\""; + + // 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"; + ostr << " cast_shadows=\"" << lpmode << "\""; + } + // spot specific stuff + bool has_halo = ((lamp->type==LA_SPOT) && (lamp->mode & LA_HALO) && (lamp->haint>0.0)); if (lamp->type==LA_SPOT) { // conversion already changed spotsize to cosine of half angle float ld = 1-lamp->spotsi; //convert back to blender slider setting if (ld!=0) ld = 1.f/ld; - ostr << " size=\"" << acos(lamp->spotsi)*180.0/M_PI << "\"" - << " blend=\"" << lamp->spotbl*ld << "\"" - << " beam_falloff=\"2\""; // no Blender equivalent (yet) + ostr << " size=\"" << acos(lamp->spotsi)*180.0/M_PI << "\"" + << " blend=\"" << lamp->spotbl*ld << "\"" + << " beam_falloff=\"2\""; // no Blender equivalent (yet) + // halo params + if (has_halo) { + ostr << "\n\thalo=\"on\" " << "res=\"" << lamp->YF_bufsize << "\"\n"; + int hsmp = ((12-lamp->shadhalostep)*16)/12; + hsmp = (hsmp+1)*16; // makes range (16, 272) for halostep(12, 0), good enough? + ostr << "\tsamples=\"" << hsmp << "\" shadow_samples=\"" << (lamp->samp*lamp->samp) << "\"\n"; + ostr << "\thalo_blur=\"0\" shadow_blur=\"" << (lamp->soft*0.01f) << "\"\n"; + ostr << "\tfog_density=\"" << (lamp->haint*0.2f) << "\""; + } + } + else if (is_softL) { + // softlight + ostr << " res=\"" << lamp->YF_bufsize << "\"" + << " radius=\"" << lamp->soft << "\"" + << " bias=\"" << lamp->bias << "\""; + } + else if (is_sphereL) { + // spherelight + int psm=0, sm = lamp->samp*lamp->samp; + if (sm>=25) psm = sm/5; + ostr << " radius=\"" << lamp->YF_ltradius << "\"" + << " samples=\"" << sm << "\"" + << " psamples=\"" << psm << "\"" + << " qmc_method=\"1\""; + } + else if (lamp->type==LA_YF_PHOTON) { + string qmc="off"; + if (lamp->YF_useqmc) qmc="on"; + ostr << "\n\tphotons=\"" << lamp->YF_numphotons << "\"" + << " search=\"" << lamp->YF_numsearch << "\"" + << " depth=\"" << lamp->YF_phdepth << "\"" + << " use_QMC=\"" << qmc << "\"" + << " angle=\"" << acos(lamp->spotsi)*180.0/M_PI << "\""; + float cl = lamp->YF_causticblur/sqrt((float)lamp->YF_numsearch); + ostr << "\n\tfixedradius=\"" << lamp->YF_causticblur << "\" cluster=\"" << cl << "\""; } ostr << " >\n"; @@ -1146,11 +1204,13 @@ void yafrayFileRender_t::writeLamps() ostr << "\t<from x=\"" << -lpvec[0] << "\" y=\"" << -lpvec[1] << "\" z=\"" << -lpvec[2] << "\" />\n"; else ostr << "\t<from x=\"" << lpco[0] << "\" y=\"" << lpco[1] << "\" z=\"" << lpco[2] << "\" />\n"; - // 'to' for spot, already calculated by Blender - if (lamp->type==LA_SPOT) + // 'to' for spot/photonlight, already calculated by Blender + if ((lamp->type==LA_SPOT) || (lamp->type==LA_YF_PHOTON)) { ostr << "\t<to x=\"" << lpco[0] + lpvec[0] << "\" y=\"" << lpco[1] + lpvec[1] << "\" z=\"" << lpco[2] + lpvec[2] << "\" />\n"; + if (has_halo) ostr << "\t<fog r=\"1\" g=\"1\" b=\"1\" />\n"; + } // color // rgb in LampRen is premultiplied by energy, power is compensated for that above diff --git a/source/blender/yafray/intern/export_Plugin.cpp b/source/blender/yafray/intern/export_Plugin.cpp index 1e035073a24..5063974b59e 100644 --- a/source/blender/yafray/intern/export_Plugin.cpp +++ b/source/blender/yafray/intern/export_Plugin.cpp @@ -638,10 +638,10 @@ void yafrayPluginRender_t::writeMaterialsAndModulators() { // for yafray, bump factor is negated (unless negative option of 'Nor', // is not affected by 'Neg') - // scaled down quite a bit for yafray when image type, otherwise used directly + // 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 *= 2e-3f; + if (tex->type==TEX_IMAGE) nf/=60.f; else nf/=30.f; mparams["normal"]=yafray::parameter_t(nf); } @@ -1100,53 +1100,112 @@ void yafrayPluginRender_t::writeLamps() yafray::paramMap_t params; string type=""; LampRen* lamp = R.la[i]; + if (lamp->type==LA_AREA) { writeAreaLamp(lamp, i, iview); continue; } + // TODO: add decay setting in yafray - if (lamp->type==LA_LOCAL) - params["type"]=yafray::parameter_t("pointlight"); + bool is_softL=false, is_sphereL=false; + if (lamp->type==LA_LOCAL) { + if (lamp->mode & LA_YF_SOFT) { + // shadowmapped omnidirectional light + params["type"] = yafray::parameter_t("softlight"); + is_softL = true; + } + else if ((lamp->mode & LA_SHAD_RAY) && (lamp->YF_ltradius>0.0)) { + // area sphere, only when ray shadows enabled and radius>0.0 + params["type"] = yafray::parameter_t("spherelight"); + is_sphereL = true; + } + else params["type"] = yafray::parameter_t("pointlight"); + } else if (lamp->type==LA_SPOT) - params["type"]=yafray::parameter_t("spotlight"); - else if ((lamp->type==LA_SUN) || (lamp->type==LA_HEMI)) // for now, hemi same as sun - params["type"]=yafray::parameter_t("sunlight"); - else - { + params["type"] = yafray::parameter_t("spotlight"); + else if ((lamp->type==LA_SUN) || (lamp->type==LA_HEMI)) // hemi exported as sun + params["type"] = yafray::parameter_t("sunlight"); + else if (lamp->type==LA_YF_PHOTON) + params["type"] = yafray::parameter_t("photonlight"); + else { // possibly unknown type, ignore cout << "Unknown Blender lamp type: " << lamp->type << endl; continue; } + //no name available here, create one char temp[16]; sprintf(temp,"LAMP%d",i+1); - params["name"]=yafray::parameter_t(temp); + params["name"] = yafray::parameter_t(temp); // color already premultiplied by energy, so only need distance here - float pwr; - if (lamp->mode & LA_SPHERE) - { - // best approx. as used in LFexport script (LF d.f.m. 4pi?) - pwr = lamp->dist*(lamp->dist+1)*(0.25/M_PI); - //decay = 2; - } - else - { - if ((lamp->type==LA_LOCAL) || (lamp->type==LA_SPOT)) + float pwr = 1; // default for sun/hemi, distance irrelevant + 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?) + pwr = lamp->dist*(lamp->dist+1)*(0.25/M_PI); + //decay = 2; + } + else { pwr = lamp->dist; - else pwr = 1; // sun/hemi distance irrelevent. + //decay = 1; + } + } + params["power"] = yafray::parameter_t(pwr); + + // 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"; + params["cast_shadows"] = yafray::parameter_t(lpmode); } - params["power"]=yafray::parameter_t(pwr); - 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"; - params["cast_shadows"]=yafray::parameter_t(lpmode); + // spot specific stuff - if (lamp->type==LA_SPOT) - { + bool has_halo = ((lamp->type==LA_SPOT) && (lamp->mode & LA_HALO) && (lamp->haint>0.0)); + if (lamp->type==LA_SPOT) { // conversion already changed spotsize to cosine of half angle float ld = 1-lamp->spotsi; //convert back to blender slider setting if (ld!=0) ld = 1.f/ld; - params["size"]=yafray::parameter_t(acos(lamp->spotsi)*180.0/M_PI); - params["blend"]=yafray::parameter_t(lamp->spotbl*ld); - params["beam_falloff"]=yafray::parameter_t(2.0); + params["size"] = yafray::parameter_t(acos(lamp->spotsi)*180.0/M_PI); + params["blend"] = yafray::parameter_t(lamp->spotbl*ld); + params["beam_falloff"] = yafray::parameter_t(2.0); + // halo params + if (has_halo) { + params["halo"] = yafray::parameter_t("on"); + params["res"] = yafray::parameter_t(lamp->YF_bufsize); + int hsmp = ((12-lamp->shadhalostep)*16)/12; + hsmp = (hsmp+1)*16; // makes range (16, 272) for halostep(12, 0), good enough? + params["samples"] = yafray::parameter_t(hsmp); + params["shadow_samples"] = yafray::parameter_t(lamp->samp*lamp->samp); + params["halo_blur"] = yafray::parameter_t(0.0); + params["shadow_blur"] = yafray::parameter_t(lamp->soft*0.01f); + params["fog_density"] = yafray::parameter_t(lamp->haint*0.2f); + } + } + else if (is_softL) { + // softlight + params["res"] = yafray::parameter_t(lamp->YF_bufsize); + params["radius"] = yafray::parameter_t(lamp->soft); + params["bias"] = yafray::parameter_t(lamp->bias); + } + else if (is_sphereL) { + // spherelight + int psm=0, sm = lamp->samp*lamp->samp; + if (sm>=25) psm = sm/5; + params["radius"] = yafray::parameter_t(lamp->YF_ltradius); + params["samples"] = yafray::parameter_t(sm); + params["psamples"] = yafray::parameter_t(psm); + params["qmc_method"] = yafray::parameter_t(1); + } + else if (lamp->type==LA_YF_PHOTON) { + string qmc="off"; + if (lamp->YF_useqmc) qmc="on"; + params["photons"] = yafray::parameter_t(lamp->YF_numphotons); + params["search"] = yafray::parameter_t(lamp->YF_numsearch); + params["depth"] = yafray::parameter_t(lamp->YF_phdepth); + params["use_QMC"] = yafray::parameter_t(qmc); + params["angle"] = yafray::parameter_t(acos(lamp->spotsi)*180.0/M_PI); + float cl = lamp->YF_causticblur/sqrt((float)lamp->YF_numsearch); + params["fixedradius"] = yafray::parameter_t(lamp->YF_causticblur); + params["cluster"] = yafray::parameter_t(cl); } // transform lamp co & vec back to world @@ -1161,14 +1220,17 @@ void yafrayPluginRender_t::writeLamps() params["from"] = yafray::parameter_t(yafray::point3d_t(-lpvec[0], -lpvec[1], -lpvec[2])); else params["from"] = yafray::parameter_t(yafray::point3d_t(lpco[0], lpco[1], lpco[2])); - // 'to' for spot, already calculated by Blender - if (lamp->type==LA_SPOT) - params["to"]=yafray::parameter_t(yafray::point3d_t(lpco[0] + lpvec[0], - lpco[1] + lpvec[1], - lpco[2] + lpvec[2])); + // 'to' for spot/photonlight, already calculated by Blender + if ((lamp->type==LA_SPOT) || (lamp->type==LA_YF_PHOTON)) { + params["to"] = yafray::parameter_t(yafray::point3d_t(lpco[0] + lpvec[0], + lpco[1] + lpvec[1], + lpco[2] + lpvec[2])); + if (has_halo) params["fog"] = yafray::parameter_t(yafray::color_t(1.0, 1.0, 1.0)); + } + // color // rgb in LampRen is premultiplied by energy, power is compensated for that above - params["color"]=yafray::parameter_t(yafray::color_t(lamp->r,lamp->g,lamp->b)); + params["color"] = yafray::parameter_t(yafray::color_t(lamp->r, lamp->g, lamp->b)); yafrayGate->addLight(params); } } |