// DiffusionReflectance Public Methods
 DiffusionReflectance(const Spectrum &sigma_a, const Spectrum &sigmap_s,
                      float eta) {
     A = (1.f + Fdr(eta)) / (1.f - Fdr(eta));
     sigmap_t = sigma_a + sigmap_s;
     sigma_tr = Sqrt(3.f * sigma_a * sigmap_t);
     alphap = sigmap_s / sigmap_t;
     zpos = Spectrum(1.f) / sigmap_t;
     zneg = zpos * (1.f + (4.f/3.f) * A);
 }
Ejemplo n.º 2
0
void SubsurfaceFromDiffuse(const Spectrum &Kd, float meanPathLength,
        float eta, Spectrum *sigma_a, Spectrum *sigma_prime_s) {
    float A = (1.f + Fdr(eta)) / (1.f - Fdr(eta));
    float rgb[3];
    Kd.ToRGB(rgb);
    float sigma_prime_s_rgb[3], sigma_a_rgb[3];
    for (int i = 0; i < 3; ++i) {
       float alphap = RdToAlphap(rgb[i], A);
       float sigma_tr = 1.f / meanPathLength;
       float sigma_prime_t = sigma_tr / sqrtf(3.f * 1.f - alphap);
       sigma_prime_s_rgb[i] = alphap * sigma_prime_t;
       sigma_a_rgb[i] = sigma_prime_t - sigma_prime_s_rgb[i];
    }
    *sigma_a = Spectrum::FromRGB(sigma_a_rgb);
    *sigma_prime_s = Spectrum::FromRGB(sigma_prime_s_rgb);
}
Ejemplo n.º 3
0
void subsurfaceFromDiffuse(const Spectrum &Kd, double meanPathLength,
        double eta, Spectrum *sigma_a, Spectrum *sigma_prime_s) {
    double A = (1.f + Fdr(eta)) / (1.f - Fdr(eta));
    double rgb[3];
    Kd.toRGB(rgb);
    double sigma_prime_s_rgb[3], sigma_a_rgb[3];
    for (int i = 0; i < 3; ++i) {
       // Compute $\alpha'$ for RGB component, compute scattering properties
       double alphap = RdToAlphap(rgb[i], A);
       double sigma_tr = 1.f / meanPathLength;
       double sigma_prime_t = sigma_tr / sqrtf(3.f * (1.f - alphap));
       sigma_prime_s_rgb[i] = alphap * sigma_prime_t;
       sigma_a_rgb[i] = sigma_prime_t - sigma_prime_s_rgb[i];
    }
    *sigma_a = Spectrum::fromRGB(sigma_a_rgb);
    *sigma_prime_s = Spectrum::fromRGB(sigma_prime_s_rgb);
}
Spectrum DipoleSubsurfaceIntegrator::Li(const Scene *scene, const Renderer *renderer,
        const RayDifferential &ray, const Intersection &isect,
        const Sample *sample, RNG &rng, MemoryArena &arena) const {
    Spectrum L(0.);
    Vector wo = -ray.d;
    // Compute emitted light if ray hit an area light source
    L += isect.Le(wo);

    // Evaluate BSDF at hit point
    BSDF *bsdf = isect.GetBSDF(ray, arena);
    const Point &p = bsdf->dgShading.p;
    const Normal &n = bsdf->dgShading.nn;

    Spectrum rho_dr = Spectrum(1.0f);

    // Evaluate BSSRDF and possibly compute subsurface scattering
    BSSRDF *bssrdf = isect.GetBSSRDF(ray, arena);
    if (bssrdf && octree) {	
        Spectrum sigma_a  = bssrdf->sigma_a();
        Spectrum sigmap_s = bssrdf->sigma_prime_s();
        Spectrum sigmap_t = sigmap_s + sigma_a;
        if (!sigmap_t.IsBlack()) {
            // Use hierarchical integration to evaluate reflection from dipole model
            PBRT_SUBSURFACE_STARTED_OCTREE_LOOKUP(const_cast<Point *>(&p));
            DiffusionReflectance Rd(sigma_a, sigmap_s, bssrdf->eta());
            Spectrum Mo = octree->Mo(octreeBounds, p, Rd, maxError);
            FresnelDielectric fresnel(1.f, bssrdf->eta());
            Spectrum Ft = Spectrum(1.f) - fresnel.Evaluate(AbsDot(wo, n));
            float Fdt = 1.f - Fdr(bssrdf->eta());

	    // modulate SSS contribution by rho_dr
            //L += (INV_PI * Ft) * (Fdt * Mo);
	    rho_dr = wet->integrate_BRDF(bsdf, ray.d, 10, BxDFType(BSDF_REFLECTION | BSDF_GLOSSY));
	    L += (INV_PI * Ft) * (Fdt * Mo) * (Spectrum(1.0f) - rho_dr);
	    //L += (INV_PI * Ft) * (Fdt * Mo) * (Spectrum(0.0f));
	    
            PBRT_SUBSURFACE_FINISHED_OCTREE_LOOKUP();
        }
    }

    L += UniformSampleAllLights(scene, renderer, arena, p, n,
        wo, isect.rayEpsilon, ray.time, bsdf, sample, rng, lightSampleOffsets,
        bsdfSampleOffsets);

    if (ray.depth < maxSpecularDepth) {
        // Trace rays for specular reflection and refraction.

      //TODO: this has no effect?
        L += SpecularReflect(ray, bsdf, rng, isect, renderer, scene,
			     sample, arena);
        L += SpecularTransmit(ray, bsdf, rng, isect,
			      renderer, scene, sample, arena);
    }
    return L;
}