【问题标题】:Algorithm for reducing texture changes in collection of meshes减少网格集合中纹理变化的算法
【发布时间】:2023-03-03 20:41:02
【问题描述】:

我有一组网格,每个网格可以有 1 到 N 个纹理。我正在寻找一种算法,它可以让我对网格进行排序以减少纹理更改的数量。将使用单一纹理的网格组合在一起相对简单,我发现棘手的是:

  1. 在网格使用两个纹理(我将其表示为纹理 A 和 B)的情况下,对集合进行排序,以便首先绘制仅使用纹理 A 的网格组,然后是加载 A 的网格和 B,然后是只使用 B 的网格。

  2. 在网格使用 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


【解决方案1】:

当我写这个问题时,我预感到这个问题在某种程度上与Traveling Salesman Problem 有关,但我不是 100% 确定,所以为了安全起见,我删除了标签。然而,在进一步思考这个问题后,我确实得出了我的预感是正确的结论。

我解决问题的方法如下:

我从一组模型开始(我在这里定义为“Segments”):

我复制所有可能的纹理负载变化。例如,加载 3 个纹理的段在加载纹理的方式上有 3 个阶乘变化:

接下来,我按纹理负载对片段进行分组:

现在我生成了一个将所有组相互连接的网络,其中纹理加载(组之间)产生的成本为 1,没有纹理加载为 0。无需连接共享段的组,因为这是冗余的(在本例中,无需连接 A+B 和 B+A):

这是一个 TSP,所以现在只需使用您喜欢的方法求解最短路径。这是一个可能的解决方案(注意 B+A 被忽略,因为 A+B 已经加载了这两个段):

这是使用最近邻解决方案在this model 上运行此算法的输出。可能不是最好的解决方案(尽管它看起来是正确的),但它绝对是比强制所有 28 种可能的解决方案更好的方法:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-30
    • 1970-01-01
    • 2020-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-27
    相关资源
    最近更新 更多