I’m trying to load a PNG file from a folder and I tried to use LoadRawTextureData() since from what I read it is much faster than LoadImage().
But obviously something went wrong or I’m not using it correctly.
private CancellationTokenSource cts;
private void GetImageRawData()
{
cts = new CancellationTokenSource();
var token = cts.Token;
File.ReadAllBytesAsync(filePath, token)
.ContinueWith(task => Dispatcher.EnqueueAction(() =>
{
// The Dispatcher class let me run this code in the MainThread.
cts?.Dispose();
LoadRawTextureData(task.Result);
}));
}
private void LoadImage(byte[] rawData)
{
Texture2D tex = new(2, 2, TextureFormat.RGBA32, false);
tex.LoadImage(rawData);
RawImage.TrySetTexture(tex);
}
private void LoadRawTextureData(byte[] rawData)
{
// The width and height of the PNG file are actually 3024x3024, found from the file's properties
Texture2D tex = new Texture2D(3024, 3024, TextureFormat.RGBA32, false);
tex.LoadRawTextureData(rawData);
tex.Apply();
RawImage.TrySetTexture(tex);
}
I tried LoadImage() and it works perfectly, but is very performance heavy.
And when I use LoadRawTextureData() I get this error:
UnityException: LoadRawTextureData: not enough data provided (will result in overread).
What am I doing wrong here?
LoadRawTextureData requires actual raw texture data as it is represented in memory. Which format that data has to have depends only on the Texture2D format. You created a TextureFormat.RGBA32 texture. So the data you have to provide has to be raw RGBA data. You load a png image which is a deflate compressed section based file format and can not be read or interpreted by your GPU.
Those are the texture formats that your GPU supports (and not every GPU necessarily supports all of them.) There are only a few compressed texture formats which actually have hardware support by the GPU. Namely DXT, PowerVR(only on iOS devices), ETC (Open GLES2+), ASTC(should be supported by most GPUs) and a few others. Those are all texture formats and not necessarily file formats. As I said LoadRawTextureData expects byte data as it is represented in memory.
You can not load PNG files this way. At least not without some loading and decoding logic that actually creates / prepares the raw data that the LoadRawTextureData method expects. So no, LoadRawTextureData is not just a faster LoadTexture method. If it was, it would have replaced the old one.
edit
Just to make it clear. When you want to load raw RGBA32 data for a 3024x3024 image, the byte array would need to have a size of 36,578,304 bytes. Each consecutive 4 bytes in the array would denote one pixel and the order is R G B A and each channel is represented by one byte.
If you need to load huge textures dynamically in the background, you would need to use some external image library that you could run on a separate thread to load and decode the image from disk and prepare that 36 MB data array on that separate thread. Once the loading has finished you could use LoadRawTextureData to quickly load that data onto the GPU on the main thread.