|
LightMap数据及文件自定义优化处理
这一步其实很简单,但是如果有时间做的更完善的话可以在BakeLightMap WorldSettings中增加自定义配置选项,以更加灵活的在移动端生成自己想要的数据。
UnrealEngine\Engine\Source\Runtime\Engine\Private\LightMap.cpp
void FLightMapPendingTexture::CreateUObjects()
{
...
if (bIncludeNonVirtualTextures)
{...}
...
}
我们定位到此Function可以看到有VT和不带VT的两种处理方式,我们目前只看不带VT的处理方式。if(bIncludeNonVirtualTextures){...}这里主要有SkyOcclusionTexture,AOMaterialMaskTexture,ShadowMapTexture,Textures.几个部分要处理。在移动端可以根据项目需求自己去灵配置调整自己的需求,比如有的项目就把ShadowMap和LightTextures整合到一起,LightTextures上半部分是LightMapColor,下半部分是Shadow等等。
if (bIncludeNonVirtualTextures)
{
if (NeedsSkyOcclusionTexture())
{
SkyOcclusionTexture = NewObject<ULightMapTexture2D>(Outer, GetSkyOcclusionTextureName(GLightmapCounter));
}
if (NeedsAOMaterialMaskTexture())
{
AOMaterialMaskTexture = NewObject<ULightMapTexture2D>(Outer, GetAOMaterialMaskTextureName(GLightmapCounter));
}
if (NeedsStaticShadowTexture())
{
ShadowMapTexture = NewObject<UShadowMapTexture2D>(Outer, GetShadowTextureName(GLightmapCounter));
}
//以上三项,可以自己配置到WorldSettings面板里加自定义参数,或者直接在对应方法里返回T o F.
//返回F的直接就不生成了,就很简单。
// Encode and compress the coefficient textures.
for (uint32 CoefficientIndex = 0; CoefficientIndex < NUM_STORED_LIGHTMAP_COEF; CoefficientIndex += 2)
{
Textures[CoefficientIndex] = nullptr;
// Skip generating simple lightmaps if wanted.
static const auto CVarSupportLowQualityLightmaps = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT(&#34;r.SupportLowQualityLightmaps&#34;));
const bool bAllowLowQualityLightMaps = (!CVarSupportLowQualityLightmaps) || (CVarSupportLowQualityLightmaps->GetValueOnAnyThread() != 0);
if ((!bAllowLowQualityLightMaps) && CoefficientIndex >= LQ_LIGHTMAP_COEF_INDEX)
{
continue;
}
// Create the light-map texture for this coefficient.
if (CoefficientIndex >= NUM_HQ_LIGHTMAP_COEF) {
auto Texture = NewObject<ULightMapTexture2D>(Outer, GetLightmapName(GLightmapCounter, CoefficientIndex));
Textures[CoefficientIndex] = Texture;
//LQ的LightMap在此~~
}
else
{
//HQ的在此,也可以通过配置~
}
}
}
接下来定位到:EncodeCoefficientTexture()
void FLightMapPendingTexture::EncodeCoefficientTexture(int32 CoefficientIndex, UTexture* Texture, uint32 LayerIndex, const FColor& TextureColor, bool bEncodeVirtualTexture)
{
...
}
这和Function就是主要是编码LightMap的地方,UE默认的情况下会把LightMap上半部分编码为LightMapColor,下半部分编码为LightMapDirectionality。材质面板中可以配置这个材质是否使用LightMapDirectionality。如果不需要的话我们可以把这部分对应的shader一并优化一下。
接下来我们开始捋一捋EncodeCoefficientTexture()的代码。
代码段首先是定义基础文件格式,如果你不用Alpha通道,则CompressionNoAlpha =true;
我们现在是用了A通道,所以是FALSE,现在A通道写全局AO的,当然你也可以放到下半部分,都可以,增加一次采样,节省了空间。
LightMap格式以及AO等都不是SRGB的要注意一下。所以SRGB是FALSE。
这里面也有处理VT的部分,我们针对移动端的部分目前暂不考虑VT的部分。如果你需要用下半部分mipData1,MipCoverageData1就保留。
// Lock all mip levels.
FColor* MipData0[MAX_TEXTURE_MIP_COUNT] = { 0 };
//FColor* MipData1[MAX_TEXTURE_MIP_COUNT] = { 0 };
int8* MipCoverageData0[MAX_TEXTURE_MIP_COUNT] = { 0 };
//int8* MipCoverageData1[MAX_TEXTURE_MIP_COUNT] = { 0 };
{
const int32 StartBottom = GetSizeX() * GetSizeY();
for (int32 MipIndex = 0; MipIndex < NumMips; ++MipIndex)
{
const int32 MipSizeX = FMath::Max(1, TextureSizeX >> MipIndex);
const int32 MipSizeY = FMath::Max(1, TextureSizeY >> MipIndex);
MipData0[MipIndex] = (FColor*)Texture->Source.LockMip(0, LayerIndex, MipIndex);
MipCoverageData0[MipIndex] = (int8*)FMemory::Malloc(MipSizeX * MipSizeY);
/*if (bEncodeVirtualTexture)
{
// 2 coefficients are stored on adjacent VT layers
MipData1[MipIndex] = (FColor*)Texture->Source.LockMip(0, LayerIndex + 1, MipIndex);
MipCoverageData1[MipIndex] = (int8*)FMemory::Malloc(MipSizeX * MipSizeY);
}
else
{
// 2 coefficients are stored on the top/bottom halves of the same destination texture
MipData1[MipIndex] = MipData0[MipIndex] + StartBottom;
MipCoverageData1[MipIndex] = MipCoverageData0[MipIndex] + StartBottom;
}*/
}
}
接下来看RGBA通道写数据的部分,A通道写入AO,注掉了下半部分的内容。当然你也可以把下半部分写入其他内容。但是。每调整一个小地方,对应的整体很多地方都要做相应的调整,UV,Shader部分等等。。。
for (int32 Y = Allocation->MappedRect.Min.Y; Y < Allocation->MappedRect.Max.Y; ++Y)
{
for (int32 X = Allocation->MappedRect.Min.X; X < Allocation->MappedRect.Max.X; ++X)
{
const FLightMapCoefficients& SourceCoefficients = Allocation->RawData[Y * Allocation->TotalSizeX + X];
int32 DestY = Y - Allocation->MappedRect.Min.Y + Allocation->OffsetY;
int32 DestX = X - Allocation->MappedRect.Min.X + Allocation->OffsetX;
FColor& DestColor = MipData0[0][DestY * TextureSizeX + DestX];
int8& DestCoverage = MipCoverageData0[0][DestY * TextureSizeX + DestX];
// modify by zhoujie remove dirLightNormal;
//FColor& DestBottomColor = MipData1[0][DestX + DestY * TextureSizeX];
// int8& DestBottomCoverage = MipCoverageData1[0][DestX + DestY * TextureSizeX];
#if VISUALIZE_PACKING
if (X == Allocation->MappedRect.Min.X || Y == Allocation->MappedRect.Min.Y ||
X == Allocation->MappedRect.Max.X - 1 || Y == Allocation->MappedRect.Max.Y - 1 ||
X == Allocation->MappedRect.Min.X + 1 || Y == Allocation->MappedRect.Min.Y + 1 ||
X == Allocation->MappedRect.Max.X - 2 || Y == Allocation->MappedRect.Max.Y - 2)
{
DestColor = FColor::Red;
}
else
{
DestColor = FColor::Green;
}
#else // VISUALIZE_PACKING
//RGBA通道编码在这里,A通道写入了AOMaterialMask。
DestColor.R = SourceCoefficients.Coefficients[CoefficientIndex][0];
DestColor.G = SourceCoefficients.Coefficients[CoefficientIndex][1];
DestColor.B = SourceCoefficients.Coefficients[CoefficientIndex][2];
DestColor.A = SourceCoefficients.AOMaterialMask;
//下半部分内容清理,当然你可以写入你想要的其他内容。
// DestBottomColor.R = SourceCoefficients.Coefficients[CoefficientIndex + 1][0];
// DestBottomColor.G = SourceCoefficients.Coefficients[CoefficientIndex + 1][1];
// DestBottomColor.B = SourceCoefficients.Coefficients[CoefficientIndex + 1][2];
// DestBottomColor.A = SourceCoefficients.Coefficients[CoefficientIndex + 1][3];
if (GVisualizeLightmapTextures)
{
DestColor = TextureColor;
}
// uint8 -> int8
//DestCoverage = DestBottomCoverage = SourceCoefficients.Coverage / 2;
DestCoverage = SourceCoefficients.Coverage / 2;
if (SourceCoefficients.Coverage > 0)
{
NumLightmapMappedTexels++;
}
else
{
NumLightmapUnmappedTexels++;
}
以上就是几个LightMap处理的关键的点。
最后LightMap.cpp里红框的几个Function可以多读读。
最后大家要怎么玩(′‵) 看融汇能力咯~
最后插入之前发布的视频。
后续会将怎么自定义天光的参数,通过自定义的天光参数调整全局的LightMap GI和AO以及ILC等部分。 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|