00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "stdafx.h"
00027 #include "integrators/diffuseprt.h"
00028 #include "sh.h"
00029 #include "light.h"
00030 #include "scene.h"
00031 #include "camera.h"
00032 #include "intersection.h"
00033 #include "paramset.h"
00034 #include "montecarlo.h"
00035
00036
00037 DiffusePRTIntegrator::DiffusePRTIntegrator(int lm, int ns)
00038 : lmax(lm), nSamples(RoundUpPow2(ns)) {
00039 c_in = new Spectrum[SHTerms(lmax)];
00040 }
00041
00042
00043 DiffusePRTIntegrator::~DiffusePRTIntegrator() {
00044 delete[] c_in;
00045 }
00046
00047
00048 void DiffusePRTIntegrator::Preprocess(const Scene *scene,
00049 const Camera *camera, const Renderer *renderer) {
00050 BBox bbox = scene->WorldBound();
00051 Point p = .5f * bbox.pMin + .5f * bbox.pMax;
00052 RNG rng;
00053 MemoryArena arena;
00054 SHProjectIncidentDirectRadiance(p, 0.f, camera->shutterOpen, arena,
00055 scene, false, lmax, rng, c_in);
00056 }
00057
00058
00059 void DiffusePRTIntegrator::RequestSamples(Sampler *sampler, Sample *sample, const Scene *scene) {
00060 }
00061
00062
00063 Spectrum DiffusePRTIntegrator::Li(const Scene *scene, const Renderer *,
00064 const RayDifferential &ray, const Intersection &isect,
00065 const Sample *sample, RNG &rng, MemoryArena &arena) const {
00066 Spectrum L = 0.f;
00067 Vector wo = -ray.d;
00068
00069 L += isect.Le(wo);
00070
00071
00072 BSDF *bsdf = isect.GetBSDF(ray, arena);
00073 const Point &p = bsdf->dgShading.p;
00074 const Normal &n = bsdf->dgShading.nn;
00075
00076
00077
00078 Spectrum *c_transfer = arena.Alloc<Spectrum>(SHTerms(lmax));
00079 SHComputeDiffuseTransfer(p, Faceforward(n, wo), isect.rayEpsilon,
00080 scene, rng, nSamples, lmax, c_transfer);
00081
00082
00083 Spectrum Kd = bsdf->rho(wo, rng, BSDF_ALL_REFLECTION) * INV_PI;
00084 Spectrum Lo = 0.f;
00085 for (int i = 0; i < SHTerms(lmax); ++i)
00086 Lo += c_in[i] * c_transfer[i];
00087 return L + Kd * Lo.Clamp();
00088 }
00089
00090
00091 DiffusePRTIntegrator *CreateDiffusePRTIntegratorSurfaceIntegrator(const ParamSet ¶ms) {
00092 int lmax = params.FindOneInt("lmax", 4);
00093 int ns = params.FindOneInt("nsamples", 4096);
00094 return new DiffusePRTIntegrator(lmax, ns);
00095 }
00096
00097