Add Adaptive Spectral color prediction mode
This commit is contained in:
@@ -33,6 +33,11 @@ namespace {
|
||||
constexpr float TD_EFFECTIVE_ALPHA_DENSITY_SCALE = 0.6761904762f;
|
||||
constexpr float TD_EFFECTIVE_ALPHA_PASS_DENSITY = 0.05f;
|
||||
constexpr float TD_EFFECTIVE_ALPHA_WHITE_DENSITY = 0.35f;
|
||||
constexpr float ADAPTIVE_SPECTRAL_DENSITY_SCALE = 1.8f;
|
||||
constexpr float ADAPTIVE_SPECTRAL_PASS_DENSITY = 0.12f;
|
||||
constexpr float ADAPTIVE_SPECTRAL_SURFACE_SCATTER = 0.08f;
|
||||
constexpr float ADAPTIVE_SPECTRAL_NEUTRAL_MIX = 0.16f;
|
||||
constexpr float ADAPTIVE_SPECTRAL_SCATTER_WARMTH = 0.35f;
|
||||
constexpr float OKLAB_SOFT_CAP4_DARK4_MIN_L_WEIGHT = 1.f;
|
||||
constexpr float OKLAB_SOFT_CAP4_DARK4_MAX_AB_WEIGHT = 4.f;
|
||||
constexpr float OKLAB_SOFT_CAP4_DARK4_DARK_PENALTY = 4.f;
|
||||
@@ -653,6 +658,19 @@ std::array<float, 3> td_effective_alpha_transmission(const std::array<float, 3>
|
||||
return transmission_from_density_bias(td_effective_alpha_density_bias(srgb_color, role), scalar_transmission);
|
||||
}
|
||||
|
||||
std::array<float, 3> adaptive_spectral_density(const std::array<float, 3> &srgb_color)
|
||||
{
|
||||
const std::array<float, 3> linear = srgb_to_linear_color(srgb_color);
|
||||
std::array<float, 3> density;
|
||||
for (size_t channel = 0; channel < 3; ++channel)
|
||||
density[channel] = std::max(ADAPTIVE_SPECTRAL_PASS_DENSITY,
|
||||
-std::log(std::clamp(linear[channel], 1e-4f, 0.9999f)));
|
||||
const float weighted = std::max(1e-6f, linear_luminance(density));
|
||||
for (float &value : density)
|
||||
value /= weighted;
|
||||
return density;
|
||||
}
|
||||
|
||||
float ordered_stack_layer_opacity(const std::vector<float> &layer_opacities,
|
||||
const std::vector<float> &layer_opacities_by_depth,
|
||||
size_t component_count,
|
||||
@@ -779,6 +797,77 @@ std::array<float, 3> mix_ordered_stack_td_effective_alpha(
|
||||
return linear_to_srgb_color(accumulated);
|
||||
}
|
||||
|
||||
std::array<float, 3> mix_ordered_stack_adaptive_spectral(const std::vector<std::array<float, 3>> &colors_with_background,
|
||||
const std::vector<uint16_t> &surface_to_deep,
|
||||
const std::vector<float> &layer_opacities,
|
||||
const std::vector<float> &layer_opacities_by_depth)
|
||||
{
|
||||
if (colors_with_background.empty() || surface_to_deep.empty())
|
||||
return colors_with_background.empty() ? std::array<float, 3>{ { 0.f, 0.f, 0.f } } : colors_with_background.back();
|
||||
|
||||
const size_t component_count = colors_with_background.size() - 1;
|
||||
const std::array<float, 3> warm { 0.58f, 0.46f, 0.32f };
|
||||
std::array<float, 3> neutral;
|
||||
for (size_t channel = 0; channel < 3; ++channel) {
|
||||
neutral[channel] =
|
||||
(1.f - ADAPTIVE_SPECTRAL_SCATTER_WARMTH) * colors_with_background.back()[channel] +
|
||||
ADAPTIVE_SPECTRAL_SCATTER_WARMTH * warm[channel];
|
||||
}
|
||||
|
||||
std::vector<std::array<float, 3>> densities;
|
||||
densities.reserve(component_count);
|
||||
for (size_t component_idx = 0; component_idx < component_count; ++component_idx)
|
||||
densities.emplace_back(adaptive_spectral_density(colors_with_background[component_idx]));
|
||||
|
||||
std::array<float, 3> accumulated { 0.f, 0.f, 0.f };
|
||||
std::array<float, 3> remaining { 1.f, 1.f, 1.f };
|
||||
bool surface_layer = true;
|
||||
for (size_t depth_idx = 0; depth_idx < surface_to_deep.size(); ++depth_idx) {
|
||||
const uint16_t component_idx = surface_to_deep[depth_idx];
|
||||
if (size_t(component_idx) >= component_count)
|
||||
continue;
|
||||
const float opacity = ordered_stack_layer_opacity(layer_opacities,
|
||||
layer_opacities_by_depth,
|
||||
component_count,
|
||||
depth_idx,
|
||||
component_idx);
|
||||
const float scalar_transmission = std::pow(1.f - opacity, ADAPTIVE_SPECTRAL_DENSITY_SCALE);
|
||||
std::array<float, 3> transmission;
|
||||
for (size_t channel = 0; channel < 3; ++channel)
|
||||
transmission[channel] = std::pow(std::clamp(scalar_transmission, 1e-4f, 0.9999f),
|
||||
densities[size_t(component_idx)][channel]);
|
||||
if (surface_layer) {
|
||||
for (float &channel_transmission : transmission) {
|
||||
const float channel_opacity =
|
||||
std::clamp(ADAPTIVE_SPECTRAL_SURFACE_SCATTER +
|
||||
(1.f - ADAPTIVE_SPECTRAL_SURFACE_SCATTER) * (1.f - channel_transmission),
|
||||
1e-4f,
|
||||
0.9999f);
|
||||
channel_transmission = 1.f - channel_opacity;
|
||||
}
|
||||
surface_layer = false;
|
||||
}
|
||||
std::array<float, 3> layer;
|
||||
for (size_t channel = 0; channel < 3; ++channel)
|
||||
layer[channel] =
|
||||
(1.f - ADAPTIVE_SPECTRAL_NEUTRAL_MIX) * colors_with_background[size_t(component_idx)][channel] +
|
||||
ADAPTIVE_SPECTRAL_NEUTRAL_MIX * neutral[channel];
|
||||
const std::array<float, 3> layer_linear = srgb_to_linear_color(layer);
|
||||
for (size_t channel = 0; channel < 3; ++channel) {
|
||||
const float channel_opacity = 1.f - transmission[channel];
|
||||
accumulated[channel] += remaining[channel] * channel_opacity * layer_linear[channel];
|
||||
remaining[channel] *= transmission[channel];
|
||||
}
|
||||
if (std::max({ remaining[0], remaining[1], remaining[2] }) <= 1e-5f)
|
||||
break;
|
||||
}
|
||||
|
||||
const std::array<float, 3> background_linear = srgb_to_linear_color(neutral);
|
||||
for (size_t channel = 0; channel < 3; ++channel)
|
||||
accumulated[channel] += remaining[channel] * background_linear[channel];
|
||||
return linear_to_srgb_color(accumulated);
|
||||
}
|
||||
|
||||
std::array<float, 3> mix_ordered_stack_with_buffers(const std::vector<std::array<float, 3>> &colors_with_background,
|
||||
std::vector<float> &weights,
|
||||
const std::vector<uint16_t> &surface_to_deep,
|
||||
@@ -789,7 +878,8 @@ std::array<float, 3> mix_ordered_stack_with_buffers(const std::vector<std::array
|
||||
bool td_effective_alpha_correction,
|
||||
const std::vector<ColorSolverStackComponentRole> &component_roles,
|
||||
const std::vector<float> &layer_opacities_by_depth,
|
||||
const ColorSolverCalibratedStackModel *calibrated_stack_model)
|
||||
const ColorSolverCalibratedStackModel *calibrated_stack_model,
|
||||
bool adaptive_spectral_correction)
|
||||
{
|
||||
if (colors_with_background.empty() || surface_to_deep.empty())
|
||||
return colors_with_background.empty() ? std::array<float, 3>{ { 0.f, 0.f, 0.f } } : colors_with_background.back();
|
||||
@@ -809,7 +899,8 @@ std::array<float, 3> mix_ordered_stack_with_buffers(const std::vector<std::array
|
||||
td_effective_alpha_correction,
|
||||
component_roles,
|
||||
layer_opacities_by_depth,
|
||||
nullptr);
|
||||
nullptr,
|
||||
adaptive_spectral_correction);
|
||||
return eval_current_linear_affine_model(base, calibrated_stack_model->coefficients_linear_rgb);
|
||||
}
|
||||
case ColorSolverCalibratedStackModelKind::AlphaEffective:
|
||||
@@ -821,6 +912,8 @@ std::array<float, 3> mix_ordered_stack_with_buffers(const std::vector<std::array
|
||||
}
|
||||
}
|
||||
|
||||
if (adaptive_spectral_correction)
|
||||
return mix_ordered_stack_adaptive_spectral(colors_with_background, surface_to_deep, layer_opacities, layer_opacities_by_depth);
|
||||
if (td_effective_alpha_correction)
|
||||
return mix_ordered_stack_td_effective_alpha(colors_with_background, surface_to_deep, layer_opacities, 0.f, component_roles, layer_opacities_by_depth);
|
||||
if (beer_lambert_rgb_correction)
|
||||
@@ -1169,7 +1262,8 @@ void append_ordered_stack_candidate(ColorSolverOrderedStackCandidateSet &c
|
||||
bool td_effective_alpha_correction,
|
||||
const std::vector<ColorSolverStackComponentRole> &component_roles,
|
||||
const std::vector<float> &layer_opacities_by_depth,
|
||||
const ColorSolverCalibratedStackModel *calibrated_stack_model)
|
||||
const ColorSolverCalibratedStackModel *calibrated_stack_model,
|
||||
bool adaptive_spectral_correction)
|
||||
{
|
||||
std::vector<uint16_t> simulated_surface_to_deep;
|
||||
const std::vector<uint16_t> *mix_stack = &surface_to_deep;
|
||||
@@ -1188,7 +1282,8 @@ void append_ordered_stack_candidate(ColorSolverOrderedStackCandidateSet &c
|
||||
td_effective_alpha_correction,
|
||||
component_roles,
|
||||
layer_opacities_by_depth,
|
||||
calibrated_stack_model);
|
||||
calibrated_stack_model,
|
||||
adaptive_spectral_correction);
|
||||
const std::array<float, 3> perceptual = oklab_from_srgb(mixed);
|
||||
candidates.rgbs.emplace_back(mixed[0]);
|
||||
candidates.rgbs.emplace_back(mixed[1]);
|
||||
@@ -1305,7 +1400,8 @@ std::array<float, 3> mix_color_solver_ordered_stack(const std::vector<std::array
|
||||
bool td_effective_alpha_correction,
|
||||
const std::vector<ColorSolverStackComponentRole> &component_roles,
|
||||
const std::vector<float> &layer_opacities_by_depth,
|
||||
const ColorSolverCalibratedStackModel *calibrated_stack_model)
|
||||
const ColorSolverCalibratedStackModel *calibrated_stack_model,
|
||||
bool adaptive_spectral_correction)
|
||||
{
|
||||
if (component_colors.empty() || surface_to_deep.empty())
|
||||
return background_rgb;
|
||||
@@ -1323,7 +1419,8 @@ std::array<float, 3> mix_color_solver_ordered_stack(const std::vector<std::array
|
||||
td_effective_alpha_correction,
|
||||
component_roles,
|
||||
layer_opacities_by_depth,
|
||||
calibrated_stack_model);
|
||||
calibrated_stack_model,
|
||||
adaptive_spectral_correction);
|
||||
}
|
||||
|
||||
std::array<float, 3> color_solver_oklab_from_srgb(const std::array<float, 3> &rgb)
|
||||
@@ -1463,7 +1560,8 @@ std::string color_solver_ordered_stack_candidate_cache_key(const std::vector<std
|
||||
const std::vector<ColorSolverStackComponentRole> &component_roles,
|
||||
bool beam_search_stack_expansion,
|
||||
const std::vector<float> &layer_opacities_by_depth,
|
||||
const ColorSolverCalibratedStackModel *calibrated_stack_model)
|
||||
const ColorSolverCalibratedStackModel *calibrated_stack_model,
|
||||
bool adaptive_spectral_correction)
|
||||
{
|
||||
std::ostringstream key;
|
||||
key << component_colors.size();
|
||||
@@ -1473,12 +1571,13 @@ std::string color_solver_ordered_stack_candidate_cache_key(const std::vector<std
|
||||
key << "|lim" << candidate_limit;
|
||||
key << "|item" << stack_item_limit;
|
||||
const float safe_surface_scatter =
|
||||
td_effective_alpha_correction ?
|
||||
(td_effective_alpha_correction || adaptive_spectral_correction) ?
|
||||
0.f :
|
||||
std::clamp(std::isfinite(surface_scatter) ? surface_scatter : 0.f, 0.f, 0.5f);
|
||||
key << "|ss" << int(std::lround(safe_surface_scatter * 1000000.f));
|
||||
key << "|bl" << (beer_lambert_rgb_correction ? 1 : 0);
|
||||
key << "|ea" << (td_effective_alpha_correction ? 1 : 0);
|
||||
key << "|as" << (adaptive_spectral_correction ? 1 : 0);
|
||||
key << "|beam" << (beam_search_stack_expansion ? 1 : 0);
|
||||
if (td_effective_alpha_correction) {
|
||||
key << "|role";
|
||||
@@ -1535,7 +1634,8 @@ ColorSolverOrderedStackCandidateSet build_color_solver_ordered_stack_candidates(
|
||||
const std::vector<ColorSolverStackComponentRole> &component_roles,
|
||||
bool beam_search_stack_expansion,
|
||||
const std::vector<float> &layer_opacities_by_depth,
|
||||
const ColorSolverCalibratedStackModel *calibrated_stack_model)
|
||||
const ColorSolverCalibratedStackModel *calibrated_stack_model,
|
||||
bool adaptive_spectral_correction)
|
||||
{
|
||||
ColorSolverOrderedStackCandidateSet candidates;
|
||||
int simulated_depth = simulated_stack_depth > 0 ? simulated_stack_depth : stack_depth;
|
||||
@@ -1578,7 +1678,8 @@ ColorSolverOrderedStackCandidateSet build_color_solver_ordered_stack_candidates(
|
||||
td_effective_alpha_correction,
|
||||
component_roles,
|
||||
layer_opacities_by_depth,
|
||||
calibrated_stack_model);
|
||||
calibrated_stack_model,
|
||||
adaptive_spectral_correction);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1633,7 +1734,8 @@ ColorSolverOrderedStackCandidateSet build_color_solver_ordered_stack_candidates(
|
||||
td_effective_alpha_correction,
|
||||
component_roles,
|
||||
layer_opacities_by_depth,
|
||||
calibrated_stack_model);
|
||||
calibrated_stack_model,
|
||||
adaptive_spectral_correction);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -1666,7 +1768,8 @@ const ColorSolverOrderedStackCandidateSet &color_solver_ordered_stack_candidates
|
||||
const std::vector<ColorSolverStackComponentRole> &component_roles,
|
||||
bool beam_search_stack_expansion,
|
||||
const std::vector<float> &layer_opacities_by_depth,
|
||||
const ColorSolverCalibratedStackModel *calibrated_stack_model)
|
||||
const ColorSolverCalibratedStackModel *calibrated_stack_model,
|
||||
bool adaptive_spectral_correction)
|
||||
{
|
||||
const std::string key =
|
||||
color_solver_ordered_stack_candidate_cache_key(component_colors,
|
||||
@@ -1683,7 +1786,8 @@ const ColorSolverOrderedStackCandidateSet &color_solver_ordered_stack_candidates
|
||||
component_roles,
|
||||
beam_search_stack_expansion,
|
||||
layer_opacities_by_depth,
|
||||
calibrated_stack_model);
|
||||
calibrated_stack_model,
|
||||
adaptive_spectral_correction);
|
||||
auto it = cache.find(key);
|
||||
if (it != cache.end())
|
||||
return it->second;
|
||||
@@ -1703,7 +1807,8 @@ const ColorSolverOrderedStackCandidateSet &color_solver_ordered_stack_candidates
|
||||
component_roles,
|
||||
beam_search_stack_expansion,
|
||||
layer_opacities_by_depth,
|
||||
calibrated_stack_model)).first->second;
|
||||
calibrated_stack_model,
|
||||
adaptive_spectral_correction)).first->second;
|
||||
}
|
||||
|
||||
ColorSolverOrderedStackResult solve_color_solver_ordered_stack_result_for_target(
|
||||
|
||||
@@ -152,7 +152,8 @@ std::array<float, 3> mix_color_solver_ordered_stack(const std::vector<std::array
|
||||
bool td_effective_alpha_correction = false,
|
||||
const std::vector<ColorSolverStackComponentRole> &component_roles = {},
|
||||
const std::vector<float> &layer_opacities_by_depth = {},
|
||||
const ColorSolverCalibratedStackModel *calibrated_stack_model = nullptr);
|
||||
const ColorSolverCalibratedStackModel *calibrated_stack_model = nullptr,
|
||||
bool adaptive_spectral_correction = false);
|
||||
std::array<float, 3> color_solver_oklab_from_srgb(const std::array<float, 3> &rgb);
|
||||
std::array<float, 3> color_solver_srgb_from_oklab(const std::array<float, 3> &oklab);
|
||||
|
||||
@@ -184,7 +185,8 @@ std::string color_solver_ordered_stack_candidate_cache_key(const std::vector<std
|
||||
const std::vector<ColorSolverStackComponentRole> &component_roles = {},
|
||||
bool beam_search_stack_expansion = false,
|
||||
const std::vector<float> &layer_opacities_by_depth = {},
|
||||
const ColorSolverCalibratedStackModel *calibrated_stack_model = nullptr);
|
||||
const ColorSolverCalibratedStackModel *calibrated_stack_model = nullptr,
|
||||
bool adaptive_spectral_correction = false);
|
||||
ColorSolverOrderedStackCandidateSet build_color_solver_ordered_stack_candidates(
|
||||
const std::vector<std::array<float, 3>> &component_colors,
|
||||
const std::vector<float> &layer_opacities,
|
||||
@@ -200,7 +202,8 @@ ColorSolverOrderedStackCandidateSet build_color_solver_ordered_stack_candidates(
|
||||
const std::vector<ColorSolverStackComponentRole> &component_roles = {},
|
||||
bool beam_search_stack_expansion = false,
|
||||
const std::vector<float> &layer_opacities_by_depth = {},
|
||||
const ColorSolverCalibratedStackModel *calibrated_stack_model = nullptr);
|
||||
const ColorSolverCalibratedStackModel *calibrated_stack_model = nullptr,
|
||||
bool adaptive_spectral_correction = false);
|
||||
const ColorSolverOrderedStackCandidateSet &color_solver_ordered_stack_candidates(
|
||||
ColorSolverOrderedStackCandidateCache &cache,
|
||||
const std::vector<std::array<float, 3>> &component_colors,
|
||||
@@ -217,7 +220,8 @@ const ColorSolverOrderedStackCandidateSet &color_solver_ordered_stack_candidates
|
||||
const std::vector<ColorSolverStackComponentRole> &component_roles = {},
|
||||
bool beam_search_stack_expansion = false,
|
||||
const std::vector<float> &layer_opacities_by_depth = {},
|
||||
const ColorSolverCalibratedStackModel *calibrated_stack_model = nullptr);
|
||||
const ColorSolverCalibratedStackModel *calibrated_stack_model = nullptr,
|
||||
bool adaptive_spectral_correction = false);
|
||||
ColorSolverOrderedStackResult solve_color_solver_ordered_stack_result_for_target(
|
||||
const ColorSolverOrderedStackCandidateSet &candidates,
|
||||
const std::array<float, 3> &target_rgb,
|
||||
|
||||
@@ -816,6 +816,8 @@ static std::string top_surface_contoning_color_prediction_mode_name(int mode)
|
||||
return "rgb_beer_lambert";
|
||||
if (mode == int(TextureMappingZone::ContoningColorPredictionBasicReflectance))
|
||||
return "basic_reflectance";
|
||||
if (mode == int(TextureMappingZone::ContoningColorPredictionAdaptiveSpectral))
|
||||
return "adaptive_spectral";
|
||||
if (mode == int(TextureMappingZone::ContoningColorPredictionCalibratedCurrentLinearAffine))
|
||||
return "calibrated_current_linear_affine";
|
||||
if (mode == int(TextureMappingZone::ContoningColorPredictionCalibratedTdAlphaEffective))
|
||||
@@ -841,6 +843,10 @@ static int top_surface_contoning_color_prediction_mode_from_name(std::string nam
|
||||
name == "basic_reflectance_no_td_correction" ||
|
||||
name == "no_td_correction")
|
||||
return int(TextureMappingZone::ContoningColorPredictionBasicReflectance);
|
||||
if (name == "adaptive_spectral" ||
|
||||
name == "adaptive_spectral_td" ||
|
||||
name == "adaptive_spectral_td_effective")
|
||||
return int(TextureMappingZone::ContoningColorPredictionAdaptiveSpectral);
|
||||
if (name == "calibrated_current_linear_affine" ||
|
||||
name == "calibrated_current_affine" ||
|
||||
name == "current_linear_affine" ||
|
||||
@@ -2584,7 +2590,7 @@ void TextureMappingManager::load_entries(const std::string &serialized,
|
||||
color_prediction_mode_it->get<int>() :
|
||||
TextureMappingZone::DefaultTopSurfaceContoningColorPredictionMode,
|
||||
int(TextureMappingZone::ContoningColorPredictionDefault),
|
||||
int(TextureMappingZone::ContoningColorPredictionCalibratedDepthKernelLinear));
|
||||
int(TextureMappingZone::ContoningColorPredictionAdaptiveSpectral));
|
||||
zone.top_surface_contoning_beer_lambert_rgb_correction_enabled =
|
||||
TextureMappingZone::DefaultTopSurfaceContoningBeerLambertRgbCorrectionEnabled;
|
||||
zone.top_surface_contoning_td_effective_alpha_correction_enabled =
|
||||
|
||||
@@ -101,7 +101,8 @@ struct TextureMappingZone
|
||||
ContoningColorPredictionCalibratedCurrentLinearAffine = 4,
|
||||
ContoningColorPredictionCalibratedTdAlphaEffective = 5,
|
||||
ContoningColorPredictionCalibratedFreeAlphaEffective = 6,
|
||||
ContoningColorPredictionCalibratedDepthKernelLinear = 7
|
||||
ContoningColorPredictionCalibratedDepthKernelLinear = 7,
|
||||
ContoningColorPredictionAdaptiveSpectral = 8
|
||||
};
|
||||
|
||||
enum TopSurfaceContoningPolygonizationMode : uint8_t {
|
||||
@@ -232,7 +233,7 @@ struct TextureMappingZone
|
||||
static constexpr bool DefaultTopSurfaceContoningTdAdjustmentEnabled = true;
|
||||
static constexpr bool DefaultTopSurfaceContoningSurfaceScatterEnabled = false;
|
||||
static constexpr int DefaultTopSurfaceContoningColorPredictionMode = int(ContoningColorPredictionDefault);
|
||||
static constexpr int SlicerDefaultTopSurfaceContoningColorPredictionMode = int(ContoningColorPredictionTdEffectiveAlpha);
|
||||
static constexpr int SlicerDefaultTopSurfaceContoningColorPredictionMode = int(ContoningColorPredictionAdaptiveSpectral);
|
||||
static constexpr bool DefaultTopSurfaceContoningVariableLayerHeightCompensationEnabled = true;
|
||||
static constexpr bool DefaultTopSurfaceContoningBeerLambertRgbCorrectionEnabled =
|
||||
SlicerDefaultTopSurfaceContoningColorPredictionMode == int(ContoningColorPredictionBeerLambertRgb);
|
||||
@@ -396,7 +397,7 @@ struct TextureMappingZone
|
||||
return SlicerDefaultTopSurfaceContoningColorPredictionMode;
|
||||
return std::clamp(mode,
|
||||
int(ContoningColorPredictionTdEffectiveAlpha),
|
||||
int(ContoningColorPredictionCalibratedDepthKernelLinear));
|
||||
int(ContoningColorPredictionAdaptiveSpectral));
|
||||
}
|
||||
|
||||
static bool top_surface_contoning_color_prediction_mode_is_calibrated(int mode)
|
||||
|
||||
@@ -410,6 +410,9 @@ TextureMappingContoningSolver::TextureMappingContoningSolver(const TextureMappin
|
||||
const int effective_color_prediction_mode =
|
||||
TextureMappingZone::effective_top_surface_contoning_color_prediction_mode(
|
||||
zone.top_surface_contoning_color_prediction_mode);
|
||||
m_adaptive_spectral_correction_enabled =
|
||||
m_td_adjustment_enabled &&
|
||||
effective_color_prediction_mode == int(TextureMappingZone::ContoningColorPredictionAdaptiveSpectral);
|
||||
m_td_effective_alpha_correction_enabled =
|
||||
m_td_adjustment_enabled &&
|
||||
(effective_color_prediction_mode == int(TextureMappingZone::ContoningColorPredictionTdEffectiveAlpha) ||
|
||||
@@ -573,7 +576,8 @@ std::optional<std::array<float, 3>> TextureMappingContoningSolver::stack_rgb(
|
||||
m_td_effective_alpha_correction_enabled,
|
||||
m_component_roles,
|
||||
depth_layer_opacities,
|
||||
m_calibrated_stack_model.valid() ? &m_calibrated_stack_model : nullptr);
|
||||
m_calibrated_stack_model.valid() ? &m_calibrated_stack_model : nullptr,
|
||||
m_adaptive_spectral_correction_enabled);
|
||||
}
|
||||
|
||||
std::vector<float> TextureMappingContoningSolver::layer_opacities_by_depth(
|
||||
@@ -739,7 +743,8 @@ TextureMappingContoningStack TextureMappingContoningSolver::solve_impl(
|
||||
m_component_roles,
|
||||
beam_search_stack_expansion_enabled,
|
||||
depth_layer_opacities,
|
||||
m_calibrated_stack_model.valid() ? &m_calibrated_stack_model : nullptr);
|
||||
m_calibrated_stack_model.valid() ? &m_calibrated_stack_model : nullptr,
|
||||
m_adaptive_spectral_correction_enabled);
|
||||
}
|
||||
const ColorSolverOrderedStackResult solved =
|
||||
solve_color_solver_ordered_stack_result_for_target(*ordered_candidates, target_rgb, ColorSolverMode::OklabSoftCap4Dark4);
|
||||
|
||||
@@ -87,6 +87,7 @@ private:
|
||||
float m_surface_scatter { 0.f };
|
||||
ColorSolverMixModel m_mix_model { ColorSolverMixModel::PigmentPainter };
|
||||
bool m_td_adjustment_enabled { false };
|
||||
bool m_adaptive_spectral_correction_enabled { false };
|
||||
bool m_beer_lambert_rgb_correction_enabled { false };
|
||||
bool m_td_effective_alpha_correction_enabled { false };
|
||||
bool m_variable_layer_height_compensation_enabled { false };
|
||||
|
||||
@@ -714,8 +714,6 @@ std::map<unsigned int, unsigned int> raw_top_surface_slot_component_id_map(
|
||||
}
|
||||
}
|
||||
|
||||
const float max_match_distance_sq =
|
||||
TextureMappingManager::poor_color_match_distance() * TextureMappingManager::poor_color_match_distance();
|
||||
for (size_t component_idx = 0; component_idx < target_keys.size() && component_idx < mapping.size(); ++component_idx) {
|
||||
if (mapping[component_idx] != sentinel)
|
||||
continue;
|
||||
@@ -732,7 +730,7 @@ std::map<unsigned int, unsigned int> raw_top_surface_slot_component_id_map(
|
||||
best_source = source_idx;
|
||||
}
|
||||
}
|
||||
if (best_source < source_colors.size() && best_distance_sq <= max_match_distance_sq) {
|
||||
if (best_source < source_colors.size()) {
|
||||
mapping[component_idx] = best_source;
|
||||
used[best_source] = 1;
|
||||
}
|
||||
|
||||
@@ -98,6 +98,7 @@ struct TexturePreviewSimulationSettings
|
||||
bool contoning_flat_surface_quantization = false;
|
||||
bool contoning_flat_surface_pattern_blend = false;
|
||||
bool contoning_flat_surface_td_adjustment = false;
|
||||
bool contoning_flat_surface_adaptive_spectral_correction = false;
|
||||
bool contoning_flat_surface_beer_lambert_rgb_correction = false;
|
||||
bool contoning_flat_surface_td_effective_alpha_correction = false;
|
||||
bool contoning_flat_surface_beam_search_stack_expansion = false;
|
||||
@@ -1197,8 +1198,6 @@ std::unordered_map<unsigned int, uint16_t> raw_top_surface_component_indices_for
|
||||
}
|
||||
}
|
||||
|
||||
const float max_match_distance_sq =
|
||||
TextureMappingManager::poor_color_match_distance() * TextureMappingManager::poor_color_match_distance();
|
||||
for (size_t component_idx = 0; component_idx < target_keys.size() && component_idx < mapping.size(); ++component_idx) {
|
||||
if (mapping[component_idx] != sentinel)
|
||||
continue;
|
||||
@@ -1216,7 +1215,7 @@ std::unordered_map<unsigned int, uint16_t> raw_top_surface_component_indices_for
|
||||
best_source = source_idx;
|
||||
}
|
||||
}
|
||||
if (best_source < source_colors.size() && best_distance_sq <= max_match_distance_sq) {
|
||||
if (best_source < source_colors.size()) {
|
||||
mapping[component_idx] = best_source;
|
||||
used[best_source] = 1;
|
||||
}
|
||||
@@ -1333,7 +1332,8 @@ std::optional<std::array<float, 3>> raw_top_surface_stack_rgb_for_texture_previe
|
||||
std::vector<float>{},
|
||||
settings.contoning_flat_surface_calibrated_stack_model.valid() ?
|
||||
&settings.contoning_flat_surface_calibrated_stack_model :
|
||||
nullptr);
|
||||
nullptr,
|
||||
settings.contoning_flat_surface_adaptive_spectral_correction);
|
||||
}
|
||||
|
||||
std::vector<std::array<float, 3>> colors;
|
||||
@@ -2949,7 +2949,8 @@ std::array<float, 3> contoning_flat_surface_rgb_for_texture_preview(
|
||||
std::vector<float>{},
|
||||
settings.contoning_flat_surface_calibrated_stack_model.valid() ?
|
||||
&settings.contoning_flat_surface_calibrated_stack_model :
|
||||
nullptr);
|
||||
nullptr,
|
||||
settings.contoning_flat_surface_adaptive_spectral_correction);
|
||||
}
|
||||
}
|
||||
if (!candidates.empty()) {
|
||||
@@ -3111,6 +3112,9 @@ std::optional<TexturePreviewSimulationSettings> texture_preview_simulation_setti
|
||||
settings.contoning_flat_surface_beer_lambert_rgb_correction =
|
||||
settings.contoning_flat_surface_td_adjustment &&
|
||||
effective_color_prediction_mode == int(TextureMappingZone::ContoningColorPredictionBeerLambertRgb);
|
||||
settings.contoning_flat_surface_adaptive_spectral_correction =
|
||||
settings.contoning_flat_surface_td_adjustment &&
|
||||
effective_color_prediction_mode == int(TextureMappingZone::ContoningColorPredictionAdaptiveSpectral);
|
||||
settings.contoning_flat_surface_td_effective_alpha_correction =
|
||||
settings.contoning_flat_surface_td_adjustment &&
|
||||
(effective_color_prediction_mode == int(TextureMappingZone::ContoningColorPredictionTdEffectiveAlpha) ||
|
||||
@@ -3179,6 +3183,7 @@ std::optional<TexturePreviewSimulationSettings> texture_preview_simulation_setti
|
||||
contoning_flat_surface_preview_layer_opacities(settings);
|
||||
if (settings.contoning_flat_surface_layer_opacities.size() != settings.component_colors.size()) {
|
||||
settings.contoning_flat_surface_td_adjustment = false;
|
||||
settings.contoning_flat_surface_adaptive_spectral_correction = false;
|
||||
settings.contoning_flat_surface_beer_lambert_rgb_correction = false;
|
||||
settings.contoning_flat_surface_td_effective_alpha_correction = false;
|
||||
} else {
|
||||
@@ -3233,6 +3238,7 @@ size_t texture_preview_simulation_signature(const ModelVolume &model_volume,
|
||||
mix(std::hash<int>{}(settings.contoning_flat_surface_quantization ? 1 : 0));
|
||||
mix(std::hash<int>{}(settings.contoning_flat_surface_pattern_blend ? 1 : 0));
|
||||
mix(std::hash<int>{}(settings.contoning_flat_surface_td_adjustment ? 1 : 0));
|
||||
mix(std::hash<int>{}(settings.contoning_flat_surface_adaptive_spectral_correction ? 1 : 0));
|
||||
mix(std::hash<int>{}(settings.contoning_flat_surface_beer_lambert_rgb_correction ? 1 : 0));
|
||||
mix(std::hash<int>{}(settings.contoning_flat_surface_td_effective_alpha_correction ? 1 : 0));
|
||||
mix(std::hash<int>{}(settings.contoning_flat_surface_beam_search_stack_expansion ? 1 : 0));
|
||||
@@ -3356,7 +3362,8 @@ TexturePreviewSimulationResult build_simulated_texture_preview_result(size_t sig
|
||||
std::vector<float>{},
|
||||
settings.contoning_flat_surface_calibrated_stack_model.valid() ?
|
||||
&settings.contoning_flat_surface_calibrated_stack_model :
|
||||
nullptr) :
|
||||
nullptr,
|
||||
settings.contoning_flat_surface_adaptive_spectral_correction) :
|
||||
ColorSolverOrderedStackCandidateSet{};
|
||||
const std::vector<TexturePreviewMixCandidate> contoning_flat_surface_candidates =
|
||||
use_contoning_flat_surface_quantization &&
|
||||
|
||||
@@ -2340,6 +2340,8 @@ static int texture_mapping_generic_solver_mode_from_choice_selection(int selecti
|
||||
static wxString texture_mapping_contoning_color_prediction_mode_label(int mode)
|
||||
{
|
||||
switch (TextureMappingZone::effective_top_surface_contoning_color_prediction_mode(mode)) {
|
||||
case int(TextureMappingZone::ContoningColorPredictionAdaptiveSpectral):
|
||||
return _L("Adaptive Spectral");
|
||||
case int(TextureMappingZone::ContoningColorPredictionBeerLambertRgb):
|
||||
return _L("RGB Beer-Lambert - not recommended");
|
||||
case int(TextureMappingZone::ContoningColorPredictionBasicReflectance):
|
||||
@@ -4332,6 +4334,7 @@ private:
|
||||
|
||||
m_top_surface_contoning_td_correction_choice->Clear();
|
||||
add_mode(int(TextureMappingZone::ContoningColorPredictionDefault));
|
||||
add_mode(int(TextureMappingZone::ContoningColorPredictionAdaptiveSpectral));
|
||||
add_mode(int(TextureMappingZone::ContoningColorPredictionTdEffectiveAlpha));
|
||||
add_mode(int(TextureMappingZone::ContoningColorPredictionBeerLambertRgb));
|
||||
add_mode(int(TextureMappingZone::ContoningColorPredictionBasicReflectance));
|
||||
|
||||
Reference in New Issue
Block a user