How to create UCanvas object without using BeginDrawCanvasToRenderTarget()
Hello!
I am working on combining the base color texture and normal map texture used in a material for an avatar’s clothing into each single texture.
To do this I am using a TextureRenderTarget and a UCanvas. Below is the code.
UCanvas* BaseColorCanvas;
BaseRenderTarget = UKismetRenderingLibrary::CreateRenderTarget2D(GetWorld(), AtlasSize, AtlasSize);
UKismetRenderingLibrary::ClearRenderTarget2D(GetWorld(), BaseRenderTarget, FLinearColor::Transparent);
UCanvas* NormalCanvas;
NormalRenderTarget = UKismetRenderingLibrary::CreateRenderTarget2D(GetWorld(), AtlasSize, AtlasSize);
UKismetRenderingLibrary::ClearRenderTarget2D(GetWorld(), NormalRenderTarget, FLinearColor::Transparent);
FVector2D SizeOfAtlas(AtlasSize, AtlasSize);
UKismetRenderingLibrary::BeginDrawCanvasToRenderTarget(GetWorld(), BaseRenderTarget, BaseColorCanvas, SizeOfAtlas, BaseColorContext);
UKismetRenderingLibrary::BeginDrawCanvasToRenderTarget(GetWorld(), NormalRenderTarget, NormalCanvas, SizeOfAtlas, NormalContext);
TArray<USceneComponent*> AvatarCompList;
Avatar->GetRootComponent()->GetChildrenComponents(true, AvatarCompList);
for (auto Component : AvatarCompList)
{
for (FString ChildComp : BodyComponents)
{
if (Component->GetName() == ChildComp)
{
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(TEXT("base")))
DrawMaterialToRenderTargetNMakeTexture(Component->GetName(), SMCMaterialInterface, ParaInfo, BaseColorCanvas);
else if (ParaInfo.Name.ToString().Contains(TEXT("normal")))
DrawMaterialToRenderTargetNMakeTexture(Component->GetName(), SMCMaterialInterface, ParaInfo, NormalCanvas);
}
++Row;
if (Row == RowNColumnMaxNum)
{
Row = 0;
++Column;
}
}
}
}
UKismetRenderingLibrary::EndDrawCanvasToRenderTarget(GetWorld(), BaseColorContext);
UKismetRenderingLibrary::EndDrawCanvasToRenderTarget(GetWorld(), NormalContext);
When I checked the output, the base color texture that should have been drawn in the BaseRenderTarget was drawn in the NormalRenderTarget. The BaseRenderTarget was empty with a clear color.
During the debugging process, I discovered that the BaseColorCanvas and NormalCanvas were pointing to the same UCanvas object after passing through UKismetRenderingLibrary::BeginDrawCanvasToRenderTarget(). This happens because the UCanvas parameter passed to UKismetRenderingLibrary::BeginDrawCanvasToRenderTarget() is assigned a variable ‘CanvasForRenderingToTarget’ of UWorld.
So it looks like I need to create two UCanvas objects without using UKismetRenderingLibrary::BeginDrawCanvasToRenderTarget() to draw the base color texture and normal map texture properly.
I’m wondering if I’m on the right track and need some clues on how to accomplish my goal.
It looks like I need to use NewObject() to create a UCanvas directly, but then I have no idea how to replace UKismetRenderingLibrary::EndDrawCanvasToRenderTarget().
If anyone with a clue to my predicament could post, I’d really, really appreciate it! :)///