Hi everybody.
I’m trying to utilize integer-based texture format for my volume textures, as it makes more sense to my application than loading [0,1]-normalized floats and then converting them back to integers through multiplication and rounding.
The thing is, it seems that every possible texture format works, except the ones I want to use. Once I set my texture format to R(8/16/32)_(U/S)INT, I can no longer read the data from it in a material.
This is my code for generating the texture -
void CreateVolumeTextureTransient(UVolumeTexture*& OutTexture, EPixelFormat PixelFormat, FIntVector Dimensions,
uint8* BulkData, bool bUAVTargetable) {
int BlockBytes = GPixelFormats[PixelFormat].BlockBytes;
int TotalBytes = Dimensions.X * Dimensions.Y * Dimensions.Z * BlockBytes;
UVolumeTexture* TransientTexture =
NewObject<UVolumeTexture>(
GetTransientPackage(),
NAME_None,
RF_Transient
);
TransientTexture->SRGB = false;
TransientTexture->NeverStream = true;
TransientTexture->CompressionNone = true;
TransientTexture->PlatformData = new FTexturePlatformData();
TransientTexture->PlatformData->SizeX = Dimensions.X;
TransientTexture->PlatformData->SizeY = Dimensions.Y;
TransientTexture->PlatformData->NumSlices = Dimensions.Z;
TransientTexture->PlatformData->PixelFormat = PixelFormat;
// Allocate first mipmap.
FTexture2DMipMap* Mip = new FTexture2DMipMap();
TransientTexture->PlatformData->Mips.Add(Mip);
Mip->BulkData.Lock(LOCK_READ_WRITE);
void* Data = Mip->BulkData.Realloc(TotalBytes);
if (BulkData) {
FMemory::Memcpy(Data, BulkData, TotalBytes);
}
else {
FMemory::Memset(Data, 0, TotalBytes);
}
Mip->BulkData.Unlock();
TransientTexture->UpdateResource();
OutTexture = TransientTexture;
}
And in the material, I use a custom node to read voxel values without interpolation, like so:
int LabelValue = Volume.Load(int4(xPos, yPos, zPos, 0)).r;
if (LabelValue > 0) return float4(1.0, 1.0, 1.0, 1.0);
else return float4(0.0, 0.0, 0.0, 0.0);
Now, if I use any floating-point format (G8, G16, R32F) and set inside any values that map to 1.0 or higher when read, I can see the expected white color in those spots of the Volume Texture. However, once I switch to e.g. PF_R32_INT, I keep getting straight zeroes from the texture Load(), no matter what I put in my data array when creating the texture.
I stepped through the UpdateResource RHI call-stack and everything points to the initial data really getting set into the texture.
Anybody has experienced this problem before? I’ll be making a custom compute shader tomorrow to try to check if the data actually gets transferred into the texture during creation, but I don’t have the willpower now.