将任意方块打包成矩形

时间:2015-02-16 12:30:18

标签: image algorithm textures packing texture-packing

为了提供一些上下文,我在3D场景中为不同的对象提供了几个光照贴图,我想将其打包到单个纹理中。光照贴图是方形的,具有不同的尺寸,不一定是2的幂(尽管如果能够提供更好的解决方案,可以包括这种限制)。生成的纹理的大小是任意的,但应尽可能为方形。我必须保持像素完美,不能使用旋转。速度不是问题,这不适用于时间要求严格的应用程序。

我找到的基本算法over at GameDev.SE可以这样工作:

  1. 按区域对光照贴图进行排序,从大
  2. 开始
  3. 以光栅扫描顺序浏览输出纹理[固定宽度或根据需要增加]
  4. 将光照贴图置于第一个可能的位置
  5. 重复下一个光照贴图,直至完成
  6. 虽然这听起来合理且易于实现,但我想知道这个算法对于我的目的是否是一个不错的选择,或者是否有更简单的解决方案。特别是,我对以下内容感兴趣:

    • 我能不能以某种方式使用方形纹理?
    • 有没有办法预先计算出输出的最佳方形尺寸?
    • 我是否可以充分利用只有两个人的力量?纹理?

1 个答案:

答案 0 :(得分:1)

按高度启发式排序仍然有效。即使是这个稍微简单的版本也可以工作:按高度排序,在同一y上从左到右放置,每次到达右侧时,都会增加此行上最大纹理的y。这样你甚至不必找到一个位置,你已经知道你将它放在哪里。如果身高没有太大的变化,这种方法很有效,但它可能很糟糕。

据我所知,没有办法预先计算尺寸。但是,尝试这样做会导致无功能的两种尺寸。猜测一个大小(sqrt(总面积)四舍五入到2的幂)并且如果不是所有东西都可以将其增加2倍,那么应该快速找到最佳尺寸。

如果你所包装的所有东西都是两个尺寸的力量,那么你可以做一些更简单的事情。将所有内容放入堆中,并尝试将大小相等的4个组放在一个下一个大小的块中。不会总是4,这意味着更大的区域中有一些空的空间。

如果它们不是2的幂,那么这里有一个替代方案可能比高度排序技巧更好一些。它的速度要慢得多,而且不值得包装很多小件物品,但是当物品的尺寸完全不同时,我发现它很有用。它基于区域分裂,在这方面它提醒了KD树,但它并不是真的那样(因为这里关于区域,没有"点&# 34)。无论如何,你使用一个树,其中每个内部节点代表一个分裂,奇数级别在一个轴上分裂,而偶数级别在另一个轴上分裂。放置项目时,递归找到它可以适合的第一个位置。

这是基本的事情。我发现第一次尝试将它放在某个地方很有用#34;很好地" (这样它会产生少于2个分裂,因此它恰好在宽度或高度或两者中适合某些区域)并且只有在没有这样的地方时才适合它适合的第一个地方。此外,我发现存储每个节点具有的空闲区域很有用。和它的实际矩形"在节点中。可以在递归期间计算尺寸和位置,并且该区域根本不是必需的,但是具有正确的实际矩形是方便的并且可以提前跳过太满的自由区域节点。首先按区域进行反向排序可以帮助减少一次分割的区域,然后可以永远不会被使用(而在大项目之后放入小项目应该没有问题),但它仍然几乎不是最佳的。