aboutsummaryrefslogtreecommitdiff
path: root/vrayPlug/plugin/shaveVrayBaseBSDF.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'vrayPlug/plugin/shaveVrayBaseBSDF.cpp')
-rw-r--r--vrayPlug/plugin/shaveVrayBaseBSDF.cpp325
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);
+}
+