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/directlighting.h"
00028 #include "intersection.h"
00029 #include "paramset.h"
00030
00031
00032 DirectLightingIntegrator::DirectLightingIntegrator(LightStrategy st, int md) {
00033 maxDepth = md;
00034 strategy = st;
00035 lightSampleOffsets = NULL;
00036 bsdfSampleOffsets = NULL;
00037 }
00038
00039
00040 DirectLightingIntegrator::~DirectLightingIntegrator() {
00041 delete[] lightSampleOffsets;
00042 delete[] bsdfSampleOffsets;
00043 }
00044
00045
00046 void DirectLightingIntegrator::RequestSamples(Sampler *sampler,
00047 Sample *sample, const Scene *scene) {
00048 if (strategy == SAMPLE_ALL_UNIFORM) {
00049
00050 uint32_t nLights = scene->lights.size();
00051 lightSampleOffsets = new LightSampleOffsets[nLights];
00052 bsdfSampleOffsets = new BSDFSampleOffsets[nLights];
00053 for (uint32_t i = 0; i < nLights; ++i) {
00054 const Light *light = scene->lights[i];
00055 int nSamples = light->nSamples;
00056 if (sampler) nSamples = sampler->RoundSize(nSamples);
00057 lightSampleOffsets[i] = LightSampleOffsets(nSamples, sample);
00058 bsdfSampleOffsets[i] = BSDFSampleOffsets(nSamples, sample);
00059 }
00060 lightNumOffset = -1;
00061 }
00062 else {
00063
00064 lightSampleOffsets = new LightSampleOffsets[1];
00065 lightSampleOffsets[0] = LightSampleOffsets(1, sample);
00066 lightNumOffset = sample->Add1D(1);
00067 bsdfSampleOffsets = new BSDFSampleOffsets[1];
00068 bsdfSampleOffsets[0] = BSDFSampleOffsets(1, sample);
00069 }
00070 }
00071
00072
00073 Spectrum DirectLightingIntegrator::Li(const Scene *scene,
00074 const Renderer *renderer, const RayDifferential &ray,
00075 const Intersection &isect, const Sample *sample, RNG &rng, MemoryArena &arena) const {
00076 Spectrum L(0.f);
00077
00078 BSDF *bsdf = isect.GetBSDF(ray, arena);
00079 Vector wo = -ray.d;
00080 const Point &p = bsdf->dgShading.p;
00081 const Normal &n = bsdf->dgShading.nn;
00082
00083 L += isect.Le(wo);
00084
00085
00086 if (scene->lights.size() > 0) {
00087
00088 switch (strategy) {
00089 case SAMPLE_ALL_UNIFORM:
00090 L += UniformSampleAllLights(scene, renderer, arena, p, n, wo,
00091 isect.rayEpsilon, ray.time, bsdf, sample, rng,
00092 lightSampleOffsets, bsdfSampleOffsets);
00093 break;
00094 case SAMPLE_ONE_UNIFORM:
00095 L += UniformSampleOneLight(scene, renderer, arena, p, n, wo,
00096 isect.rayEpsilon, ray.time, bsdf, sample, rng,
00097 lightNumOffset, lightSampleOffsets, bsdfSampleOffsets);
00098 break;
00099 }
00100 }
00101 if (ray.depth + 1 < maxDepth) {
00102 Vector wi;
00103
00104 L += SpecularReflect(ray, bsdf, rng, isect, renderer, scene, sample,
00105 arena);
00106 L += SpecularTransmit(ray, bsdf, rng, isect, renderer, scene, sample,
00107 arena);
00108 }
00109 return L;
00110 }
00111
00112
00113 DirectLightingIntegrator *CreateDirectLightingIntegrator(const ParamSet ¶ms) {
00114 int maxDepth = params.FindOneInt("maxdepth", 5);
00115 LightStrategy strategy;
00116 string st = params.FindOneString("strategy", "all");
00117 if (st == "one") strategy = SAMPLE_ONE_UNIFORM;
00118 else if (st == "all") strategy = SAMPLE_ALL_UNIFORM;
00119 else {
00120 Warning("Strategy \"%s\" for direct lighting unknown. "
00121 "Using \"all\".", st.c_str());
00122 strategy = SAMPLE_ALL_UNIFORM;
00123 }
00124 return new DirectLightingIntegrator(strategy, maxDepth);
00125 }
00126
00127