mirror of
https://github.com/drewcassidy/quicktex.git
synced 2024-09-13 06:37:34 +00:00
Add endpoint search refinement
In theory, this is all of the rgbcx feature set!
This commit is contained in:
parent
06c9bacab0
commit
70c8169711
@ -55,6 +55,7 @@ BC1Encoder::BC1Encoder(InterpolatorPtr interpolator) : _interpolator(interpolato
|
||||
_endpoint_mode = EndpointMode::PCA;
|
||||
_orderings4 = 16;
|
||||
_orderings3 = 8;
|
||||
_search_rounds = 256;
|
||||
|
||||
OrderTable<3>::Generate();
|
||||
OrderTable<4>::Generate();
|
||||
@ -138,8 +139,12 @@ void BC1Encoder::EncodeBlock(Color4x4 pixels, BC1Block *dest) const {
|
||||
FindSelectors<ColorMode::ThreeColorBlack>(pixels, trial_result, ErrorMode::Full);
|
||||
RefineBlockLS<ColorMode::ThreeColorBlack>(pixels, trial_result, metrics_no_black, ErrorMode::Full, total_ls_passes);
|
||||
|
||||
if (trial_result.error < result.error) {
|
||||
result = trial_result; }
|
||||
if (trial_result.error < result.error) { result = trial_result; }
|
||||
}
|
||||
|
||||
// refine endpoints by searching for nearby colors
|
||||
if (result.error > 0 && _search_rounds > 0) {
|
||||
EndpointSearch(pixels, result, metrics);
|
||||
}
|
||||
|
||||
WriteBlock(result, dest);
|
||||
@ -743,4 +748,72 @@ void BC1Encoder::RefineBlockCF(Color4x4 &pixels, EncodeResults &block, BlockMetr
|
||||
}
|
||||
}
|
||||
|
||||
void BC1Encoder::EndpointSearch(Color4x4 &pixels, EncodeResults &block, BlockMetrics &metrics) const {
|
||||
if ((bool)(block.color_mode & ColorMode::Solid)) return;
|
||||
|
||||
static const std::array<Vector4Int, 16> voxels = {{
|
||||
{1, 0, 0, 3}, // 0
|
||||
{0, 1, 0, 4}, // 1
|
||||
{0, 0, 1, 5}, // 2
|
||||
{-1, 0, 0, 0}, // 3
|
||||
{0, -1, 0, 1}, // 4
|
||||
{0, 0, -1, 2}, // 5
|
||||
{1, 1, 0, 9}, // 6
|
||||
{1, 0, 1, 10}, // 7
|
||||
{0, 1, 1, 11}, // 8
|
||||
{-1, -1, 0, 6}, // 9
|
||||
{-1, 0, -1, 7}, // 10
|
||||
{0, -1, -1, 8}, // 11
|
||||
{-1, 1, 0, 13}, // 12
|
||||
{1, -1, 0, 12}, // 13
|
||||
{0, -1, 1, 15}, // 14
|
||||
{0, 1, -1, 14}, // 15
|
||||
}};
|
||||
|
||||
unsigned prev_improvement_index = 0;
|
||||
int forbidden_direction = -1;
|
||||
|
||||
for (unsigned i = 0; i < _search_rounds; i++) {
|
||||
const unsigned voxel_index = (unsigned)(i & 15);
|
||||
assert((unsigned)voxels[(unsigned)voxels[voxel_index][3]][3] == voxel_index); // make sure voxels are symmetrical
|
||||
|
||||
if ((int)(i & 31) == forbidden_direction) continue;
|
||||
|
||||
Vector4Int delta = voxels[voxel_index];
|
||||
EncodeResults trial_result = block;
|
||||
|
||||
if (i & 16) {
|
||||
trial_result.low.r = (uint8_t)clamp(trial_result.low.r + delta[0], 0, 31);
|
||||
trial_result.low.g = (uint8_t)clamp(trial_result.low.g + delta[1], 0, 63);
|
||||
trial_result.low.b = (uint8_t)clamp(trial_result.low.b + delta[2], 0, 31);
|
||||
} else {
|
||||
trial_result.high.r = (uint8_t)clamp(trial_result.high.r + delta[0], 0, 31);
|
||||
trial_result.high.g = (uint8_t)clamp(trial_result.high.g + delta[1], 0, 63);
|
||||
trial_result.high.b = (uint8_t)clamp(trial_result.high.b + delta[2], 0, 31);
|
||||
}
|
||||
|
||||
switch(block.color_mode) {
|
||||
default:
|
||||
case ColorMode::FourColor:
|
||||
FindSelectors<ColorMode::FourColor>(pixels, trial_result, _error_mode);
|
||||
break;
|
||||
case ColorMode::ThreeColor:
|
||||
FindSelectors<ColorMode::ThreeColor>(pixels, trial_result, ErrorMode::Full);
|
||||
break;
|
||||
case ColorMode::ThreeColorBlack:
|
||||
FindSelectors<ColorMode::ThreeColorBlack>(pixels, trial_result, ErrorMode::Full);
|
||||
break;
|
||||
}
|
||||
|
||||
if (trial_result.error < block.error) {
|
||||
block = trial_result;
|
||||
|
||||
forbidden_direction = delta[3] | (i & 16);
|
||||
prev_improvement_index = i;
|
||||
}
|
||||
|
||||
if (i - prev_improvement_index > 32) break;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace rgbcx
|
@ -162,5 +162,7 @@ class BC1Encoder final : public BlockEncoder<BC1Block, 4, 4> {
|
||||
template <ColorMode M> void RefineBlockLS(Color4x4 &pixels, EncodeResults &block, BlockMetrics &metrics, ErrorMode error_mode, unsigned passes) const;
|
||||
|
||||
template <ColorMode M> void RefineBlockCF(Color4x4 &pixels, EncodeResults &block, BlockMetrics &metrics, ErrorMode error_mode, unsigned orderings) const;
|
||||
|
||||
void EndpointSearch(Color4x4 &pixels, EncodeResults &block, BlockMetrics &metrics) const;
|
||||
};
|
||||
} // namespace rgbcx
|
||||
|
Loading…
Reference in New Issue
Block a user