【发布时间】:2023-03-03 20:41:02
【问题描述】:
我有一组网格,每个网格可以有 1 到 N 个纹理。我正在寻找一种算法,它可以让我对网格进行排序以减少纹理更改的数量。将使用单一纹理的网格组合在一起相对简单,我发现棘手的是:
-
在网格使用两个纹理(我将其表示为纹理 A 和 B)的情况下,对集合进行排序,以便首先绘制仅使用纹理 A 的网格组,然后是加载 A 的网格和 B,然后是只使用 B 的网格。
-
在网格使用 N 个纹理(例如 3,我将其表示为纹理 A、B 和 C)的情况下,找出组织该网格中的面的最佳方法,以便可以将平凡的组以类似于 1) 的方式加载。例如,我可以重新组织网格的面,以便加载顺序为 [B A C] 或 [C B A]。这有效地让我忽略了中间的纹理负载,我可以将其视为具有两个纹理的网格(分别为 [B C] 和 [C A])。
描述这个问题的另一种方式是:我有一组“任务”要做。每项任务都需要我访问节点集合中的 1 到 N 个唯一节点。我可以有多个相同的任务,但是每次我重做一个任务时,我必须按照与上次相同的顺序遍历节点。找到减少状态变化次数的路径(状态变化从一个节点转移到另一个节点)。
我假设已经有一种类似于我想要完成的算法的算法,可能是某种寻路算法,或者可能已经在现代图形库/驱动程序中实现。
请不要告诉我“改为按 Z 对网格进行排序会更有效”或按纹理分割我的网格,这不是这个问题的重点。这不适用于实时应用程序。
【问题讨论】:
-
从使用纹理 [A B] 到使用纹理 [C D] 的状态更改比使用 [A D] 的状态更改更昂贵。换句话说,仅进行(任何形式的)状态更改是否是主要成本? (例如,我可以想象告诉驱动程序更改哪些纹理绑定到哪些单元是一个恒定时间操作,而不管更新了多少纹理单元。)在这种情况下,最好利用最大纹理单元可以同时加载。并且只需根据缓存性能访问未使用的纹理的 0,0 uvs。我其实不知道。
-
排序词典能满足您的要求吗?例如将
a,ab,ac,abc,b, bc,c排序为a, ab, abc, ac, b, bc, c?另一种方法是为任何交换分配一个成本,并使用 BFS 来最小化交换(统一成本搜索)。 -
@Wyck 在这种特殊情况下,这是针对旧游戏机(特别是 Nintendo64),所以我无法使用现代的现代解决方案。 N64 有一个非常小的 4kb 纹理缓存,这意味着要利用加载多个纹理需要非常小的纹理大小。
-
@c0der 是的,字典排序是解决这个问题的一种方法。
-
字典排序非常简单:online-ide.com/7gqNtwXu5G
标签: algorithm sorting graphics path-finding