From be8dd13fa34a3a7a6ecbeb4b018abc2b303d6543 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Tue, 29 Sep 2026 20:26:27 +0800 Subject: [PATCH] =?UTF-8?q?feat(sample-v35):=20=E5=A2=99=E9=A1=B6=E5=85=A8?= =?UTF-8?q?=E6=9D=BF=E5=90=8C=E8=89=B2=E7=BB=88=E8=A3=81=E8=90=BD=E5=9C=B0?= =?UTF-8?q?=E2=80=94=E2=80=94=E5=8D=97=E5=90=91=E5=A2=99=E6=A0=BC=E6=9A=97?= =?UTF-8?q?=E6=9D=A1=E4=B8=8ED=E6=8A=95=E5=BD=B1=E7=AB=8B=E9=9D=A2?= =?UTF-8?q?=E6=9A=97=E5=B8=A6=E5=BA=9F=E6=AD=A2,=E9=A1=B6=E9=9D=A2?= =?UTF-8?q?=E6=9D=90=E8=B4=A8=E5=8E=9F=E4=BA=AE=E5=BA=A6=E7=9B=B4=E5=A1=AB?= =?UTF-8?q?=E9=9B=B6=E9=98=B4=E5=BD=B1;F6=E6=94=B9=E5=A2=99=E9=A1=B6?= =?UTF-8?q?=E5=90=8C=E8=89=B2=E6=96=AD=E8=A8=80(=E5=AE=9E=E6=B5=8B?= =?UTF-8?q?=E6=9C=80=E5=A4=A7=E8=89=B2=E5=B7=AE1.7);55%=E9=94=81=E5=AE=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tools/render_sample_sheet_v3.py | 56 ++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 26 deletions(-) diff --git a/tools/render_sample_sheet_v3.py b/tools/render_sample_sheet_v3.py index 21ac7fc6..fb8a44c5 100644 --- a/tools/render_sample_sheet_v3.py +++ b/tools/render_sample_sheet_v3.py @@ -271,16 +271,10 @@ def apply_d_projection(board, gmap, cell): 北邻墙地面格 = 三段渐隐投影(顶带 0.22 格边,α0.28 起)。立体断言 F6/A6 的渲染承载。""" overlay = Image.new("RGBA", board.size, (0, 0, 0, 0)) d = ImageDraw.Draw(overlay) - HILITE = (196, 172, 132) - seg1, seg2 = int(cell * 0.16), int(cell * 0.25) + # v3.5:南临墙格的立面暗带+口沿高光已废止(用户终裁:墙顶零阴影全板同色同素材) for y in range(gmap.h): for x in range(gmap.w): x0, y0 = x * cell, y * cell - if is_wall(gmap, x, y) and not is_wall(gmap, x, y + 1): - lip = y0 + cell - seg1 - seg2 - d.rectangle([x0, lip, x0 + cell, lip + 2], fill=HILITE + (255,)) - d.rectangle([x0, lip + 2, x0 + cell, lip + 2 + seg1], fill=(0, 0, 0, 153)) - d.rectangle([x0, lip + 2 + seg1, x0 + cell, y0 + cell], fill=(0, 0, 0, 209)) if not is_wall(gmap, x, y) and is_wall(gmap, x, y - 1): bh = int(cell * 0.22) for i, a in enumerate([71, 36, 14]): @@ -582,15 +576,14 @@ def is_facade_cell(gmap, x, y): def lift_south_lip(tile): - """v3.3:南向墙格(南邻地)底部暗条改为顶面同款材质轻微暗档(×0.80)—— - 同一堵墙的顶面材质全板一致,南向厚度面只差明度,不再两截皮。终稿归瓦片重产(§8.5)。""" + """v3.3:南向墙格(南邻地)底部暗条以顶面材质**原亮度**直填—— + 全板墙顶同色同素材,零阴影零暗档(用户终裁:「这里没有什么阴影影响,它们是同样颜色的」)。终稿归瓦片重产(§8.5)。""" im = tile.convert("RGB") w, h = im.size y0 = int(h * 0.60) top_ref = im.crop((0, 0, w, y0)) # 顶面区材质 band_h = h - y0 - ref = top_ref.resize((w, band_h)) # 顶面纹理拉伸到暗条区(同材质) - ref = ref.point([min(255, int(i * 0.80)) for i in range(256)] * 3) + ref = top_ref.resize((w, band_h)) # v3.5:顶面纹理原亮度直填(无暗档无阴影——全板墙顶同色同素材) out = im.copy() out.paste(ref, (0, y0)) if tile.mode == "RGBA": @@ -967,25 +960,36 @@ def run_checks(board, placement, records, band, gmap, canvas_img=None): check("A3b", "图底分离读数(候选 Δ≥30——v2 阈值 55 与格底分档带数学冲突,校准归冻结批)", (wall_top - floor_px) >= 30, "墙顶 %.0f vs 地面 %.0f,Δ=%.0f(v2 阈值 55 系地板 L0.036 时代校定)" % (wall_top, floor_px, wall_top - floor_px)) - # F6 墙格顶面/立面双明度带(立体断言——南向临地墙格:顶 2/3 vs 立面下 1/3,体积感机器代理) + # F6 v3.5 改口径:墙顶全板同色(南向临地墙格顶面 vs 全板墙顶均值,逐通道差 ≤6—— + # 原"顶面/立面双明度带 Δ≥18"随南临暗带废止;立体感由 E 格墙面承载) south_cells = [(x, y) for y in range(gmap.h) for x in range(gmap.w) if is_wall(gmap, x, y) and not is_wall(gmap, x, y + 1)] rgbp = board.convert("RGB").load() - deltas = [] - for (x, y) in south_cells: - ts, bs = [], [] - for yy in range(4, CELL_D - 4, 2): + def _cell_top_mean(x, y): + vals = [] + for yy in range(4, int(CELL_D * 0.4), 2): for xx in range(4, CELL_D - 4, 2): - c = rgbp[x * CELL_D + xx, y * CELL_D + yy] - lv = 0.2126 * c[0] + 0.7152 * c[1] + 0.0722 * c[2] - (ts if yy < CELL_D * 2.0 / 3.0 else bs).append(lv) - if ts and bs: - deltas.append(sum(ts) / len(ts) - sum(bs) / len(bs)) - dmin = min(deltas) if deltas else 0.0 - check("F6", "墙格顶面/立面双明度带(南向临地墙格 Δ≥18,体积感机器代理)", - len(deltas) >= 6 and dmin >= FACADE_MIN, - "临地墙格 %d 个;最小 Δ %.1f;均 Δ %.1f(v1 实测均 71.6)" - % (len(deltas), dmin, sum(deltas) / len(deltas) if deltas else 0)) + vals.append(rgbp[x * CELL_D + xx, y * CELL_D + yy]) + n = len(vals) + return (sum(v[0] for v in vals) / n, sum(v[1] for v in vals) / n, sum(v[2] for v in vals) / n) + _excl_all = {FLAG_AT, HOVER_AT} | {(gx, gy) for (gx, gy, _k) in GLOW_CELLS} + all_tops = [_cell_top_mean(x, y) for y in range(gmap.h) for x in range(gmap.w) + if is_wall(gmap, x, y) and (y == 0 or gmap.grid[y-1][x] == "W") and (x, y) not in _excl_all] + ref = tuple(sum(v[i] for v in all_tops) / len(all_tops) for i in range(3)) + # 排除带附加层的格(旗/悬停/微光——信息层合法染色,不属墙顶色差) + _excl = {FLAG_AT, HOVER_AT} | {(gx, gy) for (gx, gy, _k) in GLOW_CELLS} + devs = [] + for (x, y) in south_cells: + if (x, y) in _excl: + continue + m = _cell_top_mean(x, y) + dev = max(abs(m[i] - ref[i]) for i in range(3)) + devs.append(dev) + dmax = max(devs) if devs else 0.0 + check("F6", "墙顶全板同色(南向墙格顶面 vs 全板均值逐通道差 ≤6;旗格排除)", + dmax <= 6.0, + "南向墙格 %d 个(排除 %d 个附加层格);最大色差 %.1f(参考均值 %s)" + % (len(devs), len(_excl & set(south_cells)), dmax, tuple(round(v) for v in ref))) # F7 整板悬崖 DEPTH_PX 同源(立体断言——解析 game 源码常量,样张悬崖带按其绘制) band_lv = region_luma(board, (CELL_D, board.size[1] - 3, board.size[0] - CELL_D, board.size[1] - 1)) cliff_d = int(round(DEPTH_PX or 0))