acdream/tests/AcDream.Core.Tests
Erik 63b50c5291 fix(sky): retail-faithful keyframe lerp — separate-channel color/bright
Retail's SkyDesc::GetLighting at 0x00500ac9 (decomp lines 261317-261331)
lerps each color channel and the brightness scalar SEPARATELY, then
multiplies post-lerp:

  arg4.r = lerp(k1.amb_color.r, k2.amb_color.r, u)
  arg4.g = lerp(k1.amb_color.g, k2.amb_color.g, u)
  arg4.b = lerp(k1.amb_color.b, k2.amb_color.b, u)
  arg3   = lerp(k1.amb_bright, k2.amb_bright, u)
  final  = (arg4.rgb * arg3, ...)

acdream pre-multiplied (color × bright) at LOAD time
(`SkyDescLoader.cs:558-559`) and then lerped the product. For any
keyframe pair where both color and brightness change, the two are
mathematically distinct. Example, k1=(white, b=0.5) k2=(black, b=1.0)
at u=0.5:
  - retail: color=gray(0.5), bright=0.75 → final = (0.375, 0.375, 0.375)
  - acdream: lerp((0.5,0.5,0.5), (0,0,0), 0.5) = (0.25, 0.25, 0.25)

For Rainy/Cloudy DayGroups transitioning between dim and bright
keyframes, this contributes to subtle brightness divergence vs retail.

Refactor:
  SkyKeyframe stores DirColor / DirBright / AmbColor / AmbBright
    SEPARATELY (raw, not pre-multiplied).
  Computed properties SunColor and AmbientColor return the
    post-multiplied product, keeping the shader uniform interface
    (uSunColor / uAmbientColor) unchanged.
  SkyStateProvider.Interpolate lerps each raw channel, then constructs
    a new SkyKeyframe whose computed properties yield the correct
    post-lerp multiply.
  SkyDescLoader now stores raw values without pre-multiplying.
  GameWindow comment updated; no functional change there.
  Default factory + tests updated to use the new constructor parameters
    with DirBright=AmbBright=1.0 (preserving exact existing behavior).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 15:02:35 +02:00
..
Allegiance feat(allegiance): Phase H.2 AllegianceRequests + AllegianceTree model 2026-04-18 17:17:45 +02:00
Audio feat(audio): Phase E.2 OpenAL engine + SoundTable cookbook + hook wiring 2026-04-18 16:38:26 +02:00
Chat fix(chat): /help client-side handler + System dedup + ThatIsNotAValidCommand template 2026-04-25 21:22:07 +02:00
Combat feat(combat): Phase E.4 AttackTargetRequest + combat notification pipeline 2026-04-18 16:58:14 +02:00
Input feat(input): #24 Phase K.2 - auto-enter player mode at login + MMB mouse-look + DebugPanel free-fly + Tab to chat-input focus 2026-04-26 09:20:17 +02:00
Items feat(items): Phase F.2 ItemRepository + AppraiseRequest round-trip 2026-04-18 16:55:36 +02:00
Lighting feat(lighting): Phase G.2 — Setup.Lights + SetLightHook wiring 2026-04-19 10:46:49 +02:00
Meshing feat(net): Phase 6.6 — parse UpdateMotion (0xF74C) into MotionUpdated event 2026-04-11 20:33:26 +02:00
Physics fix(anim): physics velocity now sourced from MotionData — option B / r03 §1.3 2026-04-19 15:06:08 +02:00
Player feat(player): #5 PlayerDescription parser — Stam/Mana via attribute block 2026-04-25 16:42:24 +02:00
Plugins feat(core): add IGameState, IEvents, WorldEvents with replay-on-subscribe 2026-04-10 20:29:29 +02:00
Rendering feat(app): Phase B.2 — ChaseCamera (third-person follow camera) 2026-04-12 14:26:20 +02:00
Spells fix(player): EnchantmentMask bit fix + Vitae key=0 + absolute Vitals overlay 2026-04-25 18:15:20 +02:00
Streaming fix(app): Phase A.1 — pending-spawn list in GpuWorldState (proper fix) 2026-04-11 23:19:40 +02:00
Terrain fix(terrain): align per-cell triangle geometry with ACE's ConstructPolygons convention 2026-04-21 13:20:59 +02:00
Textures feat(core): SurfaceDecoder — add PFID_P8, PFID_R8G8B8, and PFID_X8R8G8B8 2026-04-11 19:23:57 +02:00
Vfx weather(phase-6a): port retail PhysicsScript runtime 2026-04-24 11:20:39 +02:00
World fix(sky): retail-faithful keyframe lerp — separate-channel color/bright 2026-04-27 15:02:35 +02:00
AcDream.Core.Tests.csproj feat(app): Phase A.1 — StreamingRegion (window set + diff with hysteresis) 2026-04-11 22:01:45 +02:00
SmokeTest.cs chore: phase 1 — add Core, Abstractions, App, Tests projects 2026-04-10 09:22:33 +02:00