PBRT_V2 总结记录 <59> AggregateVolume

本文深入解析了AggregateVolume类,该类用于处理多个VolumeRegion的集合,简化了场景管理和体积积分器的实现。文章详细介绍了AggregateVolume的构造函数、成员变量以及关键方法如sigma_a、sigma_s、Lve、p、sigma_t、tau和IntersectP的实现原理和作用。

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.

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值