Description

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);
	OutData.SetNumUninitialized(FromColorData.Num());
	for (int Index = 0, Num = FromColorData.Num(); Index < Num; Index++)
	{
		OutData[Index] = FLinearColor(FromColorData[Index]);
	}
}
Steps to Reproduce

Reach out to Ryan Mayeda for a test project that he used to validate that things were broken and that this change fixed them.

Here are the repro steps:

  1. Download open the attached project (LinuxRenderPrecision) on both Windows and Linux.
  2. Default map is SphereMap, select the Cine Camera Actor in it.
  3. Run Quick Render on Selected Camera (this should already be set, you just have to click the button).
  4. Compare the output from both operating systems in a viewing application such as OpenRV or Nuke, they should look the same.

See attached examples of "before" output on Linux (QuickRenderSequence.LinuxCurrent.depth.0000.exr) and Windows (QuickRenderSequence.Windows.depth.0000.exr).  In the "before" examples, Linux was incorrect and Windows was/is correct.

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.

0
Login to Vote

Fixed
ComponentUE - Rendering Architecture - RHI
Affects Versions5.3
Target Fix5.7
Fix Commit46329626
CreatedMar 4, 2024
ResolvedSep 30, 2025
UpdatedOct 6, 2025
View Jira Issue