unity-game-engine

In Unity, I want to bulk convert some textures from .tga to .png and update references


I have an asset pack I'm prototyping with that uses some high-quality tga textures, at 2048x2048. There are 250 of them, which means my Asset folder is huge. I know that for some rendering cases, .tga is better than .png, but for my use case, portability is more important than texture quality.

I want to convert all these .tga into .png, and then update all Material references to use the new .pngs. Deleting the old .tga is totally fine - I don't need to preserve them. I know how to bulk-convert images easily; I just want to update the references in the .mat files to use the new textures.

The textures are all used in materials which use the Standard Shader, and are either used for fields Albedo, Metallic, Normal Map, or Occlusion. There's no weird custom shaders I need to update references for.

Is there an automated way to do this?


Solution

  • The simplest way, IMO, would be to replace the files in-place, preserving the .meta files so the guids wouldn't change. This way you wouldn't even need to update the material references, which is always a pain to do in Unity.

    The procedure:

    1. bulk-convert the TGAs to PNGs (with Unity closed or at least unfocused)
    2. delete all the TGAs, but not the associated .tga.meta files
    3. rename all the .tga.meta files to .png.meta
    4. then reopen/refocus Unity, let it reimport: you should be all set. Unity think the textures are the same and just need reimporting. It will even preserve the import settings.

    You could automate the renaming (step 3) using a simple batch or shell script. If your project is under source-control, use you CVS's command-line rename interface to keep the textures' history. And if it's not, then obviously you make a backup copy of your project.

    As a side-note:

    I know that for some rendering cases, .tga is better than .png

    This is not true. When Unity imports the textures, it converts them to a GPU/platform-specific format (this goes in the library), and the original format of the texture makes no difference.

    for my use case, portability is more important than texture quality.

    PNG has a lossless-compression option, so you can have both smaller size and pixel-perfect quality, no downside compared to TGA (except maybe the import time would be slightly longer due to decompression).

    Edit from @escapecharacter: This worked perfectly. Here's documentation of what I did. FYI, I'm on Windows using bash. My project is tracked in version control so I wasn't cautious about breaking changes. From my Textures directory:

    To convert .meta files:

    for i in *.tga.meta; do git mv $i ${i/.tga.meta/.png.meta}; done
    

    To convert the .tga to .png, I used ImageMagick installed via choco:

    for f in *.tga; do magick ./"$f" ./"${f%.tga}.png"; done;
    

    To clean up the .tga:

    rm *.tga