fix(jump-hop): clean magenta cutout fringes
This commit is contained in:
@@ -385,7 +385,13 @@ fn remove_generated_asset_sheet_green_screen_background(
|
||||
let mut red = pixels[offset] as f32;
|
||||
let mut green = pixels[offset + 1] as f32;
|
||||
let mut blue = pixels[offset + 2] as f32;
|
||||
let blend = clamp_generated_asset_sheet_unit(contamination.max(0.22));
|
||||
let blend = if options.key_color.is_green_screen() {
|
||||
clamp_generated_asset_sheet_unit(contamination.max(0.22))
|
||||
} else {
|
||||
// 中文注释:洋红 / 青色等非绿幕 key 的残留更容易表现成彩边,
|
||||
// 需要比绿幕更强地向主体邻近色收敛,避免 PNG 边缘继续带 key 色。
|
||||
clamp_generated_asset_sheet_unit((key_score * 1.35).max(contamination).max(0.28))
|
||||
};
|
||||
|
||||
if let Some((sample_red, sample_green, sample_blue)) = sample {
|
||||
red = lerp_generated_asset_sheet_channel(red, sample_red as f32, blend);
|
||||
@@ -400,6 +406,17 @@ fn remove_generated_asset_sheet_green_screen_background(
|
||||
green = green.min(sample_green as f32 + 26.0);
|
||||
blue = blue.min(sample_blue as f32 + 26.0);
|
||||
}
|
||||
if !options.key_color.is_green_screen() && key_score > 0.04 {
|
||||
let defringed = suppress_generated_asset_sheet_key_color_fringe(
|
||||
[red, green, blue],
|
||||
[sample_red as f32, sample_green as f32, sample_blue as f32],
|
||||
key_score,
|
||||
options.key_color,
|
||||
);
|
||||
red = defringed[0];
|
||||
green = defringed[1];
|
||||
blue = defringed[2];
|
||||
}
|
||||
} else {
|
||||
if options.key_color.is_green_screen() && key_score > 0.04 {
|
||||
let toned_green = (green - (green - red.max(blue)) * 0.78)
|
||||
@@ -417,10 +434,26 @@ fn remove_generated_asset_sheet_green_screen_background(
|
||||
blue = blue.min(toned_value);
|
||||
}
|
||||
}
|
||||
if !options.key_color.is_green_screen() && key_score > 0.04 {
|
||||
let neutral = (red + green + blue) / 3.0;
|
||||
let defringed = suppress_generated_asset_sheet_key_color_fringe(
|
||||
[red, green, blue],
|
||||
[neutral, neutral, neutral],
|
||||
key_score,
|
||||
options.key_color,
|
||||
);
|
||||
red = defringed[0];
|
||||
green = defringed[1];
|
||||
blue = defringed[2];
|
||||
}
|
||||
}
|
||||
|
||||
let mut next_alpha = alpha;
|
||||
let edge_fade = (key_score * 0.35).max(white_score * 0.28);
|
||||
let edge_fade = if options.key_color.is_green_screen() {
|
||||
(key_score * 0.35).max(white_score * 0.28)
|
||||
} else {
|
||||
(key_score * 0.48).max(white_score * 0.28)
|
||||
};
|
||||
if edge_fade > 0.08 {
|
||||
next_alpha = ((alpha as f32) * (1.0 - edge_fade)).round() as u8;
|
||||
if next_alpha < 10 {
|
||||
@@ -448,6 +481,37 @@ fn remove_generated_asset_sheet_green_screen_background(
|
||||
changed
|
||||
}
|
||||
|
||||
pub(super) fn suppress_generated_asset_sheet_key_color_fringe(
|
||||
color: [f32; 3],
|
||||
target: [f32; 3],
|
||||
key_score: f32,
|
||||
key_color: GeneratedAssetSheetKeyColor,
|
||||
) -> [f32; 3] {
|
||||
let strength = clamp_generated_asset_sheet_unit(key_score * 1.18);
|
||||
let key_channels = [
|
||||
key_color.red as f32 / 255.0,
|
||||
key_color.green as f32 / 255.0,
|
||||
key_color.blue as f32 / 255.0,
|
||||
];
|
||||
let mut next = color;
|
||||
|
||||
for index in 0..3 {
|
||||
if key_channels[index] >= 0.66 {
|
||||
let cap = target[index] + 18.0 + (1.0 - strength) * 28.0;
|
||||
next[index] = next[index].min(lerp_generated_asset_sheet_channel(
|
||||
next[index],
|
||||
cap,
|
||||
strength,
|
||||
));
|
||||
} else if key_channels[index] <= 0.34 {
|
||||
next[index] =
|
||||
lerp_generated_asset_sheet_channel(next[index], target[index], strength * 0.72);
|
||||
}
|
||||
}
|
||||
|
||||
next
|
||||
}
|
||||
|
||||
fn compute_generated_asset_sheet_key_score(
|
||||
pixel: [u8; 4],
|
||||
key_color: GeneratedAssetSheetKeyColor,
|
||||
|
||||
Reference in New Issue
Block a user