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

PBRT_V2 總結記錄 AggregateVolume

AggregateVolume 類


class AggregateVolume : public VolumeRegion {
public:
    // AggregateVolume Public Methods
    AggregateVolume(const vector<VolumeRegion *> &r);
    ~AggregateVolume();
    BBox WorldBound() const;
    bool IntersectP(const Ray &ray, float *t0, float *t1) const;
    Spectrum sigma_a(const Point &, const Vector &, float) const;
    Spectrum sigma_s(const Point &, const Vector &, float) const;
    Spectrum Lve(const Point &, const Vector &, float) const;
    float p(const Point &, const Vector &, const Vector &, float) const;
    Spectrum sigma_t(const Point &, const Vector &, float) const;
    Spectrum tau(const Ray &ray, float, float) const;
private:
    // AggregateVolume Private Data
    vector<VolumeRegion *> regions;
    BBox bound;
};

類的作用:

(AggregateVolume 儲存 一系列的 volumeRegion,就像 Aggregate 類的作用是基本上一致的,但是這個AggregateVolume 就是為了處理 VolumeRegion,而且這個 AggregateVolume 實現比較簡單,主要是遍歷 自己儲存的所有的 VolumeRegion)

Just as Aggregate implementations can hold sets of Primitives, the AggregateVolume
holds one or more VolumeRegions. There are two main reasons to provide volume
aggregates in pbrt. First, doing so simplifies the Scene and the implementation of
VolumeIntegrators, since they can both be written to make calls to a single aggregate
volume region, rather than looping over all of the regions in the scene. Second,
AggregateVolume implementations have the potential to use 3D spatial data structures to
improve efficiency by culling volumes that are far from a particular ray or lookup point.

Here, we will just implement a simple AggregateVolume that stores an array of all the
volumes in the scene and loops over them in each of its method implementations.
This
implementation is inefficient for scenes with many distinct VolumeRegions.

 

1. 建構函式

AggregateVolume::AggregateVolume(const vector<VolumeRegion *> &r) {
    regions = r;
    for (uint32_t i = 0; i < regions.size(); ++i)
        bound = Union(bound, regions[i]->WorldBound());
}

作用:

(建構函式直接儲存 一個vertor 的 VolumeRegion ,並且計算 他們的整體包圍盒)

The AggregateVolume constructor is simple. It copies the vector of VolumeRegions passed
in and computes the bound that encloses them all.

 

2.  sigma_a,sigma_s,Lve,p,sigma_t,tau


Spectrum AggregateVolume::sigma_a(const Point &p, const Vector &w,
                                  float time) const {
    Spectrum s(0.);
    for (uint32_t i = 0; i < regions.size(); ++i)
        s += regions[i]->sigma_a(p, w, time);
    return s;
}


Spectrum AggregateVolume::sigma_s(const Point &p, const Vector &w, float time) const {
    Spectrum s(0.);
    for (uint32_t i = 0; i < regions.size(); ++i)
        s += regions[i]->sigma_s(p, w, time);
    return s;
}


Spectrum AggregateVolume::Lve(const Point &p, const Vector &w, float time) const {
    Spectrum L(0.);
    for (uint32_t i = 0; i < regions.size(); ++i)
        L += regions[i]->Lve(p, w, time);
    return L;
}


float AggregateVolume::p(const Point &p, const Vector &w, const Vector &wp,
        float time) const {
    float ph = 0, sumWt = 0;
    for (uint32_t i = 0; i < regions.size(); ++i) {
        float wt = regions[i]->sigma_s(p, w, time).y();
        sumWt += wt;
        ph += wt * regions[i]->p(p, w, wp, time);
    }
    return ph / sumWt;
}


Spectrum AggregateVolume::sigma_t(const Point &p, const Vector &w, float time) const {
    Spectrum s(0.);
    for (uint32_t i = 0; i < regions.size(); ++i)
        s += regions[i]->sigma_t(p, w, time);
    return s;
}


Spectrum AggregateVolume::tau(const Ray &ray, float step, float offset) const {
    Spectrum t(0.);
    for (uint32_t i = 0; i < regions.size(); ++i)
        t += regions[i]->tau(ray, step, offset);
    return t;
}

作用:

(上面的幾個函式, sigma_a,sigma_s,Lve,p,sigma_t,tau,只是遍歷 每一個 VolumeRegion的對應的方法,累加起來,這裡需要注意的就是,p函式 不只是累加,而是加權平均)

As described earlier, the implementations of most of the various VolumeRegion interface
methods loop over the individual regions.
We will show AggregateVolume::sigma_a() as
an example; the rest are similar and not shown here. Note that it forwards(前向) the call on
to each contained VolumeRegion and adds the results.

 

3. bool AggregateVolume::IntersectP(const Ray &ray,  float *t0, float *t1) const

作用:

bool AggregateVolume::IntersectP(const Ray &ray,
                                 float *t0, float *t1) const {
    *t0 = INFINITY;
    *t1 = -INFINITY;
    for (uint32_t i = 0; i < regions.size(); ++i) {
        float tr0, tr1;
        if (regions[i]->IntersectP(ray, &tr0, &tr1)) {
            *t0 = min(*t0, tr0);
            *t1 = max(*t1, tr1);
        }
    }
    return (*t0 < *t1);
}

作用:

(這裡每一個VolumeRegion 進行 計算 IntersectP得到 每一個 VolumeRegion 的 t0 和 t1,把最小和最大的 t 計算出來)

The parametric t range of the ray over all the volumes is equal to the extent from the minimum of all of
the regions’ tmin values to the maximum of all of the tmax values.