Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Converting from DXT4 format to RGBA

Discussion in 'Shaders' started by Rights2PWN, Nov 23, 2019.

  1. Rights2PWN

    Rights2PWN

    Joined:
    Oct 18, 2018
    Posts:
    3
    I'm looking to convert a normal map that is formatted to be DXT4 to be RGBA so I can use the setpixel() command on it
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,256
    DXT4? Is that a typo? I don’t even know if Unity will read a DXT4 texture. It certainly can’t create a file in that format, and it’s a terrible format for a normal map...

    What’s the source of this texture, and what are you looking to do with it? If you’re importing a texture that’s already in a compressed format, like a .dds file, you can blit it to a render texture of the same size and color depth (ARGB32) and then use ReadPixels() to read that into a RGBA32 Texture2D of the same dimensions.
     
  3. Rights2PWN

    Rights2PWN

    Joined:
    Oct 18, 2018
    Posts:
    3
    Yes that was a typo. I meant to say DTX5. That is the output for when I use the .format command on the normal map texture that I'm using on my player avatar. I haven't worked with compressing textures before so I'm not sure how I can modify this normal map using the setPixel() command. When i tried using the setPixel() command on the DTX5 texture, it throws an error. When i tried to ReadPixels() into a new ARGB32 texture, the texture turns out pink.
     
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,256
    Ah, that makes more sense. Unity’s normal maps on the desktop are saved in a swizzled DXT5 format, where the x of the normal map is stored in the alpha, the y in the green channel, and the other two channels are set to 1. I’ve posted more in depth explanations why, but the TLDR version is you get better quality by doing it that way than using the original coloring of the normal map stored using DXT1 compression.

    You also can’t use SetPixel(s) on compressed textures since compressed textures aren’t stored as individual pixels. They’re stored in compressed blocks of pixels, in DXT formats its blocks of 4x4 pixels. Technically you can read and override individual blocks, but that’s a bit more work. When you call GetPixel(s) on a compressed texture it’s decompressing the texture to the stored values.

    Presumably this is something you’re doing at runtime. For that you can use GetPixels, apply your modifications to a new RGBA32 Texture2D, call Compress() to transform it into a DXT5 texture, and use Graphics.CopyTexture() to copy the data back to the original texture.