组合网格时控制位置和材质

Control position and materia when combining meshes

我正在程序化地生成基于 3d grid/tile 的 16x16 块块地形。现在我已经到了我想要向这些块中添加其他自定义创建的网格(如道路和树木)的地步。我通过每米放置 2 个三角形并根据高度图升高此 tile/quad 的角来创建地形。

我已经为我的模型创建了一个单独的网格数组,我想复制它们并将它们与地形结合起来以节省绘制调用。我目前正在使用 MeshCombine 尝试此操作,但我 运行 遇到了 2 个问题。

  1. 我无法定位我的自定义网格。网格没有变换,所以我不能将变换矩阵与组合一起使用。创建一个完整的游戏对象是多余的。我可以偏移自定义网格的每个顶点,但我觉得必须有更简单的方法,例如设置原点或将网格作为一个整体进行变换。

  2. 我的网格显示不正确。显然是因为他们得到了我用于地形的 material。所以 l mat ID 1 得到了地形分配的 material 而 mat ID 2 根本没有被渲染。我似乎无法以编程方式更改它,所以我是否必须在我的 3D 应用程序中正确设置它们?像这样:

    • 地形 ID1
    • 道路 ID2 + ID3
    • 树ID4+ID5
    • 建筑物 ID6+ID7+ID8+等

您可能会认为这很乏味。所以我正在寻找一种方法来从 FBX 模型添加一个网格,包括一个位置,它是 materials 到我程序生成的网格。

我开始想办法了,我会边走边更新和清理这个答案。

CombineInstance可以取一个变换矩阵,在你要组合的网格上设置变换。不幸的是 new Transform 是不可能的,但幸运的是从头开始创建变换矩阵同样容易。

    Matrix4x4 transformMatrix = new Matrix4x4();
    //transformMatrix.SetTRS(position, quaternion, scale)
    transformMatrix.SetTRS(new Vector3(0, 10, 0), Quaternion.Euler(-90, 0, 0), new Vector3(1, 1, 1));

为了使 material 正确,我们需要为每个具有不同 material 的 subMesh 添加相同的网格到数组中的下一个 CombineInstance 索引。

    for (int i = 0; i < customMesh.subMeshCount; i++)
    {
        combine[currentIndex + i].mesh = Instantiate(customMesh);
        combine[currentIndex + i].transform = transformMatrix;
        combine[currentIndex + i].subMeshIndex = i;
    }

然而,这意味着对于每个子网格我们都需要增加我们的 materials 列表,即使子网格使用相同的 materials。在我的例子中,我所有的网格都共享 materials,我最终会以这种方式为每个块得到一个包含数千个元素的数组。

我可能会采用的方式 fix/circumvent 它只是使用纹理来定义道路的不同部分,因此它只有一个纹理和一个 material。对于树和每个块加载所有道路,然后是所有树等。这确实引发了一些问题:

  • 如果我给每个不同的路段赋予它自己的纹理,我需要首先为每个块放置所有路 [0] 然后所有路 [1] 等。
  • 如果我给每个面都赋予它独特的纹理 space 并且稍后想要添加一个额外的部分,我需要将我的 UV space 推到周围或为那个单独的添加一个额外的 material片.

两种选择都不理想。

我能想到的另一种方法是先处理共享 material 元素。就像道路一样,人行道使用混凝土 material,中心使用沥青 material。现在首先对所有第一个(混凝土)子网格道路执行 运行,然后对第二个子网格执行另一个 运行。但这是非常ugly/hacky,不仅你需要确保所有子网格索引共享相同material。如果你也想对建筑物使用混凝土 material,你要么再次获得重复的 material 条目,要么以某种方式需要 运行 在道路(混凝土)之后立即对建筑物(混凝土)进行子网格化子网格。

因为使用大型可平铺 material 或什至只是没有纹理的平面阴影颜色并在需要时重复使用这些 textures/materials 是非常好的和常见的,我仍在寻找解决方案这个。

以下会很好,它确实需要对某些网格进行一些自定义调整。

material[0] = asphalt;
material[1] = concrete;
material[2] = wood;

//Roads
int matIndex = 0;
for (int i = 0; i < customMesh.subMeshCount; i++)
{
    combine[currentIndex + i].mesh = Instantiate(customMesh);
    combine[currentIndex + i].transform = transformMatrix;
    //combine[currentIndex + i].subMeshIndex = i;
    //Instead assign a material index.
    combine[currentIndex + i].materialIndex = matIndex + i;
}

//building
int matIndex = 1;
for (int i = 0; i < customMesh.subMeshCount; i++)
{
    combine[currentIndex + i].mesh = Instantiate(customMesh);
    combine[currentIndex + i].transform = transformMatrix;
    combine[currentIndex + i].materialIndex = matIndex + i;
}