PBRT_V2 总结记录 InfiniteAreaLight

InfiniteAreaLight 类

class InfiniteAreaLight : public Light {
public:
    // InfiniteAreaLight Public Methods
    InfiniteAreaLight(const Transform &light2world, const Spectrum &power, int ns,
        const string &texmap);
    ~InfiniteAreaLight();
    Spectrum Power(const Scene *) const;
    bool IsDeltaLight() const { return false; }
    Spectrum Le(const RayDifferential &r) const;
    Spectrum Sample_L(const Point &p, float pEpsilon, const LightSample &ls,
        float time, Vector *wi, float *pdf, VisibilityTester *visibility) const;
    Spectrum Sample_L(const Scene *scene, const LightSample &ls, float u1, float u2,
        float time, Ray *ray, Normal *Ns, float *pdf) const;
    float Pdf(const Point &, const Vector &) const;
    void SHProject(const Point &p, float pEpsilon, int lmax, const Scene *scene,
        bool computeLightVis, float time, RNG &rng, Spectrum *coeffs) const;
private:
    // InfiniteAreaLight Private Data
    MIPMap<RGBSpectrum> *radianceMap;
    Distribution2D *distribution;
};

类的作用:

(这里就是环境光,使用一张图片来表示环境,而且,把方向转换为球坐标,球坐标限定为[0,1],再采样图片)

Another useful kind of light is the infinite area light—an infinitely faraway area light
source that surrounds the entire scene. One way to visualize this light is as an enormous
sphere that casts light into the scene from every direction. One important use
of infinite area lights is for environment lighting, where an image that represents illumination
in an environment is used to illuminate synthetic objects as if they were in
that environment.

A widely used representation for light for this application is the latitude–longitude radiance
map.
The EnvironmentCamera can be used to create image maps for the light. Like the other lights, the InfiniteAreaLight
takes a transformation matrix; here, its use is to orient the image map.

It then uses spherical coordinates to map from directions on the sphere to (θ , φ) directions, and from there
to (u, v) texture coordinates.
The provided transformation thus determines which direction
is “up.”

1. 构造函数

InfiniteAreaLight::InfiniteAreaLight(const Transform &light2world,
        const Spectrum &L, int ns, const string &texmap)
    : Light(light2world, ns) {
    int width = 0, height = 0;
    RGBSpectrum *texels = NULL;
    // Read texel data from _texmap_ into _texels_
    if (texmap != "") {
        texels = ReadImage(texmap, &width, &height);
        if (texels)
            for (int i = 0; i < width * height; ++i)
                texels[i] *= L.ToRGBSpectrum();
    }
    if (!texels) {
        width = height = 1;
        texels = new RGBSpectrum[1];
        texels[0] = L.ToRGBSpectrum();
    }
    radianceMap = new MIPMap<RGBSpectrum>(width, height, texels);
    delete[] texels;
    // Initialize sampling PDFs for infinite area light

    // Compute scalar-valued image _img_ from environment map
    float filter = 1.f / max(width, height);
    float *img = new float[width*height];
    for (int v = 0; v < height; ++v) {
        float vp = (float)v / (float)height;
        float sinTheta = sinf(M_PI * float(v+.5f)/float(height));
        for (int u = 0; u < width; ++u) {
            float up = (float)u / (float)width;
            img[u+v*width] = radianceMap->Lookup(up, vp, filter).y();
            img[u+v*width] *= sinTheta;
        }
    }

    // Compute sampling distributions for rows and columns of image
    distribution = new Distribution2D(img, width, height);
    delete[] img;
}

作用:

(加载图片并生成MipMap实例,剩下的待定...)

The constructor loads the image data from disk and creates a MIPMap to store it.

The other code fragment in the constructor is related to Monte Carlo sampling of InfiniteAreaLights
and will be defined later, in Section 14.6.5.

2. Spectrum Sample_L(const Point &p, float pEpsilon, const LightSample &ls,
        float time, Vector *wi, float *pdf, VisibilityTester *visibility) const;

作用:

(待定。。。)

Because InfiniteAreaLights cast light from all directions, it’s also necessary to useMonte
Carlo integration to compute reflected light due to illumination from them. Therefore,
the InfiniteAreaLight::Sample_L() method will be defined in Section 14.6.

3.  Spectrum Power(const Scene *) const;

Spectrum InfiniteAreaLight::Power(const Scene *scene) const {
    Point worldCenter;
    float worldRadius;
    scene->WorldBound().BoundingSphere(&worldCenter, &worldRadius);
    return M_PI * worldRadius * worldRadius *
        Spectrum(radianceMap->Lookup(.5f, .5f, .5f), SPECTRUM_ILLUMINANT);
}

作用:

Like directional lights, the total power from the infinite area light is related to the surface
area of the scene:

4. 

Spectrum InfiniteAreaLight::Le(const RayDifferential &r) const {
    Vector wh = Normalize(WorldToLight(r.d));
    float s = SphericalPhi(wh) * INV_TWOPI;
    float t = SphericalTheta(wh) * INV_PI;
    return Spectrum(radianceMap->Lookup(s, t), SPECTRUM_ILLUMINANT);
}

作用:

Because infinite area lights need to be able to contribute radiance to rays that don’t
hit any geometry in the scene, we’ll add a method to the base Light class that returns
emitted radiance due to that light along a ray that didn’t hit anything in the scene. (The
default implementation for other lights returns no radiance.) It is the responsibility of
the integrators to call this method for these rays.

猜你喜欢

转载自blog.csdn.net/aa20274270/article/details/84288280
今日推荐