The reason RGBA8 works is because it and FloatRGBA are the only supported texture formats for these functions. Here’s a relevant code snippet:
FColor UKismetRenderingLibrary::ReadRenderTargetPixel(UObject* WorldContextObject, UTextureRenderTarget2D* TextureRenderTarget, int32 X, int32 Y)
{
TArray<FColor> Samples;
TArray<FLinearColor> LinearSamples;
switch (ReadRenderTargetHelper(Samples, LinearSamples, WorldContextObject, TextureRenderTarget, X, Y, 1, 1))
{
case PF_B8G8R8A8:
check(Samples.Num() == 1 && LinearSamples.Num() == 0);
return Samples[0];
case PF_FloatRGBA:
check(Samples.Num() == 0 && LinearSamples.Num() == 1);
return LinearSamples[0].ToFColor(true);
case PF_Unknown:
default:
return FColor::Red;
}
}
Notice how it returns Red for unsupported formats.
As for performance, this method is going to be sloow regardless, especially if you’re doing it with just BP. If you write some custom C++, you can look at the source code and find it’s making a sample rectangle of width 1 and height 1. Maybe you can give it a bigger rect and perform 1 large sample vs tons of small 1 pixel ones? There’s probably a better way tbh.