1. 程式人生 > >PBRT_V2 總結記錄 GonioPhotometricLight

PBRT_V2 總結記錄 GonioPhotometricLight

GonioPhotometricLight 類

class GonioPhotometricLight : public Light {
public:
    // GonioPhotometricLight Public Methods
    GonioPhotometricLight(const Transform &light2world, const Spectrum &, const
    string &texname);
    Spectrum Sample_L(const Point &p, float pEpsilon, const LightSample &ls,
        float time, Vector *wi, float *pdf, VisibilityTester *vis) const;
    ~GonioPhotometricLight() { delete mipmap; }
    bool IsDeltaLight() const { return true; }
    Spectrum Scale(const Vector &w) const {
        Vector wp = Normalize(WorldToLight(w));
        swap(wp.y, wp.z);
        float theta = SphericalTheta(wp);
        float phi   = SphericalPhi(wp);
        float s = phi * INV_TWOPI, t = theta * INV_PI;
        return (mipmap == NULL) ? 1.f :
            Spectrum(mipmap->Lookup(s, t), SPECTRUM_ILLUMINANT);
    }
    Spectrum Power(const Scene *) 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;
private:
    // GonioPhotometricLight Private Data
    Point lightPos;
    Spectrum Intensity;
    MIPMap<RGBSpectrum> *mipmap;
};

類的作用:

(這個光源,根據方向,查詢圖片的值,利用圖片的值來 縮放 發射出來的 intensity)

In this section, we’ll implement a light source that uses goniophotometric diagrams encoded in
2D image maps to describe the emission distribution of the light. The implementation
is very similar to the point light sources defined previously in this section; it scales the
intensity based on the outgoing direction according to the goniophotometric diagram’s
values.

 

1. 建構函式

GonioPhotometricLight::GonioPhotometricLight(const Transform &light2world,
        const Spectrum &intensity, const string &texname)
    : Light(light2world) {
    lightPos = LightToWorld(Point(0,0,0));
    Intensity = intensity;
    // Create _mipmap_ for _GonioPhotometricLight_
    int width, height;
    RGBSpectrum *texels = ReadImage(texname, &width, &height);
    if (texels) {
        mipmap = new MIPMap<RGBSpectrum>(width, height, texels);
        delete[] texels;
    }
    else mipmap = NULL;
}

作用:

(建構函式需要 intensity 和 image, image 就是用來 縮放 intensity 用的)

The GonioPhotometricLight constructor takes a base intensity and an image map that
scales the intensity based on the angular distribution of light.

Like ProjectionLight, GonioPhotometricLight constructs a MIPMap of the distribution’s
image map, also always using RGBSpectrum values.

 

2. 

Spectrum GonioPhotometricLight::Sample_L(const Point &p, float pEpsilon,
        const LightSample &ls, float time, Vector *wi, float *pdf, VisibilityTester *visibility) const {
    *wi = Normalize(lightPos - p);
    *pdf = 1.f;
    visibility->SetSegment(p, pEpsilon, lightPos, 0., time);
    return Intensity * Scale(-*wi) / DistanceSquared(lightPos, p);
}

    Spectrum Scale(const Vector &w) const {
        Vector wp = Normalize(WorldToLight(w));
        swap(wp.y, wp.z);
        float theta = SphericalTheta(wp);
        float phi   = SphericalPhi(wp);
        float s = phi * INV_TWOPI, t = theta * INV_PI;
        return (mipmap == NULL) ? 1.f :
            Spectrum(mipmap->Lookup(s, t), SPECTRUM_ILLUMINANT);
    }

作用:

(最主要的函式就是Scale,Scale主要的思路就是 計算 一個方向 w的球座標出來,再把球座標變換到 [0,1],再進行取樣圖片)

The GonioPhotometricLight::Sample_L() method s essentially
identical to the SpotLight::Sample_L() and ProjectionLight::Sample_L() methods that
use a helper function to scale the amount of radiance. It assumes that the scale texture
is encoded using spherical coordinates, so that the given direction needs to be converted
to θ and φ values and scaled to [0, 1] before being used to index into the texture. Goniophotometric
diagrams are usually defined in a coordinate space where the y axis is
up, whereas the spherical coordinate utility routines assume that z is up, so y and z are
swapped before doing the conversion.

 

 

3. 

Spectrum GonioPhotometricLight::Power(const Scene *) const {
    return 4.f * M_PI * Intensity *
        Spectrum(mipmap ? mipmap->Lookup(.5f, .5f, .5f) : 1.f, SPECTRUM_ILLUMINANT);
}

作用:

The Power() method’s computation is inaccurate because the spherical coordinate parameterization
of directions has various distortions, particularly near the +z and −z
directions. Again, this error is acceptable for the uses of this method in pbrt.