- Home /
TextureFormat BGR does not exist
Unity has many texture formats, but it does not have one of the most common ones when it comes to raw image data read from a video capture card. I want BGR24 or BGR, meaning Blue (8bits), Green(8bits), and Red(8bits) in that order.
BGRA32 is there, but it won't work in my case. Do you know if there is another name for BGR24 or it just simply does not exist in Unity?
Please note that I do not want to convert my raw data from BGR24 to RGB24 manually and then use RGB24 to read it to a texture because it will add delay to my rendering.
Uhm do you talk about loading the image at runtime manually? If not Unity does convert images on import.
If you talk about loading images at runtime, how do you actually load them into the Texture2D? Doing a single for loop through a Color32 array is extremely fast, even when you have 25$$anonymous$$ pixels(5k x 5k)
It's not really a choice Unity made but simply the fact that certain hardware simply doesn't support BGRA as upload format. Actually BGR or RGB is no internally used format at all as your GPU almost always has a 4byte alignment so image data is converted to ARGB anyways.
You should add more details about your actual situation
The raw data for the image comes in in BGR format, and the image is 1920x1080, so the raw data is 1920x1080x3 bytes large. I am loading them into a texture object in the following way:
Texture2D tex = new Texture2D(1920, 1080, TextureFormat.RGB24, false);
// The code below is done at every frame. It's basically strea$$anonymous$$g the raw data co$$anonymous$$g from a video capture card.
if(rawData is available) {
tex.LoadRawTextureData(rawData, 1920 * 1080 * 3);
tex.Apply();
render tex
mark rawData not available
}
this works fine, but Red and Blue is swapped in the resulting image; that's why I just want simply BGR24.
Well, first of all you should avoid creating a new Texture each frame. This will be horrible slow. Also keep in $$anonymous$$d that Texture2D objects need to be explicitly destroyed with Destroy(tex)
otherwise you will run out of memory soon.
Hopefully your byte array is also cached and not recreated for every image. Otherwise you end up with a massive amount garbage every frame.
If you don't want to do any conversion of the format on the CPU you can always simply write a shader which swaps the components in the fragment shader. You actually don't need to do any fancy swapping code as inside a shader you can simply use c.bgr
and assign it to an rgb
value. But it depends on what you actually want to do with the textures.
Again internally the GPU never stores images in BGR format. Have a look at this page which is all about the internal image format of OpenGL. The 3 letter word "BGR" can't be found a single time on that page. Yes, most OpenGL versions and most hardware do support a BGR "transfer format" for loading images into the GPU but they need to be converted during loading the image.
Note that pushing a video stream through the CPU and Texture2D API will never give you good results in terms of speed. You might want to look into writing a native code lowlevel plugin. But again it depends on the usage.
1)Thanks for pointing out that I should avoid creating a new texture each frame and I should destroy it later. If you have read my comment carefully, you would notice that the line of code creating the texture is above the comment "// The code below is done at every frame" The texture creation is only done once.
2) The rawData points to the same address, no new memory is allocated. Only the content itself is updated.
3) I haven't digged into the shader in Unity yet, and I am pretty sure I will have to for speed. and I agree that I might be able to turn c.bgr to c.rgb in Unity shader if it's is similar to OpenGL shader.
4)I agree that OpenGL does not store image in BGR format, but rather in RGB or others. Here I am NOT trying to store the raw Data as BGR. It seems like in Unity (more specifically, the Texture2D API), the source format and destination format has to be the same, and BGR happens to be the source format.
Below is what I want to achieve in OpenGL terms
glTexImage2D(GL_TEXTURE_2D, // Type of texture
0,
GL_RGB, // Internal colour format for texture
frameWidth,
frameHeight,
0, // Border width in pixels (can either be 1 or 0)
GL_BGR, // Input image format
GL_UNSIGNED_BYTE, // Image data type
rawData); // The actual
5) will not do any image processing in CPU. will be done in shader. If the fact of using Texture2D involes lots of processing, then I will have to pass the raw data to the Unity shader directly. and what's the equivalent of OpenGL texture in Unity, Again, I'm new to Unity. and will look into Unity shader.
$$anonymous$$y original question: Does BGR24 exists in Unity TextureFormat? or it exists, but it's called something else? I don't seem to find it.
Your answer

Follow this Question
Related Questions
Application.CaptureScreenshot on a Texture2D? 1 Answer
Why is my texture like this? 1 Answer
Encoding metadata in a texture 1 Answer
Update Texture type to GUI during runtime 0 Answers
Splatmap and Corresponding Textures to 1 final Texture 1 Answer