Skip to content

Instantly share code, notes, and snippets.

@dvessel
Created January 2, 2023 17:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dvessel/4884272446e68956740aef261b54d3c1 to your computer and use it in GitHub Desktop.
Save dvessel/4884272446e68956740aef261b54d3c1 to your computer and use it in GitHub Desktop.
notes on working with texture packs.

Texture Packs and Resource Packs Information

https://forums.dolphin-emu.org/Thread-how-to-install-texture-packs-custom-textures-info

DDS vs. PNG Packs:

You NEVER want to use both a PNG and DDS pack together, always pick one or the other. The short version is, if a texture pack author provides both a DDS and PNG version of their texture/resource pack, you most likely want to use the DDS version. The reason is that DDS is much faster to load than PNG and is less likely to "stutter" when textures are loaded in. There is a caveat to DDS textures, and that is reduced image quality. But, a properly created DDS texture pack will be nearly indistinguishable from its PNG counterpart.

There are several types of DDS formats, ranging from BC1-BC7, and can also be known as DXT1-DXT5. The format that users should be concerned about in regards to Dolphin texture packs is the BC7 format. If a texture pack is using BC7 DDS textures, the user must have a DX11 capable GPU or the textures will not load. In this case, the user must use a PNG version of the pack, or find/request a version of the pack that does not use BC7 textures. Fortunately, this should become more and more rare as hardware evolves and users upgrade their equipment.

DDS Packs:

  • Faster to load than PNG.
  • Mostly or completely eliminates stuttering.
  • Compression leads to loss in quality.
  • Usually larger file sizes than PNG.
  • Should only be used as texture packs.
  • Harder to edit/work with than PNG.

PNG Packs:

  • Slower to load than DDS.
  • May cause stuttering when loaded in.
  • Highest quality textures.
  • Usually smaller file sizes than DDS.
  • Mostly used for archival purposes.
  • Easier to edit for other texture developers.

Dolphin Custom Texture Basic Info:

A quick overview of a texture dumped by Dolphin. It will look something like this: tex1_256x256_m_efef240984783a47_14.png.

  • The header "tex1" means that this is the first revision of the new format.
  • Next is the dimensions, the dumped texture has the dimensions 256x256.
  • Next is the letter "m", which says this is a mipmap texture.
  • Next is the unique hash of the texture.
  • Last is a flag for the texture format. https://wiki.tockdom.com/wiki/Image_Formats

Features of the current texture format:

  • No Game ID in the texture name. When converting a pack for another region, you only need to rename the GameID folder (or use the region free 3 letter equivalent).
  • Texture packs can have any number of sub-folders that contain textures within the GameID folder for better organization.
  • Textures can be dumped with ANY Texture Cache accuracy setting, and are are always compatible with every Texture Cache accuracy.
  • The dimensions of the original texture are now in the file name so there is a permanent reference for your custom texture.
  • Paletted textures once retextured, load up correctly everywhere in the game. (There are exceptions, see section on wildcards).
  • If a texture requires mipmaps, the dimensions will be followed with an "m" flag (Example: tex1_256x256_m_efef240984783a47_14.png).
  • If a texture has arbitrary mipmaps, then the texture will end with an "_arb" suffix (Example: tex1_128x32_m_acb0eea2ba61e548_2_arb.png).
  • The "_arb" suffix can be used on any custom texture to draw mipmaps at a fixed distance (see section on arbitrary mipmaps).

Mipmap Textures:

Some textures dumped by Dolphin contain the mipmap (_m) flag, and are accompanied by smaller versions of the same image that contain a (_mip#) suffix. These are known as mipmap textures. Mipmaps are a collection of images all containing the same image but created at progressively smaller resolutions. Some textures require mipmaps to avoid "shimmering" in the distance. Mipmaps can also contain different images on lower levels to create unique effects. These are called arbitrary mipmaps and are covered more in the next section. Textures without the "m" flag should not be created with mipmaps. Dolphin will not make use of mipmaps if the game that the texture was dumped from did not make use of mipmaps for that texture.

Dimensions for each Mipmap level should be half of the dimensions of the previous level, and should be created all the way down to 1x1. Each MipMap texture name must end with the level of the Mipmap that it represents. For example, level 1 should end with "_mip1, level 2 should end with "_mip2", level 3 should end with "_mip3", etc. Below is an example of properly creating mipmaps for a mipmap texture.

  • Level 00: tex1_256x256_m_efef240984783a47_14.png : 1024x1024
  • Level 01: tex1_256x256_m_efef240984783a47_14_mip1.png : 512x512
  • Level 02: tex1_256x256_m_efef240984783a47_14_mip2.png : 256x256
  • Level 03: tex1_256x256_m_efef240984783a47_14_mip3.png : 128x128
  • Level 04: tex1_256x256_m_efef240984783a47_14_mip4.png : 64x64
  • Level 05: tex1_256x256_m_efef240984783a47_14_mip5.png : 32x32
  • Level 06: tex1_256x256_m_efef240984783a47_14_mip6.png : 16x16
  • Level 07: tex1_256x256_m_efef240984783a47_14_mip7.png : 8x8
  • Level 08: tex1_256x256_m_efef240984783a47_14_mip8.png : 4x4
  • Level 09: tex1_256x256_m_efef240984783a47_14_mip9.png : 2x2
  • Level 10: tex1_256x256_m_efef240984783a47_14_mip10.png : 1x1

The final mipmap should always have dimensions of 1x1. This holds true even if a dimension hits 1 before the other. In this case, continue to halve the larger dimension, and keep using 1 for the other.

  • Level 00: tex1_128x512_m_940b020ff9e6dda0_14.png : 512x2048
  • Level 01: tex1_128x512_m_940b020ff9e6dda0_14_mip1.png : 256x1024
  • Level 02: tex1_128x512_m_940b020ff9e6dda0_14_mip2.png : 128x512
  • Level 03: tex1_128x512_m_940b020ff9e6dda0_14_mip3.png : 64x256
  • Level 04: tex1_128x512_m_940b020ff9e6dda0_14_mip4.png : 32x128
  • Level 05: tex1_128x512_m_940b020ff9e6dda0_14_mip5.png : 16x64
  • Level 06: tex1_128x512_m_940b020ff9e6dda0_14_mip6.png : 8x32
  • Level 07: tex1_128x512_m_940b020ff9e6dda0_14_mip7.png : 4x16
  • Level 08: tex1_128x512_m_940b020ff9e6dda0_14_mip8.png : 2x8
  • Level 09: tex1_128x512_m_940b020ff9e6dda0_14_mip9.png : 1x4
  • Level 10: tex1_128x512_m_940b020ff9e6dda0_14_mip10.png : 1x2
  • Level 11: tex1_128x512_m_940b020ff9e6dda0_14_mip11.png : 1x1

Starting with Dolphin 5.0-3506, DDS textures can have built-in mipmaps and do not require external mipmaps mentioned above. This means a DDS texture and all of its mipmaps can be built into a single file. PNG images can not have internal mipmaps, and will always need another image per mipmap layer. DDS internal mipmaps should only be created within mipmap "m" textures, otherwise it's a waste of resources as Dolphin will not make use of them.

Arbitrary Mipmap Effects:

Arbitrary mipmaps contain images that differ from the base image/top level. The purpose of arbitrary mipmaps is to create effects that appear/disappear depending on how far the texture is away from the camera. The vast majority of games for the Gamecube and Wii do not use arbitrary mipmap effects, but there are a few that do. One of the greatest examples is the Super Mario Galaxy games which make heavy use of these effects. Textures that have these mipmap effects will dump with the "_arb" suffix under the condition that GPU Texture Decoding is disabled. If it is enabled, textures will not dump with the "_arb" suffix and it may be difficult to know which textures have these effects. Dolphin has the ability to draw these mipmap effects at a fixed distance at any Internal Resolution setting in order to see them the way they were "meant to be seen" by the game's developers, but again, GPU Texture Decoding must be disabled.

Below is an example of a lava texture that uses arbitrary mipmaps in Super Mario Galaxy, as dumped by Dolphin. [Image: u1hMqCc.png] And how it looks in-game can be seen here (with GPU Texture Decoding disabled). [Image: WWgVc6I.png]

Starting with Dolphin 5.0-6197, custom textures can now make proper use of arbitrary mipmaps. Before custom texture mipmaps were drawn at a distance that was defined by the Internal Resolution and Anisotropic Filtering settings, making where they appear unpredictable. Now textures that include the "_arb" suffix, mipmaps will appear at a fixed distance so the artist has full control over where these effects appear. The "_arb" suffix can be added to any custom texture to draw mipmaps at a fixed distance, or it can be removed from textures that dump with the suffix to dynamically draw mipmaps depending on Internal Resolution and Anisotropic Filtering settings. It will be up to the artist or pack maintainer to decide when to use the "_arb" suffix.

Not long after came Dolphin 5.0-6199. This update picks the same mipmap level for custom textures as it would the game's stock textures, meaning it's possible to perfectly line up custom texture effects with the game's stock effects. This also allows for much higher resolution mipmaps. For the best results, the texture's upscaling factor should match the target Internal Resolution setting. Meaning, a 128x128 texture, upscaled by 4x, resulting in a 512x512 texture, will look best at 4x Internal Resolution.

Duplicate Dumps and the Wildcard Character:

A secret feature has been available for years that allows using a wildcard character if the same texture dumps with multiple hashes. Unfortunately, this character (*) was invalid for filenames in Windows. Starting with Dolphin 5.0-8619 the wildcard character has been changed to ($) so Windows users can take advantage of this feature.

Sometimes paletted textures will dump multiple times when the tlut hash changes.

[Image: wzAkM7z.png]

While this is not a common issue (in fact it is very rare), it can happen. Games that are known to be affected are The Legend of Zelda: Twilight Princess (Wii) and Wind Waker (GC). Without the wildcard, every instance of this dump would need to be found in order to have it retextured all the time. This is a nearly impossible feat that wastes a lot of time dumping and ultimately precious disk space. So using the example above, a "$" can be used as the second hash which will effectively retexture every instance.

Example: tex1_48x51_53403146169829a2_$_9.dds

DDS Textures in Dolphin:

There is a lot to this format, so I'm only going to cover some basic information that pertains to creating DDS textures for Dolphin. I have linked a few articles at the bottom of this section that goes much further into detail than I will here. DDS textures have the advantage that they are faster than PNG textures. DDS can completely avoid or greatly reduce stuttering that custom textures may introduce. The situation for PNG textures is improved with the option Prefetch Custom Textures, but DDS will still outperform PNG because they are decoded much faster on the GPU.

The disadvantage of DDS textures is that they are compressed with a lossy algorithm, meaning, the overall quality of the image is reduced when converting to DDS. The quality hit can be avoided using uncompressed DDS textures, but they are much larger in file size and require the same amount of VRAM as PNG. This makes them ideal for UI elements, but not so much for environments and other large textures. Uncompressed DDS textures do however still have a speed advantage over PNG.

  • Dolphin currently supports four types of DDS block compression: BC1 (DXT1), BC2 (DXT3), BC3 (DXT5), and BC7.
  • It also supports uncompressed DDS textures: DX9 ARGB, DX10 RGBA, or DX10 BGRA. Ishiiruka can not use DX10 RGBA, Red/Blue will be reversed.
  • DXT1 textures are half the size of DXT5/BC7, and are faster than most other formats. Not recommended for images with transparency.
  • DXT3 should not normally be used as it is the same size as DXT5, only supports 4-bit alpha, and can create noticeable banding.
  • DXT5 textures may yield higher quality than DXT1 textures. This is the format that should be used for images with alpha (if not converting to BC7).
  • BC7 offers much higher quality than most other formats, is equal in size to DXT5, and has the same VRAM requirements. Requires a DX11 capable GPU.
  • Uncompressed provides lossless quality, but are 4x the size of DXT5/BC7 and require 4x the VRAM. These should only be used for smaller textures (like UI/HUD elements).
  • DDS textures can have built-in internal mipmaps. These are supported starting with Dolphin 5.0-3506.
  • I personally suggest creating packs using BC7 and uncompressed textures going forward. My custom texture tool can aid in converting packs using these formats.

This is a great article on the D3D9 DDS format: http://www.buckarooshangar.com/flightgear/tut_dds.html

An in-depth explanation of the types of DDS block compression: http://www.reedbeta.com/blog/understanding-bcn-texture-compression-formats/

How to calculate the file size of a DDS texture (I've seen many misconceptions on this, so hopefully this clears things up): http://bhemuhelp.unaux.com/other/ctt/DDS_Size_Calculations.txt

Custom Texture Dolphin Revisions:

  • Dolphin 4.0-5234 - Introduction of the the latest texture format.
  • Dolphin 4.0-8583 - Support 3-digit GameIDs for custom texture folder.
  • Dolphin 5.0-3506 - Natively support DDS textures and internal mipmaps.
  • Dolphin 5.0-4894 - Support for loading DDS BC7 custom textures.
  • Dolphin 5.0-6197 - Treat custom textures with "_arb" suffix as having arbitrary mipmaps.
  • Dolphin 5.0-6199 - Apply custom texture scale for arbitrary mipmaps.
  • Dolphin 5.0-6208 - Remove support for old custom texture format.
  • Dolphin 5.0-7631 - Replace usage of SOIL with libpng.
  • Dolphin 5.0-8598 - Use simplified libpng PNG reading (fixes PNG transparency bugs since 5.0-7631).
  • Dolphin 5.0-8606 - Fix critical buffer overflow in LoadPNG (fixes crash since 5.0-8598).
  • Dolphin 5.0-8619 - Change wildcard to Windows compatible character.
  • Dolphin 5.0-9217 - Implement resource packs (an alternative to texture packs).
  • Dolphin 5.0-9558 - Support compressed resource packs.

Supported compression types in Dolphin

Taken from S3_Texture_Compression (Wikipedia) and condensed to what's relevant to Dolphin's texture support.

Codecs

There are five three variations of the S3TC algorithm (named DXT1 through DXT5, referring to the FourCC code assigned by Microsoft to each format), each designed for specific types of image data. All convert a 4×4 block of pixels to a 64-bit or 128-bit quantity, resulting in compression ratios of 6:1 with 24-bit RGB input data or 4:1 with 32-bit RGBA input data. S3TC is a lossy compression algorithm, resulting in image quality degradation, an effect which is minimized by the ability to increase texture resolutions while maintaining the same memory requirements. Hand-drawn cartoon-like images do not compress well which usually generate artifacts.

Like many modern image compression algorithms, S3TC only specifies the method used to decompress images, allowing implementers to design the compression algorithm to suit their specific needs, although the patent still covers compression algorithms. The nVidia GeForce 256 through to GeForce 4 cards also used 16-bit interpolation to render DXT1 textures, which resulted in banding when unpacking textures with color gradients. Again, this created an unfavorable impression of texture compression, not related to the fundamentals of the codec itself.

DXT1,BC1: 1-bit Alpha/Opaque

Suited to large textures due to the memory savings.

  • Alpha Premultiplied: Yes
  • Compression Ratio: 6:1 (for 24-bit source image)
  • Texture Type: Simple 1-bit Alpha/Opaque

DXT1 or Block Compression 1, is the smallest variation of S3TC, storing 16 input pixels in 64 bits of output, consisting of two 16-bit RGB 5:6:5 color values and a 4x4 two-bit lookup table. Simple 1-bit alpha is supported.

Note that a black border surrounding the transparent area can appear when linear texture filtering and alpha test is used, due to colors being interpolated between the color of opaque texel and neighbouring black transparent texel.

DXT3,BC2: Explicit alpha

Color compression works the same way as BC1 (opaque version) but more bits are allocated to the alpha channel. No real benefits to this codec. Takes up the same amount of memory as BC5/7 with no benefits. Avoid it.

  • Alpha Premultiplied: No
  • Compression Ratio: 4:1
  • Texture Type: Sharp Alpha

DXT3 or Block Compression 2, converts 16 input pixels (corresponding to a 4x4 pixel block) into 128 bits of output, consisting of 64 bits of alpha channel data (4 bits for each pixel) followed by 64 bits of color data, encoded the same way as DXT1.

DXT5,BC3: Interpolated alpha

If your hardware supports BC7 compression, use that. The only benefit to this codec is for smooth alpha gradients in mobile hardware without BC7 support.

  • Alpha Premultiplied: No
  • Compression Ratio: 4:1
  • Texture Type: Gradient Alpha

DXT5 or Block Compression 3, converts 16 input pixels into 128 bits of output, consisting of 64 bits of alpha channel data (two 8-bit alpha values and a 4x4 3-bit lookup table) followed by 64 bits of color data (encoded the same way as DXT1). Because DXT5 use an interpolated alpha scheme, they generally produce superior results for alpha gradients than DXT3.

BPTC,BC7: High quality compression

Most textures should use this codec if your hardware supports it. It takes up the same amount of RAM and storage as BC2 and 3 but the results are superior. Use BC1 to cut down on resource usage when it makes sense and BC7 when you need the quality. Best for small and medium sized textures.

  • Alpha premultiplied: No
  • Compression ratio: 4:1
  • Texture Type: Gradient Alpha

BC7 encodes 16 input RGB8/RGBA8 pixels into 128 bits of output. BC7 have a much more complex algorithm with a selection of encoding modes. The quality is much better as a result.

Encoding with this codec can take a lot more computing power but there are mature tools to speed up the process.

Command line examples with Cuttlefish.

Precompiled binaries for Cuttlefish available. Windows/Mac/Linux supported. Apple M1 (ARM) binaries must be compiled manually.

Alpha is enabled by default [standard]. Disable it [none] or set it to premultiply [pre-multipied] based on the codec. The -j option or --jobs [n] is to enable multi-threading. Set it for a nice boost in performance.

DXT1,BC1 with 1-bit alpha:

cuttlefish -j --format bc1_rgba --alpha pre-multiped -i input.png -o output.dds

DXT1,BC1 opaque:

cuttlefish -j --format bc1_rgb --alpha none -i input.png -o output.dds

BPTC,BC7:

cuttlefish -j --format bc7 -i input.png -o output.dds

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment