The FLinearColor implementation for FVulkanDynamicRHI is incorrect. FLinearColor stores 32 bit floats in linear space, while FColor stores 8 bit integers encoded with sRGB applied. The implementation for RHIReadSurfaceData in the Vulkan RHI layer reads the data back from the GPU as linear, converts it to FColor, then converts it back to FLinearColor, which drops a large amount of precision of the underlying data.

void FVulkanDynamicRHI::RHIReadSurfaceData(FRHITexture* TextureRHI, FIntRect Rect, TArray<FLinearColor>& OutData, FReadSurfaceDataFlags InFlags)
	TArray<FColor> FromColorData;
	RHIReadSurfaceData(TextureRHI, Rect, FromColorData, InFlags);
	for (int Index = 0, Num = FromColorData.Num(); Index < Num; Index++)
		OutData[Index] = FLinearColor(FromColorData[Index]);
Steps to Reproduce

See implementation of FVulkanDynamicRHI::RHIReadSurfaceData.

Have Comments or More Details?

There's no existing public thread on this issue, so head over to Questions & Answers just mention UE-208863 in the post.

Login to Vote

ComponentUE - Rendering Architecture - RHI
Affects Versions5.3
Target Fix5.5
CreatedMar 4, 2024
UpdatedMar 11, 2024