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.

猜你喜欢

转载自blog.csdn.net/aa20274270/article/details/84099172