void DiffusePRTIntegrator::Preprocess(const Scene *scene, const Camera *camera, const Renderer *renderer) { BBox bbox = scene->WorldBound(); Point p = .5f * bbox.pMin + .5f * bbox.pMax; RNG rng; MemoryArena arena; SHProjectIncidentDirectRadiance(p, 0.f, camera->shutterOpen, arena, scene, false, lmax, rng, c_in); }
void GlossyPRTIntegrator::Preprocess(const Scene *scene, const Camera *camera, const Renderer *renderer) { // Project direct lighting into SH for _GlossyPRTIntegrator_ BBox bbox = scene->WorldBound(); Point p = .5f * bbox.pMin + .5f * bbox.pMax; RNG rng; MemoryArena arena; c_in = new Spectrum[SHTerms(lmax)]; SHProjectIncidentDirectRadiance(p, 0.f, camera->shutterOpen, arena, scene, false, lmax, rng, c_in); // Compute glossy BSDF matrix for PRT B = new Spectrum[SHTerms(lmax)*SHTerms(lmax)]; SHComputeBSDFMatrix(Kd, Ks, roughness, rng, 1024, lmax, B); }
void CreateRadProbeTask::Run() { // Compute region in which to compute incident radiance probes int sx = pointNum % nProbes[0]; int sy = (pointNum / nProbes[0]) % nProbes[1]; int sz = pointNum / (nProbes[0] * nProbes[1]); Assert(sx >= 0 && sx < nProbes[0]); Assert(sy >= 0 && sy < nProbes[1]); Assert(sz >= 0 && sz < nProbes[2]); float tx0 = float(sx) / nProbes[0], tx1 = float(sx+1) / nProbes[0]; float ty0 = float(sy) / nProbes[1], ty1 = float(sy+1) / nProbes[1]; float tz0 = float(sz) / nProbes[2], tz1 = float(sz+1) / nProbes[2]; BBox b(bbox.Lerp(tx0, ty0, tz0), bbox.Lerp(tx1, ty1, tz1)); // Initialize common variables for _CreateRadProbeTask::Run()_ RNG rng(pointNum); Spectrum *c_probe = new Spectrum[SHTerms(lmax)]; MemoryArena arena; uint32_t nFound = 0, lastVisibleOffset = 0; for (int i = 0; i < 256; ++i) { if (nFound == 32) break; // Try to compute radiance probe contribution at _i_th sample point // Compute _i_th candidate point _p_ in cell's bounding box float dx = RadicalInverse(i+1, 2); float dy = RadicalInverse(i+1, 3); float dz = RadicalInverse(i+1, 5); Point p = b.Lerp(dx, dy, dz); // Skip point _p_ if not indirectly visible from camera if (scene->IntersectP(Ray(surfacePoints[lastVisibleOffset], p - surfacePoints[lastVisibleOffset], 1e-4f, 1.f, time))) { uint32_t j; // See if point is visible to any element of _surfacePoints_ for (j = 0; j < surfacePoints.size(); ++j) if (!scene->IntersectP(Ray(surfacePoints[j], p - surfacePoints[j], 1e-4f, 1.f, time))) { lastVisibleOffset = j; break; } if (j == surfacePoints.size()) continue; } ++nFound; // Compute SH coefficients of incident radiance at point _p_ if (includeDirectInProbes) { for (int i = 0; i < SHTerms(lmax); ++i) c_probe[i] = 0.f; SHProjectIncidentDirectRadiance(p, 0.f, time, arena, scene, true, lmax, rng, c_probe); for (int i = 0; i < SHTerms(lmax); ++i) c_in[i] += c_probe[i]; } if (includeIndirectInProbes) { for (int i = 0; i < SHTerms(lmax); ++i) c_probe[i] = 0.f; SHProjectIncidentIndirectRadiance(p, 0.f, time, renderer, origSample, scene, lmax, rng, nIndirSamples, c_probe); for (int i = 0; i < SHTerms(lmax); ++i) c_in[i] += c_probe[i]; } arena.FreeAll(); } // Compute final average value for probe and cleanup if (nFound > 0) for (int i = 0; i < SHTerms(lmax); ++i) c_in[i] /= nFound; delete[] c_probe; prog.Update(); }