Using render target for pixel colors

If you need to draw exact specific color values in a material from a render target, set the render target’s Texture Group to 2D Pixels (unfiltered)

The format RGBA32f seems to work with least problems. RGBA8 seems ideal in terms of size, but it comes with a number of problems where UE insists on converting between linear and srgb colorspaces, which causes a lot of problems. RGBA32f doesn’t seem to have any of those.

You can read pixels from the RGBA32f render target via ReadLinearColorPixels or maybe ReadPizxels and this will give the same data back as written in. With RGBA8, it appears there’s always some color distortion and the value doesn’t quite match.

UE5 issues

As of UE5, this seems to also require Mip Gen Settings to be set to Unfiltered. If it’s set to anything else (including No Mipmaps) it breaks in shipping and will make the result blurry.

Above may be wrong.

Saving and loading a render target

Export TArray<uint8> from RT:

FRenderTarget* RT = RenderTarget->GameThread_GetRenderTargetResource();
TArray<FColor> Pixels;
RT->ReadPixels(Pixels);
 
int32 RTWidth;
int32 RTHeight;
RenderTarget->GetSize(RTWidth, RTHeight);
 
TArray<uint8> PixelsUint;
FImageUtils::CompressImageArray(RTWidth, RTHeight, Pixels, PixelsUint);

Import TArray<uint8> back into RT:

UCanvas* Canvas;
FVector2D Size;
FDrawToRenderTargetContext Context;
UKismetRenderingLibrary::BeginDrawCanvasToRenderTarget(this, RenderTarget, Canvas, Size, Context);
 
Canvas->K2_DrawTexture(Texture, FVector2D::ZeroVector, Size, FVector2D::ZeroVector, FVector2D::UnitVector, FLinearColor::White, BLEND_Opaque);
 
UKismetRenderingLibrary::EndDrawCanvasToRenderTarget(this, Context);