diff options
Diffstat (limited to 'vrayPlug/plugin/shaveVrayBaseBSDF.cpp')
| -rw-r--r-- | vrayPlug/plugin/shaveVrayBaseBSDF.cpp | 325 |
1 files changed, 325 insertions, 0 deletions
diff --git a/vrayPlug/plugin/shaveVrayBaseBSDF.cpp b/vrayPlug/plugin/shaveVrayBaseBSDF.cpp new file mode 100644 index 0000000..3211508 --- /dev/null +++ b/vrayPlug/plugin/shaveVrayBaseBSDF.cpp @@ -0,0 +1,325 @@ +// Shave and a Haircut +// (c) 2019 Epic Games +// US Patent 6720962 + +/********************************************************************** + *< + FILE: shaveVrayBaseBSDF.h ( was HairVrBaseBSDF.h ) + + DESCRIPTION: Generic class for BSDFs + + CREATED BY: Vladimir Dubovoy <[email protected]> + + HISTORY: created 09-09-2008 ( as part of 3ds Max + VRay hair shaders) + merged 31-03-2010 + + *> + **********************************************************************/ + +#include "shaveVrayBaseBSDF.h" + + +void shaveVrayBaseBSDF::init(const VR::VRayContext &rc, + const VR::Color &reflectionColor, + const VR::Color &diffuseColor, + const VR::Color &ambientColor, + const VR::Color &specularTint, + const VR::Color &specularTint2, + float ambDiff, + float specularLevel, + float reflectionGlossiness, int ns, + const VR::Color &transp, + const VR::ShadeVec &hairDir, + float requiredTransparency, + bool cameraVisibility, + bool reflVisibility, + bool refrVisibility, + bool lightVisibility, + bool giVisibility, + float selfshadow, + bool recvshadow) +{ + this->hairDir=hairDir; + + // Russian roulette for the transparency for camera rays; this drastically + // improves render times for soft transprent hair by reducing the number of + // lighting calculations, for roughly the same visual result. It could be + // slightly noisier, but the speed gain is worth it. + if (rc.rayresult.transpLevel>0 && 0==(rc.rayparams.rayType & (VR::RT_SHADOW | VR::RT_INDIRECT | VR::RT_LIGHT | VR::RT_LIGHTMAP))) { + float t=const_cast<VR::VRayContext&>(rc).getDMCValue(); + if (t<requiredTransparency) { + requiredTransparency=1.0f; + } else { + requiredTransparency=0.0f; + } + requiredTransparency=VR::clamp(requiredTransparency, 0.0f, 1.0f); + } + /////////////// + if(((rc.rayparams.rayType & (VR::RT_SHADOW | VR::RT_LIGHT | VR::RT_LIGHTMAP)) != 0) && !lightVisibility) + { + requiredTransparency=1.0f; + } + else if(((rc.rayparams.rayType & VR::RT_INDIRECT) != 0) && !giVisibility) + { + requiredTransparency=1.0f; + } + else if(rc.rayparams.totalLevel == 0 && !cameraVisibility) + { + requiredTransparency=1.0f; + } + else if(rc.rayparams.totalLevel != 0) + { + if((rc.rayparams.rayType & VUtils::RT_REFLECT) && !reflVisibility) + requiredTransparency=1.0f; + else if((rc.rayparams.rayType & VUtils::RT_REFRACT) && !refrVisibility) + requiredTransparency=1.0f; + + } + ////// self shadowing ///////// + //printf("selfshadow %f\n",selfshadow);fflush(stdout); + if(recvshadow) + { + if(selfshadow != 1.0f && requiredTransparency!=1.0f) + { + if ((rc.rayparams.rayType & VR::RT_SHADOW)!=0 + && rc.parent!=NULL && rc.parent->rayresult.sd==rc.rayresult.sd) + { + //requiredTransparency=1.0f; + requiredTransparency = (1.0f - selfshadow); + } + } + } + //else if (requiredTransparency!=1.0f && (rc.rayparams.rayType & VR::RT_SHADOW)!=0 + // && rc.parent!=NULL && rc.parent->rayresult.sd!=rc.rayresult.sd) + //{ + // requiredTransparency=1.0f; + //} + + this->requiredTransparency=requiredTransparency; + this->isGatherPoint = rc.vray->getSequenceData().globalLightManager->isGatheringPoint(rc) != 0; + + float contrib=(1.0f-requiredTransparency); // *0.5f; + + _reflect_filter() = VR::toShadeCol(reflectionColor)*contrib*0.5f; + _transparency() = VR::toShadeCol(transp); + _diffuse() = VR::toShadeCol(diffuseColor)*contrib; + _ambient() = VR::toShadeCol(ambientColor); + _spec_tint() = VR::toShadeCol(specularTint); + _spec_tint2() = VR::toShadeCol(specularTint2); + _ambdiff() = ambDiff; + _speclvl() = specularLevel; + _cameraVisibility() = cameraVisibility; + _lightVisibility() = lightVisibility; + _giVisibility() = giVisibility; + _combineSampling()= rc.vray->getSequenceData().globalLightManager->isGatheringPoint(rc) != 0; + + float divd=(reflectionGlossiness*70.0f); + divd*=divd; + if (divd<1e-6f) { + _glossiness()=0.0f; + } else { + _glossiness() = divd; + } + _normal() = rc.rayresult.normal; + _gnormal()= rc.rayresult.gnormal; + + +} +/* +| from BRDFSampler +*/ +VR::ShadeCol shaveVrayBaseBSDF::getDiffuseColor(VR::ShadeCol &lightColor) +{ + VR::ShadeCol res=lightColor*diffuse(); + lightColor*=currentTransp; + //performance test + //lightColor.makeZero(); + return res; +} +/* +| from BRDFSampler +*/ +VR::ShadeCol shaveVrayBaseBSDF::getLightMult(VR::ShadeCol &lightColor) +{ + VR::ShadeCol res = lightColor*diffuse(); + lightColor*=currentTransp; + //performance test + //lightColor.makeZero(); + return res; +} +/* +| from BRDFSampler +*/ + +VR::ShadeCol getColorFromDir(const VR::Vector &a) { + return VR::ShadeCol(a.x, a.y, a.z)*0.5f+VR::ShadeCol(0.5f, 0.5f, 0.5f); +} + +// This is based on Kajiya, J. T. and Kay, T. L., "Rendering Fur with Three Dimensional Texures", +// in SIGGRAPH '89: Proceedings of the 16th annual conference on Computer graphics and interactive techniques +inline VR::real getGlossyProbability(const VR::ShadeVec &direction, const VR::ShadeVec &viewDir, const VR::ShadeVec &hairDir, float p) +{ + float cs1=(float) (direction*hairDir); + float sn1=sqrtf(VR::Max(0.0f, 1.0f-cs1*cs1)); + + float cs=(float) (viewDir*hairDir); + float sn=sqrtf(VR::Max(0.0f, 1.0f-cs*cs)); + + float k = VR::Max(0.0f, cs1*cs+sn1*sn); + k=powf(k, p); + + return k; +} + +VR::ShadeCol shaveVrayBaseBSDF::eval(const VR::VRayContext &rc, const VR::ShadeVec &direction, + VR::ShadeCol &lightColor, VR::ShadeCol &origLightColor, float probLight, int flags) +{ + //if(((rc.rayparams.rayType & (VR::RT_SHADOW | VR::RT_LIGHT | VR::RT_LIGHTMAP)) != 0) && !lightVisibility()) + //{ + // return VR::ShadeCol(0.0f, 0.0f, 0.0f); + //} + //else if(((rc.rayparams.rayType & VR::RT_INDIRECT) != 0) && !giVisibility()) + //{ + // return VR::ShadeCol(0.0f, 0.0f, 0.0f); + //} + //else if(rc.rayparams.totalLevel == 0 && !cameraVisibility()) + //{ + // return origLightColor;//VR::ShadeCol(0.0f, 0.0f, 0.0f); + //} + + float cs0=(float) (direction*rc.rayresult.normal); + VR::ShadeVec d2; + if (cs0<0.0f) return VR::ShadeCol(0.0f, 0.0f, 0.0f); + + float cs=(float) (direction*hairDir); + + ///////////// performance test ////////////// + ///////////// white-like BSDF ///////////// + //VR::ShadeCol res; + //if ((flags & FBRDF_DIFFUSE)==0) res.makeZero(); + //else { + // float k=cs; + // // Apply combined sampling ONLY if GI is on which will pick up the rest of the result + // if (isGatherPoint) { + // float probReflection=k*2.0f; + // probReflection*=probReflection; + // probLight*=probLight; + // k*=probLight/(probLight+probReflection); + // } + // res=lightColor*k; + //} + //lightColor.makeZero(); + //origLightColor.makeZero(); + //return res; + //////////////////////////////////////////// + + VR::ShadeCol res; + VR::ShadeCol diff; + VR::ShadeCol spec; + VR::ShadeCol spec2; + + res.makeZero(); + diff.makeZero(); + spec.makeZero(); + spec2.makeZero(); + + //use spec_tint() and spec_tint2() - to get speclar colors + //test + //printf("spec_tint %f %f %f \n",spec_tint().r, spec_tint().g, spec_tint().b); + //printf("spec_tint2 %f %f %f \n",spec_tint2().r, spec_tint2().g, spec_tint2().b); + + //if(isGatherPoint)//does not make a difference for perfromance -- 01-11-2010 + { + if (flags & FBRDF_DIFFUSE) + { + float sn=sqrtf(VR::Max(0.0f, 1.0f-cs*cs)); + float K = sn*ambdiff() + (1.0f - ambdiff()); + diff = (lightColor*diffuse())*K; + } + if (glossiness() > 0.0f && (flags & FBRDF_SPECULAR) && + ((rc.rayparams.rayType & VR::RT_NOSPECULAR)==0)) + { + VUtils::real k = getGlossyProbability(direction, rc.rayparams.viewDir, hairDir, glossiness()); + if (k>1.0f) k=1.0f; + spec = (speclvl()*k)*(reflect_filter()*lightColor); + spec *= spec_tint(); + d2=direction*.7+rc.rayparams.viewDir*.3; + d2.makeNormalized0(); + + VUtils::real k2 = getGlossyProbability(d2, rc.rayparams.viewDir, hairDir, glossiness()*.55f); + if (k2>1.0f) k2=1.0f; + spec2 = (speclvl()*k2)*(reflect_filter()*lightColor); + spec2 *= spec_tint2(); + } + + lightColor*=currentTransp; + origLightColor*=currentTransp; + + res = diff + spec+spec2; + } + return res; +} +/* +| from BRDFSampler +*/ +VR::ShadeCol shaveVrayBaseBSDF::getTransparency(const VR::VRayContext &rc) +{ + return VR::ShadeCol(currentTransp, currentTransp, currentTransp); +} + +void shaveVrayBaseBSDF::traceForward(VR::VRayContext &rc, int doDiffuse) +{ + if (!doDiffuse) + rc.mtlresult.color.makeZero(); + else + rc.mtlresult.color=diffuse()*rc.evalDiffuse(); + +// joe dec23 if(requiredTransparency < 0.0001f) + if ((requiredTransparency < 0.15f)||( (rc.rayparams.rayType & VR::RT_CAMERA)==0 ) ) + { + rc.mtlresult.transp.set(0.0f, 0.0f, 0.0f); + rc.mtlresult.alpha.set(1.0f, 1.0f, 1.0f); +// rc.mtlresult.alphaTransp=rc.mtlresult.transp; + rc.mtlresult.alphaTransp.set(0.0f, 0.0f, 0.0f); + } + else + { + rc.mtlresult.transp.set(requiredTransparency, requiredTransparency, requiredTransparency); + rc.mtlresult.alpha=rc.mtlresult.transp.whiteComplement(); + rc.mtlresult.alphaTransp=rc.mtlresult.transp; + } + + VR::Fragment *f=rc.mtlresult.fragment; + if (f) { + const VR::ShadeCol diffColor=diffuse(); + const VR::ShadeCol rawGI(rc.evalDiffuse()); + const VR::ShadeCol finalGI = rawGI * diffColor; + f->setChannelDataByAlias(REG_CHAN_VFB_DIFFUSE, &diffColor); + + // raw GI shows the light contribution from the GI + f->setChannelDataByAlias(REG_CHAN_VFB_RAWGI, &rawGI); + f->setChannelDataByAlias(REG_CHAN_VFB_GI, &finalGI); + } +} + +/* +| from BRDFSampler +*/ +VR::RenderChannelsInfo* shaveVrayBaseBSDF::getRenderChannels() +{ + return &VR::RenderChannelsInfo::reflectChannels; +} + +/* +| from BSDFSampler +*/ +VR::BRDFSampler* shaveVrayBaseBSDF::getBRDF(VR::BSDFSide side) +{ + if (side == VR::bsdfSide_front) + currentTransp=(1.0f+requiredTransparency)*0.5f; + else + currentTransp=2.0f*requiredTransparency/(1.0f+requiredTransparency); + + return static_cast<VR::BRDFSampler*>(this); +} + |