Download

Bizarre float behaviour in PF_A32R32B32G32F 2DTexture

Hi all,

I’m creating a texture from a TArray, that requires high precision. The array of floats is to be passed in via blueprint, but here is the simple piece of code that is generating and returning the texture:

UTexture2D* UBioCodeLibrary::EncodeColoursToTexture(const TArray<float> Colours, int32 TexSize)
{
	//Load in a new Texture2D
	UTexture2D* LoadedT2D = NULL;
	LoadedT2D = UTexture2D::CreateTransient(TexSize, TexSize, PF_A32B32G32R32F);
	if (!LoadedT2D) return NULL;

	//Copy!
	void* TextureData = LoadedT2D->PlatformData->Mips[0].BulkData.Lock(LOCK_READ_WRITE);
	FMemory::Memcpy(TextureData, Colours.GetData(), Colours.Num());
	LoadedT2D->PlatformData->Mips[0].BulkData.Unlock();

	//Update!
	LoadedT2D->UpdateResource();

	return LoadedT2D;
}

I am working with an even sided texture for simplicity currently.

Here is the weird part, you would expect each pixel to contain an RGBA float, that is 4 floats. And it does, I can pass an array and have the first values of the array: [1,0,0,0,1,0,0,0… etc] to make the first 2 pixels of the texture red.

Infact I can make any pixel I want whatever value I want by changing the appropraite item in the array.
For an 8x8 pixel texture, I can change the array items 252,253,254,255, to values 1,0,0,0 to make the final pixel red for example.
However, this behaviour only works when the total size of the float array is 1024 (for a 8x8 pixel, i.e. 256 float arrary 884). If I make it larger, the game crashes, if I make it smaller, the entire texture no longer completely fills up (if I make it 512, only the first half of the texture is controllable - but the indices to control which pixel are still the same i.e. 255 still contols the “last” pixel of the 8x8 pixel texture, and positions 0,1,2,3, of the array still control RGBA for the 1st pixel?)

This seems really weird - I would expect an float array of size 256 to suffice - especially as changed the last 4 items of the array (252,253,254,255] directly changes the final pixel of my texture.

Why do I need so many more values up to 1024 in the array to have typical behaviour?
All values in the TArray from 256-1203 can be anything - I passed random floats and there was no change, I can also just resize the array to whatever values they are once resized and no change. They just seem to have to be there?

Can anyone shed some light on the situation?

Here’s a pick where I set 252, 253, and 254 to 1.0, 0.3, and 0.1 respectively to get last pixel in my 8x8 texture exactly what I wanted (with a calibration square to make it easy to see)
However I had to resize the 256 sized array to 1024 to get this behaviour.

Many thanks.

The 3rd parameter you provide Memcpy should be the amount of bytes to copy, not the amount of array members. You want to pass in Colours.Num() * sizeof(float).
At the moment you are only copying one quarter of the values to the texture.

1 Like

Oh of course! :sweat_smile:, this makes so much sense, thank you!