microsoft / DirectXTex

DirectXTex texture processing library
https://walbourn.github.io/directxtex/
MIT License
1.79k stars 438 forks source link

Custom per-channel RGB weighting for DXT1-3 compress #84

Open elasota opened 6 years ago

elasota commented 6 years ago

The current "Compress" functions take all settings as a single flags DWORD and individual parameters, i.e.:

HRESULT __cdecl Compress( _In_ const Image& srcImage, _In_ DXGI_FORMAT format, _In_ DWORD compress, _In_ float threshold, _Out_ ScratchImage& cImage);

Using a compression settings struct aggregating all of the options instead would allow better forward compatibility, since non-flag options (or more than 32 flags) could be added without requiring new function signatures.

walbourn commented 6 years ago

What new options where you thinking of adding here?

Generally I can't break existing API signature compatibility, but I could certainly add new functions:

struct CompressOptions
{
    float threshold;
    ???
};

HRESULT __cdecl CompressEx( _In_ const Image& srcImage, _In_ DXGI_FORMAT format,
     _In_ DWORD compress, const CompressOptions& opts, _Out_ ScratchImage& cImage);
elasota commented 6 years ago

Configurable per-channel weights is probably the most important.

I'm not sure if ASTC support is planned, but if it is, then configurability will become more important because ASTC block configs are highly modular, so exhaustive searching the entire config space is much less practical and heuristics will be more important. The reference encoder has about 20 scalar options.

Some of those options would be useful in current-generation formats anyway, like the deblocking parameter (boosts edge pixel importance).

walbourn commented 3 years ago

Right now we have two 'channel-weight' options:

The default (as was in D3DX's DXT1-5 compressor for it's entire history):

// Perceptual weightings for the importance of each channel.
const HDRColorA g_Luminance(0.2125f / 0.7154f, 1.0f, 0.0721f / 0.7154f, 1.0f);
const HDRColorA g_LuminanceInv(0.7154f / 0.2125f, 1.0f, 0.7154f / 0.0721f, 1.0f);

I added an option via TEX_COMPRESS_UNIFORM to just use (1,1,1,1) weights (it was added to some Xbox 360 era tooling).

Are you thinking per-image custom weights are a thing worth tweaking, or is there some other common weighting scheme that you think would be useful?