UE4 LightMap 记录

// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.

#include "ExportLMBPLibrary.h"
#include "ExportLM.h"
#include "Runtime/Engine/Classes/Engine/Engine.h"
#include "Editor.h"
#include "Runtime/Core/Public/Logging/LogMacros.h"
#include "Runtime/Engine/Classes/Exporters/Exporter.h"
#include "Runtime/Engine/Public/AssetExportTask.h"
#include "Runtime/CoreUObject/Public/UObject/GCObjectScopeGuard.h"
#include "Runtime/Renderer/Private/ScenePrivate.h"
#include "Runtime/RHI/Public/RHIResources.h"
#include "Runtime/Json/Public/Json.h"
#include "Runtime/Engine/Public/ImageUtils.h"
#include "Runtime/ImageWrapper/Public/IImageWrapper.h"
#include "Runtime/ImageWrapper/Public/IImageWrapperModule.h"
#include "Runtime/ImageWrapper/Private/ImageWrapperBase.h"
#include "Runtime/Engine/Classes/Engine/TextureRenderTarget2D.h"
#include "Runtime/RenderCore/Public/RenderUtils.h"
#include "Runtime/Core/Public/Math/Color.h"
#include "Runtime/CoreUObject/Public/Serialization/BulkData.h"
#include "Runtime/Engine/Public/ShadowMap.h"


UExportLMBPLibrary::UExportLMBPLibrary(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{

}

float UExportLMBPLibrary::ExportLMSampleFunction(float Param)
{
	return -1;
}

void SetValue(FColor* OutImageBytes, const UTexture2D* LMTexture2D, int32 SX, int32 SY, ETextureSourceFormat CurrFormat)
{
	

	/*Texture->CompressionSettings = OldCompressionSettings;
	Texture->MipGenSettings = OldMipGenSettings;
	Texture->SRGB = OldSRGB;
	Texture->UpdateResource();*/


	//2
	//UTexture2D* abc = (UTexture2D*)LMTexture2D;
	//FTexture2DMipMap* MyMipMap = &abc->PlatformData->Mips[0];
	//UE_LOG(LogTemp, Warning, TEXT("name: %d"), MyMipMap->SizeX);
	//
	//FByteBulkData* RawImageData = &MyMipMap->BulkData;
	//UE_LOG(LogTemp, Warning, TEXT("name: %s"), *(RawImageData->GetFilename()));
	//void* a = RawImageData->Lock(LOCK_READ_ONLY);
	FColor* FormatedImageData = static_cast<FColor*>(RawImageData->Lock(LOCK_READ_ONLY));
	//if (a == nullptr)
	//{
	//	UE_LOG(LogTemp, Warning, TEXT("name: %s"), *(FString("nullptr")));
	//}
	//RawImageData->Unlock();
	//abc->UpdateResource();
	
	TArray< FColor > SurfaceData ;
	SurfaceData.Empty();
	SurfaceData.AddZeroed(SX * SY);
	UTexture2D* MyTexture2D = (UTexture2D*)LMTexture2D;
	TextureCompressionSettings OldCompressionSettings = MyTexture2D->CompressionSettings; 
	TextureMipGenSettings OldMipGenSettings = MyTexture2D->MipGenSettings; 
	bool OldSRGB = MyTexture2D->SRGB;

	MyTexture2D->CompressionSettings = TextureCompressionSettings::TC_VectorDisplacementmap;
	MyTexture2D->MipGenSettings = TextureMipGenSettings::TMGS_NoMipmaps;
	MyTexture2D->SRGB = false;
	MyTexture2D->UpdateResource();

	const FColor* FormatedImageData = static_cast<const FColor*>(MyTexture2D->PlatformData->Mips[0].BulkData.LockReadOnly());
	if (FormatedImageData == nullptr)
	{
		UE_LOG(LogTemp, Warning, TEXT("name: %s"), *(FString("nullptr")));
	}

	switch (CurrFormat)
	{
	case TSF_BGRA8:
		for (int32 X = 0; X < SX; X++)
		{
			for (int32 Y = 0; Y < SY; Y++)
			{
				SurfaceData[Y * SX + X] = FormatedImageData[Y * SX + X];
			}
		}
		break;
	case TSF_G8:
		TArray<FColor> tc;
		for (int32 x = 0; x < SX *SY / 4; x++)
		{
			{
				FColor c = FormatedImageData[x];
				FColor r = FColor(c.R, c.R, c.R, c.R);
				FColor g = FColor(c.G, c.G, c.G, c.G);
				FColor b = FColor(c.B, c.B, c.B, c.B);
				FColor a = FColor(c.A, c.A, c.A, c.A);
				tc.Add(r);
				tc.Add(g);
				tc.Add(b);
				tc.Add(a);

			}
		}

		for (int32 X = 0; X < SX; X++)
		{
			for (int32 Y = 0; Y < SY; Y++)
			{
				//FColor PixelColor = FormatedImageData[0];
				 Do the job with the pixel
				/*int r = int(FMath::RandRange(0, 255));
				int g = int(FMath::RandRange(0, 255));
				int b = int(FMath::RandRange(0, 255));
				int a = int(FMath::RandRange(0, 255));
				FColor text = FColor(r,g,b,a);*/
				//SurfaceData[Y * SX + X] = text;
				//FColor c = FormatedImageData[Y * SX + X];

				SurfaceData[Y * SX + X] = tc[Y * SX + X];
			}
		}
		break;
	}

	/*FColor PixelColor1 = FormatedImageData[SX*SY-1];
	UE_LOG(LogTemp, Warning, TEXT("name: %s"), *(PixelColor1.ToString()));*/
	/*for (int32 i = 0; i < 100; i++)
	{
		FColor PixelColor1 = FormatedImageData[i];
	    UE_LOG(LogTemp, Warning, TEXT("name: %s"), *(PixelColor1.ToString()));
	}*/
	

	//----not use-----
	/*for (int32 i = 0; i < ImageBytes; ++i)
	{
		SurfaceData.Add(FormatedImageData[i]);
	}*/
	//OutImageData = FormatedImageData->ReinterpretAsLinear();
	//----not use-----
	if (SurfaceData.Num() > 0)
	{
		FMemory::Memcpy(OutImageBytes, &SurfaceData[0], SurfaceData.Num() * sizeof(FColor));
		//UE_LOG(LogTemp, Warning, TEXT("name: %d"), SurfaceData.Num());
	}
	
	LMTexture2D->PlatformData->Mips[0].BulkData.Unlock();
}

void ExportExr(UTexture2D* LMTexture2D, ETextureSourceFormat CurrFormat,FString FileNameExr)
{
	if (LMTexture2D != nullptr)
	{
		FIntPoint Size(LMTexture2D->GetSizeX(), LMTexture2D->GetSizeY());
		TArray64<uint8> RawData;
		//int32 ImageBytes = LMTexture2D->Source.GetSizeOnDisk();
		int32 ImageBytes = Size.X*Size.Y*sizeof(FColor);
		//UE_LOG(LogTemp, Warning, TEXT("name: %d"), ImageBytes);
		RawData.AddUninitialized(ImageBytes);

		SetValue((FColor*)RawData.GetData(), LMTexture2D, Size.X, Size.Y, CurrFormat);

		int32 BitsPerPixel = 8;
		ERGBFormat RGBFormat = ERGBFormat::BGRA;
		switch (CurrFormat)
		{
		case TSF_BGRA8:
			BitsPerPixel = 8;
			RGBFormat = ERGBFormat::BGRA;
			break;
		case TSF_G8:
			BitsPerPixel = 8;
			//RGBFormat = ERGBFormat::Gray;
			break;
		}

		IImageWrapperModule& ImageWrapperModule = FModuleManager::Get().LoadModuleChecked<IImageWrapperModule>(TEXT("ImageWrapper"));

		TSharedPtr<IImageWrapper> EXRImageWrapper = ImageWrapperModule.CreateImageWrapper(EImageFormat::EXR);

		if (RawData.GetData() != NULL)
		{
			EXRImageWrapper->SetRaw(RawData.GetData(), RawData.GetAllocatedSize(), Size.X, Size.Y, RGBFormat, BitsPerPixel);

			const TArray<uint8>& Data = EXRImageWrapper->GetCompressed(100);
			//UE_LOG(LogTemp, Warning, TEXT("name: %s %d"), *FileNameExr, (Data).Num());
			FFileHelper::SaveArrayToFile(Data, *FileNameExr);
		}
		else
		{
			UE_LOG(LogTemp, Warning, TEXT("name: %s"), *FString("RawData is empty"));
		}


		//if (TexRT->GetFormat() == PF_B8G8R8A8 || TexRT->GetFormat() == PF_FloatRGBA)
		if (LMTexture2D->Source.GetFormat() == TSF_BGRA8)
		{
			//UE_LOG(LogTemp, Warning, TEXT("nameX: %d"), Size.X);
			/*UE_LOG(LogTemp, Warning, TEXT("nameY: %d"), Size.Y);
			UE_LOG(LogTemp, Warning, TEXT("nameT: %d"), ImageBytes);*/

		}
	}
}

TArray<float> ConvertFVector4ToArray(FVector4 &Data)
{
	TArray<float> Result;
	Result.Add(Data.X);
	Result.Add(Data.Y);
	Result.Add(Data.Z);
	Result.Add(Data.W);
	return Result;
}

void UExportLMBPLibrary::ExportLMAll(FString ExportPath)
{
	FWorldContext& Context = GEditor->GetEditorWorldContext();
	UWorld* World = Context.World();
	if (World)
	{
		TArray<UTexture2D*> LightMapsAndShadowMaps;
		World->GetLightMapsAndShadowMaps(World->GetCurrentLevel(), LightMapsAndShadowMaps);
		//UE_LOG(LogTemp, Warning, TEXT("LightMapsAndShadowMaps: %d"), LightMapsAndShadowMaps.Num());
		FText lable = FText::FromString("Exporting exr...");
		FScopedSlowTask Progress(float(LightMapsAndShadowMaps.Num()), lable, true);
		Progress.MakeDialog(true, true);
		for (auto ObjIt = LightMapsAndShadowMaps.CreateConstIterator(); ObjIt; ++ObjIt)
		{
			if (Progress.ShouldCancel())
			{
				break;
			}
			Progress.EnterProgressFrame(1.f);

			UTexture2D* CurrentObject = *ObjIt;

			if (CurrentObject)
			{
				FString ObjectName = CurrentObject->GetName();
				if (ObjectName.StartsWith("HQ_"))
				{
					ExportExr(CurrentObject, TSF_BGRA8, ExportPath + "/HQ/" + ObjectName+".exr");
				}
			}
		}
	}
}

void UExportLMBPLibrary::ExportLMSceneData(FString ExportPath, bool IsExportExr)
{
	if (IsExportExr)
	{
		ExportLMAll(ExportPath);
	}
	
	FWorldContext& Context = GEditor->GetEditorWorldContext();
	UWorld* World = Context.World();
	if (World)
	{
		FScene* Scene = (FScene*)(World->Scene);
		FString JsonOutString;
		TSharedRef<TJsonWriter<TCHAR, TCondensedJsonPrintPolicy<TCHAR>>> Writer = TJsonWriterFactory< TCHAR, TCondensedJsonPrintPolicy<TCHAR> >::Create(&JsonOutString);
		Writer->WriteObjectStart();
		int32 PSPNum = Scene->PrimitiveSceneProxies.Num();
		FText lable = FText::FromString("Exporting lightmap config...");
		FScopedSlowTask Progress(float(PSPNum), lable, true);
		Progress.MakeDialog(true, true);
		for (int32 Index = 0; Index < PSPNum; Index++)
		{
			if (Progress.ShouldCancel())
			{
				break;
			}
			Progress.EnterProgressFrame(1.f);
			FPrimitiveSceneProxy* PrimitiveSceneProxy = Scene->PrimitiveSceneProxies[Index];

			FPrimitiveSceneProxy::FLCIArray LCIs;
			PrimitiveSceneProxy->GetLCIs(LCIs);

			check(LCIs.Num() == PrimitiveSceneProxy->GetPrimitiveSceneInfo()->GetNumLightmapDataEntries());
			
			int32 LightmapDataOffset = PrimitiveSceneProxy->GetPrimitiveSceneInfo()->GetLightmapDataOffset();
			FString ResourceName = PrimitiveSceneProxy->GetResourceName().ToString();
			FString OwnerName = PrimitiveSceneProxy->GetOwnerName().ToString();
			Writer->WriteObjectStart(OwnerName);
			Writer->WriteValue(L"ResourceName", ResourceName);
			//Writer->WriteValue(L"LightmapDataIndex", LightmapDataOffset);
			
			if (LCIs.Num() > 0)
			{
				const FLightMap* LightMap = LCIs[0]->GetLightMap();
				if (LightMap)
				{
					const ULightMapTexture2D* LMTexture2D = LightMap->GetInteraction(ERHIFeatureLevel::SM5).GetTexture(true);
					FString LMName = LMTexture2D->GetName();
					Writer->WriteValue(L"LightmapName", LMName);

					FLightmapSceneShaderData LightmapSceneData(LCIs[0], Scene->GetFeatureLevel());
					//Writer->WriteObjectStart(L"LightMapSceneData");
					/*Writer->WriteValue(L"StaticShadowMapMasks", LightmapSceneData.Data[0].ToString());
					Writer->WriteValue(L"InvUniformPenumbraSizes", LightmapSceneData.Data[1].ToString());
					Writer->WriteValue(L"LightMapCoordinateScaleBias", LightmapSceneData.Data[2].ToString());
					Writer->WriteValue(L"ShadowMapCoordinateScaleBias", LightmapSceneData.Data[3].ToString());*/
					Writer->WriteValue(L"LightMapCoordinateScaleBias", ConvertFVector4ToArray(LightmapSceneData.Data[2]));
					Writer->WriteValue(L"LightMapScale0", ConvertFVector4ToArray(LightmapSceneData.Data[4]));
					Writer->WriteValue(L"LightMapScale1", ConvertFVector4ToArray(LightmapSceneData.Data[5]));
					Writer->WriteValue(L"LightMapAdd0", ConvertFVector4ToArray(LightmapSceneData.Data[6]));
					Writer->WriteValue(L"LightMapAdd1", ConvertFVector4ToArray(LightmapSceneData.Data[7]));
					//Writer->WriteObjectEnd();
				}
			}
			Writer->WriteObjectEnd();
		}
		Writer->WriteObjectEnd();
		Writer->Close();
		FFileHelper::SaveStringToFile(JsonOutString, *ExportPath.Append("/LightMapConfig.json"));
	}
}

猜你喜欢

转载自blog.csdn.net/sh15285118586/article/details/120891069
今日推荐