diff --git a/applications/PoP/docs/shadow_atlas_plan.md b/applications/PoP/docs/shadow_atlas_plan.md index 5bbd3be..c20ba52 100644 --- a/applications/PoP/docs/shadow_atlas_plan.md +++ b/applications/PoP/docs/shadow_atlas_plan.md @@ -95,9 +95,24 @@ XOR идёт по тому, что УЖЕ на экране, то есть ре кадр. При 16 цветах разница уже есть: гибрид вдвое срезает «сильно» (257 → 129), но заметных всё равно две с лишним тысячи. -Решение: **32 цвета, стратегия A** — она проще всех и оставляет ВСЕ частые -цвета пиксельно точными. Если когда-нибудь понадобится ужаться до 16, -брать гибрид C, а не «самые частые». +### Решение: **16 цветов, стратегия C (гибрид 10 + 6)** + +Числа выше — про пиксели, а решает глаз. Отрендерил одни и те же кадры в +трёх видах (точный цвет / 32 / 16) и сравнил в увеличении ×3: **отличий +не видно**. Объяснение в самих числах: перцептивно значимых пикселей при +16 цветах 2 275 на 253 кадра, это ~9 пикселей на кадр при ~1 000 видимых, +и они РАССЫПАНЫ по контуру, а не собраны в пятно. + +Поэтому берём 16, а не 32: экономим блок палитры (пригодится под будущие +наборы — принцесса, визирь, мышь), а разница неразличима. + +**Но стратегия обязана быть гибридной.** При 16 цветах «взять самые +частые» вдвое хуже по грубым промахам (257 пикселей против 129), и это +единственное место, где выбор стратегии виден. Гибрид: 10 самых частых +берём ТОЧНО, оставшиеся 6 слотов отдаём под взвешенные кластеры хвоста. + +Если в реальной игре кайма всё же будет резать глаз — переход на 32 цвета +это одна константа в упаковщике и один блок палитры, данные не меняются. ## 4. Палитра: что занято и куда класть @@ -115,8 +130,9 @@ XOR идёт по тому, что УЖЕ на экране, то есть ре 16. Оговорки: 0xFF в наших атласах это маркер прозрачности, а запись 0 правит `flash_bg`, так что блоки 0x00 и 0xF0 лучше не трогать. -**Берём 0xA0..0xBF** (32 слота) — сразу за стражем, персонажи остаются -сгруппированы. +**Берём 0xA0..0xAF** (16 слотов) — сразу за стражем, персонажи остаются +сгруппированы, а блок 0xB0 остаётся свободным (под 32 цвета Тени, если +понадобится, или под будущие наборы). Важно: в наших атласах прозрачность кодируется байтом 0xFF, а исходный индекс 0 в них означает «прозрачно». У Тени **чёрный — настоящий цвет** @@ -137,12 +153,13 @@ XOR идёт по тому, что УЖЕ на экране, то есть ре ## 6. План работ **Ш1. Упаковщик** `toolchain/pop_pack_shadow.py`: прогнать оба набора -через алгоритм §1, собрать 32-цветную палитру, выдать +через алгоритм §1, собрать 16-цветную палитру гибридом (10 точных + 6 +кластеров хвоста), выдать `poc/res/shadow/shadow0..N.atl` + `shadow.pal` + `pop_shadow_atlas.h`. Критерий: предпросмотр PNG совпадает с видом Тени в SDLPoP. **Ш2. Загрузка**: `pop_shadow_load()` рядом с `pop_kid_load`, палитра в -0xA0..0xBF, и обе страницы дабл-буфера (как `bg_load_tile_pal`). +0xA0..0xAF, и обе страницы дабл-буфера (как `bg_load_tile_pal`). Грузить ЛЕНИВО — только когда на уровне есть Тень (4, 5, 6, 12), иначе 28 страниц EMM висят зря.