PBRT_V2 总结记录 SpotLight

SpotLight 类

class SpotLight : public Light {
public:
    // SpotLight Public Methods
    SpotLight(const Transform &light2world, const Spectrum &, float width, float fall);
    Spectrum Sample_L(const Point &p, float pEpsilon, const LightSample &ls, float time,
        Vector *wi, float *pdf, VisibilityTester *vis) const;
    bool IsDeltaLight() const { return true; }
    float Falloff(const Vector &w) const;
    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:
    // SpotLight Private Data
    Point lightPos;
    Spectrum Intensity;
    float cosTotalWidth, cosFalloffStart;
};

类的作用:

(聚光灯,属于点光源,在光源坐标空间中原点,往 +z 轴 方向照射)

Spotlights are a handy variation on point lights; rather than shining illumination in
all directions, they emit light in a cone of directions from their position. For simplicity,
we will define the spotlight in the light coordinate system to always be at position
(0, 0, 0) and pointing down the +z axis.
To place or orient it elsewhere in the scene, the Light::WorldToLight transformation should be set accordingly.

1. 构造函数

SpotLight::SpotLight(const Transform &light2world,
                     const Spectrum &intensity, float width, float fall)
    : Light(light2world) {
    lightPos = LightToWorld(Point(0,0,0));
    Intensity = intensity;
    cosTotalWidth = cosf(Radians(width));
    cosFalloffStart = cosf(Radians(fall));
}

作用:

(定义了两个角度,一个是 totalWidth, 一个是 falloffStart, 在[0, falloffStart] 之间,是不需要衰减,[falloffStart,totalWidth] 开始衰减,衰减到0为止)

Two angles are passed to the constructor to set the extent of the SpotLight’s cone: the
overall angular width of the cone and the angle at which falloff starts (Figure 12.4). The
constructor precomputes and stores the cosines of these angles for use in the SpotLight’s
methods.

Figure 12.4: Spotlights are defined by two angles, falloffStart and totalWidth. Objects inside the
inner cone of angles, up to falloffStart , are fully illuminated by the light. The directions between
falloffStart and totalWidth are a transition zone that ramps down from full illumination to no illumination,
such that points outside the totalWidth cone aren’t illuminated at all.
The cosine of the angle
between the vector to a point p and the spotlight axis, θ, can easily be computed with a dot product.

2. 

Spectrum SpotLight::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 * Falloff(-*wi) / DistanceSquared(lightPos, p);
}


作用:

(基本上与 Point Light的Sample_L 一致,但是就是多了 Falloff 衰减函数)

The SpotLight::Sample_L() method is almost identical to PointLight::Sample_L(), except
that it also calls the Falloff() method, which computes the distribution of light
accounting for the spotlight cone. This computation is encapsulated in a separate method
since other SpotLight methods will need to perform it as well.

3. 

float SpotLight::Falloff(const Vector &w) const {
    Vector wl = Normalize(WorldToLight(w));
    float costheta = wl.z;
    if (costheta < cosTotalWidth)     return 0.;
    if (costheta > cosFalloffStart)   return 1.;
    // Compute falloff inside spotlight cone
    float delta = (costheta - cosTotalWidth) /
                  (cosFalloffStart - cosTotalWidth);
    return delta*delta*delta*delta;
}

作用:

(Falloff 衰减函数的最要思路就是,第一步,先把 点 P 变换到 光源坐标系中,再 计算 P与 +Z 轴的夹角,就是下面的公式,cosstheta = wl.z, 那么,如果夹角比 totalWidth要大的话,就表示完全衰减,如果是在小于 falloffStart的话,就不进行衰减,如果是falloffStart和totalWidth之间的话,就渐变衰减)

To compute the spotlight’s strength for a receiving point p, this first step is to compute
the cosine of the angle between the vector from the spotlight origin to p and the vector
along the center of the spotlight’s cone.
To compute the cosine of the offset angle to a
point p, we have (Figure 12.4)

4. 

Spectrum SpotLight::Power(const Scene *) const {
    return Intensity * 2.f * M_PI *
           (1.f - .5f * (cosFalloffStart + cosTotalWidth));
}

作用:

The solid angle subtended by a cone with spread angle θ is 2π(1− cos θ). Therefore,
the integral over directions on the sphere that gives power from radiant intensity can be
solved to compute the total power of a light that only emits illumination in a cone. For
the spotlight, we can reasonably approximate the power of the light by computing the
solid angle of directions that is covered by the cone with a spread angle cosine halfway
between width and fall.

猜你喜欢

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