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]); } }
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:
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.
There's no existing public thread on this issue, so head over to Questions & Answers just mention UE-208863 in the post.
0 |
Component | UE - Rendering Architecture - RHI |
---|---|
Affects Versions | 5.3 |
Target Fix | 5.7 |
Fix Commit | 46329626 |
---|
Created | Mar 4, 2024 |
---|---|
Resolved | Sep 30, 2025 |
Updated | Oct 6, 2025 |