UE4 生成Lightmap uv算法

到了在这里,我们将进行建立光照图uv

最重要的工具类类是FLayoutUV,其工作流程分为三步

  1. Packer.SetVersion(LightmapUVVersion);

  2. Packer.FindCharts(OverlappingCorners);

  3. Packer.FindBestPacking(MinLightmapResolution);

Version

Version就是上图中的那个version,其是一个枚举类型如下

在这里我们使用的是ForceLightmapPadding = 7,所以也就是说这个类有更多的东西需要我们来挖掘。

Chart

这里的FOverlappingCorners是所有重叠的角落,是通过

FindCharts

FMeshChart

MeshChart是一个

  1. struct FMeshChart

  2. {

  3. uint32 FirstTri;

  4. uint32 LastTri;

  5. FVector2D MinUV;

  6. FVector2D MaxUV;

  7. float UVArea;

  8. FVector2D UVScale;

  9. FVector2D WorldScale;

  10. FVector2D PackingScaleU;

  11. FVector2D PackingScaleV;

  12. FVector2D PackingBias;

  13. int32 Join[4];

  14. int32 Id;

  15. }

首先我们要知道的是,其实我们的光照UV是需要一套原UV来进行生成的。

所以,第一步就是得到另一套所有的uv

  1. TexCoords.SetNumUninitialized( NumIndexes );

  2. for( uint32 i = 0; i < NumIndexes; i++ )

  3. {

  4. TranslatedMatches[i] = -1;

  5. TexCoords[i] = MeshView.GetInputTexcoord(i);

  6. }

之后,我们将进行DisjointSet的结构填充

FDisjointSet意为,不相交的一组,我们接下来其实就是构建

对于整个mesh里面的每一个Indice,我们都要判断其是否拥有重叠

  1. 如果有重叠的话,我们还要判断这个在这么一个OverlappingCorners中,有哪些是跟自己的位置能够匹配的,也就是看这两个地方是否是极其接近,说实话,这之前OverlappingCorners不就是一重判断了嘛,为什么这里还要进行一次判断,难道这里的相近的意思不一致嘛。

  1. 如果我们能在OverlappingCorners中找到,有一个点和自己的比较相近,自己的命名为i,另外的一个为j。会将这个index所在的三角形中的另外的两个点找到,对于i,i1,i2,;j,j1,j2。然后再position的范围内,比较

  2. bool bEdgeMatch21 = PositionsMatch( i2, j1 );

  3. bool bEdgeMatch12 = PositionsMatch( i1, j2 );

  4. 这里是判断是否拥有共边,如果有共边的话,将共边的另一个点为ie,je,我们将那么我们看i,j,和ie,je这两个点的uv是否一致是否这两个三角形的uv是在一起的。

  5. 如果共边(这里的共边指的是原uv里面这两个边是否是相同的位置),将bUnion=true,也就是说这里可以当作一个简单的相连的集合加入到DisjointSet

  6. 如果不共边,我们就看这个i,j,和ie,je顶点的normal,如果normal是一致的,那么我们就可以说这两个三角形是共面的,计算

  7. FVector2D EdgeUVi = TexCoords[ie] - TexCoords[i];

  8. FVector2D EdgeUVj = TexCoords[je] - TexCoords[j];

  9. bool bTranslatedUVMatch = ( EdgeUVi - EdgeUVj ).IsNearlyZero(UVLAYOUT_THRESH_UVS_ARE_SAME);

如果这两个的差接近0,那么我们就能觉得这里的两个边空间位置相同,uv长度相同,那么我们将其加入TranslatedMatches

  1. 如果这个两个三角形连法线都不是在一起的。也就是不在一个平面,那么我们不做其他操作

之后,进行排序,这里是再SortedTris里面记录DisjointSet里面的i

  1. 对每一个三角形,建立 chart,也就是每一个三角形都会拥有一个chat,一开始的chat都是初始化的操作。填充DisjointSetToChartMap

  2. 建立完每一个chat后,