Beispiel #1
0
Spectrum SingleScatteringIntegrator::Li(const Scene *scene, const Renderer *renderer,
        const RayDifferential &ray, const Sample *sample,
        Spectrum *T, MemoryArena &arena) const {
    VolumeRegion *vr = scene->volumeRegion;
    float t0, t1;
    if (!vr || !vr->IntersectP(ray, &t0, &t1)) {
        *T = 1.f;
        return 0.f;
    }
    // Do single scattering volume integration in _vr_
    Spectrum Lv(0.);

    // Prepare for volume integration stepping
    int nSamples = Ceil2Int((t1-t0) / stepSize);
    float step = (t1 - t0) / nSamples;
    Spectrum Tr(1.f);
    Point p = ray(t0), pPrev;
    Vector w = -ray.d;
    t0 += sample->oneD[scatterSampleOffset][0] * step;

    // Compute sample patterns for single scattering samples
    float *lightNum = arena.Alloc<float>(nSamples);
    LDShuffleScrambled1D(1, nSamples, lightNum, *sample->rng);
    float *lightComp = arena.Alloc<float>(nSamples);
    LDShuffleScrambled1D(1, nSamples, lightComp, *sample->rng);
    float *lightPos = arena.Alloc<float>(2*nSamples);
    LDShuffleScrambled2D(1, nSamples, lightPos, *sample->rng);
    u_int sampOffset = 0;
    for (int i = 0; i < nSamples; ++i, t0 += step) {
        // Advance to sample at _t0_ and update _T_
        pPrev = p;
        p = ray(t0);
        Ray tauRay(pPrev, p - pPrev, 0.f, 1.f, ray.time, ray.depth);
        Spectrum stepTau = vr->tau(tauRay,
                                   .5f * stepSize, sample->rng->RandomFloat());
        Tr *= Exp(-stepTau);

        // Possibly terminate ray marching if transmittance is small
        if (Tr.y() < 1e-3) {
            const float continueProb = .5f;
            if (sample->rng->RandomFloat() > continueProb) break;
            Tr /= continueProb;
        }

        // Compute single-scattering source term at _p_
        Lv += Tr * vr->Lve(p, w, ray.time);
        Spectrum ss = vr->sigma_s(p, w, ray.time);
        if (!ss.IsBlack() && scene->lights.size() > 0) {
            int nLights = scene->lights.size();
            int ln = min(Floor2Int(lightNum[sampOffset] * nLights),
                         nLights-1);
            Light *light = scene->lights[ln];
            // Add contribution of _light_ due to scattering at _p_
            float pdf;
            VisibilityTester vis;
            Vector wo;
            LightSample ls(lightComp[sampOffset], lightPos[2*sampOffset],
                           lightPos[2*sampOffset+1]);
            Spectrum L = light->Sample_L(p, 0.f, ls, ray.time, &wo, &pdf, &vis);
            if (!L.IsBlack() && pdf > 0.f && vis.Unoccluded(scene)) {
                Spectrum Ld = L * vis.Transmittance(scene, renderer, NULL, sample->rng, arena);
                Lv += Tr * ss * vr->p(p, w, -wo, ray.time) * Ld * float(nLights) / pdf;
            }
        }
        ++sampOffset;
    }
    *T = Tr;
    return Lv * step;
}
Beispiel #2
0
Spectrum PhotonVolumeIntegrator::Li(const Scene *scene, const Renderer *renderer,
        const RayDifferential &ray, const Sample *sample, RNG &rng,
        Spectrum *T, MemoryArena &arena) const {
 	
 	VolumeRegion *vr = scene->volumeRegion;
    RainbowVolume* rv = dynamic_cast<RainbowVolume*>(vr);
 	KdTree<Photon>* volumeMap = photonShooter->volumeMap; 

 	float t0, t1;
 	if (!vr || !vr->IntersectP(ray, &t0, &t1) || (t1-t0) == 0.f){
 		*T = 1.f;
 	 	return 0.f;
 	 }
 	// Do single scattering & photon multiple scattering volume integration in _vr_
 	Spectrum Lv(0.);


 	// Prepare for volume integration stepping
 	int nSamples = Ceil2Int((t1-t0) / stepSize);
 	float step = (t1 - t0) / nSamples;
 	Spectrum Tr(1.f);
 	Point p = ray(t0), pPrev;
 	Vector w = -ray.d;
 	t0 += sample->oneD[scatterSampleOffset][0] * step;

 	float *lightNum = arena.Alloc<float>(nSamples);
    LDShuffleScrambled1D(1, nSamples, lightNum, rng);
    float *lightComp = arena.Alloc<float>(nSamples);
    LDShuffleScrambled1D(1, nSamples, lightComp, rng);
    float *lightPos = arena.Alloc<float>(2*nSamples);
    LDShuffleScrambled2D(1, nSamples, lightPos, rng);
 	int sampOffset = 0;

 	ClosePhoton *lookupBuf = new ClosePhoton[nSamples];

 	for (int i = 0; i < nSamples; ++i, t0 += step) {
 		// Advance to sample at _t0_ and update _T_
 		pPrev = p;
 		p = ray(t0);

 		Ray tauRay(pPrev, p - pPrev, 0.f, 1.f, ray.time, ray.depth);

 		Spectrum stepTau = vr->tau(tauRay,.5f * stepSize, rng.RandomFloat());
 		Tr = Exp(-stepTau);

 		// Possibly terminate raymarching if transmittance is small.
 		if (Tr.y() < 1e-3) {
 			const float continueProb = .5f;
 			if (rng.RandomFloat() > continueProb){
 				Tr = 0.f;
 				break;
 			}
 			Tr /= continueProb;
 		}
		
		
 		// Compute single-scattering source term at _p_ & photon mapped MS
 		Spectrum L_i(0.);
 		Spectrum L_d(0.);
 		Spectrum L_ii(0.);
 		
 		// Lv += Tr*vr->Lve(p, w, ray.time);
 		Spectrum ss = vr->sigma_s(p, w, ray.time);
 		Spectrum sa = vr->sigma_a(p, w, ray.time);

 		if (!ss.IsBlack() && scene->lights.size() > 0) {
 			int nLights = scene->lights.size();
 			int ln =
 				min(Floor2Int(lightNum[sampOffset] * nLights),
 				    nLights-1);
 			Light *light = scene->lights[ln];
 			// Add contribution of _light_ due to scattering at _p_
 			float pdf;
 			VisibilityTester vis;
 			Vector wo;

 			LightSample ls(lightComp[sampOffset], lightPos[2*sampOffset],
                           lightPos[2*sampOffset+1]);
            Spectrum L = light->Sample_L(p, 0.f, ls, ray.time, &wo, &pdf, &vis);
            

 			if (!L.IsBlack() && pdf > 0.f && vis.Unoccluded(scene)) {

                Spectrum Ld = L * vis.Transmittance(scene,renderer, NULL, rng, arena);
                if(rv){
                    L_d = rv->rainbowReflection(Ld, ray.d, wo);
                }
                else {
                    L_d = vr->p(p, w, -wo, ray.time) * Ld * float(nLights)/pdf;
                }
 			}
 		}
		// Compute 'indirect' in-scattered radiance from photon map
        if(!rv){
            L_ii += LPhoton(volumeMap, nUsed, lookupBuf, w, p, vr, maxDistSquared, ray.time);
        }
        
		// Compute total in-scattered radiance
		if (sa.y()!=0.0 || ss.y()!=0.0)
			L_i = L_d + (ss/(sa+ss))*L_ii;
		else
			L_i = L_d;

		Spectrum nLv = (sa*vr->Lve(p,w,ray.time)*step) + (ss*L_i*step) + (Tr * Lv)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            ;

		Lv = nLv;
 		sampOffset++;
 	}
 	*T = Tr;
	return Lv;
}