UE4 生成Lightmap uv算法
到了在这里,我们将进行建立光照图uv
最重要的工具类类是FLayoutUV,其工作流程分为三步
-
Packer.SetVersion(LightmapUVVersion);
-
Packer.FindCharts(OverlappingCorners);
-
Packer.FindBestPacking(MinLightmapResolution);
Version
Version就是上图中的那个version,其是一个枚举类型如下
在这里我们使用的是ForceLightmapPadding =
7,所以也就是说这个类有更多的东西需要我们来挖掘。
Chart
这里的FOverlappingCorners是所有重叠的角落,是通过
FindCharts
FMeshChart
MeshChart是一个
-
struct FMeshChart
-
{
-
uint32 FirstTri;
-
uint32 LastTri;
-
FVector2D MinUV;
-
FVector2D MaxUV;
-
float UVArea;
-
FVector2D UVScale;
-
FVector2D WorldScale;
-
FVector2D PackingScaleU;
-
FVector2D PackingScaleV;
-
FVector2D PackingBias;
-
int32 Join[4];
-
int32 Id;
-
}
首先我们要知道的是,其实我们的光照UV是需要一套原UV来进行生成的。
所以,第一步就是得到另一套所有的uv
-
TexCoords.SetNumUninitialized( NumIndexes );
-
for( uint32 i = 0; i < NumIndexes; i++ )
-
{
-
TranslatedMatches[i] = -1;
-
TexCoords[i] = MeshView.GetInputTexcoord(i);
-
}
之后,我们将进行DisjointSet的结构填充
FDisjointSet意为,不相交的一组,我们接下来其实就是构建
对于整个mesh里面的每一个Indice,我们都要判断其是否拥有重叠
- 如果有重叠的话,我们还要判断这个在这么一个OverlappingCorners中,有哪些是跟自己的位置能够匹配的,也就是看这两个地方是否是极其接近,说实话,这之前OverlappingCorners不就是一重判断了嘛,为什么这里还要进行一次判断,难道这里的相近的意思不一致嘛。
-
如果我们能在OverlappingCorners中找到,有一个点和自己的比较相近,自己的命名为i,另外的一个为j。会将这个index所在的三角形中的另外的两个点找到,对于i,i1,i2,;j,j1,j2。然后再position的范围内,比较
-
bool bEdgeMatch21 = PositionsMatch( i2, j1 );
-
bool bEdgeMatch12 = PositionsMatch( i1, j2 );
-
这里是判断是否拥有共边,如果有共边的话,将共边的另一个点为ie,je,我们将那么我们看i,j,和ie,je这两个点的uv是否一致是否这两个三角形的uv是在一起的。
-
如果共边(这里的共边指的是原uv里面这两个边是否是相同的位置),将bUnion=true,也就是说这里可以当作一个简单的相连的集合加入到DisjointSet中
-
如果不共边,我们就看这个i,j,和ie,je顶点的normal,如果normal是一致的,那么我们就可以说这两个三角形是共面的,计算
-
FVector2D EdgeUVi = TexCoords[ie] - TexCoords[i];
-
FVector2D EdgeUVj = TexCoords[je] - TexCoords[j];
-
bool bTranslatedUVMatch = ( EdgeUVi - EdgeUVj ).IsNearlyZero(UVLAYOUT_THRESH_UVS_ARE_SAME);
如果这两个的差接近0,那么我们就能觉得这里的两个边空间位置相同,uv长度相同,那么我们将其加入TranslatedMatches
- 如果这个两个三角形连法线都不是在一起的。也就是不在一个平面,那么我们不做其他操作
之后,进行排序,这里是再SortedTris里面记录DisjointSet里面的i
-
对每一个三角形,建立 chart,也就是每一个三角形都会拥有一个chat,一开始的chat都是初始化的操作。填充DisjointSetToChartMap
-
建立完每一个chat后,