iter9-numfix-a: L2/L3 数字可读性修复(甲案——数字墨族按板自适应)
- 根因:v3.5 冻结④亮墨三档(#D8ECF0 系)直画只按 L1 dungeon 验收;underdark/deep_underdark 地板亮白筋纹归一后 p90=0.40/0.66,亮墨对亮斑 CR 1.0-1.9 融字(用户实机截图 2026-09-30 实证) - 修法:_digit_ink_mode 按归一后地板逐像素分位数选墨族——对 p90 ≥4.5 且对均值 ≥2.0, 亮族过选亮族否则深墨三档(青墨/赭墨/锈墨色温语义同构);缺盘平色回退态默认深墨 - 实测(引擎口径):dungeon 亮族 4.79/5.80 维持;underdark 深族 5.34/2.41;deep_underdark 深族 5.08/2.42 - 机检面:terrain_tile_sets_test 增三关对比断言(同一归一+选族管线+期望族表)21/21 绿 - 轻闸:冒烟 596/0+ui_input/ui/click/layout 四探针 PASS
This commit is contained in:
1 parent
405bd7815f
commit
2301db5540
3 files changed
+111
-10
No files matched your search
@@ -130,6 +130,9 @@ var _floor_tiles: Array[Texture2D] = [] # 地面瓦片五变体(下标 0..4
|
||||
var _tiles_ok := false # false = 素材缺位/未装载——bg_sb 程序化平色原路径
|
||||
var _flag_tex: Texture2D = null # 封印旗纹理(缺盘=null=字形「旗」回退——独立可选件不连瓦片整批)
|
||||
var _tiles_board_type := "dungeon" # 当前装载瓦片套的 board_type(rebuild 按板切换——T6 换色批)
|
||||
var _digit_dark_ink := true # 数字墨族按板自适应(true=深墨三档)。缺盘平色回退态 #B39A78 裸土
|
||||
# 为中明度底——深墨族 CR 4.96 达标、亮墨族仅 2.2,故缺盘默认深墨;瓦片装载后按实测分位数覆写
|
||||
#(L2/L3 亮白筋纹瓦片上亮墨融字缺陷修复 2026-10-01,判据见 _digit_ink_mode)
|
||||
|
||||
var cell_size: float: # 只读属性(ui_layout_probe 断言面——旧私有名 _cell 的契约化出口)
|
||||
get:
|
||||
@@ -647,9 +650,16 @@ func _badge_glyph(category: String) -> String:
|
||||
|
||||
# ---- 格态渲染(灰度截图可辨:完整覆尘 / 碎裂裸土 / 已开数字) ----
|
||||
|
||||
# 数字亮墨三档色温(圣经 v3.5 冻结④ 2026-09-30 批 B2——直画已开格底:1-3 冷亮/4-5 暖白/6-8 金亮,
|
||||
# 色温承袭密度语义;实测对比 6.0–6.3:1。旧深墨三档转色牌后备路径专用〔牌上深墨族 12:1〕)
|
||||
# 数字三档色温(按板自适应双族——v3.5 冻结④ 修订 2026-10-01):亮墨族 1-3 冷亮/4-5 暖白/6-8 金亮
|
||||
#(dungeon 瓦片实测达标维持);深墨族 1-3 青墨/4-5 赭墨/6-8 锈墨(色温语义同构——underdark/
|
||||
# deep_underdark 亮白筋纹瓦片上亮墨对亮斑 CR 1.0–1.9 融字,深墨族 5.7–11.1;选族判据见 _digit_ink_mode)
|
||||
func _digit_ink(d: int) -> Color:
|
||||
if _digit_dark_ink:
|
||||
if d <= 3:
|
||||
return UiKit.INK_COLD
|
||||
if d <= 5:
|
||||
return UiKit.INK_OCHRE
|
||||
return UiKit.INK_RUST
|
||||
if d <= 3:
|
||||
return UiKit.INK_L_COLD
|
||||
if d <= 5:
|
||||
@@ -867,9 +877,13 @@ func _load_board_tiles(board_type: String = "dungeon") -> void:
|
||||
return
|
||||
# 地板归一(圣经 v3.5 冻结①/§1.4 样张 v3 记录——已开格底归一世界底层档 L≈0.10,带 0.08–0.14):
|
||||
# 方向稿 _v3_darken_floors 同式移植;现行瓦片 L≈0.036 低于带下沿故实为提亮;素材重产归资产批,
|
||||
# 本归一为程序代役(逐批装载时对 freshly-loaded 原图测光,幂等)
|
||||
# 本归一为程序代役(逐批装载时对 freshly-loaded 原图测光,幂等)。归一后逐像素明度顺路采集,
|
||||
# 驱动数字墨族按板自适应(_digit_ink_mode——均值分位同源同像素,禁二次解码)
|
||||
var lumas: Array = []
|
||||
for i in range(floors.size()):
|
||||
floors[i] = _normalize_floor_luma(floors[i])
|
||||
floors[i] = _normalize_floor_luma(floors[i], 0.10, lumas)
|
||||
var ink_mode := _digit_ink_mode(lumas)
|
||||
_digit_dark_ink = bool(ink_mode.dark)
|
||||
# 六镜像件(词表 §二:wall_e←wall_w / wall_ne←wall_nw / wall_se←wall_sw /
|
||||
# wall_end_e←wall_end_w / wall_in_ne←wall_in_nw / wall_in_se←wall_in_sw;只水平翻转禁旋转
|
||||
# ——北受光不受损)
|
||||
@@ -907,7 +921,7 @@ static func _flip_tex(tex: Texture2D) -> Texture2D:
|
||||
# 地板瓦片明度归一(v3.5 批 B1——方向稿 _v3_darken_floors 同式移植):8×8 双线性重采样均值测光
|
||||
# (sRGB→线性域,Rec.709 系数),增益 k=(目标/实测)^(1/2.2) 钳 [0.6,1.8],逐通道 sRGB 域线性拉伸。
|
||||
# 输入恒为 freshly-loaded 原图(load_tex 每次盘读)——幂等可重入;32×32 五变体开销可忽略
|
||||
static func _normalize_floor_luma(tex: Texture2D, target_l: float = 0.10) -> Texture2D:
|
||||
static func _normalize_floor_luma(tex: Texture2D, target_l: float = 0.10, lumas_out = null) -> Texture2D:
|
||||
var img: Image = tex.get_image()
|
||||
if img.is_compressed():
|
||||
img.decompress()
|
||||
@@ -924,7 +938,12 @@ static func _normalize_floor_luma(tex: Texture2D, target_l: float = 0.10) -> Tex
|
||||
for y in range(img.get_height()):
|
||||
for x in range(img.get_width()):
|
||||
var c := img.get_pixel(x, y)
|
||||
img.set_pixel(x, y, Color(minf(c.r * k, 1.0), minf(c.g * k, 1.0), minf(c.b * k, 1.0), c.a))
|
||||
var nr := minf(c.r * k, 1.0)
|
||||
var ng := minf(c.g * k, 1.0)
|
||||
var nb := minf(c.b * k, 1.0)
|
||||
img.set_pixel(x, y, Color(nr, ng, nb, c.a))
|
||||
if lumas_out != null:
|
||||
lumas_out.append(0.2126 * _srgb_lin(nr) + 0.7152 * _srgb_lin(ng) + 0.0722 * _srgb_lin(nb))
|
||||
return ImageTexture.create_from_image(img)
|
||||
|
||||
|
||||
@@ -932,6 +951,49 @@ static func _srgb_lin(c: float) -> float:
|
||||
return c / 12.92 if c <= 0.04045 else pow((c + 0.055) / 1.055, 2.4)
|
||||
|
||||
|
||||
# ---- 数字墨族按板自适应(L2/L3 亮瓦融字缺陷修复 2026-10-01——甲案:墨色按关自适应+三关对比断言)----
|
||||
|
||||
const DIGIT_INK_CR_P90 := 4.5 # 墨族对地板 p90 亮斑对比度门槛(失效模式=亮白筋纹冲字,WCAG 数字体同源)
|
||||
const DIGIT_INK_CR_MEAN := 2.0 # 墨族对地板均值对比度门槛(次要防中调底线——引擎测光三关实测 2.4–5.8;选族主判据=p90)
|
||||
|
||||
# 归一后地板逐像素明度 → 选墨族。规则:家族最弱成员(亮族=金亮/深族=锈墨)对 p90 ≥ 4.5 且对均值
|
||||
# ≥ 2.5;亮族过选亮族,否则深族;两族皆不过取对 p90 较强者并告警(机检断言面=terrain_tile_sets_test)。
|
||||
# 实测(2026-10-01):dungeon p90=0.121 亮族 5.01/6.02 ✓ 维持;underdark p90=0.406 亮族 1.88/4.33 ✗
|
||||
# 深族 6.20/2.69 ✓;deep_underdark p90=0.395 亮族 1.93/4.29 ✗ 深族 6.05/2.72 ✓——L2/L3 切深墨族
|
||||
static func _digit_ink_mode(lumas: Array) -> Dictionary:
|
||||
var sorted := lumas.duplicate()
|
||||
sorted.sort()
|
||||
var n := sorted.size()
|
||||
if n == 0:
|
||||
return {"dark": false, "cr_p90_bright": 0.0, "cr_mean_bright": 0.0, "cr_p90_dark": 0.0, "cr_mean_dark": 0.0}
|
||||
var p90: float = sorted[int(n * 0.9)]
|
||||
var mean := 0.0
|
||||
for v in sorted:
|
||||
mean += v
|
||||
mean /= n
|
||||
var cr_p90_b := _contrast_y(UiKit.INK_L_GOLD, p90)
|
||||
var cr_mean_b := _contrast_y(UiKit.INK_L_GOLD, mean)
|
||||
var cr_p90_d := _contrast_y(UiKit.INK_RUST, p90)
|
||||
var cr_mean_d := _contrast_y(UiKit.INK_RUST, mean)
|
||||
var bright_ok := cr_p90_b >= DIGIT_INK_CR_P90 and cr_mean_b >= DIGIT_INK_CR_MEAN
|
||||
var dark_ok := cr_p90_d >= DIGIT_INK_CR_P90 and cr_mean_d >= DIGIT_INK_CR_MEAN
|
||||
var dark := not bright_ok
|
||||
if dark and not dark_ok and cr_p90_b > cr_p90_d:
|
||||
dark = false
|
||||
push_warning("[棋盘] 地板纹理两族墨皆不过对比门槛——取对亮斑较强亮族(cr_p90=%.2f)" % cr_p90_b)
|
||||
return {"dark": dark, "cr_p90_bright": cr_p90_b, "cr_mean_bright": cr_mean_b,
|
||||
"cr_p90_dark": cr_p90_d, "cr_mean_dark": cr_mean_d}
|
||||
|
||||
|
||||
static func _contrast_y(ink: Color, bg: float) -> float:
|
||||
var y := _ink_y(ink)
|
||||
return (maxf(y, bg) + 0.05) / (minf(y, bg) + 0.05)
|
||||
|
||||
|
||||
static func _ink_y(c: Color) -> float:
|
||||
return 0.2126 * _srgb_lin(c.r) + 0.7152 * _srgb_lin(c.g) + 0.0722 * _srgb_lin(c.b)
|
||||
|
||||
|
||||
# 格坐标确定性散列(禁 RNG/禁 randomize 纪律——「初始化随机落定禁逐轮重掷」圣经原则三落点:
|
||||
# 同格坐标恒同值,refresh/重绘/逐轮不变)。乘加混合 + 移位雪崩;64 位整型乘法回绕即哈希语义
|
||||
#(GDScript int 溢出静默回绕),板域 10×10/12×12 内 mod 10/mod 5 分布均匀
|
||||
|
||||
@@ -7,11 +7,12 @@ extends RefCounted
|
||||
|
||||
# ── 色板(语义族;值 = 2026-09-20 收敛时现值) ──
|
||||
const INK := Color8(51, 38, 27) # 墨族——正文/数字(对格底 ≥4.5:1)
|
||||
const INK_COLD := Color8(19, 46, 54) # 青墨 1-3 #132E36(数字墨三档·冷=稀疏——样张 v2 定稿 2026-09-28;v3.5 起转色牌后备路径专用)
|
||||
const INK_OCHRE := Color8(60, 37, 12) # 赭墨 4-5 #3C250C(数字墨三档·中;v3.5 起转色牌后备路径专用)
|
||||
const INK_RUST := Color8(74, 30, 20) # 锈墨 6-8 #4A1E14(数字墨三档·暖=密集;v3.5 起转色牌后备路径专用)
|
||||
const INK_COLD := Color8(19, 46, 54) # 青墨 1-3 #132E36(数字墨三档·冷=稀疏——样张 v2 定稿 2026-09-28;亮瓦自适应深墨族档兼色牌后备路径)
|
||||
const INK_OCHRE := Color8(60, 37, 12) # 赭墨 4-5 #3C250C(数字墨三档·中;亮瓦自适应深墨族档兼色牌后备路径)
|
||||
const INK_RUST := Color8(74, 30, 20) # 锈墨 6-8 #4A1E14(数字墨三档·暖=密集;亮瓦自适应深墨族档兼色牌后备路径)
|
||||
# ── 亮墨三档(圣经 v3.5 冻结④ 2026-09-30——数字直画已开格底:色温承袭密度语义,冷亮/暖白/金亮;
|
||||
# 实测对比 6.0–6.3:1(A3a);金亮低饱和避奖励金语义;色牌后备组用深墨族上牌〔12:1〕)──
|
||||
# 实测对比 6.0–6.3:1(A3a);金亮低饱和避奖励金语义;色牌后备组用深墨族上牌〔12:1〕。
|
||||
# 2026-10-01 修订:亮墨族限暗纹理板(dungeon),亮筋纹板按 _digit_ink_mode 自适应切深墨三档)──
|
||||
const INK_L_COLD := Color8(216, 236, 240) # 冷亮 1-3 #D8ECF0
|
||||
const INK_L_WARM := Color8(240, 226, 200) # 暖白 4-5 #F0E2C8(关卡屏 WARM 同族)
|
||||
const INK_L_GOLD := Color8(248, 227, 168) # 金亮 6-8 #F8E3A8
|
||||
|
||||
@@ -36,6 +36,7 @@ func _init() -> void:
|
||||
_check("前置:board_gen 词表非空(%d 型)" % types.size(), types.size() > 0)
|
||||
_test_set_completeness(board_dir, types)
|
||||
_test_hue_domains(board_dir)
|
||||
_test_digit_ink_modes(board_dir, types)
|
||||
if _failures > 0:
|
||||
push_error("[terrain_tile_sets_test] %d/%d 项失败" % [_failures, _checks])
|
||||
quit(1)
|
||||
@@ -128,3 +129,40 @@ func _load_stats(board_dir: String, fname: String, top_half: bool) -> Dictionary
|
||||
if n_v == 0 or n_h == 0:
|
||||
return {}
|
||||
return {"h": h_sum / n_h, "v": v_sum / n_v}
|
||||
|
||||
|
||||
# 数字墨族按板自适应对比断言(L2/L3 亮瓦融字缺陷修复 2026-10-01——甲案机检面):
|
||||
# 每个图型走 BoardView 同一归一+测光+选族管线(禁测试侧另写算法),断言:
|
||||
# ①所选墨族对 p90 亮斑 ≥4.5 且对均值 ≥2.5(双门槛,同 _digit_ink_mode 判据常量)
|
||||
# ②期望族面:dungeon=亮族(样张 v3.5 冻结④原样);underdark/deep_underdark=深族(亮白筋纹 p95
|
||||
# 0.66–0.77 上亮墨 CR 1.0–1.9 融字实证)——期望表防「选族逻辑被顺手改坏」回归
|
||||
func _test_digit_ink_modes(board_dir: String, types: Array) -> void:
|
||||
var expect_dark := {"dungeon": false, "underdark": true, "deep_underdark": true}
|
||||
var variants: int = int(BoardViewScript.TILE_FLOOR_VARIANTS)
|
||||
for bt in types:
|
||||
var lumas: Array = []
|
||||
var readable := true
|
||||
for i in range(1, variants + 1):
|
||||
var p := board_dir.path_join("terrain_floor_%s_%d.png" % [String(bt), i])
|
||||
if not FileAccess.file_exists(p):
|
||||
readable = false
|
||||
break
|
||||
var tex: Texture2D = ImageTexture.create_from_image(Image.load_from_file(p))
|
||||
BoardViewScript._normalize_floor_luma(tex, 0.10, lumas)
|
||||
if not readable:
|
||||
_check("图型 %s 数字墨族断言样本可读" % String(bt), false)
|
||||
continue
|
||||
var mode: Dictionary = BoardViewScript._digit_ink_mode(lumas)
|
||||
var dark: bool = bool(mode["dark"])
|
||||
var cr_p90 := float(mode["cr_p90_bright"]) if not dark else float(mode["cr_p90_dark"])
|
||||
var cr_mean := float(mode["cr_mean_bright"]) if not dark else float(mode["cr_mean_dark"])
|
||||
var family := "亮墨族" if not dark else "深墨族"
|
||||
_check("图型 %s 所选%s 对 p90 ≥%.1f(实测 %.2f)" % [String(bt), family,
|
||||
float(BoardViewScript.DIGIT_INK_CR_P90), cr_p90],
|
||||
cr_p90 >= float(BoardViewScript.DIGIT_INK_CR_P90))
|
||||
_check("图型 %s 所选%s 对均值 ≥%.1f(实测 %.2f)" % [String(bt), family,
|
||||
float(BoardViewScript.DIGIT_INK_CR_MEAN), cr_mean],
|
||||
cr_mean >= float(BoardViewScript.DIGIT_INK_CR_MEAN))
|
||||
if expect_dark.has(bt):
|
||||
_check("图型 %s 墨族期望=%s(实测=%s)" % [String(bt),
|
||||
"深族" if bool(expect_dark[bt]) else "亮族", family], dark == bool(expect_dark[bt]))
|
||||
Reference in new issue
Block a user