bool RoughPlasticBsdf::sample(SurfaceScatterEvent &event) const
{
    if (event.wi.z() <= 0.0f)
        return false;

    bool sampleR = event.requestedLobe.test(BsdfLobes::GlossyReflectionLobe);
    bool sampleT = event.requestedLobe.test(BsdfLobes::DiffuseReflectionLobe);

    if (!sampleR && !sampleT)
        return false;

    const Vec3f &wi = event.wi;
    float eta = 1.0f/_ior;
    float Fi = Fresnel::dielectricReflectance(eta, wi.z());
    float substrateWeight = _substrateWeight*_avgTransmittance*(1.0f - Fi);
    float specularWeight = Fi;
    float specularProbability = specularWeight/(specularWeight + substrateWeight);

    if (sampleR && (event.sampler->nextBoolean(specularProbability) || !sampleT)) {
        float roughness = (*_roughness)[*event.info].x();
        if (!RoughDielectricBsdf::sampleBase(event, true, false, roughness, _ior, _distribution))
            return false;
        if (sampleT) {
            Vec3f diffuseAlbedo = albedo(event.info);
            float Fo = Fresnel::dielectricReflectance(eta, event.wo.z());

            Vec3f brdfSubstrate = ((1.0f - Fi)*(1.0f - Fo)*eta*eta)*(diffuseAlbedo/(1.0f - diffuseAlbedo*_diffuseFresnel))*INV_PI*event.wo.z();
            Vec3f brdfSpecular = event.weight*event.pdf;
            float pdfSubstrate = SampleWarp::cosineHemispherePdf(event.wo)*(1.0f - specularProbability);
            float pdfSpecular = event.pdf*specularProbability;

            event.weight = (brdfSpecular + brdfSubstrate)/(pdfSpecular + pdfSubstrate);
            event.pdf = pdfSpecular + pdfSubstrate;
        }
        return true;
    } else {
        Vec3f wo(SampleWarp::cosineHemisphere(event.sampler->next2D()));
        float Fo = Fresnel::dielectricReflectance(eta, wo.z());
        Vec3f diffuseAlbedo = albedo(event.info);

        event.wo = wo;
        event.weight = ((1.0f - Fi)*(1.0f - Fo)*eta*eta)*(diffuseAlbedo/(1.0f - diffuseAlbedo*_diffuseFresnel));
        if (_scaledSigmaA.max() > 0.0f)
            event.weight *= std::exp(_scaledSigmaA*(-1.0f/event.wo.z() - 1.0f/event.wi.z()));

        event.pdf = SampleWarp::cosineHemispherePdf(event.wo);
        if (sampleR) {
            Vec3f brdfSubstrate = event.weight*event.pdf;
            float  pdfSubstrate = event.pdf*(1.0f - specularProbability);
            Vec3f brdfSpecular = RoughDielectricBsdf::evalBase(event, true, false, (*_roughness)[*event.info].x(), _ior, _distribution);
            float pdfSpecular  = RoughDielectricBsdf::pdfBase(event, true, false, (*_roughness)[*event.info].x(), _ior, _distribution);
            pdfSpecular *= specularProbability;

            event.weight = (brdfSpecular + brdfSubstrate)/(pdfSpecular + pdfSubstrate);
            event.pdf = pdfSpecular + pdfSubstrate;
        }
        event.sampledLobe = BsdfLobes::DiffuseReflectionLobe;
    }
    return true;
}
Vec3f RoughPlasticBsdf::eval(const SurfaceScatterEvent &event) const
{
    bool sampleR = event.requestedLobe.test(BsdfLobes::GlossyReflectionLobe);
    bool sampleT = event.requestedLobe.test(BsdfLobes::DiffuseReflectionLobe);
    if (!sampleR && !sampleT)
        return Vec3f(0.0f);
    if (event.wi.z() <= 0.0f || event.wo.z() <= 0.0f)
        return Vec3f(0.0f);

    Vec3f glossyR(0.0f);
    if (sampleR)
        glossyR = RoughDielectricBsdf::evalBase(event, true, false, (*_roughness)[*event.info].x(), _ior, _distribution);

    Vec3f diffuseR(0.0f);
    if (sampleT) {
        float eta = 1.0f/_ior;
        float Fi = Fresnel::dielectricReflectance(eta, event.wi.z());
        float Fo = Fresnel::dielectricReflectance(eta, event.wo.z());

        Vec3f diffuseAlbedo = albedo(event.info);

        diffuseR = ((1.0f - Fi)*(1.0f - Fo)*eta*eta*event.wo.z()*INV_PI)*(diffuseAlbedo/(1.0f - diffuseAlbedo*_diffuseFresnel));
        if (_scaledSigmaA.max() > 0.0f)
            diffuseR *= std::exp(_scaledSigmaA*(-1.0f/event.wo.z() - 1.0f/event.wi.z()));
    }

    return glossyR + diffuseR;
}
Beispiel #3
0
bool MixedBsdf::sample(SurfaceScatterEvent &event) const
{
    float ratio;
    if (!adjustedRatio(event.requestedLobe, event.info, ratio))
        return false;

    if (event.sampler->nextBoolean(ratio)) {
        if (!_bsdf0->sample(event))
            return false;

        float pdf0 = event.pdf*ratio;
        float pdf1 = _bsdf1->pdf(event)*(1.0f - ratio);
        Vec3f f = event.weight*event.pdf*ratio + _bsdf1->eval(event)*(1.0f - ratio);
        event.pdf = pdf0 + pdf1;
        event.weight = f/event.pdf;
    } else {
        if (!_bsdf1->sample(event))
            return false;

        float pdf0 = _bsdf0->pdf(event)*ratio;
        float pdf1 = event.pdf*(1.0f - ratio);
        Vec3f f = _bsdf0->eval(event)*ratio + event.weight*event.pdf*(1.0f - ratio);
        event.pdf = pdf0 + pdf1;
        event.weight = f/event.pdf;
    }

    event.weight *= albedo(event.info);
    return true;
}
Beispiel #4
0
Vec3f PlasticBsdf::eval(const SurfaceScatterEvent &event) const
{
    if (event.wi.z() <= 0.0f || event.wo.z() <= 0.0f)
        return Vec3f(0.0f);

    bool evalR = event.requestedLobe.test(BsdfLobes::SpecularReflectionLobe);
    bool evalT = event.requestedLobe.test(BsdfLobes::DiffuseReflectionLobe);

    float eta = 1.0f/_ior;
    float Fi = Fresnel::dielectricReflectance(eta, event.wi.z());
    float Fo = Fresnel::dielectricReflectance(eta, event.wo.z());

    if (evalR && checkReflectionConstraint(event.wi, event.wo)) {
        return Vec3f(Fi);
    } else if (evalT) {
        Vec3f diffuseAlbedo = albedo(event.info);

        Vec3f brdf = ((1.0f - Fi)*(1.0f - Fo)*eta*eta*event.wo.z()*INV_PI)*
                (diffuseAlbedo/(1.0f - diffuseAlbedo*_diffuseFresnel));

        if (_scaledSigmaA.max() > 0.0f)
            brdf *= std::exp(_scaledSigmaA*(-1.0f/event.wo.z() - 1.0f/event.wi.z()));
        return brdf;
    } else {
        return Vec3f(0.0f);
    }
}
bool RoughConductorBsdf::sample(SurfaceScatterEvent &event) const
{
    if (!event.requestedLobe.test(BsdfLobes::GlossyReflectionLobe))
        return false;
    if (event.wi.z() <= 0.0f)
        return false;

    // TODO Re-enable this?
    //float sampleRoughness = (1.2f - 0.2f*std::sqrt(std::abs(event.wi.z())))*_roughness;
    float roughness = (*_roughness)[*event.info].x();
    float sampleRoughness = roughness;
    float alpha = Microfacet::roughnessToAlpha(_distribution, roughness);
    float sampleAlpha = Microfacet::roughnessToAlpha(_distribution, sampleRoughness);

    Vec3f m = Microfacet::sample(_distribution, sampleAlpha, event.sampler->next2D(BsdfSample));
    float wiDotM = event.wi.dot(m);
    event.wo = 2.0f*wiDotM*m - event.wi;
    if (wiDotM <= 0.0f || event.wo.z() <= 0.0f)
        return false;
    float G = Microfacet::G(_distribution, alpha, event.wi, event.wo, m);
    float D = Microfacet::D(_distribution, alpha, m);
    float mPdf = Microfacet::pdf(_distribution, sampleAlpha, m);
    float pdf = mPdf*0.25f/wiDotM;
    float weight = wiDotM*G*D/(event.wi.z()*mPdf);
    Vec3f F = Fresnel::conductorReflectance(_eta, _k, wiDotM);

    event.pdf = pdf;
    event.weight = albedo(event.info)*(F*weight);
    event.sampledLobe = BsdfLobes::GlossyReflectionLobe;
    return true;
}
Beispiel #6
0
Vec3f ConductorBsdf::eval(const SurfaceScatterEvent &event) const
{
    bool evalR = event.requestedLobe.test(BsdfLobes::SpecularReflectionLobe);
    if (evalR && checkReflectionConstraint(event.wi, event.wo))
        return albedo(event.info)*Fresnel::conductorReflectance(_eta, _k, event.wi.z());
    else
        return Vec3f(0.0f);
}
Beispiel #7
0
Vec3f LambertBsdf::eval(const SurfaceScatterEvent &event) const
{
    if (!event.requestedLobe.test(BsdfLobes::DiffuseReflectionLobe))
        return Vec3f(0.0f);
    if (event.wi.z() <= 0.0f || event.wo.z() <= 0.0f)
        return Vec3f(0.0f);
    return albedo(event.info)*INV_PI*event.wo.z();
}
Beispiel #8
0
bool ConductorBsdf::sample(SurfaceScatterEvent &event) const
{
    if (!event.requestedLobe.test(BsdfLobes::SpecularReflectionLobe))
        return false;

    event.wo = Vec3f(-event.wi.x(), -event.wi.y(), event.wi.z());
    event.pdf = 1.0f;
    event.weight = albedo(event.info)*Fresnel::conductorReflectance(_eta, _k, event.wi.z());
    event.sampledLobe = BsdfLobes::SpecularReflectionLobe;
    return true;
}
Beispiel #9
0
bool LambertBsdf::sample(SurfaceScatterEvent &event) const
{
    if (!event.requestedLobe.test(BsdfLobes::DiffuseReflectionLobe))
        return false;
    if (event.wi.z() <= 0.0f)
        return false;
    event.wo  = SampleWarp::cosineHemisphere(event.sampler->next2D());
    event.pdf = SampleWarp::cosineHemispherePdf(event.wo);
    event.weight = albedo(event.info);
    event.sampledLobe = BsdfLobes::DiffuseReflectionLobe;
    return true;
}
Vec3f RoughWireBcsdf::eval(const SurfaceScatterEvent &event) const
{
    if (!event.requestedLobe.test(BsdfLobes::GlossyLobe) || event.wo.z() == 0.0f)
        return Vec3f(0.0f);

    float sinThetaI = event.wi.y();
    float sinThetaO = event.wo.y();
    float cosThetaI = trigInverse(sinThetaI);
    float cosThetaO = trigInverse(sinThetaO);
    float cosPhi = event.wo.z()/std::sqrt(event.wo.x()*event.wo.x() + event.wo.z()*event.wo.z());

    Vec3f attenuation = albedo(event.info)*Fresnel::conductorReflectance(_eta, _k, trigHalfAngle(event.wi.dot(event.wo)));

    return attenuation*N(cosPhi)*M(_v, sinThetaI, sinThetaO, cosThetaI, cosThetaO);
}
Beispiel #11
0
bool PlasticBsdf::sample(SurfaceScatterEvent &event) const
{
    if (event.wi.z() <= 0.0f)
        return false;

    bool sampleR = event.requestedLobe.test(BsdfLobes::SpecularReflectionLobe);
    bool sampleT = event.requestedLobe.test(BsdfLobes::DiffuseReflectionLobe);

    const Vec3f &wi = event.wi;
    float eta = 1.0f/_ior;
    float Fi = Fresnel::dielectricReflectance(eta, wi.z());
    float substrateWeight = _avgTransmittance*(1.0f - Fi);
    float specularWeight = Fi;
    float specularProbability;
    if (sampleR && sampleT)
        specularProbability = specularWeight/(specularWeight + substrateWeight);
    else if (sampleR)
        specularProbability = 1.0f;
    else if (sampleT)
        specularProbability = 0.0f;
    else
        return false;

    if (sampleR && event.sampler->nextBoolean(specularProbability)) {
        event.wo = Vec3f(-wi.x(), -wi.y(), wi.z());
        event.pdf = specularProbability;
        event.weight = Vec3f(Fi/specularProbability);
        event.sampledLobe = BsdfLobes::SpecularReflectionLobe;
    } else {
        Vec3f wo(SampleWarp::cosineHemisphere(event.sampler->next2D()));
        float Fo = Fresnel::dielectricReflectance(eta, wo.z());
        Vec3f diffuseAlbedo = albedo(event.info);

        event.wo = wo;
        event.weight = ((1.0f - Fi)*(1.0f - Fo)*eta*eta)*(diffuseAlbedo/(1.0f - diffuseAlbedo*_diffuseFresnel));
        if (_scaledSigmaA.max() > 0.0f)
            event.weight *= std::exp(_scaledSigmaA*(-1.0f/event.wo.z() - 1.0f/event.wi.z()));

        event.pdf = SampleWarp::cosineHemispherePdf(event.wo)*(1.0f - specularProbability);
        event.weight /= 1.0f - specularProbability;
        event.sampledLobe = BsdfLobes::DiffuseReflectionLobe;
    }
    return true;
}
Vec3f RoughConductorBsdf::eval(const SurfaceScatterEvent &event) const
{
    if (!event.requestedLobe.test(BsdfLobes::GlossyReflectionLobe))
        return Vec3f(0.0f);
    if (event.wi.z() <= 0.0f || event.wo.z() <= 0.0f)
        return Vec3f(0.0f);

    float roughness = (*_roughness)[*event.info].x();
    float alpha = Microfacet::roughnessToAlpha(_distribution, roughness);

    Vec3f hr = (event.wi + event.wo).normalized();
    float cosThetaM = event.wi.dot(hr);
    Vec3f F = Fresnel::conductorReflectance(_eta, _k, cosThetaM);
    float G = Microfacet::G(_distribution, alpha, event.wi, event.wo, hr);
    float D = Microfacet::D(_distribution, alpha, hr);
    float fr = (G*D*0.25f)/event.wi.z();

    return albedo(event.info)*(F*fr);
}
Beispiel #13
0
Vec3f PhongBsdf::eval(const SurfaceScatterEvent &event) const
{
    bool evalGlossy  = event.requestedLobe.test(BsdfLobes::GlossyReflectionLobe);
    bool evalDiffuse = event.requestedLobe.test(BsdfLobes::DiffuseReflectionLobe);

    if (!evalGlossy && !evalDiffuse)
        return Vec3f(0.0f);
    if (event.wi.z() <= 0.0f || event.wo.z() <= 0.0f)
        return Vec3f(0.0f);

    float result = 0.0f;
    if (evalDiffuse)
        result += _diffuseRatio*INV_PI;
    if (evalGlossy) {
        float cosTheta = Vec3f(-event.wi.x(), -event.wi.y(), event.wi.z()).dot(event.wo);
        if (cosTheta > 0.0f)
            result += std::pow(cosTheta, _exponent)*_brdfFactor*(1.0f - _diffuseRatio);
    }

    return albedo(event.info)*event.wo.z()*result;
}
Beispiel #14
0
Vec3f OrenNayarBsdf::eval(const SurfaceScatterEvent &event) const
{
    if (!event.requestedLobe.test(BsdfLobes::DiffuseReflectionLobe))
        return Vec3f(0.0f);
    if (event.wi.z() <= 0.0f || event.wo.z() <= 0.0f)
        return Vec3f(0.0f);

    const Vec3f &wi = event.wi;
    const Vec3f &wo = event.wo;

    float thetaR = std::acos(event.wo.z());
    float thetaI = std::acos(event.wi.z());
    float alpha = max(thetaR, thetaI);
    float beta  = min(thetaR, thetaI);
    float sinAlpha = std::sin(alpha);
    float denom = (wi.x()*wi.x() + wi.y()*wi.y())*(wo.x()*wo.x() + wo.y()*wo.y());
    float cosDeltaPhi;
    if (denom == 0.0f)
        cosDeltaPhi = 1.0f;
    else
        cosDeltaPhi = (wi.x()*wo.x() + wi.y()*wo.y())/std::sqrt(denom);

    const float RoughnessToSigma = 1.0f/std::sqrt(2.0f);
    float sigma = RoughnessToSigma*(*_roughness)[*event.info].x();
    float sigmaSq = sigma*sigma;

    float C1 = 1.0f - 0.5f*sigmaSq/(sigmaSq + 0.33f);
    float C2 = 0.45f*sigmaSq/(sigmaSq + 0.09f);
    if (cosDeltaPhi >= 0.0f)
        C2 *= sinAlpha;
    else
        C2 *= sinAlpha - cube((2.0f*INV_PI)*beta);
    float C3 = 0.125f*(sigmaSq/(sigmaSq + 0.09f))*sqr((4.0f*INV_PI*INV_PI)*alpha*beta);

    float fr1 = (C1 + cosDeltaPhi*C2*std::tan(beta) + (1.0f - std::abs(cosDeltaPhi))*C3*std::tan(0.5f*(alpha + beta)));
    float fr2 = 0.17f*sigmaSq/(sigmaSq + 0.13f)*(1.0f - cosDeltaPhi*sqr((2.0f*INV_PI)*beta));

    Vec3f diffuseAlbedo = albedo(event.info);
    return (diffuseAlbedo*fr1 + diffuseAlbedo*diffuseAlbedo*fr2)*wo.z()*INV_PI;
}
Beispiel #15
0
void
Vegetation::output (Log& log) const
{
  output_value (N (), "N", log);
  output_value (N_fixated (), "N_fixated", log);
  output_value (LAI (), "LAI", log);
  output_value (height (), "height", log);
  output_value (cover (), "cover", log);
  output_value (LAIvsH (), "LAIvsH", log);
  output_value (HvsLAI (), "HvsLAI", log);
  output_value (ACExt_PAR (), "ACExt_PAR", log);
  output_value (ACRef_PAR (), "ACRef_PAR", log);
  output_value (ACExt_NIR (), "ACExt_NIR", log);
  output_value (ACRef_NIR (), "ACRef_NIR", log);
  output_value (ARExt (), "ARExt", log);
  output_value (EpFactorDry (), "EpFactorDry", log);
  output_value (EpFactorWet (), "EpFactorWet", log);
  output_value (albedo (), "albedo", log);
  output_value (interception_capacity (), "interception_capacity", log);
  output_value (shadow_stomata_conductance (), 
                "shadow_stomata_conductance", log);
  output_value (sunlit_stomata_conductance (),
                "sunlit_stomata_conductance", log);
}
bool RoughWireBcsdf::sample(SurfaceScatterEvent &event) const
{
    if (!event.requestedLobe.test(BsdfLobes::GlossyLobe))
        return false;

    float xi1 = event.sampler->next1D();
    Vec2f xi23 = event.sampler->next2D();

    float sinThetaI = event.wi.y();
    float cosThetaI = trigInverse(sinThetaI);

    float sinPhi = sampleN(xi1);
    float sinThetaO = sampleM(_v, sinThetaI, cosThetaI, xi23.x(), xi23.y());

    float cosPhi = trigInverse(sinPhi);
    float cosThetaO = trigInverse(sinThetaO);

    event.wo = Vec3f(sinPhi*cosThetaO, sinThetaO, cosPhi*cosThetaO);
    event.pdf = N(cosPhi)*M(_v, sinThetaI, sinThetaO, cosThetaI, cosThetaO);
    event.weight = albedo(event.info)*Fresnel::conductorReflectance(_eta, _k, trigHalfAngle(event.wi.dot(event.wo)));
    event.sampledLobe = BsdfLobes::GlossyLobe;

    return true;
}
Beispiel #17
0
Vec3f MixedBsdf::eval(const SurfaceScatterEvent &event) const
{
    float ratio = (*_ratio)[*event.info].x();
    return albedo(event.info)*(_bsdf0->eval(event)*ratio + _bsdf1->eval(event)*(1.0f - ratio));
}