Hello everyone
After a lot of trial and error, I was able to get the basecolor of the TextureSampleParameter2D used by the material to RenderTarget with the original color.
After drawing the pixel values from the RenderTarget to the Texture, I exported the Texture to a .jpg using the ‘Export to Disk’ node in the Blueprint, and the basecolor was drawn in the original color as expected.
But… The problem is the normalmap.
When I take the normalmap to the RenderTarget, I get a watered down yellow color instead of the original bluish color.
If I draw the Texture with the pixel values from the RenderTarget, and then use the ‘Export to Disk’ node, I get the same watery yellow .jpg file.
I tried all sorts of things in the code, including changing the CompressionSettings and SRGB values, but the normal map was still drawn to the RenderTarget in wash out yellow. Below is my code.
void ADynamicTextureAtlas::CheckNormalColor(UTexture2D* InTexture)
{
TextureCompressionSettings OldCompressionSettings = InTexture->CompressionSettings;
TextureMipGenSettings OldMipGenSettings = InTexture->MipGenSettings;
bool OldSRGB = InTexture->SRGB;
InTexture->CompressionSettings = TextureCompressionSettings::TC_VectorDisplacementmap;
InTexture->MipGenSettings = TextureMipGenSettings::TMGS_NoMipmaps;
InTexture->SRGB = false;
InTexture->UpdateResource();
const FColor* NormalTexture = reinterpret_cast<const FColor*>(InTexture->GetPlatformData()->Mips[0].BulkData.LockReadOnly());
UE_LOG(LogTemp, Log, TEXT("R: %d, G: %d, B: %d, A: %d"), NormalTexture[0].R, NormalTexture[0].G, NormalTexture[0].B, NormalTexture[0].A);
InTexture->GetPlatformData()->Mips[0].BulkData.Unlock();
InTexture->CompressionSettings = OldCompressionSettings;
InTexture->MipGenSettings = OldMipGenSettings;
InTexture->SRGB = OldSRGB;
InTexture->UpdateResource();
}
bool ADynamicTextureAtlas::TestFunction(FString BaseOrNormal, UTextureRenderTarget2D* InputRenderTarget, UTextureRenderTarget2D*& OutRenderTerget)
{
if (!Avatar || !BaseOfDynamicMaterial)
return false;
UCanvas* BaseColorCanvas;
FVector2D SizeOfAtlas(AtlasSize, AtlasSize);
UKismetRenderingLibrary::BeginDrawCanvasToRenderTarget(GetWorld(), InputRenderTarget, BaseColorCanvas, SizeOfAtlas, BaseOrNormalContext);
{
TArray<USceneComponent*> AvatarCompList;
Avatar->GetRootComponent()->GetChildrenComponents(true, AvatarCompList);
for (USceneComponent* Component : AvatarCompList)
{
if (Component->GetName() == TEXT("Torso")) //Torso, Legs, Feet
{
USkeletalMeshComponent* SMComponent = Cast<USkeletalMeshComponent>(Component);
UMaterialInterface* SMCMaterialInterface = SMComponent->GetMaterial(0);
TArray<FMaterialParameterInfo> OutParameterInfo;
TArray<FGuid> OutParameterIds;
SMCMaterialInterface->GetAllTextureParameterInfo(OutParameterInfo, OutParameterIds);
for (const FMaterialParameterInfo& ParaInfo : OutParameterInfo)
{
if (ParaInfo.Name.ToString().Contains(BaseOrNormal)) //base, normal
{
UTexture* TextureForMID;
SMCMaterialInterface->GetTextureParameterValue(ParaInfo, TextureForMID);
//UTexture2D* InTexture = Cast<UTexture2D>(TextureForMID);
//if (InTexture)
// CheckNormalColor(InTexture);
FVector2D ScreenPosition(Row * TextureSize, Column * TextureSize);
FVector2D ScreenSize(TextureSize, TextureSize);
FVector2D CoordinatePosition(0.f, 0.f);
BaseColorCanvas->K2_DrawTexture(TextureForMID, ScreenPosition, ScreenSize, CoordinatePosition, FVector2D::UnitVector, FLinearColor::White, EBlendMode::BLEND_Opaque); //FLinearColor::Transparent, BLEND_Translucent, EBlendMode::BLEND_Opaque
}
}
}
}
}
UKismetRenderingLibrary::EndDrawCanvasToRenderTarget(GetWorld(), BaseOrNormalContext);
OutRenderTerget = InputRenderTarget;
UTexture2D* RTToTexture = UTexture2D::CreateTransient(InputRenderTarget->SizeX, InputRenderTarget->SizeY, PF_B8G8R8A8, FName(*BaseOrNormal));
RTToTexture->CompressionSettings = TextureCompressionSettings::TC_VectorDisplacementmap;
RTToTexture->SRGB = false; //InputRenderTarget->SRGB
#if WITH_EDITORONLY_DATA
RTToTexture->MipGenSettings = TMGS_NoMipmaps;
#endif
RTToTexture->UpdateResource();
TArray<FColor> OutRenderTargetPixel; //FFloat16Color
FRenderTarget* RTResource = InputRenderTarget->GameThread_GetRenderTargetResource();
RTResource->ReadPixels(OutRenderTargetPixel); //RTResource->ReadFloat16Pixels(OutRenderTargetPixel);
uint8* TextureData = reinterpret_cast<uint8*>(RTToTexture->GetPlatformData()->Mips[0].BulkData.Lock(LOCK_READ_WRITE));
{
--TextureData;
//FMemory::Memcpy(TextureData, OutRenderTargetPixel.GetData(), OutRenderTargetPixel.Num());
for (int32 i = 0; i < OutRenderTargetPixel.Num(); ++i)
{
const FColor& Color = OutRenderTargetPixel[i];
*(++TextureData) = Color.B;
*(++TextureData) = Color.G;
*(++TextureData) = Color.R;
*(++TextureData) = Color.A;
}
}
RTToTexture->GetPlatformData()->Mips[0].BulkData.Unlock();
RTToTexture->CompressionSettings = BaseOrNormal == FString("base") ? TextureCompressionSettings::TC_Default : TextureCompressionSettings::TC_Normalmap; //TC_Default, TC_Normalmap, TC_HDR
RTToTexture->SRGB = true; //base is true, normal is false
//RTToTexture->MipGenSettings = TMGS_LeaveExistingMips; //TMGS_FromTextureGroup
RTToTexture->UpdateResource();
if (BaseOrNormal == FString("base"))
AvatarTextureAtlas.BaseColorTex = RTToTexture;
else
AvatarTextureAtlas.NormalTex = RTToTexture;
return true;
}
I was so frustrated that I checked the pixel colors of the normalmap before it was drawn to the RenderTarget, but of course they were the same as the original colors.
When I checked the pixel values of the RenderTarget in ‘RTResource->ReadPixels(OutRenderTargetPixel)’, the B value of RGB became 0 and the RG value was also different from the original.
I’m wondering how on earth I can get the normalmap colors to be drawn to the RenderTarget as they were originally…!
I’m anxiously waiting for your help ;_;