How to save a texture to BC3 Unorm Srgb format?

Hi! I want to use saving to the desired format using the console or a bat file, possibly using a python script to simplify recursive processing. The problem is in the color space, I can’t find how to save it to “sRGB” without changing the texture itself. In “PVRTC”, when saving, the color of the texture breaks, it becomes either darker or lighter. However, it is still stored in the “BC3 UNORM LINEAR”. In NVTT, I did not find at all how to save to the encoding I need. For clarity, I will fix 2 textures: 1 is the texture that is used by the game itself (i.e. a file from the developers), 2 is a file saved manually in Paintnet. The problem is not to save, but to automate the process so that it does not take so much time and to eliminate manual work.

There are some screenshots and files from the game for example. Couldn’t attach when updating to a post:
https://drive.google.com/drive/folders/1Fiaybc1kEknjbvSKmvHZ87tcH5OZxbFC?usp=sharing

Hi @sartakovanton163!

For the Texture Tools Exporter, to save to DXGI_FORMAT_BC3_UNORM_SRGB, you’ll want to use the --export-transfer-function option added in Texture Tools Exporter 2024.1.0, like this:

"C:\Program Files\NVIDIA Corporation\NVIDIA Texture Tools\nvtt_export.exe" example.png -f bc3 --export-transfer-function srgb -o example.dds

It looks, though, like you’re using the core NVTT library (i.e. Context::compress()), and calling OutputOptions::setSrgbFlag(true) correctly – Manual saving.dds already has the correct DXGI format (byte 0x80 in Manual saving.dds is 74, which is DXGI_FORMAT_BC3_UNORM_SRGB). Maybe something else is the issue?

For batch processing, I usually write a short custom script, like this:

import os
import subprocess
in_dir = # Put your input directory here
out_dir = # Put your output directory here
nvtt_export_exe = r"C:\Program Files\NVIDIA Corporation\NVIDIA Texture Tools\nvtt_export.exe"

for subdirectory, dirs, files in os.walk(in_dir):
    for file in files:
        in_file = os.path.join(subdirectory, file)
        # We'll write the output file in this directory. Since nvtt_export
        # doesn't create directories, we'll create it beforehand:
        out_file_dir = out_dir + subdirectory[len(in_dir):]
        os.makedirs(out_file_dir, exist_ok=True)
        # Place it in the same relative location, and append ".dds" to the end:
        out_file = os.path.join(out_file_dir, file + ".dds")
        # Compress in_file to out_file,
        args = [nvtt_export_exe, in_file, "-f", "bc3",
                "--export-transfer-function", "srgb", "-o", out_file]
        print(args, flush=True)
        # Add check=True if you want to throw an error if compressing any image
        # failed:
        subprocess.run(args)

Hope this helps!

1 Like

Thanks it helped)

1 Like