cmpfn_tp set_ordering (cmpfn_tp criterion, lie_Index n, object g) { if (criterion!=height_decr && criterion!=height_incr) return criterion; if (g==NULL || n!=Lierank(g)) return criterion==height_decr ? deg_decr : deg_incr; /* substitute */ if (level_vec==NULL || int_eq_grp_grp(g,level_vec_group)==(object)bool_false) { if (level_vec!=NULL) freearr(level_vec); level_vec=Lv(g); level_vec_group=g; } return criterion; }
Spectrum EmissionIntegrator::Li(const Scene *scene, const Renderer *renderer, const RayDifferential &ray, const Sample *sample, RNG &rng, Spectrum *T, MemoryArena &arena) const { VolumeRegion *vr = scene->volumeRegion; Assert(sample != NULL); float t0, t1; if (!vr || !vr->IntersectP(ray, &t0, &t1) || (t1-t0) == 0.f) { *T = Spectrum(1.f); return 0.f; } // Do emission-only 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); pbrt::Point p = ray(t0), pPrev; Vector w = -ray.d; t0 += sample->oneD[scatterSampleOffset][0] * step; 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 ray marching if transmittance is small if (Tr.y() < 1e-3) { const float continueProb = .5f; if (rng.RandomFloat() > continueProb) { Tr = 0.f; break; } Tr /= continueProb; } // Compute emission-only source term at _p_ Lv += Tr * vr->Lve(p, w, ray.time); } *T = Tr; return Lv * step; }
Spectrum VSDScatteringIntegrator::LiSingle(const Scene *scene, const Renderer *renderer, const RayDifferential &ray, const Sample *sample, RNG &rng, Spectrum *T, MemoryArena &arena) const { VolumeRegion *vr = scene->volumeRegion; float t0, t1; vr->IntersectP(ray, &t0, &t1); // 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; t0 += sample->oneD[scatterSampleOffset][0] * step; // Compute the emission from the voxels, not from the light sources 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 ray marching if transmittance is small if (Tr.y() < 1e-3) { const float continueProb = .5f; if (rng.RandomFloat() > continueProb) { Tr = 0.f; break; } Tr /= continueProb; } // Compute emission term at _p_ Lv += Tr * vr->PhotonDensity(p); } *T = Tr; return Lv * step; }
Spectrum SingleScatteringFluorescenceRWLIntegrator::Li(const Scene *scene, const Renderer *renderer, const RayDifferential &ray, const Sample *sample, RNG &rng, Spectrum *T, MemoryArena &arena) const { VolumeRegion *vr = scene->volumeRegion; float t0, t1; if (!vr || !vr->IntersectP(ray, &t0, &t1) || (t1-t0) == 0.f) { *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, rng); float *lightComp = arena.Alloc<float>(nSamples); LDShuffleScrambled1D(1, nSamples, lightComp, rng); float *lightPos = arena.Alloc<float>(2*nSamples); LDShuffleScrambled2D(1, nSamples, lightPos, rng); uint32_t 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, 0.5f * stepSize, rng.RandomFloat()); Tr *= Exp(-stepTau); // Possibly terminate ray marching if transmittance is small if (Tr.y() < 1e-3) { const float continueProb = .5f; if (rng.RandomFloat() > continueProb) { Tr = 0.f; break; } Tr /= continueProb; } // Compute fluorescence emission Spectrum sigma = vr->Mu(p, w, ray.time); if (!sigma.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 the in-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); int lambdaExcIndex = light->GetLaserWavelengthIndex(); float Lpower = Ld.GetLaserEmissionPower(lambdaExcIndex); float yield = vr->Yeild(Point()); Spectrum fEx = vr->fEx(Point()); Spectrum fEm = vr->fEm(Point()); float scale = fEx.GetSampleValueAtWavelengthIndex(lambdaExcIndex); Lv += Lpower * Tr * sigma * vr->p(p, w, -wo, ray.time) * scale * fEm * yield * float(nLights) / pdf; } } ++sampOffset; } *T = Tr; return Lv * step; }
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; }
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; }
Spectrum VolumeIntegrator::Li(Ray ray, Spectrum *T) { int numSamples; double step; int numVolumes = mScene->getVolumeCount(); VolumeRegion **volumes = mScene->getVolumes(); if(numVolumes < 1) { return 0.; } double t1, t0 = 0; Vec3 n; Surface surface; if(!volumes[0]->bounds().test_intersect(ray, &t0, &t1, &n)) return 0; if(ray.maxt < t1) t1 = ray.maxt; numSamples = (int)((t1 - t0) / mStepSize); if(numSamples == 0) numSamples = 1; //printf("NumSamples: %d\n", numSamples); step = (t1 - t0) / (double)numSamples; t0 += ((rand() / (float)RAND_MAX)) * step; //printf("T02: %f\n", t0); //printf("step: %f\n", step); //TODO: NOTE: multiple volumes will need aggregators! //*T = *T * Color(0.5); Spectrum Lv(0); LightSource** lights = mScene->getLightSources(); Vec3 p = ray(t0); Vec3 pPrev; Vec3 w = ray.direction * -1; Spectrum Tr(1.); for( int i = 0; i < numSamples; ++i, t0 += step ) { pPrev = p; p = ray(t0); //printf("T03: %f\n", t0); //printf("Step: %f\n", step); //printf("Difference: %s %s\n", p.str(), ray(t0 + step).str()); //printf("Curr T: %f\n", (p - pPrev).length()); Ray tRay = Ray(pPrev, p - pPrev, 0.0, step); Spectrum stepTau = volumes[0]->tau(tRay, 0.5 * step, 0); Tr = Tr * Exp(stepTau * -1); if (Tr.toTrans() < 1e-3) { const float continueProb = .5f; if ((rand() / (float)RAND_MAX) > continueProb) break; Tr = Tr / continueProb; }//else if (stepTau.toTrans() > 0.99995) // continue; Lv = Lv + volumes[0]->Lve(p); Spectrum ss = volumes[0]->sigma_s(p); if(!ss.isBlack()) { //printf("Lighting?\n"); LightSource *light = lights[0]; Vec3 wL = light->position - p; wL.norm(); Ray shadRay = Ray(p, wL); if(!mScene->intersect(shadRay, &surface) || (surface.t > (p-wL).length())) { Spectrum lTr = Exp(volumes[0]->tau(shadRay, mStepSize * 2, 0.0) * -1); //printf("P: %s\n", p.str()); //printf("LTR: %f, %f, %f\n", lTr.r(), lTr.g(), lTr.b()); Spectrum Ld = lTr * lights[0]->color; //printf("Not black.\n\tcurloc: %f, %f, %f\n\tlightTrn: %.2f, %.2f, %.2f\n\tLightCol: %.2f, %.2f, %.2f\n\tSingleSc: %.2f, %.2f, %.2f\n\tCurTrans: %.2f, %.2f, %.2f\n", \ p.x(), p.y(), p.z(), lTr.r(), lTr.g(), lTr.b(), lights[0]->color.r(), lights[0]->color.g(), lights[0]->color.b(), ss.r(), ss.g(), ss.b(), Tr.r(), Tr.g(), Tr.b()); Lv = Lv + Ld * ss * Tr;// * volumes[0]->phase(p, w, wL * 1); //printf("Phase: %f\n", volumes[0]->phase(p, w, wL)); } }
Spectrum VSDScatteringIntegrator::LiMultiple(const Scene *scene, const Renderer *renderer, const RayDifferential &ray, const Sample *sample, RNG &rng, Spectrum *T, MemoryArena &arena) const { VolumeRegion *vr = scene->volumeRegion; float t0, t1; vr->IntersectP(ray, &t0, &t1); // Do multiple scattering volume integration in _vr_ Spectrum Lv(0.); // Prepare for random walk Spectrum Tr(1.f); Point p = ray(t0), pPrev = ray.o; // printf("%f %f %f, ", p.x, p.y, p.z); int steps = 0; // Sample the events in a random walk // BBox bb = vr->WorldBound(); // printf("%f %f %f & %f %f %f \n", // bb.pMin.x, bb.pMin.y, bb.pMin.z, bb.pMax.x, bb.pMax.y, bb.pMax.z); while(vr->WorldBound().Inside(p)) { //printf("%f %f %f %d \n", p.x, p.y, p.z, steps); steps++; // Sample direction Vector wi = -ray.d, wo; float pdfDirection = 0.f; if(!vr->SampleDirection(p, wi, wo, &pdfDirection, rng)) { // printf("return 1 \n"); return Lv; } Ray r(p, wo, 0); // Sample a distance float pdfDistance = 0.f; float tDist; Point pSample; if(!vr->SampleDistance(r, &tDist, pSample, &pdfDistance, rng)) { // printf("return 2 \n"); return Lv; } // Compute the transmittance pPrev = p; p = r(tDist); Ray tauRay(pPrev, p - pPrev, 0.f, 1.f, r.time, r.depth); Spectrum stepTau = vr->tau(tauRay, .5f * stepSize, rng.RandomFloat()); Tr *= Exp(-stepTau); // Possibly terminate random walk if transmittance is small if (Tr.y() < 1e-3) { const float continueProb = .5f; if (rng.RandomFloat() > continueProb) { Tr = 0.f; // printf("return 3 \n"); break; } Tr /= continueProb; } // Compute emission term at _p_ Lv += Tr * vr->PhotonDensity(p) / (pdfDistance * pdfDirection); } // printf("%f %f %f %d \n", p.x, p.y, p.z, steps); // printf("%d, ", steps); return Lv; }