Efradeca commited on
Commit
d3eb565
·
verified ·
1 Parent(s): 57a3f82

chore: deploy private lightloom build

Browse files
frontend/js/stage-scroll.js CHANGED
@@ -42,11 +42,17 @@ const Scroll = (() => {
42
  const MARCH_BIN = 7; // binary-refine steps inside the bracketed interval
43
  const VEL_TAU = 0.18; // s — exponential smoothing time-const for scroll velocity
44
  const VEL_REF = 220.0; // px/s mapped to full +/-1 parallax (scroll ~110px/s => ~0.5 budget)
45
- const AERIAL_DESAT = 0.06; // WHISPER desaturation at the far plane. Bigger values (0.45 then 0.15)
46
- // muted the picture — and DepthAnything reads big regions of painterly/
47
- // low-poly scenes as "far", so even a depth-gated cue spreads. Vivid wins.
48
- const AERIAL_HAZE = 0.05; // WHISPER haze tint toward far (kept tiny for the same reason)
49
- const AERIAL_BLUR = 0.35; // texel-scale of the far-plane 4-tap micro-blur (softens disocclusion)
 
 
 
 
 
 
50
  const HAZE_TINT = [0.62, 0.68, 0.78]; // cool sky/haze tint
51
  let imgCanvas = null, depCanvas = null, imgCtx = null, depCtx = null;
52
  let imgTex = null, depTex = null;
@@ -106,6 +112,16 @@ const Scroll = (() => {
106
  float d = pow(clamp(d0, 0.0, 1.0), uGamma);
107
  return clamp(uFocus + (d - uFocus) * uGain, 0.0, 1.0);
108
  }
 
 
 
 
 
 
 
 
 
 
109
  void main(){
110
  // view ray (parallax-occlusion): eyepoint shifts horizontally by P across the ray. ray param
111
  // t in [0,1]; ray height descends 1 -> 0; surface = heightAt(baseUv - P*t). First t where
@@ -152,15 +168,7 @@ const Scroll = (() => {
152
  c = mix(c, vec3(luma), uAerialDesat * farness);
153
  c = mix(c, uHazeTint, uAerialHaze * farness * farness);
154
 
155
- // NO sRGB re-encode here. The strip is a CanvasTexture sampled by a *custom* fragment shader,
156
- // so texture2D(uImg) returns the painter's already-sRGB bytes verbatim (Three.js only injects a
157
- // sRGB->linear decode for BUILT-IN materials, never for a raw texture2D() in a ShaderMaterial),
158
- // and this shader writes gl_FragColor straight to the framebuffer (no <colorspace_fragment>
159
- // chunk -> the renderer adds no output conversion either). Applying toSRGB() here was a SECOND
160
- // gamma OETF on top of the painter's: it lifted blacks 0.10->0.35 and mids 0.50->0.74, washing
161
- // every scene to a milky grey fog (worst in shadows) while .stylegrid PNGs stayed vivid. Output
162
- // the values as-is so on-screen color == the painter's color. (Aerial mixes above run in sRGB,
163
- // fine for a subtle cue.)
164
  c *= mix(0.92, 1.05, dHit); // near a touch brighter (aerial cue)
165
  float vy = smoothstep(0.0, 0.12, vUv.y) * smoothstep(1.0, 0.88, vUv.y);
166
  c *= mix(0.82, 1.0, vy);
 
42
  const MARCH_BIN = 7; // binary-refine steps inside the bracketed interval
43
  const VEL_TAU = 0.18; // s — exponential smoothing time-const for scroll velocity
44
  const VEL_REF = 220.0; // px/s mapped to full +/-1 parallax (scroll ~110px/s => ~0.5 budget)
45
+ const AERIAL_DESAT = 0.04; // whisper far-plane desaturation (depth cue). Verified: at 0.04 far content
46
+ // keeps ~85-96% chroma; the near-brightness mix below also reads as depth.
47
+ const AERIAL_HAZE = 0.0; // OFF. This was THE grey-blue fog: HAZE_TINT below is a LINEAR color that
48
+ // DISPLAYS at [206,215,229]/255 (bright grey-blue) after toSRGB, and mixing
49
+ // it in LINEAR space lifts dark/shadow pixels ~4x (sRGB-16 -> ~53), so big
50
+ // "far" regions milked out. DepthAnything reads large painterly areas as far,
51
+ // spreading it everywhere. Lowering it (0.45->0.15->0.05) kept firing; ZERO is
52
+ // the qualitative fix (line below becomes a no-op). Verified twice: removes the
53
+ // cast completely, does NOT darken (haze/desat are pre-toSRGB; brightness term
54
+ // untouched), parallax geometry untouched.
55
+ const AERIAL_BLUR = 0.35; // texel-scale of the far-plane 4-tap micro-blur — spatial only, no desat
56
  const HAZE_TINT = [0.62, 0.68, 0.78]; // cool sky/haze tint
57
  let imgCanvas = null, depCanvas = null, imgCtx = null, depCtx = null;
58
  let imgTex = null, depTex = null;
 
112
  float d = pow(clamp(d0, 0.0, 1.0), uGamma);
113
  return clamp(uFocus + (d - uFocus) * uGain, 0.0, 1.0);
114
  }
115
+ // Linear -> sRGB OETF. REQUIRED: the strip CanvasTexture has colorSpace=SRGB, which in three r160
116
+ // uploads it as SRGB8_ALPHA8 (WebGLTextures.getInternalFormat, three.module.js:24171), so the GPU
117
+ // DECODES sRGB->linear on every texture2D(uImg) sample -> c is LINEAR here. This custom shader has
118
+ // no <colorspace_fragment> chunk, so the renderer adds no output encode. We must encode linear->sRGB
119
+ // ourselves or the framebuffer (outputColorSpace=SRGB) shows the picture ~2.2-gamma too dark.
120
+ vec3 toSRGB(vec3 c){
121
+ c = max(c, vec3(0.0));
122
+ vec3 lo = c * 12.92; vec3 hi = 1.055 * pow(c, vec3(1.0/2.4)) - 0.055;
123
+ return mix(lo, hi, step(vec3(0.0031308), c));
124
+ }
125
  void main(){
126
  // view ray (parallax-occlusion): eyepoint shifts horizontally by P across the ray. ray param
127
  // t in [0,1]; ray height descends 1 -> 0; surface = heightAt(baseUv - P*t). First t where
 
168
  c = mix(c, vec3(luma), uAerialDesat * farness);
169
  c = mix(c, uHazeTint, uAerialHaze * farness * farness);
170
 
171
+ c = toSRGB(c); // linear -> sRGB for the framebuffer (see note above)
 
 
 
 
 
 
 
 
172
  c *= mix(0.92, 1.05, dHit); // near a touch brighter (aerial cue)
173
  float vy = smoothstep(0.0, 0.12, vUv.y) * smoothstep(1.0, 0.88, vUv.y);
174
  c *= mix(0.82, 1.0, vy);
src/lightloom/paint/scroll.py CHANGED
@@ -119,7 +119,9 @@ def outpaint_right(
119
  from PIL import Image
120
 
121
  width = overlap + seg_w
122
- canvas = Image.new("RGB", (width, height), (90, 105, 120))
 
 
123
  mask = Image.new("L", (width, height), 255) # generate everything…
124
  if context is not None:
125
  ctx = context.crop((context.width - overlap, 0, context.width, context.height))
 
119
  from PIL import Image
120
 
121
  width = overlap + seg_w
122
+ # neutral grey base (matches the proven-vivid fresh/stylegrid path); the old blue-grey
123
+ # (90,105,120) is a saturated tint that can bleed at the first strip / disoccluded edges.
124
+ canvas = Image.new("RGB", (width, height), (128, 128, 128))
125
  mask = Image.new("L", (width, height), 255) # generate everything…
126
  if context is not None:
127
  ctx = context.crop((context.width - overlap, 0, context.width, context.height))