diff --git a/CHANGELOG.md b/CHANGELOG.md index 27f99d7b..2b23a4fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ - 部署指南:固定访问地址、反代开 HTTP/2、Cloudflare 缓存规则。 ### 界面 +- 官方战场场景的光照改回提取出的官方值:直射光和烘焙光不再被压暗,场景不再明显偏暗(#549,PR #554,感谢 @xcdoge)。 - 最后一个还没选策略的玩家不再看到可点的「跳过」按钮:已经选完的玩家仍显示在顺序里,但不算可以让过去的人(PR #546,感谢 @Xinglan233)。 ### 工具与开发 diff --git a/docs/design/client.md b/docs/design/client.md index b7d1bfe2..65472eb5 100644 --- a/docs/design/client.md +++ b/docs/design/client.md @@ -92,7 +92,7 @@ Findings (2026-09-28): 卫戍协议 levels have no scene bundle (`mapId` null; t Correction (2026-10-11, GitHub #532; PR #533 by @andrew05060414): the first finding above was made off season and is wrong. While a season runs, the official hot-update list carries **one prebuilt scene per battlefield** — `scenes/activities/act1autochess/level_act1autochess_m01…m07` and `scenes/activities/act2autochess/level_act2autochess_m01…m04` (each with `…/lightingdata.ab` and `…_lighting_settings.ab`; Android versions `25-11-21-15-21-44_ee1197`, `26-03-13-06-11-47_14fb99`, `26-04-13-12-31-42_e9b560`); the lists of 2026-09-13 and 2026-10-08 have none, and no 卫戍协议 level data either. The asset index of those versions (`.idx`: each bundle's dependencies) gives each scene's art: act1 m01–m07 and act2 m02 / m04 depend on `arts/maps/map_autochesssand` (m05 and act2 m04 also on `map_doss_shore`), act2 m01 on `map_lakegarden` + `map_syracuse_metro`, act2 m03 on `map_kxmr` + `map_lm_center`. **No battlefield scene depends on `arts/maps/map_autochess`** (the metal theme the procedural board below draws; in the current client the 矢量突破 scenes `act3break` use it). A scene holds the logic tiles (`(row,col)#tileKey` at anchor-local (col, row, −height), high ground 0.4), the art under `GraphicHolder` (static parts merged into "Combined Mesh (root: scene)" objects, lightmapped: Shadowmask mode, one directional key light), and three sub-graphics `HIDDEN@1…3` (`MapSubGraphicHolder`) that the game switches on: the left normal field, the right normal field and the boss field — the areas of `layout.js AREAS`. -Official battlefield scenes (`board3d/load.js loadScenePack`, `scene.js setScenePack`, `materials.js sceneMaterial`): when `data/local-assets.json` lists `scene/`, the 3D board draws that scene instead of the procedural tiles, cliffs and background plane; the devices, gate / objective boxes, field edges and terrain overlays stay as below. The base part is always drawn; a `HIDDEN@n` part is drawn when its centre lies in one of the built areas. Chunks of those shown parts that share a material and a lightmap page are one mesh when the area is built (`load.js mergeSceneChunks`); water shares a mesh across pages because its shader has no lightmap. A switched-off part stays out of that mesh. Without the scene (not extracted, a load failure, an unknown `version`) the procedural metal board is drawn as before. Approximations: the official shaders are not reproduced — a lit material is albedo × (the lightmap's baked light + key light · N·L · the baked shadow mask), in linear light; normal, metallic and emission maps, the vertex-colour blend (`_HG_VERTEX_COLOR_BLEND_ON`), the sky box, the map effects (`mapeff_*`) and the post-processing profile are not drawn; `Torappu/Scene/StylizedWater` is the board's water shader in the material's colours; crates cast no shadow on a scene. **[ASSUMED]** `SCENE_LIGHT` (`direct` 0.8, `indirect` 0.4, `ambient` 0.2: tuned by eye against the PRTS screenshot of 战场#06, the official post-processing being unknown) and the RGBM reading of the lightmap pages (`scenes.py decode_rgbm`: Unity's linear-space decode, range 5). Owner decision (2026-10-12): these extracted files belong to the 0.2.5 asset pack and may ship in the full release zip; a lite package or a source install may download and extract them on that machine. Missing extractor dependencies keep the metal board. The repository still never stores the official files. +Official battlefield scenes (`board3d/load.js loadScenePack`, `scene.js setScenePack`, `materials.js sceneMaterial`): when `data/local-assets.json` lists `scene/`, the 3D board draws that scene instead of the procedural tiles, cliffs and background plane; the devices, gate / objective boxes, field edges and terrain overlays stay as below. The base part is always drawn; a `HIDDEN@n` part is drawn when its centre lies in one of the built areas. Chunks of those shown parts that share a material and a lightmap page are one mesh when the area is built (`load.js mergeSceneChunks`); water shares a mesh across pages because its shader has no lightmap. A switched-off part stays out of that mesh. Without the scene (not extracted, a load failure, an unknown `version`) the procedural metal board is drawn as before. Approximations: the official shaders are not reproduced — a lit material is albedo × (the lightmap's baked light + key light · N·L · the baked shadow mask), in linear light; normal, metallic and emission maps, the vertex-colour blend (`_HG_VERTEX_COLOR_BLEND_ON`), the sky box, the map effects (`mapeff_*`) and the post-processing profile are not drawn; `Torappu/Scene/StylizedWater` is the board's water shader in the material's colours; crates cast no shadow on a scene. `SCENE_LIGHT` `direct` / `indirect` are 1, the scene's own key light and baked light (0.2.6, GitHub #549, PR #554 by @xcdoge; 0.2.5 had 0.8 / 0.4 tuned by eye); **[ASSUMED]** `ambient` 0.2 (a mesh without a lightmap page; the official post-processing being unknown) and the RGBM reading of the lightmap pages (`scenes.py decode_rgbm`: Unity's linear-space decode, range 5). Owner decision (2026-10-12): these extracted files belong to the 0.2.5 asset pack and may ship in the full release zip; a lite package or a source install may download and extract them on that machine. Missing extractor dependencies keep the metal board. The repository still never stores the official files. Target: a **real 3D board layer** rendered with three.js (vendored ESM, no CDN) underneath the existing Pixi layer: - Geometry generated from `data/stages.json` like the official builder: LOW tiles = top quads; HIGH tiles = raised blocks with side walls; forbidden/void, fences, gates (red), objective (blue), hand/temp pads, special terrain; UVs mapped onto the official atlas regions (reuse/extend `public/assets/local/map/autochess/tiles.json`); normal + emission + metallic maps; lighting tuned to match official screenshots (key directional light, ambient/hemisphere, soft contact shadows); official background meshes & texture; device meshes (OBJ exported by `tools/local-extract`) with their textures; animated gate/objective effects. diff --git a/docs/history/0.2.6.md b/docs/history/0.2.6.md index 96612e01..054d8808 100644 --- a/docs/history/0.2.6.md +++ b/docs/history/0.2.6.md @@ -104,3 +104,16 @@ keeps finished players for display, so its total length cannot establish that a counts order entries absent from `draft.picks`, alongside the existing turn and quota checks. The server's `skipBand` already rejects the final player with `BAD_TARGET / nobody to pass to`; its rule remains unchanged. Regression covers normal two-, three- and four-human browser flows, the final turn, and exhausted quota. + +### 31.7 Official scene light gains (#549) + +GitHub #549 (@xcdoge, confirmed by other players): the official battlefield scenes of 0.2.5 read much darker than the +official client. 0.2.5 scaled the two light terms of `sceneMaterial` below the values the extractor stores — +`SCENE_LIGHT.direct` 0.8 and `.indirect` 0.4, tuned by eye against one PRTS screenshot and marked [ASSUMED]. From 0.2.6 +both are 1: the key light at the scene's `light.intensity` and the lightmap's baked linear light as decoded +(`scenes.py decode_rgbm`). The maintainer compared the two on 2026-10-13 and chose the official values. PR #554 by +@xcdoge also raised `LIGHTING.emissive` from 0.25 to 1; that part is not taken: it retunes the procedural metal board +and its glass, which were matched to screenshots, and does not touch the scene meshes. `ambient` 0.2 (a mesh without a +lightmap page) stays [ASSUMED]. The water (#549's second half, PR #555) is unchanged here. + +Tests: `test/render/board3d-scene.test.js`; the 3D board browser suite with the extracted scenes. diff --git a/public/js/render/board3d/materials.js b/public/js/render/board3d/materials.js index 79ec86c9..aeefc085 100644 --- a/public/js/render/board3d/materials.js +++ b/public/js/render/board3d/materials.js @@ -349,9 +349,11 @@ export function smogMaterial(THREE, tex, focus) { * not reproduced: the albedo is lit by the baked indirect light of the scene's lightmap plus the scene's key light * masked by its baked shadow, in linear light (Unity's Shadowmask lighting mode). `range` — the linear light a lightmap * texel of 1.0 stands for when scene.json has no lightRange; [ASSUMED] `ambient` — the light of a mesh without a - * lightmap page; `direct` / `indirect` — gains of the two terms (1 = the scene's own values). + * lightmap page; `direct` / `indirect` — gains of the two terms, both 1: the scene's own values (the key light's + * `light.intensity`, and the lightmap's baked linear light, whose texel is (L / lightRange)^(1/2.2)). Anything below 1 + * darkens the board against the official render — 0.2.5 had 0.8 / 0.4 tuned by eye (GitHub #549, PR #554 by @xcdoge). */ -export const SCENE_LIGHT = Object.freeze({ range: 8.0, ambient: 0.2, direct: 0.8, indirect: 0.4 }); +export const SCENE_LIGHT = Object.freeze({ range: 8.0, ambient: 0.2, direct: 1, indirect: 1 }); const colorOf = (info, key, fallback = [1, 1, 1, 1]) => { const c = info && info.colors && Array.isArray(info.colors[key]) ? info.colors[key] : fallback;