Texture channels shift Values

I’m creating a Texture2D using UTexture2D::CreateTransient(pWidth, pHeight, format); where the format is PF_R8G8B8A8

In each of those channels I convert floats into uint8 using something like

DestPtr[destIndex] = (uint8)FMath::Clamp<int32>(FMath::TruncToInt(dX *255.f), 0, 255);

When I check the log values of both the original floats and the converted uints at the point of assignment, the values are correct for their position.

I then use this Texture2D as a sample in a material (shader), in that material if I test the values, they have shifted. Let me illustrate what I mean by showing a threshold operation for values >0.5

http://i.imgur.com/m6NBU3q.png

As you can see the place where the values should be 0.5/0.5 is no longer in the center (as it was assigned at creation) but now shifted much closer to the end of the ranges.

I sampled the color values with the tone mapper disabled and this shift appears to have a quadratic fit

http://i.imgur.com/4nUMO6e.png

Is this image compression at work? If so how do I stop this from happening. I need the full 8bit values to be unaffected in order to be correctly used as UVs further down the material chain.

Thanks for any help you can provide!

Hi, getnamo

It looks like there is gamma correction. Try to use it

DynamicTexture->SRGB = 0;

Hope it helps!

That was it, thanks a lot!

I’m guessing this is the default behavior for 8bit channel textures? What about float textures(e.g. 32bit float per channel textures)? These should have enough precision to not use gamma correction or is this a default behavior for all textures?

As an aside I’ve been trying to get float channel textures to work, but they always seem to give me an access error despite being formulated in the exact same way as the example above (without the uint8 conversion).

What data structure does PF_FloatRGBA expect? when you get the MipData from

texturePointer->PlatformData->Mips[0].BulkData.Lock(LOCK_READ_WRITE)

is this essentially a float pointer to an array 4 floats wide per pixel or is there some special format I’m not aware of?

Would be great if EPixelFormat had a bit more documentation to it! Cheers again for any help!

Hi, I am sorry for a long delay.

I’m guessing this is the default
behavior for 8bit channel textures?
What about float textures(e.g. 32bit
float per channel textures)? These
should have enough precision to not
use gamma correction or is this a
default behavior for all textures?

No, as I know gamma correction is enabled by default (but exist some exceptions) and it is not depend from texture format. My opinion that PF_R8G8B8A8 format is more than enough (256^3 colors can be represented). However, if you want to hold some other type of information in the texture that require more precision (like depth, etc.) it cannot be enough.

You can use PF_A32B32G32R32F to store floats (4 floats per pixel). In addition, SRGB option has no effect on the texture sampling in this case.

PF_FloatRGBA = corresponds to DXGI_FORMAT_R16G16B16A16_FLOAT (structure FFloat16Color).

Unfortunately, there is no description for formats. I recommended to you compare this formats with standard DXGI formats Hardware Support for Direct3D 11 Formats (Windows) | Microsoft Learn Format mapping you can find in D3D11Device.cpp (from line 97).

Best regards,