3dtours fe79d75669 docs: hand the Android team the recipe/QR deltas the studio just took
The five changes recipes-web landed on 2026-09-29 (34f8601, c0aaa67, bd57dd7,
3b92e4e) only put two new fields into the shareable payload, but four of them
change the look a given recipe produces — so both halves of the story belong in
one note, next to doc 8 which was written against 6814b05.

What the note says:

- The slider/store split. Web now reads EXPOSURE as stops (-5..+5, two decimals)
  and every develop knob as -100..+100, but paramDefs translates both ways and
  the stored units did not move: exposure is still +-10 units of 0.25 EV, every
  other knob is still +-10. Android can keep its +-10 sliders and still be
  byte-compatible, so the doc says that instead of asking for a UI port.
- The one place a unit really does differ: masks[].exposure is the EV itself
  (MASK_EXPOSURE_MAX = 5) because the shader reads pow(2.0, a.x). Getting that
  wrong is a factor of four, so it gets its own row and its own acceptance test.
- The recipe format did not change. The shareable object is still
  {name, baseFilter, adjustments, frameId, useGeotag}, adjustments still travels
  whole, and Android already keeps unknown fields through import -> Look ->
  export because only hslBands is sanitized. So masks survive web -> Android ->
  web today; that is worth an explicit round-trip test rather than being relied
  on as an accident.
- The two new mask fields: temperature (2500..10000 K, NEUTRAL_K = 5500) and
  tint (+-10), resolved in readMasks so a mask stored before them carries a gain
  of exactly (1,1,1), plus the extra float4 wb[count] uniform and the one line
  c = clamp(c * wb, 0, 1) right after EXPOSURE. Gain is hoisted to JS on purpose:
  the Kelvin fit is a curve and a second copy of it in SkSL is a second answer.
- whiteBalanceGain is the same arithmetic Android already has inline in
  getSkiaColorMatrix, so the port is a lift-and-shift with a bit-identical
  matrix as its acceptance test.

One divergence is called out rather than papered over: gradientMask.ts still
runs the old cg = clamp(lifted / max(l, 0.0004), 0.55, 1.35) for the tone knobs
inside a mask, and its comment still claims that is TONE_SKSL's own gain — which
stopped being true when c0aaa67 gave the frame-wide shader the hue-preserving
knee and the five-knot ramp. A mask's HIGHLIGHT is therefore not the frame-wide
HIGHLIGHT on a smaller area, and the note says which side of that the Android
port should follow until the project owner decides.

Verified: every file:line, commit hash and unit in the note was read back out of
origin/recipes-web at 3b92e4e (toneShader.ts, colorUtils.ts, paramDefs.ts,
gradientMask.ts, types/index.ts, ToolRail.tsx, App.tsx, recipeShare.ts) and out
of this branch (src/utils/colorUtils.ts:384-394, src/types/index.ts:81-105,
src/utils/recipeShare.ts:59-110), including grep runs showing Android has no
masks field at all. The measured WB numbers quoted (1.250 -> 1.724 inside the
mask, 0.994 -> 0.994 outside) are the ones the studio's own mask-wb check
produced against the live build.

ponytail: no code touched, one file. The mask-tone alignment is left as an open
question with both candidate behaviours written down, because choosing for the
owner would bake a look decision into two codebases at once.

Co-authored-by: PenguinHarness <noreply@penguin.local>
2026-09-29 17:42:34 +07:00
2026-07-17 09:33:24 +07:00
2026-07-17 09:33:24 +07:00
2026-07-17 09:33:24 +07:00
2026-07-17 09:33:24 +07:00
2026-07-17 09:33:24 +07:00
2026-07-17 09:33:24 +07:00
2026-07-17 09:33:24 +07:00
2026-07-17 09:33:24 +07:00
2026-07-17 09:33:24 +07:00
2026-07-17 09:33:24 +07:00
2026-07-17 09:33:24 +07:00
S
Description
No description provided
Readme 6.6 GiB
Languages
TypeScript 92.9%
Kotlin 5.7%
JavaScript 1.3%