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.

猜你喜欢

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