1. 程式人生 > >PBRT_V2 總結記錄 LightSample 和 Light 補充(Sample_L)

PBRT_V2 總結記錄 LightSample 和 Light 補充(Sample_L)

LightSample 

struct LightSample {
   // LightSample Public Methods
   LightSample() { }
   LightSample(const Sample *sample, const LightSampleOffsets &offsets, uint32_t num);
   LightSample(RNG &rng) {
       uPos[0] = rng.RandomFloat();
       uPos[1] = rng.RandomFloat();
       uComponent = rng.RandomFloat();
   }
   LightSample(float up0, float up1, float ucomp) {
       Assert(up0 >= 0.f && up0 < 1.f);
       Assert(up1 >= 0.f && up1 < 1.f);
       Assert(ucomp >= 0.f && ucomp < 1.f);
       uPos[0] = up0; uPos[1] = up1;
       uComponent = ucomp;
   }
   float uPos[2], uComponent;
};

作用:

(LightSample 儲存 3個 隨機數,有一些Light是由 多個Shape組成,uComponent 主要是用來隨機選擇 哪一個shape, uPos[2] 就是 主要是用來取樣 光源 面上的一個點,這個LightSample 和BSDFSample 十分類似,可以參考《PBRT_V2 總結記錄 <85> BSDFSample 和 BSDFSampleOffsets 和 BSDF::Sample_f() 和BSDF:Pdf》)

LightSample stores a three-dimensional random sample for sampling the light source (similar to the
BSDFSample),Not all lights need all three of these samples, but for lights that are comprised of many Shapes,
then we need one sample to select which shape to sample from and two samples to choose
a point on its surface.

 

Light

class Light {
public:
    // Light Interface
    virtual ~Light();
    Light(const Transform &l2w, int ns = 1)
        : nSamples(max(1, ns)), LightToWorld(l2w),
          WorldToLight(Inverse(l2w)) {
        // Warn if light has transformation with scale
        if (WorldToLight.HasScale())
            Warning("Scaling detected in world to light transformation!\n"
                    "The system has numerous assumptions, implicit and explicit,\n"
                    "that this transform will have no scale factors in it.\n"
                    "Proceed at your own risk; your image may have errors or\n"
                    "the system may crash as a result of this.");
    }
    
    virtual float Pdf(const Point &p, const Vector &wi) const = 0;
    virtual Spectrum Sample_L(const Scene *scene, const LightSample &ls,
                              float u1, float u2, float time, Ray *ray,
                              Normal *Ns, float *pdf) const = 0;
    
    // Light Public Data
    const int nSamples;
protected:
    // Light Protected Data
    const Transform LightToWorld, WorldToLight;
};

 

1.  virtual float Pdf(const Point &p, const Vector &wi) const = 0;

作用:

The Light’s Pdf() method returns the probability density with respect to solid angle for
the light’s Sample_L() method sampling the direction wi from the point p.

 

2. virtual Spectrum Sample_L(const Scene *scene, const LightSample &ls,
float u1, float u2, float time, Ray *ray,
Normal *Ns, float *pdf) const = 0;

作用:

(這個Sample_L 利用取樣點生成一條 ray,這條Ray 是從 Light 發出的,儲存到 引數 ray中,而且,返回光源面上一點的法線到 引數 Ns中,並且會返回這個取樣點 所產生的 光源 Spectrum 值,其實就是這個光源的隨機發出 Ray,這個Ray 帶有多少 radiance)

The third light sampling method is quite different. It samples a ray from a distribution
of rays leaving the light, returning the ray in *ray and the surface normal at the point on
the light source in *Ns
. Being able to sample rays in this manner is necessary to support
algorithms that construct paths of light leaving the light source.
The returned PDF value should be expressed in terms of the product of the density
with respect to surface area on the light and the density with respect to solid angle.
The implementations of this method in this section will sample the two distributions
separately and compute their product,
rather than trying to construct and sample a joint
four-dimensional distribution. Implementations of this method may need up to five
sample values, with the two additional ones used to determine the direction of the ray
(after the first three are used to determine its origin on the light source).