PBRT_V2 总结记录 <51> MIPMap.Lookup (Triangle Filter)

 MIPMap.Lookup

template <typename T>
T MIPMap<T>::Lookup(float s, float t, float width) const {
    // Compute MIPMap level for trilinear filtering
    float level = nLevels - 1 + Log2(max(width, 1e-8f));

    // Perform trilinear interpolation at appropriate MIPMap level
    PBRT_MIPMAP_TRILINEAR_FILTER(const_cast<MIPMap<T> *>(this), s, t, width, level, nLevels);
    if (level < 0)
        return triangle(0, s, t);
    else if (level >= nLevels - 1)
        return Texel(nLevels-1, 0, 0);
    else {
        uint32_t iLevel = Floor2Int(level);
        float delta = level - iLevel;
        return (1.f-delta) * triangle(iLevel, s, t) +
               delta * triangle(iLevel+1, s, t);
    }
}


template <typename T>
T MIPMap<T>::triangle(uint32_t level, float s, float t) const {
    level = Clamp(level, 0, nLevels-1);
    s = s * pyramid[level]->uSize() - 0.5f;
    t = t * pyramid[level]->vSize() - 0.5f;
    int s0 = Floor2Int(s), t0 = Floor2Int(t);
    float ds = s - s0, dt = t - t0;
    return (1.f-ds) * (1.f-dt) * Texel(level, s0, t0) +
           (1.f-ds) * dt       * Texel(level, s0, t0+1) +
           ds       * (1.f-dt) * Texel(level, s0+1, t0) +
           ds       * dt       * Texel(level, s0+1, t0+1);
}


作用:

(个人理解,Lookup 采用三线性采样,思路: 先利用参数width(a texel spacing width),来确定MIPMap的哪一层(level层),再用 双线性插值 混合 第 level 层 (s,t)坐标附近4个texel 的值,得到v0,  同样的方法混合 第 level + 1 层的 (s,t) 附近4个texel,得到 v1, 之后再混合 v0 和 v1 ,得到最终的值)

The first of the two MIPMap::Lookup() methods uses a triangle filter over the texture
samples to remove high frequencies.
Although this filter function does not give highquality
results, it can be implemented very efficiently. In addition to the (s , t) coordinates
of the evaluation point, the caller passes this method a filter width for the lookup, giving
the extent of the region of the texture to filter across. This method filters over a square
region in texture space, so the width should be conservatively chosen to avoid aliasing
in both the s and t directions. Filtering techniques like this one that do not support a
filter extent that is nonsquare or non-axis-aligned are known as isotropic.
The primary
disadvantage of isotropic filtering algorithms is that textures viewed at an oblique angle
will appear blurry, since the required sampling rate along one axis will be very different
from the sampling rate along the other in this case.

Because filtering over many texels for wide filter widths would be inefficient, this method
chooses a MIP map level from the pyramid such that the filter region at that level would
cover four texels at that level.
Figure 10.13 illustrates this idea.

Figure 10.13: Choosing a MIP Map Level for the Triangle Filter. The MIPMap chooses a level such
that the filter covers four texels.

 

细节

1.

    // Compute MIPMap level for trilinear filtering
    float level = nLevels - 1 + Log2(max(width, 1e-8f));

:(利用 参数 w ,w是texel的宽度,计算出 哪一层的 texel 宽度是 w )

Since the resolutions of the levels of the pyramid are all powers of two, the resolution of
level L is 2^(nLevels−1−L) . Therefore, to find the level with a texel spacing width w requires
solving

for L. In general, this will be a floating-point value between two MIP map levels.

 

(推导:

log2 (1/w) = nlevels - 1 - l

- log2(w) = nlevels - 1 - l   (由于 loga (M^n) = n * loga M)

l = nlevel - 1 + log2(w)

 

2. 

    if (level < 0)
        return triangle(0, s, t);
    else if (level >= nLevels - 1)
        return Texel(nLevels-1, 0, 0);
    else {
        uint32_t iLevel = Floor2Int(level);
        float delta = level - iLevel;
        return (1.f-delta) * triangle(iLevel, s, t) +
               delta * triangle(iLevel+1, s, t);
    }

:

(像上面所说的,这里就是混合 v0 和 v1,得到最后的值,然而,怎么得到 v0 和 v1的就在 triangle 函数中)

As shown by Figure 10.13, applying a triangle filter to the four texels around the sample
point will either filter over too small a region or too large a region (except for very carefully
selected filter widths). The implementation here applies the triangle filter at both of
these levels and blends between them according to how close level is to each of them.

This helps hide the transitions from one MIP map level to the next at nearby pixels in
the final image.While applying a triangle filter to four texels at two levels in this manner
doesn’t give exactly the same result as applying it to the original highest-resolution texels,
the difference isn’t too bad in practice and the efficiency of this approach is worth this
penalty.
In any case, the elliptically weighted average filtering in the next section should
be used when texture quality is important.

 

3. 

template <typename T>
T MIPMap<T>::triangle(uint32_t level, float s, float t) const {
    level = Clamp(level, 0, nLevels-1);
    s = s * pyramid[level]->uSize() - 0.5f;
    t = t * pyramid[level]->vSize() - 0.5f;
    int s0 = Floor2Int(s), t0 = Floor2Int(t);
    float ds = s - s0, dt = t - t0;
    return (1.f-ds) * (1.f-dt) * Texel(level, s0, t0) +
           (1.f-ds) * dt       * Texel(level, s0, t0+1) +
           ds       * (1.f-dt) * Texel(level, s0+1, t0) +
           ds       * dt       * Texel(level, s0+1, t0+1);
}

template <typename T>
const T &MIPMap<T>::Texel(uint32_t level, int s, int t) const {
    Assert(level < nLevels);
    const BlockedArray<T> &l = *pyramid[level];
    // Compute texel $(s,t)$ accounting for boundary conditions
    switch (wrapMode) {
        case TEXTURE_REPEAT:
            s = Mod(s, l.uSize());
            t = Mod(t, l.vSize());
            break;
        case TEXTURE_CLAMP:
            s = Clamp(s, 0, l.uSize() - 1);
            t = Clamp(t, 0, l.vSize() - 1);
            break;
        case TEXTURE_BLACK: {
            static const T black = 0.f;
            if (s < 0 || s >= (int)l.uSize() ||
                t < 0 || t >= (int)l.vSize())
                return black;
            break;
        }
    }
    PBRT_ACCESSED_TEXEL(const_cast<MIPMap<T> *>(this), level, s, t);
    return l(s, t);
}

作用:

(这里就是上面所说的,用 双线性插值 混合 第 level 层 (s,t)坐标附近4个texel 的值,得到v0, 这里值得注意的是,传进来的参数 s,t 是纹理坐标,范围是【0,1】,这里 s * pyramid[level]->uSize() 就是把 【0,1】 -> 【0, imageResolution】)

Given floating-point texture coordinates in [0, 1]2, the MIPMap::triangle() routine uses
a triangle filter to interpolate between the four texels that surround the sample point,
as shown in Figure 10.14.

Figure 10.14: To compute the value of the image texture function at an arbitrary (s , t) position,
MIPMap::triangle() finds the four texels around (s , t) and weights them according to a triangle filter
based on their distance to (s , t). One way to implement this is as a series of linear interpolations, as
shown here: First, the two texels below (s , t) are linearly interpolated to find a value at (s, 0), and the
two texels above it are interpolated to find (s, 1). Then, (s, 0) and (s, 1) are linearly interpolated again
to find the value at (s , t).

This method first scales the coordinates by the texture resolution
at the given MIP map level in each direction, turning them into continuous texel
coordinates.
Because these are continuous coordinates, but the texels in the image map
are defined at discrete texture coordinates, it’s important to carefully convert into a common
representation. Here, we will do all of our work in discrete coordinates, mapping
the continuous texture coordinates to discrete space.

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值