PBRT_V2 总结记录 AreaLight 和 DiffuseAreaLight 和 Intersection.Le

AreaLight 类

class AreaLight : public Light {
public:
    // AreaLight Interface
    AreaLight(const Transform &l2w, int ns) : Light(l2w, ns) { }
    virtual Spectrum L(const Point &p, const Normal &n,
                       const Vector &w) const = 0;
};

类的作用:

(面积光源,需要使用Shape来作为 光源的表面)

Area lights are light sources defined by one or more Shapes that emit light from their
surface, with some directional distribution of radiance at each point on the surface.

In general, computing radiometric quantities related to area lights requires computing
integrals over the surface of the light that often can’t be computed in closed form. This
issue is addressed with theMonte Carlo integration techniques of Chapter 14. The reward
for this complexity (and computational expense) is soft shadows and more realistic
lighting effects, rather than the hard shadows and stark lighting that come from point
lights.

 

1. 

virtual Spectrum L(const Point &p, const Normal &n,
                       const Vector &w) const = 0;

作用:

(AreaLight 添加了 L 方法,传入 光源面上的一个点,和这个面的法线, 就会计算出 在 w 方向 上,Area Light的这个点的发出多少 radiance )

AreaLight adds a single new method to the Light interface, AreaLight::L(). Implementations
are given a point on the surface of the light and the surface normal and should
evaluate the area light’s emitted radiance, L, in the given outgoing direction.

 

 

DiffuseAreaLight 类

class DiffuseAreaLight : public AreaLight {
public:
    // DiffuseAreaLight Public Methods
    DiffuseAreaLight(const Transform &light2world,
        const Spectrum &Le, int ns, const Reference &shape);
    ~DiffuseAreaLight();
    Spectrum L(const Point &p, const Normal &n, const Vector &w) const {
        return Dot(n, w) > 0.f ? Lemit : 0.f;
    }
    Spectrum Power(const Scene *) const;
    bool IsDeltaLight() const { return false; }
    float Pdf(const Point &, const Vector &) const;
    Spectrum Sample_L(const Point &P, float pEpsilon, const LightSample &ls, float time,
        Vector *wo, 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;
protected:
    // DiffuseAreaLight Protected Data
    Spectrum Lemit;
    ShapeSet *shapeSet;
    float area;
};

类的作用:

(DiffuseAreaLight 是一个最基础的Area Light, 均匀的空间和方向辐射分布,也就是说,发射的所有方向的radiance都是一样的,而且只会在 法线的哪一边发射光线)

DiffuseAreaLight implements a basic area light source with a uniform spatial and directional
radiance distribution.
It only emits light on the side of the surface with outwardfacing
surface normal;
there is no emission from the other side.

 

1. 构造函数

DiffuseAreaLight::DiffuseAreaLight(const Transform &light2world,
        const Spectrum &le, int ns, const Reference &s)
    : AreaLight(light2world, ns) {
    Lemit = le;
    shapeSet = new ShapeSet(s);
    area = shapeSet->Area();
}

作用:

(在构造函数里面,先计算  area Light 的面积,值得主要的是,传进来的的Shape 是可以计算它的Area的,所以就需要细化这个Shape,所以就会涉及到 ShapeSet 类,ShapeSet 会保存一个Vector的Shape,会计算出所有的Shape的总面积。)

The constructor caches the surface area of the light source since this area calculation
may be computationally expensive
.

However, not all shapes can compute their surface
area (one example is subdivision surfaces). More generally, some shapes can’t be used
as area lights directly since they don’t implement all of the Shape methods that the
AreaLight needs to call.
For example, in the Monte Carlo sampling code in Chapter 14,
DiffuseAreaLight methods implemented there will need to call Shape methods that sample
points on the shape’s surface; these methods cannot be implemented for some types
of shapes.

Such shapes must be refined into simpler shapes until their CanIntersect() methods
return true
. This refinement is done in the DiffuseAreaLight constructor if needed. The
eventual shape or shapes that are created are stored in a container class called ShapeSet.
This class implements the Shape interface, so that the DiffuseAreaLight can be written
to store only a single Shape, thus simplifying its implementation.

 

The ShapeSet class is a simple wrapper for a vector of shapes.Most of its implementation
is in Section 14.6.4, where its methods related to random sampling collections of shapes
for Monte Carlo integration are implemented.

 

2. 

Spectrum L(const Point &p, const Normal &n, const Vector &w) const {
        return Dot(n, w) > 0.f ? Lemit : 0.f;
    }

作用:

(L 函数 先判断 是否处于 Area Light 发射光线的一面,如果是就可以判断 这个Area Light 发射了多少Radiance)

Because this area light implementation emits light from only one side of the shape’s
surface, its L() method just makes sure that the outgoing direction lies in the same
hemisphere as the normal.

 

3. Spectrum Sample_L(const Point &P, float pEpsilon, const LightSample &ls, float time,
        Vector *wo, float *pdf, VisibilityTester *visibility) const;

作用:

(看 《PBRT_V2 总结记录 <88> DistantLight 补充(Sample_L)》)

The DiffuseAreaLight::Sample_L() method isn’t as straightforward as it has been for
the other light sources described so far. Specifically, at each point in the scene, radiance
from area lights can be incident from many directions, not just a single direction as was
the case for the other lights (Figure 12.13). This leads to the question of which direction
should be chosen for this method. We will defer answering this question and providing
an implementation of this method until Section 14.6, after Monte Carlo integration has
been introduced.

 

PBRT_V2 总结记录 AreaLight 和 DiffuseAreaLight 和 Intersection.Le_第1张图片

Figure 12.13: An area light casts incident illumination along many directions, rather than from a
single direction.

 

4. 

Spectrum DiffuseAreaLight::Power(const Scene *) const {
    return Lemit * area * M_PI;
}

作用:

Emitted power from an area light with uniform emitted radiance over the surface can be
directly computed in closed form:

 

5. 

bool IsDeltaLight() const { return false; }

作用:

Finally, area lights clearly do not represent singularities, so they return false from
IsDeltaLight():

 

 

Intersection.Le 方法

Spectrum Intersection::Le(const Vector &w) const {
    const AreaLight *area = primitive->GetAreaLight();
    return area ? area->L(dg.p, dg.nn, w) : Spectrum(0.);
}

作用:

(Intersectioin.Le 主要的作用就是,计算光源表面一个点的 发射 Radiance)

For convenience, there is a method in the Intersection class that makes it easy to compute
the emitted radiance at a surface point intersected by a ray.
It gets the AreaLight
pointer from the primitive and calls its L() method.

 

你可能感兴趣的:(PBRT_V2)