@photivra/engine 2.17.0 → 2.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/CHANGELOG.md +49 -1
  2. package/CITATION.cff +1 -1
  3. package/README.md +6 -6
  4. package/SECURITY.md +1 -1
  5. package/dist/camera/sensor-equivalence.d.ts +156 -0
  6. package/dist/camera/sensor-equivalence.js +208 -0
  7. package/dist/camera/sensor-equivalence.js.map +1 -0
  8. package/dist/capture/native-environment-tabulated.d.ts +5 -0
  9. package/dist/capture/native-environment-tabulated.js +1 -1
  10. package/dist/capture/native-environment-tabulated.js.map +1 -1
  11. package/dist/core/version.d.ts +1 -1
  12. package/dist/core/version.js +1 -1
  13. package/dist/core/version.js.map +1 -1
  14. package/dist/equipment/ideal-lens.d.ts +25 -0
  15. package/dist/equipment/ideal-lens.js +21 -0
  16. package/dist/equipment/ideal-lens.js.map +1 -0
  17. package/dist/facade/catalogue-lens-signal.d.ts +94 -0
  18. package/dist/facade/catalogue-lens-signal.js +362 -0
  19. package/dist/facade/catalogue-lens-signal.js.map +1 -0
  20. package/dist/facade/defocus-image-space-provider.js +5 -2
  21. package/dist/facade/defocus-image-space-provider.js.map +1 -1
  22. package/dist/facade/display-view-lens-signal.d.ts +32 -1
  23. package/dist/facade/display-view-lens-signal.js +85 -10
  24. package/dist/facade/display-view-lens-signal.js.map +1 -1
  25. package/dist/facade/expected-signal-setup.d.ts +8 -0
  26. package/dist/facade/expected-signal-setup.js +7 -0
  27. package/dist/facade/expected-signal-setup.js.map +1 -1
  28. package/dist/facade/expected-signal.d.ts +5 -0
  29. package/dist/facade/expected-signal.js +5 -1
  30. package/dist/facade/expected-signal.js.map +1 -1
  31. package/dist/facade/generic-lens-capture.d.ts +1 -0
  32. package/dist/facade/generic-lens-capture.js +1 -0
  33. package/dist/facade/generic-lens-capture.js.map +1 -1
  34. package/dist/facade/simulate-capture.d.ts +31 -4
  35. package/dist/facade/simulate-capture.js +117 -38
  36. package/dist/facade/simulate-capture.js.map +1 -1
  37. package/dist/facade/simulate-display-view.js +1 -1
  38. package/dist/facade/simulate-display-view.js.map +1 -1
  39. package/dist/index.d.ts +3 -1
  40. package/dist/index.js +2 -0
  41. package/dist/index.js.map +1 -1
  42. package/docs/AGENT_GUIDE.md +3 -0
  43. package/docs/API_REFERENCE.md +29 -1
  44. package/docs/QUICK_START.md +49 -1
  45. package/docs/USAGE.md +43 -2
  46. package/docs/api/camera-sensor-equivalence.md +209 -0
  47. package/docs/api/core-version.md +1 -1
  48. package/docs/api/equipment-ideal-lens.md +26 -0
  49. package/docs/api/exports.json +67 -2
  50. package/docs/api/facade-simulate-capture.md +27 -4
  51. package/llms.txt +2 -0
  52. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalogue-lens-signal.js","sourceRoot":"","sources":["../../src/facade/catalogue-lens-signal.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * #568: the fast method of `simulateCapture`'s `lens.catalogue` (requested with `fast: true` or `lens.catalogue.fast`): each\n * native site's expected photo electrons from tables instead of the environment PSF quadrature's per-tap scene queries.\n * Loaded on demand with the catalogue (`generic-lens-capture.ts`), so a capture without a catalogue lens never loads it.\n *\n * What the exact method computes. The environment PSF quadrature forms, for site q of CFA channel c,\n * μ_c(q) = Σ_λ A_c(λ) Σ_k K_{q,λ}(k)·F(s_k)·L(D(s_k), λ), s_k = q + (c_x − k_x, k_y − c_y)·p,\n * with K_{q,λ} the catalogue PSF resolved at the site's own field point (`resolveLensSampledPsfKernel`: the profile's 5 × 5 field\n * nodes × 5 wavelength nodes interpolated with centroid alignment; row index k_y increases with image +Y, `sensorPsfSourcePoint`),\n * F = T·A the field factor at the tap point (vignetting throughput × distortion area factor), D the scene ray (inverse radial\n * distortion, then the rectilinear or equisolid projection at the thin-lens image distance) and A_c(λ) the electrons per unit\n * spectral radiance on the axis (the tabulated path's channel response). Every tap of a site-centre query is a lattice point.\n *\n * The approximation (the only one). Resolving K_{q,λ} at every site and spectral node is what makes the exact method slow, so the\n * fast method resolves it exactly on a field grid and blends it bilinearly between the four grid points around each site:\n * K̃_{q,λ} = Σ_g b_g(q)·K_{g,λ}.\n * The grid subdivides each interval between the profile's field nodes into at least GRID_MINIMUM_SUBDIVISIONS cells, and into\n * more where the node kernels' intensity centroids move by more than GRID_CENTROID_STEP_SITES sites across the interval (lateral\n * colour moves the PSF across the frame; a blend of two shifted kernels is not the shifted kernel). Since the blend is linear,\n * the channel response and the material radiance fold into the grid kernels once per grid point:\n * μ̃_c(q) = Σ_k F(s_k)·Σ_g b_g(q)·W_{g,c,m(s_k)}(k), W_{g,c,m}(k) = Σ_λ A_c(λ)·L_m(λ)·K_{g,λ}(k),\n * so a site costs (2R + 1)² taps instead of (2R + 1)² scene queries per spectral node. Its error against the exact method is\n * bounded by ‖K̃ − K‖₁ times the brightest tap's signal; tests measure both (test/simulate-capture-lens-catalogue-fast.test.ts).\n *\n * The scene points. The mapping is the environment's (`undistortedImagePoint`, `lensProjectionDirectionValue`, the planar\n * provider's plane point), with the radial inverse solved by Newton's method instead of bisection: both converge to the same\n * root to rounding. Outside a circular fisheye's image circle (`outsideImageCircle: \"backward-ray\"`) and beyond the horizon the\n * scene radiance is zero, as in the capture.\n */\n\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\nimport { insideRadialImageCircle, lensProjectionDirectionValue } from \"../camera/lens-projection.js\";\nimport { resolveProjectionDistanceMm } from \"../motion/camera-rotation.js\";\nimport { prepareIlluminationVignettingThroughput, type IlluminationVignettingProfile } from \"../optics/illumination-vignetting.js\";\nimport { resolveLensSampledPsfKernel, type ResolveLensSampledPsfInput } from \"../optics/lens-psf-profile.js\";\nimport type { DisplayViewScene } from \"./expected-signal.js\";\n\n/** Fewest grid cells between neighboring profile field nodes. */\nexport const CATALOGUE_FAST_GRID_MINIMUM_SUBDIVISIONS = 4;\n/** Largest move of a node kernel's intensity centroid across one grid cell, in sites (sets finer grids where lateral color moves the PSF). */\nexport const CATALOGUE_FAST_GRID_CENTROID_STEP_SITES = 0.05;\n/**\n * Largest relative difference between the fast and the exact expected electrons that the run-time verification (one site per\n * CFA phase through the exact chain, `renderTabulatedNativeRaw`) accepts; above it the capture runs the exact method.\n */\nexport const CATALOGUE_FAST_VERIFICATION_TOLERANCE = 0.005;\n/** Largest cache window, in lattice points; a larger window is evaluated without caching. */\nconst WINDOW_LIMIT = 1 << 22;\nconst NEWTON_ITERATIONS = 60;\n\nexport interface CatalogueLensSignalInput {\n nativeWidth: number;\n nativeHeight: number;\n /** Site pitch, µm. */\n pitch: number;\n /** The catalogue PSF's optical state (profile, focal length, focus, f-number, defocus), as the site inputs' `psf.configuration.psf`. */\n psf: Omit<ResolveLensSampledPsfInput, \"fieldPointMm\" | \"wavelengthNm\">;\n /** Spectral nodes and, per CFA channel (red, green, blue), the expected electrons per unit spectral radiance at each node. */\n wavelengthsNm: readonly number[];\n electronsPerRadiance: readonly [Float64Array, Float64Array, Float64Array];\n /** The scene's chart materials (the tabulated path's material tables). */\n scene: Extract<DisplayViewScene, { kind: \"materials\" }>;\n /** CFA channel index (0 red, 1 green, 2 blue) of native site (x, y). */\n channelAt(x: number, y: number): number;\n /** The radial distortion profile (r_d = r·(1 + k1ρ² + k2ρ⁴ + k3ρ⁶), ρ = r / normalizationRadiusMm); absent without distortion. */\n distortion?: { normalizationRadiusMm: number; coefficients: { k1: number; k2: number; k3: number } };\n vignetting?: IlluminationVignettingProfile;\n projection: \"rectilinear\" | \"fisheye-equisolid-angle\";\n /** True for a catalogue fisheye: a sensor point outside the image circle looks straight back and sees no scene. */\n outsideImageCircleSeesNothing: boolean;\n focalLengthMm: number;\n focusDistanceM: number;\n /** The planar provider's plane distance and frame-unit scale. */\n distanceM: number;\n metresPerFrameUnit: number;\n /** Internal test hook: resolve every site's kernels exactly (the exact method's sum, slowly) instead of blending the grid. */\n exactKernels?: boolean;\n}\n\nexport interface CatalogueLensSignal {\n /** Starts a cache window of native sites [x0, x1) × [y0, y1) (see `DisplayViewExpectedSignal.window`). */\n window(x0: number, y0: number, x1: number, y1: number): void;\n /** Expected photo electrons of native site (x, y) for its own CFA channel. */\n site(x: number, y: number): number;\n /** Scene material lookups so far. */\n readonly lookups: number;\n /** Grid points per axis (columns, rows) and how many were resolved so far. */\n readonly grid: { columns: number; rows: number; resolved: number };\n}\n\n/** A kernel's intensity centroid, in samples. */\nfunction centroid(values: readonly number[], width: number): { x: number; y: number } {\n let sum = 0, x = 0, y = 0;\n for (let i = 0; i < values.length; i++) { const v = values[i]!; sum += v; x += v * (i % width); y += v * Math.floor(i / width); }\n return { x: x / sum, y: y / sum };\n}\n\n/**\n * The grid axes: each interval between neighboring profile field nodes split into max(GRID_MINIMUM_SUBDIVISIONS,\n * ⌈Δc / GRID_CENTROID_STEP_SITES⌉) equal cells, Δc the largest centroid move between the interval's two nodes over the other\n * axis's nodes and the wavelength nodes.\n */\nexport function catalogueFastGridAxes(psf: CatalogueLensSignalInput[\"psf\"]): { x: number[]; y: number[] } {\n const profile = psf.profile, axes = profile.axes, fx = axes.fieldXmm, fy = axes.fieldYmm, wl = axes.wavelengthNm;\n const centroids = new Map<string, { x: number; y: number }>();\n for (const node of profile.nodes) {\n const c = node.coordinate;\n centroids.set(c.fieldXmm + \":\" + c.fieldYmm + \":\" + c.wavelengthNm, centroid(node.kernel.normalizedIntensity, node.kernel.widthSamples));\n }\n const at = (x: number, y: number, nm: number): { x: number; y: number } => {\n const c = centroids.get(x + \":\" + y + \":\" + nm);\n if (!c) throw new InvalidConfigurationError(\"lens.catalogue fast: the PSF profile lacks a field node.\");\n return c;\n };\n const axis = (own: readonly number[], other: readonly number[], along: boolean): number[] => {\n const out: number[] = [];\n for (let i = 0; i + 1 < own.length; i++) {\n let move = 0;\n for (const o of other) for (const nm of wl) {\n const a = along ? at(own[i]!, o, nm) : at(o, own[i]!, nm), b = along ? at(own[i + 1]!, o, nm) : at(o, own[i + 1]!, nm);\n move = Math.max(move, Math.hypot(a.x - b.x, a.y - b.y));\n }\n const cells = Math.max(CATALOGUE_FAST_GRID_MINIMUM_SUBDIVISIONS, Math.ceil(move / CATALOGUE_FAST_GRID_CENTROID_STEP_SITES - 1e-9));\n for (let k = 0; k < cells; k++) out.push(own[i]! + (own[i + 1]! - own[i]!) * k / cells);\n }\n out.push(own[own.length - 1]!);\n return out;\n };\n return { x: axis(fx, fy, true), y: axis(fy, fx, false) };\n}\n\n/** The cell [i, i + 1] of an ascending axis holding v (clamped to the ends) and v's weight toward i + 1. */\nfunction cellOf(axis: readonly number[], v: number): { i: number; f: number } {\n let lo = 0, hi = axis.length - 2;\n while (lo < hi) { const mid = (lo + hi + 1) >> 1; if (axis[mid]! <= v) lo = mid; else hi = mid - 1; }\n const f = (v - axis[lo]!) / (axis[lo + 1]! - axis[lo]!);\n return { i: lo, f: Math.min(1, Math.max(0, f)) };\n}\n\n/**\n * Internal test hook (never set by the engine): `exactKernels` makes the facade's signals resolve every site's kernels exactly;\n * `onInput` receives each input the facade builds, so a test can compare the grid blend with the exact sum site by site.\n */\nexport interface CatalogueLensSignalTestHook { exactKernels?: boolean; onInput?(input: CatalogueLensSignalInput): void }\nlet testHook: CatalogueLensSignalTestHook | undefined;\nexport function setCatalogueLensSignalTestHook(hook: CatalogueLensSignalTestHook | undefined): void { testHook = hook; }\n\n/** The fast method's expected signal (see the module comment). */\nexport function createCatalogueLensSignal(given: CatalogueLensSignalInput): CatalogueLensSignal {\n testHook?.onInput?.(given);\n const input = testHook?.exactKernels ? { ...given, exactKernels: true } : given;\n const { nativeWidth: W, nativeHeight: H, psf, wavelengthsNm, electronsPerRadiance: A, scene, channelAt } = input;\n const mmPerSite = input.pitch / 1000, nodes = wavelengthsNm.length;\n const first = psf.profile.nodes[0];\n if (!first) throw new InvalidConfigurationError(\"lens.catalogue fast: the PSF profile has no nodes.\");\n const kw = first.kernel.widthSamples, kh = first.kernel.heightSamples, cx = first.kernel.centerSampleX, cy = first.kernel.centerSampleY, taps = kw * kh;\n for (const node of psf.profile.nodes) if (node.kernel.widthSamples !== kw || node.kernel.heightSamples !== kh || node.kernel.centerSampleX !== cx || node.kernel.centerSampleY !== cy)\n throw new InvalidConfigurationError(\"lens.catalogue fast: the PSF profile's kernels differ in size.\");\n // Lattice reach of the taps around a site: x from −cx … kw − 1 − cx (as c_x − k_x), y from −cy … kh − 1 − cy.\n const reachLeft = kw - 1 - cx, reachRight = cx, reachUp = cy, reachDown = kh - 1 - cy;\n // Materials: neutral ones by reflectance (class 0, the white radiance), spectral ones by class 1 + index.\n const M = scene.materials.length, reflectance = new Float64Array(M), materialClass = new Int32Array(M);\n const spectral: Float64Array[] = [];\n scene.materials.forEach((m, index) => { if (\"neutral\" in m) reflectance[index] = m.neutral; else { materialClass[index] = 1 + spectral.length; spectral.push(m.radiance); } });\n const classes = 1 + spectral.length, classRadiance = [scene.whiteRadiance, ...spectral];\n const tableSize = 3 * classes * taps;\n // W_{c,m}(k) = Σ_λ A_c(λ)·L_m(λ)·K_λ(k) for the kernels of one field point.\n const foldKernels = (fieldXmm: number, fieldYmm: number): Float64Array => {\n const table = new Float64Array(tableSize);\n for (let n = 0; n < nodes; n++) {\n const kernel = resolveLensSampledPsfKernel({ ...psf, wavelengthNm: wavelengthsNm[n]!, fieldPointMm: { x: fieldXmm, y: fieldYmm } }).normalizedIntensity;\n if (kernel.length !== taps) throw new InvalidConfigurationError(\"lens.catalogue fast: a resolved kernel differs in size.\");\n for (let c = 0; c < 3; c++) {\n const a = A[c]![n]!;\n if (a === 0) continue;\n for (let cl = 0; cl < classes; cl++) {\n const weight = a * classRadiance[cl]![n]!, base = (c * classes + cl) * taps;\n if (weight === 0) continue;\n for (let k = 0; k < taps; k++) table[base + k] = table[base + k]! + weight * kernel[k]!;\n }\n }\n }\n return table;\n };\n // The field grid, resolved lazily (a region render resolves only the grid points around it).\n const axes = catalogueFastGridAxes(psf), gx = axes.x, gy = axes.y, GX = gx.length;\n const tables: (Float64Array | undefined)[] = new Array(GX * gy.length);\n let resolved = 0;\n const tableAt = (i: number, j: number): Float64Array => {\n const k = j * GX + i;\n let t = tables[k];\n if (!t) { t = foldKernels(gx[i]!, gy[j]!); tables[k] = t; resolved++; }\n return t;\n };\n // Each native column's and row's grid cell and blend weight (field +Y up: row y sits at −(y + ½ − H/2)·p).\n const cellX = new Int32Array(W), weightX = new Float64Array(W), cellY = new Int32Array(H), weightY = new Float64Array(H);\n for (let x = 0; x < W; x++) { const c = cellOf(gx, (x + 0.5 - W / 2) * mmPerSite); cellX[x] = c.i; weightX[x] = c.f; }\n for (let y = 0; y < H; y++) { const c = cellOf(gy, -(y + 0.5 - H / 2) * mmPerSite); cellY[y] = c.i; weightY[y] = c.f; }\n\n // The scene point and field factor of a native sensor point (mm, +Y down); factor 0 where the scene radiance is zero.\n const pd = resolveProjectionDistanceMm(input.focalLengthMm, input.focusDistanceM).projectionDistanceMm;\n const planeScale = input.distanceM / input.metresPerFrameUnit;\n const throughputAt = input.vignetting ? prepareIlluminationVignettingThroughput(input.vignetting) : undefined;\n const distortion = input.distortion, rectilinear = input.projection === \"rectilinear\";\n let mu = 0, mv = 0, mf = 0;\n const map = (xMm: number, yMm: number): void => {\n const imageX = xMm, imageY = -yMm;\n let idealX = imageX, idealY = imageY, area = 1;\n if (distortion) {\n const { k1, k2, k3 } = distortion.coefficients, norm = distortion.normalizationRadiusMm, rd = Math.hypot(imageX, imageY) / norm;\n let rho = rd;\n if (rd > 0) {\n // Newton's method on ρ·s(ρ) = ρ_d (monotonic over the profile's validated range), from ρ = ρ_d.\n let converged = false;\n for (let it = 0; it < NEWTON_ITERATIONS; it++) {\n const r2 = rho * rho, value = rho * (1 + k1 * r2 + k2 * r2 * r2 + k3 * r2 * r2 * r2) - rd, slope = 1 + 3 * k1 * r2 + 5 * k2 * r2 * r2 + 7 * k3 * r2 * r2 * r2;\n if (!(slope > 0)) break;\n const step = value / slope;\n rho -= step;\n if (Math.abs(step) <= 4 * Number.EPSILON * rho) { converged = true; break; }\n }\n if (!converged || !(rho > 0)) throw new InvalidConfigurationError(\"lens.catalogue fast: the inverse distortion did not converge.\");\n }\n const r2 = rho * rho, s = 1 + k1 * r2 + k2 * r2 * r2 + k3 * r2 * r2 * r2, derivative = 1 + 3 * k1 * r2 + 5 * k2 * r2 * r2 + 7 * k3 * r2 * r2 * r2;\n if (rd > 0) { idealX = imageX / s; idealY = imageY / s; }\n area = 1 / (s * derivative);\n if (!(area > 0) || !Number.isFinite(area)) throw new InvalidConfigurationError(\"lens.catalogue fast: the distortion area factor must stay finite and positive.\");\n }\n const factor = (throughputAt ? throughputAt({ x: imageX, y: imageY }) : 1) * area;\n if (rectilinear) { mu = idealX / pd * planeScale; mv = idealY / pd * planeScale; mf = factor; return; }\n if (input.outsideImageCircleSeesNothing && !insideRadialImageCircle(input.projection, pd, Math.hypot(idealX, idealY))) { mf = 0; return; }\n const d = lensProjectionDirectionValue(input.projection, pd, idealX, idealY);\n if (!(d.z > 0)) { mf = 0; return; }\n mu = d.x * (input.distanceM / d.z) / input.metresPerFrameUnit; mv = d.y * (input.distanceM / d.z) / input.metresPerFrameUnit; mf = factor;\n };\n let lookups = 0;\n let lm = 0, lf = 0;\n /** The material and field factor of lattice point (p, q) (sites from the top-left site, the lattice formula). */\n const lattice = (p: number, q: number): void => {\n map((p + 0.5 - W / 2) * mmPerSite, (q + 0.5 - H / 2) * mmPerSite);\n lf = mf;\n if (mf === 0) { lm = 0; return; }\n const m = scene.materialAt(mu, mv);\n if (!(m >= 0 && m < M) || !Number.isInteger(m)) throw new InvalidConfigurationError(\"Unknown chart material.\");\n lm = m; lookups++;\n };\n // The window's lattice: points [wx0, wx0 + ww) × [wy0, wy0 + wh).\n let wx0 = 0, wy0 = 0, ww = 0, wh = 0, winMaterial = new Int32Array(0), winFactor = new Float64Array(0);\n const window = (x0: number, y0: number, x1: number, y1: number): void => {\n const w = x1 - x0 + reachLeft + reachRight, h = y1 - y0 + reachUp + reachDown;\n if (!(w > 0 && h > 0) || w * h > WINDOW_LIMIT) { ww = 0; wh = 0; return; }\n wx0 = x0 - reachLeft; wy0 = y0 - reachUp; ww = w; wh = h;\n if (winMaterial.length < w * h) { winMaterial = new Int32Array(w * h); winFactor = new Float64Array(w * h); }\n for (let q = 0; q < h; q++) for (let p = 0; p < w; p++) { lattice(wx0 + p, wy0 + q); winMaterial[q * w + p] = lm; winFactor[q * w + p] = lf; }\n };\n const kernelOf = new Float64Array(tableSize);\n let cellI = -1, cellJ = -1, c00: Float64Array = kernelOf, c10: Float64Array = kernelOf, c01: Float64Array = kernelOf, c11: Float64Array = kernelOf;\n const site = (x: number, y: number): number => {\n const c = channelAt(x, y);\n let t00: Float64Array, t10: Float64Array, t01: Float64Array, t11: Float64Array, b00: number, b10: number, b01: number, b11: number;\n if (input.exactKernels) {\n kernelOf.set(foldKernels((x + 0.5 - W / 2) * mmPerSite, -(y + 0.5 - H / 2) * mmPerSite));\n t00 = t10 = t01 = t11 = kernelOf; b00 = 1; b10 = b01 = b11 = 0;\n } else {\n const i = cellX[x]!, j = cellY[y]!, fx = weightX[x]!, fy = weightY[y]!;\n // Neighboring sites share a cell: its four tables are kept from the last site.\n if (i !== cellI || j !== cellJ) { cellI = i; cellJ = j; c00 = tableAt(i, j); c10 = tableAt(i + 1, j); c01 = tableAt(i, j + 1); c11 = tableAt(i + 1, j + 1); }\n t00 = c00; t10 = c10; t01 = c01; t11 = c11;\n b00 = (1 - fx) * (1 - fy); b10 = fx * (1 - fy); b01 = (1 - fx) * fy; b11 = fx * fy;\n }\n const inside = ww > 0 && x - reachLeft >= wx0 && y - reachUp >= wy0 && x + reachRight < wx0 + ww && y + reachDown < wy0 + wh;\n const channelBase = c * classes * taps;\n let sum = 0;\n for (let ky = 0, k = 0; ky < kh; ky++) {\n const q = y + ky - cy;\n for (let kx = 0; kx < kw; kx++, k++) {\n const p = x + cx - kx;\n let m: number, f: number;\n if (inside) { const at = (q - wy0) * ww + p - wx0; m = winMaterial[at]!; f = winFactor[at]!; } else { lattice(p, q); m = lm; f = lf; }\n if (f === 0) continue;\n const cl = materialClass[m]!, at = channelBase + cl * taps + k;\n const w = b00 * t00[at]! + b10 * t10[at]! + b01 * t01[at]! + b11 * t11[at]!;\n sum += f * (cl === 0 ? reflectance[m]! * w : w);\n }\n }\n return sum;\n };\n return {\n window, site,\n get lookups(): number { return lookups; },\n get grid(): { columns: number; rows: number; resolved: number } { return { columns: GX, rows: gy.length, resolved }; }\n };\n}\n\n/** The `raw.expectedSignal` and `fast.lens.catalogue` assumptions of a capture the fast method rendered (kept here, out of the capture bundle's entry). */\nexport function catalogueFastAssumptions(run: { columns: number; rows: number; resolved: number; verificationRelativeDifference: number }):\n { id: string; value: Record<string, unknown>; explanation: string }[] {\n const tolerance = CATALOGUE_FAST_VERIFICATION_TOLERANCE, cells = CATALOGUE_FAST_GRID_MINIMUM_SUBDIVISIONS, step = CATALOGUE_FAST_GRID_CENTROID_STEP_SITES;\n return [{ id: \"raw.expectedSignal\", value: { method: \"tabulated-expected-electrons-catalogue-psf-field-grid\", verificationSites: 4, tolerance,\n verificationRelativeDifference: run.verificationRelativeDifference },\n explanation: \"Each native site's expected photo electrons are tabulated: the sum over the PSF taps of the field factor (vignetting × distortion area factor) times the \" +\n \"grid-blended kernel folded with the channel response and the material radiance (see fast.lens.catalogue). The sensor stage (dark charge, Poisson draws, read noise, ADC) \" +\n \"is the native one with each site's own seeds. One site of each CFA phase ran the exact chain (the environment PSF quadrature): its readout was reproduced bit for bit and \" +\n \"its electrons agreed with the fast ones within the tolerance (verificationRelativeDifference: the largest difference there).\" },\n { id: \"fast.lens.catalogue\", value: { method: \"field-grid-bilinear-psf\", gridColumns: run.columns, gridRows: run.rows, gridPointsResolved: run.resolved,\n minimumSubdivisions: cells, centroidStepSites: step, verificationTolerance: tolerance },\n explanation: \"Fast method (#568), an approximation of the exact one: the catalogue PSF is resolved exactly on a field grid (each interval between the profile's field nodes \" +\n \"split into at least \" + cells + \" cells, more where the node kernels' centroids move by over \" + step + \" site per cell), and each site takes the bilinear blend of its \" +\n \"four grid points' kernels instead of its own. Its error is at most the kernels' L1 difference times the brightest tap's signal; docs/LENS_CATALOGUE.md (\\\"Fast method\\\") \" +\n \"records it measured against the exact method. Distortion, vignetting and projection are the exact method's (the radial inverse by Newton's method, equal to rounding).\" }];\n}\n"]}
@@ -42,7 +42,7 @@
42
42
  import { InvalidConfigurationError } from "../core/configuration-error.js";
43
43
  import { hypot3 } from "../core/portable-math.js";
44
44
  import { isInternalSceneRadianceEvaluator, markInternalSceneRadianceEvaluator, registerInternalRadianceAccess } from "../core/internal-radiance-evaluator.js";
45
- import { lensProjectionDirectionValue, lensProjectionImagePointValue } from "../camera/lens-projection.js";
45
+ import { insideRadialImageCircle, lensProjectionDirectionValue, lensProjectionImagePointValue } from "../camera/lens-projection.js";
46
46
  import { applyPhysicalCameraRotation, resolveProjectionDistanceMm } from "../motion/camera-rotation.js";
47
47
  import { prepareIlluminationVignettingThroughput } from "../optics/illumination-vignetting.js";
48
48
  import { distortedImagePoint, undistortedImagePoint } from "../optics/sensor-environment-query.js";
@@ -58,6 +58,8 @@ export function prepareDefocusImageSpaceGeometry(geometry) {
58
58
  // The projection scale: the thin-lens image distance at the finite focus, for every projection model (the environment's).
59
59
  const pd = resolveProjectionDistanceMm(focalLengthMm, focusDistanceM).projectionDistanceMm;
60
60
  const model = lensMapping?.mapping.projectionModel ?? "rectilinear";
61
+ // #569: with "backward-ray" (catalogue fisheyes), a point outside the image circle looks straight back, as the environment's mapped query does.
62
+ const backward = lensMapping?.mapping.outsideImageCircle === "backward-ray";
61
63
  const timeDependent = omega.pitch !== 0 || omega.yaw !== 0 || omega.roll !== 0;
62
64
  // calculateIlluminationVignetting's throughput with the profile validated once (#563: the same numbers, without a result envelope per point).
63
65
  const throughputAt = vignetting ? prepareIlluminationVignettingThroughput(vignetting) : undefined;
@@ -89,7 +91,8 @@ export function prepareDefocusImageSpaceGeometry(geometry) {
89
91
  lz = pd;
90
92
  }
91
93
  else {
92
- const reference = applyPhysicalCameraRotation(lensProjectionDirectionValue(model, pd, ideal.x, ideal.y), displacement(t), "camera-to-reference");
94
+ const reference = applyPhysicalCameraRotation(backward && !insideRadialImageCircle(model, pd, Math.hypot(ideal.x, ideal.y)) ? { x: 0, y: 0, z: -1 } :
95
+ lensProjectionDirectionValue(model, pd, ideal.x, ideal.y), displacement(t), "camera-to-reference");
93
96
  lx = reference.x;
94
97
  ly = reference.y;
95
98
  lz = reference.z;
@@ -1 +1 @@
1
- {"version":3,"file":"defocus-image-space-provider.js","sourceRoot":"","sources":["../../src/facade/defocus-image-space-provider.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * `simulateCapture`'s `lens.defocus` out of focus together with a lens field mapping (`lens.projection`,\n * `lens.distortion`), `lens.vignetting` or camera rotation (#548): the geometric defocus disc applied in image space,\n * on the site lattice of the sensor, instead of on the scene plane.\n *\n * Why the object-space path does not apply. `createDiffractedPlanarProvider` convolves the scene radiance on the plane\n * lattice that the sites see through one linear map (a still, rectilinear, distortion-free camera with the same\n * radiance-to-irradiance factor everywhere). A projection, a distortion or a rotation makes the map from sensor points\n * to plane points non-linear (or time-dependent), and vignetting makes the factor vary over the field, so the disc on\n * the plane is no longer the disc on the sensor.\n *\n * The image-space model. The environment PSF quadrature (`calculateSensorPsfIrradianceQuadrature`, the per-tap path\n * `lens.diffraction` falls back to) defines a sensor-plane PSF K as\n * E(q, λ, t) = Σ_k K(k)·F(s_k)·C·L(D_t(s_k), λ),\n * with s_k = q + k·p the tap source points on the sensor (p the site pitch), D_t the scene ray of a sensor point at\n * time t (inverse distortion, the declared projection, the camera rotation at t), F = T·A the field factor (vignetting\n * throughput T, applied once before the PSF spreads the light, and the distortion area factor A = 1/det J) and C the\n * paraxial radiance-to-irradiance factor π/(4·N_w²), the same everywhere. With K the defocus disc sampled on the site\n * lattice (`createDefocusDiscSiteKernel`), every source point of a site-centre query is another lattice point, so\n * E(q, λ, t) = C·G_t(q, λ), G_t = K ⊛ (F·L∘D_t) sampled on the lattice,\n * the same sum in a different floating-point order. This provider computes G_t once per spectral node and time on the\n * sensor lattice (in row bands, as the diffraction provider does) and answers the query of lattice point q at time t with\n * G_t(q, λ) / F(q); the environment multiplies by F(q)·C again, so each site gets C·G_t(q, λ). For the still,\n * rectilinear, distortion-free camera without vignetting it is the object-space convolution (F = 1 and D linear).\n *\n * The lattices. As in the diffraction provider, a pixel aperture or anti-aliasing spots add query offsets; each distinct\n * fractional offset gets its own shifted lattice of sensor points, and every tap of a query on one lattice is on the same\n * lattice. A query is located on its lattice by mapping its scene ray back to the sensor (camera rotation inverted at the\n * request's time, the forward projection, the forward distortion), within 1e-4 site; a query that lands on no lattice point\n * is refused rather than approximated.\n *\n * Time. With camera rotation each environment temporal midpoint is a still camera, so the disc is applied to that\n * instant's image in that instant's frame: one G_t per distinct request time, cached per band. Without rotation the image\n * does not depend on time and one G is kept. The facade refuses rotation with a rolling shutter (each row's instants differ).\n *\n * What is approximate is the disc itself (`lens.defocus` labels it; the facade records the field-variation bounds of\n * each combination), not this evaluation of it.\n */\n\n// #564: a defocus kernel above 64 sites (`largeKernel`) takes the run lattice of large-defocus-lattice.ts instead of the bands:\n// the samples F·L at the same lattice points, convolved by runs in fixed tiles, then divided by each queried point's own F.\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\nimport { hypot3 } from \"../core/portable-math.js\";\nimport { isInternalSceneRadianceEvaluator, markInternalSceneRadianceEvaluator, registerInternalRadianceAccess } from \"../core/internal-radiance-evaluator.js\";\nimport type { SceneRadianceEvaluationRequest, SceneRadianceEvaluationResult } from \"../schema/scene-radiance.js\";\nimport { lensProjectionDirectionValue, lensProjectionImagePointValue, type LensProjectionModel } from \"../camera/lens-projection.js\";\nimport { applyPhysicalCameraRotation, resolveProjectionDistanceMm, type CameraAngularVelocityRadPerSec } from \"../motion/camera-rotation.js\";\nimport { prepareIlluminationVignettingThroughput, type IlluminationVignettingProfile } from \"../optics/illumination-vignetting.js\";\nimport { distortedImagePoint, undistortedImagePoint, type PreparedEnvironmentLensFieldMapping } from \"../optics/sensor-environment-query.js\";\nimport { checkedSiteKernel, createZonedGather, gatherInterior, kernelTaps, type SiteKernelFieldZones } from \"./diffraction-provider.js\";\nimport type { PlanarSceneRadianceProvider } from \"./scene-radiance.js\";\nimport { LARGE_DEFOCUS_CACHE_BYTES, createLargeDefocusNodeLattice, type LargeDefocusKernel, type LargeDefocusNodeLattice } from \"./large-defocus-lattice.js\";\n\n/** Rows of native sites per band; bands kept per time. Banding changes memory only, never values. */\nconst BAND_ROWS = 32;\nconst CACHED_BANDS = 2;\nconst LATTICE_TOLERANCE_SITES = 1e-4;\n\n/** The camera geometry the environment uses for each site query (the same options as the site inputs). */\nexport interface DefocusImageSpaceGeometry {\n focalLengthMm: number;\n focusDistanceM: number;\n angularVelocityRadPerSec: CameraAngularVelocityRadPerSec;\n /** The site inputs' `lensFieldMapping`, prepared; omitted for the ideal rectilinear, distortion-free mapping. */\n lensMapping?: PreparedEnvironmentLensFieldMapping;\n /** The site inputs' radial-illumination-vignetting profile; omitted for unity field throughput. */\n vignetting?: IlluminationVignettingProfile;\n}\n\n/** Internal: the scene ray and field factor of sensor points, and the sensor point of a scene ray, for one geometry. */\nexport interface PreparedDefocusImageSpaceGeometry {\n /**\n * The unit look direction (toward the scene, reference camera axes at exposure start) of native sensor point (x, y) mm\n * (+X right, +Y down) at time t, and its field factor F = T·A (vignetting throughput × distortion area factor).\n */\n lookOf(xMm: number, yMm: number, timeSeconds: number): { x: number; y: number; z: number; factor: number };\n /** The native sensor point (mm, +Y down) whose scene ray at time t is the look direction; undefined outside the mapping. */\n sensorPointOf(look: { x: number; y: number; z: number }, timeSeconds: number): { x: number; y: number } | undefined;\n /** True with camera rotation: the ray of a sensor point depends on time. */\n timeDependent: boolean;\n}\n\n/** Internal: prepares {@link PreparedDefocusImageSpaceGeometry} with the environment's own conventions and arithmetic. */\nexport function prepareDefocusImageSpaceGeometry(geometry: DefocusImageSpaceGeometry): PreparedDefocusImageSpaceGeometry {\n const { focalLengthMm, focusDistanceM, angularVelocityRadPerSec: omega, lensMapping, vignetting } = geometry;\n // The projection scale: the thin-lens image distance at the finite focus, for every projection model (the environment's).\n const pd = resolveProjectionDistanceMm(focalLengthMm, focusDistanceM).projectionDistanceMm;\n const model: LensProjectionModel = lensMapping?.mapping.projectionModel ?? \"rectilinear\";\n const timeDependent = omega.pitch !== 0 || omega.yaw !== 0 || omega.roll !== 0;\n // calculateIlluminationVignetting's throughput with the profile validated once (#563: the same numbers, without a result envelope per point).\n const throughputAt = vignetting ? prepareIlluminationVignettingThroughput(vignetting) : undefined;\n const displacement = (t: number): { pitch: number; yaw: number; roll: number } =>\n timeDependent ? { pitch: omega.pitch * t, yaw: omega.yaw * t, roll: omega.roll * t } : { pitch: 0, yaw: 0, roll: 0 };\n // The reference-to-camera rotation at the last time asked, as a matrix (its columns: the rotated basis vectors), so a lattice\n // lookup costs no trigonometry; the rotation is linear, so this equals rotating the vector, up to rounding.\n let matrixTime = NaN, m: number[] = [];\n const toCamera = (v: { x: number; y: number; z: number }, t: number): { x: number; y: number; z: number } => {\n if (t !== matrixTime) {\n const d = displacement(t), ex = applyPhysicalCameraRotation({ x: 1, y: 0, z: 0 }, d, \"reference-to-camera\"),\n ey = applyPhysicalCameraRotation({ x: 0, y: 1, z: 0 }, d, \"reference-to-camera\"), ez = applyPhysicalCameraRotation({ x: 0, y: 0, z: 1 }, d, \"reference-to-camera\");\n m = [ex.x, ey.x, ez.x, ex.y, ey.y, ez.y, ex.z, ey.z, ez.z];\n matrixTime = t;\n }\n return { x: m[0]! * v.x + m[1]! * v.y + m[2]! * v.z, y: m[3]! * v.x + m[4]! * v.y + m[5]! * v.z, z: m[6]! * v.x + m[7]! * v.y + m[8]! * v.z };\n };\n return {\n timeDependent,\n lookOf(xMm, yMm, t): { x: number; y: number; z: number; factor: number } {\n const image = { x: xMm, y: -yMm };\n const { ideal, distortionAreaFactor } = lensMapping ? undistortedImagePoint(lensMapping, image) : { ideal: image, distortionAreaFactor: 1 };\n let lx: number, ly: number, lz: number;\n if (model === \"rectilinear\") {\n // calculateInverseCameraRotationImageMapping: the captured ray (x/pd, y/pd, 1) in reference axes, projected at pd.\n const reference = applyPhysicalCameraRotation({ x: ideal.x / pd, y: ideal.y / pd, z: 1 }, displacement(t), \"camera-to-reference\");\n if (!(reference.z > 0)) throw new InvalidConfigurationError(\"lens.defocus: a lattice point's ray points to or behind the reference camera plane.\");\n lx = pd * (reference.x / reference.z); ly = pd * (reference.y / reference.z); lz = pd;\n } else {\n const reference = applyPhysicalCameraRotation(lensProjectionDirectionValue(model, pd, ideal.x, ideal.y), displacement(t), \"camera-to-reference\");\n lx = reference.x; ly = reference.y; lz = reference.z;\n }\n const length = hypot3(lx, ly, lz);\n const throughput = throughputAt ? throughputAt(image) : 1;\n return { x: lx / length, y: ly / length, z: lz / length, factor: throughput * distortionAreaFactor };\n },\n sensorPointOf(look, t): { x: number; y: number } | undefined {\n try {\n const c = timeDependent ? toCamera(look, t) : look;\n let ideal: { x: number; y: number };\n if (model === \"rectilinear\") {\n if (!(c.z > 0)) return undefined;\n ideal = { x: pd * (c.x / c.z), y: pd * (c.y / c.z) };\n } else ideal = lensProjectionImagePointValue(model, pd, c.x, c.y, c.z).imagePointMm;\n const image = lensMapping ? distortedImagePoint(lensMapping, ideal).pointMm : ideal;\n return Number.isFinite(image.x) && Number.isFinite(image.y) ? { x: image.x, y: -image.y } : undefined;\n } catch {\n return undefined;\n }\n }\n };\n}\n\nexport interface DefocusImageSpaceProviderInput {\n base: PlanarSceneRadianceProvider;\n geometry: PreparedDefocusImageSpaceGeometry;\n /** Each spectral node's kernel on the site lattice, (2·kernelRadius + 1)² taps, row-major (the disc, or diffraction ⊛ disc). */\n siteKernels: (wavelengthNm: number) => Float64Array;\n wavelengthsNm: readonly number[];\n kernelRadius: number;\n nativeWidth: number;\n nativeHeight: number;\n sitePitchMicrometers: number;\n /** Planar geometry of the base provider (plane distance and frame-unit scale), to find the plane point of a ray as it does. */\n distanceM: number;\n metresPerFrameUnit: number;\n /** Offsets of the query points from the site centres, in sites (+x right, +y down). Default: one zero offset. */\n queryOffsetsSites?: readonly { x: number; y: number }[];\n /** Region renders: the native sites that will be queried. Values are bit-identical to the whole render's. Default: the whole raster. */\n window?: { x: number; y: number; width: number; height: number };\n /** Most distinct request times kept per band (the temporal sample count). Default 1. */\n timesPerBand?: number;\n /** Called with the duration in ms of each band convolution (diagnostics only). */\n onConvolution?: (milliseconds: number) => void;\n /**\n * #564: a defocus kernel above the direct radius, convolved by runs in fixed tiles (`large-defocus-lattice.ts`), with each\n * node's diffraction kernel after it; used instead of `siteKernels` (`kernelRadius` is then unused).\n */\n largeKernel?: LargeDefocusKernel;\n /** #553: a field-varying kernel by zones (the cat's eye of lens.defocus), gathered instead of `siteKernels`, the same at every node. */\n fieldZones?: SiteKernelFieldZones;\n}\n\n/** Internal (not exported from the package): the base provider with the defocus disc applied in image space (#548). */\nexport function createDefocusImageSpaceProvider(input: DefocusImageSpaceProviderInput): PlanarSceneRadianceProvider {\n const { base, geometry, wavelengthsNm, nativeWidth: W, nativeHeight: H, kernelRadius: R } = input;\n const mmPerSite = input.sitePitchMicrometers / 1000;\n const index = new Map(wavelengthsNm.map((nm, i) => [nm, i]));\n const offsets = input.queryOffsetsSites ?? [{ x: 0, y: 0 }];\n const fraction = (value: number): number => { const f = value - Math.floor(value); return f > 1 - 1e-6 ? 0 : f < 1e-6 ? 0 : f; };\n const shifts: { x: number; y: number }[] = [];\n for (const o of offsets) {\n const f = { x: fraction(o.x), y: fraction(o.y) };\n if (!shifts.some((s) => Math.abs(s.x - f.x) <= 1e-6 && Math.abs(s.y - f.y) <= 1e-6)) shifts.push(f);\n }\n const M = Math.max(0, ...offsets.map((o) => Math.ceil(Math.max(Math.abs(o.x), Math.abs(o.y)) - 1e-6)));\n const LW = W + 2 * M, LH = H + 2 * M;\n const win = input.window ?? { x: 0, y: 0, width: W, height: H };\n const lx0 = Math.max(0, win.x), lx1 = Math.min(LW, win.x + win.width + 2 * M);\n const ly0 = Math.max(0, win.y), ly1 = Math.min(LH, win.y + win.height + 2 * M);\n if (!(lx0 < lx1 && ly0 < ly1)) throw new InvalidConfigurationError(\"Defocus window must overlap the native raster.\");\n const NW = lx1 - lx0, gridWidth = NW + 2 * R;\n const large = input.largeKernel;\n const kernels = large ? [] : wavelengthsNm.map((nm) => checkedSiteKernel(input.siteKernels(nm), R));\n const taps = kernels.map((kernel) => kernelTaps(kernel, R, gridWidth));\n const zonedGather = input.fieldZones ? createZonedGather(input.fieldZones, R, gridWidth, W, H, M) : undefined;\n const sharedKernel = !large && (zonedGather !== undefined || kernels.every((kernel) => kernel === kernels[0]));\n const scale = input.metresPerFrameUnit, distance = input.distanceM;\n const materialAt = base.chartMaterialAt?.bind(base), materialRadiance = base.materialRadiance?.bind(base);\n const now = (): number => globalThis.performance?.now() ?? Date.now();\n // Lattice point (li, lj) of shift s, as a native sensor point in mm (+Y down): site centre plus the shift.\n const xMmOf = (li: number, s: { x: number }): number => (li - M + 0.5 + s.x - W / 2) * mmPerSite;\n const yMmOf = (lj: number, s: { y: number }): number => (lj - M + 0.5 + s.y - H / 2) * mmPerSite;\n // Bands per time (LRU over (time, band)): values[shift][node] holds G_t / F at the band's own lattice points.\n const cache = new Map<string, Float64Array[][]>();\n const capacity = CACHED_BANDS * Math.max(1, input.timesPerBand ?? 1);\n // The last band read, so consecutive queries of one band skip the cache key (most queries).\n let lastBand = -1, lastTime = NaN, lastValues: Float64Array[][] | undefined;\n function band(b: number, time: number): Float64Array[][] {\n if (b === lastBand && time === lastTime) return lastValues!;\n const values = bandOf(b, time);\n lastBand = b; lastTime = time; lastValues = values;\n return values;\n }\n function bandOf(b: number, time: number): Float64Array[][] {\n const key = time + \":\" + b, cached = cache.get(key);\n if (cached) { cache.delete(key); cache.set(key, cached); return cached; }\n const started = input.onConvolution ? now() : 0;\n const y0 = ly0 + b * BAND_ROWS, rows = Math.min(BAND_ROWS, ly1 - y0), gridHeight = rows + 2 * R, size = gridWidth * gridHeight;\n const values = shifts.map((shift) => {\n // Each grid point's field factor and plane point (or material), shared by the spectral nodes.\n const factor = new Float64Array(size), u = new Float64Array(size), v = new Float64Array(size);\n const material = materialAt && materialRadiance ? new Int32Array(size) : undefined;\n for (let gy = 0; gy < gridHeight; gy++) {\n const yMm = yMmOf(y0 + gy - R, shift);\n for (let gx = 0; gx < gridWidth; gx++) {\n const k = gy * gridWidth + gx, look = geometry.lookOf(xMmOf(lx0 + gx - R, shift), yMm, time);\n if (!(look.z > 0)) throw new InvalidConfigurationError(\"lens.defocus: a lattice point's ray does not point toward the scene plane.\");\n // The base provider's own plane-point arithmetic for the outgoing direction −look.\n const t = distance / look.z;\n factor[k] = look.factor; u[k] = look.x * t / scale; v[k] = look.y * t / scale;\n if (material) material[k] = materialAt!(u[k]!, v[k]!);\n }\n }\n // The band's own lattice points' factors, to answer each query with G / F.\n const own = new Float64Array(rows * NW);\n for (let y = 0; y < rows; y++) for (let x = 0; x < NW; x++) own[y * NW + x] = factor[(y + R) * gridWidth + x + R]!;\n // One kernel for every node (the disc without diffraction) and fewer materials than nodes: the convolution is linear, so\n // G_λ = Σ_m L_m(λ)·(K ⊛ F·[material = m]); one convolution per material instead of one per node, the same sum regrouped.\n if (material && sharedKernel) {\n const present = [...new Set(material)];\n if (present.length < wavelengthsNm.length) {\n const perMaterial = present.map((m) => {\n const samples = new Float64Array(size);\n for (let k = 0; k < size; k++) if (material[k] === m) samples[k] = factor[k]!;\n return zonedGather ? zonedGather(samples, lx0, y0, NW, rows) : gatherInterior(samples, taps[0]!, gridWidth, NW, rows, R);\n });\n return wavelengthsNm.map((nm) => {\n const radiance = present.map((m) => materialRadiance!(m, nm)), out = new Float64Array(rows * NW);\n for (const value of radiance) if (!(value >= 0 && value <= 2 ** 100)) throw new InvalidConfigurationError(\"Irradiance samples must be finite, non-negative and within the declared magnitude.\");\n for (let k = 0; k < out.length; k++) {\n let sum = 0;\n for (let i = 0; i < present.length; i++) sum += radiance[i]! * perMaterial[i]![k]!;\n out[k] = sum / own[k]!;\n }\n return out;\n });\n }\n }\n return wavelengthsNm.map((nm, w) => {\n const samples = new Float64Array(size);\n if (material) {\n const radiance = new Map<number, number>();\n for (let k = 0; k < size; k++) {\n const m = material[k]!;\n let value = radiance.get(m);\n if (value === undefined) { value = materialRadiance!(m, nm); radiance.set(m, value); }\n samples[k] = factor[k]! * value;\n }\n } else for (let k = 0; k < size; k++) samples[k] = factor[k]! * base.radianceAt(u[k]!, v[k]!, nm);\n const gathered = zonedGather ? zonedGather(samples, lx0, y0, NW, rows) : gatherInterior(samples, taps[w]!, gridWidth, NW, rows, R);\n for (let k = 0; k < gathered.length; k++) gathered[k] = gathered[k]! / own[k]!;\n return gathered;\n });\n });\n cache.set(key, values);\n if (cache.size > capacity) cache.delete(cache.keys().next().value!);\n if (input.onConvolution) input.onConvolution(now() - started);\n return values;\n }\n /** The lattice key ((shift·LH + lj)·LW + li) of a look direction at time t, or undefined off the lattices or outside the window. */\n function keyOf(look: { x: number; y: number; z: number }, t: number): number | undefined {\n const point = geometry.sensorPointOf(look, t);\n if (point === undefined) return undefined;\n const fi = point.x / mmPerSite + W / 2 - 0.5, fj = point.y / mmPerSite + H / 2 - 0.5;\n for (let s = 0; s < shifts.length; s++) {\n const shift = shifts[s]!, i = Math.round(fi - shift.x), j = Math.round(fj - shift.y);\n if (Math.abs(fi - shift.x - i) > LATTICE_TOLERANCE_SITES || Math.abs(fj - shift.y - j) > LATTICE_TOLERANCE_SITES) continue;\n const li = i + M, lj = j + M;\n if (li < lx0 || lj < ly0 || li >= lx1 || lj >= ly1) return undefined;\n return (s * LH + lj) * LW + li;\n }\n return undefined;\n }\n function valueOf(key: number, t: number, nm: number): number {\n const w = index.get(nm);\n if (w === undefined) throw new InvalidConfigurationError(\"Defocus query is off the sensor site lattice; the image-space convolution does not apply.\");\n const li = key % LW, rest = (key - li) / LW, lj = rest % LH, s = (rest - lj) / LH;\n if (large) return largeValue(s, t, w, li, lj);\n return band(Math.floor((lj - ly0) / BAND_ROWS), t)[s]![w]![((lj - ly0) % BAND_ROWS) * NW + li - lx0]!;\n }\n // #564: one run lattice per (time, shift) of the samples F·L at the lattice points, and the own field factors F by tile, so a\n // query is answered with (K ⊛ D ⊛ F·L) / F as on the band path.\n const largeLattices = new Map<string, { lattice: LargeDefocusNodeLattice; own: Map<number, Float64Array> }>();\n const largeLatticeCount = shifts.length * Math.max(1, input.timesPerBand ?? 1);\n // Lattice points at most `reach` beyond the lattice feed queried values: the defocus kernel's radius plus the diffraction kernel's.\n const reach = large ? large.runs.radius + (large.diffraction ? large.diffraction.radius : 0) : 0;\n function largeValue(s: number, time: number, w: number, li: number, lj: number): number {\n const key = time + \":\" + s;\n let entry = largeLattices.get(key);\n if (!entry) {\n const shift = shifts[s]!;\n const lattice = createLargeDefocusNodeLattice({ kernel: large!, wavelengthsNm, capacityBytes: LARGE_DEFOCUS_CACHE_BYTES / largeLatticeCount, ...(input.onConvolution ? { onTile: input.onConvolution } : {}),\n source: (x0, y0, width, height) => {\n const size = width * height, factor = new Float64Array(size), u = new Float64Array(size), v = new Float64Array(size);\n const material = materialAt && materialRadiance ? new Int32Array(size) : undefined, beyond = new Uint8Array(size);\n for (let y = 0; y < height; y++) {\n const yMm = yMmOf(y0 + y, shift);\n for (let x = 0; x < width; x++) {\n const k = y * width + x;\n // A fixed tile's source reaches past the lattice: points beyond its reach feed no queried value, so they are 0 and never\n // mapped (the lens profiles are checked only up to the reach).\n if (x0 + x < -reach || x0 + x >= LW + reach || y0 + y < -reach || y0 + y >= LH + reach) { beyond[k] = 1; continue; }\n const look = geometry.lookOf(xMmOf(x0 + x, shift), yMm, time);\n if (!(look.z > 0)) throw new InvalidConfigurationError(\"lens.defocus: a lattice point's ray does not point toward the scene plane.\");\n const t = distance / look.z;\n factor[k] = look.factor; u[k] = look.x * t / scale; v[k] = look.y * t / scale;\n if (material) material[k] = materialAt!(u[k]!, v[k]!);\n }\n }\n return (node: number): Float64Array => {\n const nm = wavelengthsNm[node]!, samples = new Float64Array(size);\n if (material) {\n const radiance = new Map<number, number>();\n for (let k = 0; k < size; k++) {\n if (beyond[k]) continue;\n const m = material[k]!;\n let value = radiance.get(m);\n if (value === undefined) { value = materialRadiance!(m, nm); radiance.set(m, value); }\n samples[k] = factor[k]! * value;\n }\n } else for (let k = 0; k < size; k++) if (!beyond[k]) samples[k] = factor[k]! * base.radianceAt(u[k]!, v[k]!, nm);\n return samples;\n };\n } });\n entry = { lattice, own: new Map() };\n largeLattices.set(key, entry);\n if (largeLattices.size > largeLatticeCount) largeLattices.delete(largeLattices.keys().next().value!);\n }\n // The own factor of the lattice point, by 64-point tiles (kept for the request: 8 bytes per lattice point read).\n const T = 64, tx = Math.floor(li / T), ty = Math.floor(lj / T), tileKey = ty * 1048576 + tx;\n let own = entry.own.get(tileKey);\n if (!own) {\n own = new Float64Array(T * T);\n const shift = shifts[s]!;\n // Only the lattice's own points are queried; the rest of the tile is never read (and may lie beyond the lens profiles).\n for (let y = 0; y < T && ty * T + y < LH; y++) { const yMm = yMmOf(ty * T + y, shift); for (let x = 0; x < T && tx * T + x < LW; x++) own[y * T + x] = geometry.lookOf(xMmOf(tx * T + x, shift), yMm, time).factor; }\n entry.own.set(tileKey, own);\n }\n return entry.lattice.valueAt(w, li, lj) / own[(lj - ty * T) * T + li - tx * T]!;\n }\n function blurredAt(look: { x: number; y: number; z: number }, time: number, nm: number): number {\n const t = geometry.timeDependent ? time : 0, key = keyOf(look, t);\n if (key === undefined) throw new InvalidConfigurationError(\"Defocus query is off the sensor site lattice; the image-space convolution does not apply.\");\n return valueOf(key, t, nm);\n }\n const baseEvaluate = base.evaluateRadiance;\n const evaluateRadiance = (request: Readonly<SceneRadianceEvaluationRequest>): SceneRadianceEvaluationResult => {\n const result = baseEvaluate.call(base, request), o = (request.target as { outgoingDirectionUnitVector: { x: number; y: number; z: number } }).outgoingDirectionUnitVector;\n return { ...result, spectralRadianceWattsPerSquareMeterSteradianNanometer: blurredAt({ x: -o.x, y: -o.y, z: -o.z }, request.timeSecondsFromExposureStart, request.wavelengthNanometers) };\n };\n // The result is the base result with only its radiance replaced, so an engine-built base evaluator keeps its mark. Its radiance is\n // a pure function of the lattice key (and, with rotation, the request time) and the wavelength, so the lean executor may read it by\n // key, as for the diffraction provider.\n if (isInternalSceneRadianceEvaluator(baseEvaluate)) {\n markInternalSceneRadianceEvaluator(evaluateRadiance);\n // With rotation the key also carries the request time, as an index into the distinct times seen (one per temporal midpoint).\n const times: number[] = [], timeIndex = new Map<number, number>(), latticeKeys = shifts.length * LH * LW;\n registerInternalRadianceAccess(evaluateRadiance, {\n tabulated: false,\n keyOfDirection(o, time): number | undefined {\n const t = geometry.timeDependent ? time : 0, key = keyOf({ x: -o.x, y: -o.y, z: -o.z }, t);\n if (key === undefined) return undefined;\n let index = timeIndex.get(t);\n if (index === undefined) { index = times.length; times.push(t); timeIndex.set(t, index); }\n return index * latticeKeys + key;\n },\n radianceOfKey(key, nm): number {\n const index = Math.floor(key / latticeKeys);\n return valueOf(key - index * latticeKeys, times[index]!, nm);\n }\n });\n }\n return {\n sceneId: base.sceneId, providerProfileId: base.providerProfileId, radianceAt: base.radianceAt,\n evaluateRadiance,\n evaluateApertureRadiance(): SceneRadianceEvaluationResult {\n throw new InvalidConfigurationError(\"Defocus by image-space convolution does not take pupil rays.\");\n }\n };\n}\n\n/** Field-variation bounds of the image-space disc for one request (#548), recorded in the `lens.defocus` assumption. */\nexport interface DefocusFieldVariation {\n /** Sensor points the bounds were evaluated at: a grid of this many points per side over the native raster, edges included. */\n gridPointsPerSide: number;\n /**\n * Camera rotation (pitch or yaw tilts the scene plane in the camera frame): the largest change of the disc diameter, in\n * sites, between the axial depth of each scene point in the rotated camera frame and the subject distance, over the grid and\n * the rendered temporal midpoints. 0 for roll only; null without rotation.\n */\n rotationMaximumDiameterChangeSites: number | null;\n /**\n * Distortion: the largest deviation from 1 of the local scale of the distortion map (singular values of d distorted / d ideal)\n * over the grid: the relative disc-size difference to a model that blurs the ideal image and then distorts it. Null without distortion.\n */\n distortionMaximumLocalScaleDeviation: number | null;\n /**\n * A non-rectilinear projection: the largest change of the disc diameter, in sites, between the distance along each scene\n * point's ray and its axial depth (the thin-lens model uses the axial depth). Null for the rectilinear projection.\n */\n projectionMaximumDiameterChangeSites: number | null;\n}\n\n/** Internal: {@link DefocusFieldVariation} on a 9 × 9 grid of sensor points (the extremes of these smooth maps lie on the frame's edges). */\nexport function calculateDefocusFieldVariation(input: { geometry: PreparedDefocusImageSpaceGeometry; lensMapping?: PreparedEnvironmentLensFieldMapping;\n focalLengthMm: number; fNumber: number; focusDistanceM: number; subjectDistanceM: number; pitchMicrometers: number; nativeWidth: number; nativeHeight: number;\n angularVelocityRadPerSec: CameraAngularVelocityRadPerSec; temporalMidpointsSeconds: readonly number[]; diameterSites: number;\n discAt: (subjectDistanceM: number) => number }): DefocusFieldVariation {\n const { geometry, lensMapping, pitchMicrometers: pitch, nativeWidth: W, nativeHeight: H, subjectDistanceM: d, diameterSites, discAt } = input;\n const G = 9, points: { x: number; y: number }[] = [];\n for (let j = 0; j < G; j++) for (let i = 0; i < G; i++) points.push({ x: (i / (G - 1) - 0.5) * W * pitch / 1000, y: (j / (G - 1) - 0.5) * H * pitch / 1000 });\n let rotation: number | null = null;\n if (geometry.timeDependent) {\n rotation = 0;\n const omega = input.angularVelocityRadPerSec;\n for (const t of input.temporalMidpointsSeconds) {\n // The camera's optical axis at t in the reference axes; a scene point's axial depth in the rotated camera is P·axis.\n const axis = applyPhysicalCameraRotation({ x: 0, y: 0, z: 1 }, { pitch: omega.pitch * t, yaw: omega.yaw * t, roll: omega.roll * t }, \"camera-to-reference\");\n for (const p of points) {\n const look = geometry.lookOf(p.x, p.y, t), reach = d / look.z;\n const depth = reach * (look.x * axis.x + look.y * axis.y + look.z * axis.z);\n rotation = Math.max(rotation, Math.abs(discAt(depth) - diameterSites));\n }\n }\n }\n let distortion: number | null = null;\n if (lensMapping && lensMapping.mapping.distortion.kind !== \"none\") {\n distortion = 0;\n for (const p of points) {\n const scales = distortedImagePoint(lensMapping, undistortedImagePoint(lensMapping, { x: p.x, y: -p.y }).ideal);\n distortion = Math.max(distortion, scales.largestScale - 1, 1 - scales.smallestScale);\n }\n }\n let projection: number | null = null;\n if (lensMapping && lensMapping.mapping.projectionModel !== \"rectilinear\") {\n projection = 0;\n for (const p of points) {\n const look = geometry.lookOf(p.x, p.y, 0);\n projection = Math.max(projection, Math.abs(discAt(d / look.z) - diameterSites));\n }\n }\n return { gridPointsPerSide: G, rotationMaximumDiameterChangeSites: rotation, distortionMaximumLocalScaleDeviation: distortion, projectionMaximumDiameterChangeSites: projection };\n}\n"]}
1
+ {"version":3,"file":"defocus-image-space-provider.js","sourceRoot":"","sources":["../../src/facade/defocus-image-space-provider.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * `simulateCapture`'s `lens.defocus` out of focus together with a lens field mapping (`lens.projection`,\n * `lens.distortion`), `lens.vignetting` or camera rotation (#548): the geometric defocus disc applied in image space,\n * on the site lattice of the sensor, instead of on the scene plane.\n *\n * Why the object-space path does not apply. `createDiffractedPlanarProvider` convolves the scene radiance on the plane\n * lattice that the sites see through one linear map (a still, rectilinear, distortion-free camera with the same\n * radiance-to-irradiance factor everywhere). A projection, a distortion or a rotation makes the map from sensor points\n * to plane points non-linear (or time-dependent), and vignetting makes the factor vary over the field, so the disc on\n * the plane is no longer the disc on the sensor.\n *\n * The image-space model. The environment PSF quadrature (`calculateSensorPsfIrradianceQuadrature`, the per-tap path\n * `lens.diffraction` falls back to) defines a sensor-plane PSF K as\n * E(q, λ, t) = Σ_k K(k)·F(s_k)·C·L(D_t(s_k), λ),\n * with s_k = q + k·p the tap source points on the sensor (p the site pitch), D_t the scene ray of a sensor point at\n * time t (inverse distortion, the declared projection, the camera rotation at t), F = T·A the field factor (vignetting\n * throughput T, applied once before the PSF spreads the light, and the distortion area factor A = 1/det J) and C the\n * paraxial radiance-to-irradiance factor π/(4·N_w²), the same everywhere. With K the defocus disc sampled on the site\n * lattice (`createDefocusDiscSiteKernel`), every source point of a site-centre query is another lattice point, so\n * E(q, λ, t) = C·G_t(q, λ), G_t = K ⊛ (F·L∘D_t) sampled on the lattice,\n * the same sum in a different floating-point order. This provider computes G_t once per spectral node and time on the\n * sensor lattice (in row bands, as the diffraction provider does) and answers the query of lattice point q at time t with\n * G_t(q, λ) / F(q); the environment multiplies by F(q)·C again, so each site gets C·G_t(q, λ). For the still,\n * rectilinear, distortion-free camera without vignetting it is the object-space convolution (F = 1 and D linear).\n *\n * The lattices. As in the diffraction provider, a pixel aperture or anti-aliasing spots add query offsets; each distinct\n * fractional offset gets its own shifted lattice of sensor points, and every tap of a query on one lattice is on the same\n * lattice. A query is located on its lattice by mapping its scene ray back to the sensor (camera rotation inverted at the\n * request's time, the forward projection, the forward distortion), within 1e-4 site; a query that lands on no lattice point\n * is refused rather than approximated.\n *\n * Time. With camera rotation each environment temporal midpoint is a still camera, so the disc is applied to that\n * instant's image in that instant's frame: one G_t per distinct request time, cached per band. Without rotation the image\n * does not depend on time and one G is kept. The facade refuses rotation with a rolling shutter (each row's instants differ).\n *\n * What is approximate is the disc itself (`lens.defocus` labels it; the facade records the field-variation bounds of\n * each combination), not this evaluation of it.\n */\n\n// #564: a defocus kernel above 64 sites (`largeKernel`) takes the run lattice of large-defocus-lattice.ts instead of the bands:\n// the samples F·L at the same lattice points, convolved by runs in fixed tiles, then divided by each queried point's own F.\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\nimport { hypot3 } from \"../core/portable-math.js\";\nimport { isInternalSceneRadianceEvaluator, markInternalSceneRadianceEvaluator, registerInternalRadianceAccess } from \"../core/internal-radiance-evaluator.js\";\nimport type { SceneRadianceEvaluationRequest, SceneRadianceEvaluationResult } from \"../schema/scene-radiance.js\";\nimport { insideRadialImageCircle, lensProjectionDirectionValue, lensProjectionImagePointValue, type LensProjectionModel } from \"../camera/lens-projection.js\";\nimport { applyPhysicalCameraRotation, resolveProjectionDistanceMm, type CameraAngularVelocityRadPerSec } from \"../motion/camera-rotation.js\";\nimport { prepareIlluminationVignettingThroughput, type IlluminationVignettingProfile } from \"../optics/illumination-vignetting.js\";\nimport { distortedImagePoint, undistortedImagePoint, type PreparedEnvironmentLensFieldMapping } from \"../optics/sensor-environment-query.js\";\nimport { checkedSiteKernel, createZonedGather, gatherInterior, kernelTaps, type SiteKernelFieldZones } from \"./diffraction-provider.js\";\nimport type { PlanarSceneRadianceProvider } from \"./scene-radiance.js\";\nimport { LARGE_DEFOCUS_CACHE_BYTES, createLargeDefocusNodeLattice, type LargeDefocusKernel, type LargeDefocusNodeLattice } from \"./large-defocus-lattice.js\";\n\n/** Rows of native sites per band; bands kept per time. Banding changes memory only, never values. */\nconst BAND_ROWS = 32;\nconst CACHED_BANDS = 2;\nconst LATTICE_TOLERANCE_SITES = 1e-4;\n\n/** The camera geometry the environment uses for each site query (the same options as the site inputs). */\nexport interface DefocusImageSpaceGeometry {\n focalLengthMm: number;\n focusDistanceM: number;\n angularVelocityRadPerSec: CameraAngularVelocityRadPerSec;\n /** The site inputs' `lensFieldMapping`, prepared; omitted for the ideal rectilinear, distortion-free mapping. */\n lensMapping?: PreparedEnvironmentLensFieldMapping;\n /** The site inputs' radial-illumination-vignetting profile; omitted for unity field throughput. */\n vignetting?: IlluminationVignettingProfile;\n}\n\n/** Internal: the scene ray and field factor of sensor points, and the sensor point of a scene ray, for one geometry. */\nexport interface PreparedDefocusImageSpaceGeometry {\n /**\n * The unit look direction (toward the scene, reference camera axes at exposure start) of native sensor point (x, y) mm\n * (+X right, +Y down) at time t, and its field factor F = T·A (vignetting throughput × distortion area factor).\n */\n lookOf(xMm: number, yMm: number, timeSeconds: number): { x: number; y: number; z: number; factor: number };\n /** The native sensor point (mm, +Y down) whose scene ray at time t is the look direction; undefined outside the mapping. */\n sensorPointOf(look: { x: number; y: number; z: number }, timeSeconds: number): { x: number; y: number } | undefined;\n /** True with camera rotation: the ray of a sensor point depends on time. */\n timeDependent: boolean;\n}\n\n/** Internal: prepares {@link PreparedDefocusImageSpaceGeometry} with the environment's own conventions and arithmetic. */\nexport function prepareDefocusImageSpaceGeometry(geometry: DefocusImageSpaceGeometry): PreparedDefocusImageSpaceGeometry {\n const { focalLengthMm, focusDistanceM, angularVelocityRadPerSec: omega, lensMapping, vignetting } = geometry;\n // The projection scale: the thin-lens image distance at the finite focus, for every projection model (the environment's).\n const pd = resolveProjectionDistanceMm(focalLengthMm, focusDistanceM).projectionDistanceMm;\n const model: LensProjectionModel = lensMapping?.mapping.projectionModel ?? \"rectilinear\";\n // #569: with \"backward-ray\" (catalogue fisheyes), a point outside the image circle looks straight back, as the environment's mapped query does.\n const backward = lensMapping?.mapping.outsideImageCircle === \"backward-ray\";\n const timeDependent = omega.pitch !== 0 || omega.yaw !== 0 || omega.roll !== 0;\n // calculateIlluminationVignetting's throughput with the profile validated once (#563: the same numbers, without a result envelope per point).\n const throughputAt = vignetting ? prepareIlluminationVignettingThroughput(vignetting) : undefined;\n const displacement = (t: number): { pitch: number; yaw: number; roll: number } =>\n timeDependent ? { pitch: omega.pitch * t, yaw: omega.yaw * t, roll: omega.roll * t } : { pitch: 0, yaw: 0, roll: 0 };\n // The reference-to-camera rotation at the last time asked, as a matrix (its columns: the rotated basis vectors), so a lattice\n // lookup costs no trigonometry; the rotation is linear, so this equals rotating the vector, up to rounding.\n let matrixTime = NaN, m: number[] = [];\n const toCamera = (v: { x: number; y: number; z: number }, t: number): { x: number; y: number; z: number } => {\n if (t !== matrixTime) {\n const d = displacement(t), ex = applyPhysicalCameraRotation({ x: 1, y: 0, z: 0 }, d, \"reference-to-camera\"),\n ey = applyPhysicalCameraRotation({ x: 0, y: 1, z: 0 }, d, \"reference-to-camera\"), ez = applyPhysicalCameraRotation({ x: 0, y: 0, z: 1 }, d, \"reference-to-camera\");\n m = [ex.x, ey.x, ez.x, ex.y, ey.y, ez.y, ex.z, ey.z, ez.z];\n matrixTime = t;\n }\n return { x: m[0]! * v.x + m[1]! * v.y + m[2]! * v.z, y: m[3]! * v.x + m[4]! * v.y + m[5]! * v.z, z: m[6]! * v.x + m[7]! * v.y + m[8]! * v.z };\n };\n return {\n timeDependent,\n lookOf(xMm, yMm, t): { x: number; y: number; z: number; factor: number } {\n const image = { x: xMm, y: -yMm };\n const { ideal, distortionAreaFactor } = lensMapping ? undistortedImagePoint(lensMapping, image) : { ideal: image, distortionAreaFactor: 1 };\n let lx: number, ly: number, lz: number;\n if (model === \"rectilinear\") {\n // calculateInverseCameraRotationImageMapping: the captured ray (x/pd, y/pd, 1) in reference axes, projected at pd.\n const reference = applyPhysicalCameraRotation({ x: ideal.x / pd, y: ideal.y / pd, z: 1 }, displacement(t), \"camera-to-reference\");\n if (!(reference.z > 0)) throw new InvalidConfigurationError(\"lens.defocus: a lattice point's ray points to or behind the reference camera plane.\");\n lx = pd * (reference.x / reference.z); ly = pd * (reference.y / reference.z); lz = pd;\n } else {\n const reference = applyPhysicalCameraRotation(backward && !insideRadialImageCircle(model, pd, Math.hypot(ideal.x, ideal.y)) ? { x: 0, y: 0, z: -1 } :\n lensProjectionDirectionValue(model, pd, ideal.x, ideal.y), displacement(t), \"camera-to-reference\");\n lx = reference.x; ly = reference.y; lz = reference.z;\n }\n const length = hypot3(lx, ly, lz);\n const throughput = throughputAt ? throughputAt(image) : 1;\n return { x: lx / length, y: ly / length, z: lz / length, factor: throughput * distortionAreaFactor };\n },\n sensorPointOf(look, t): { x: number; y: number } | undefined {\n try {\n const c = timeDependent ? toCamera(look, t) : look;\n let ideal: { x: number; y: number };\n if (model === \"rectilinear\") {\n if (!(c.z > 0)) return undefined;\n ideal = { x: pd * (c.x / c.z), y: pd * (c.y / c.z) };\n } else ideal = lensProjectionImagePointValue(model, pd, c.x, c.y, c.z).imagePointMm;\n const image = lensMapping ? distortedImagePoint(lensMapping, ideal).pointMm : ideal;\n return Number.isFinite(image.x) && Number.isFinite(image.y) ? { x: image.x, y: -image.y } : undefined;\n } catch {\n return undefined;\n }\n }\n };\n}\n\nexport interface DefocusImageSpaceProviderInput {\n base: PlanarSceneRadianceProvider;\n geometry: PreparedDefocusImageSpaceGeometry;\n /** Each spectral node's kernel on the site lattice, (2·kernelRadius + 1)² taps, row-major (the disc, or diffraction ⊛ disc). */\n siteKernels: (wavelengthNm: number) => Float64Array;\n wavelengthsNm: readonly number[];\n kernelRadius: number;\n nativeWidth: number;\n nativeHeight: number;\n sitePitchMicrometers: number;\n /** Planar geometry of the base provider (plane distance and frame-unit scale), to find the plane point of a ray as it does. */\n distanceM: number;\n metresPerFrameUnit: number;\n /** Offsets of the query points from the site centres, in sites (+x right, +y down). Default: one zero offset. */\n queryOffsetsSites?: readonly { x: number; y: number }[];\n /** Region renders: the native sites that will be queried. Values are bit-identical to the whole render's. Default: the whole raster. */\n window?: { x: number; y: number; width: number; height: number };\n /** Most distinct request times kept per band (the temporal sample count). Default 1. */\n timesPerBand?: number;\n /** Called with the duration in ms of each band convolution (diagnostics only). */\n onConvolution?: (milliseconds: number) => void;\n /**\n * #564: a defocus kernel above the direct radius, convolved by runs in fixed tiles (`large-defocus-lattice.ts`), with each\n * node's diffraction kernel after it; used instead of `siteKernels` (`kernelRadius` is then unused).\n */\n largeKernel?: LargeDefocusKernel;\n /** #553: a field-varying kernel by zones (the cat's eye of lens.defocus), gathered instead of `siteKernels`, the same at every node. */\n fieldZones?: SiteKernelFieldZones;\n}\n\n/** Internal (not exported from the package): the base provider with the defocus disc applied in image space (#548). */\nexport function createDefocusImageSpaceProvider(input: DefocusImageSpaceProviderInput): PlanarSceneRadianceProvider {\n const { base, geometry, wavelengthsNm, nativeWidth: W, nativeHeight: H, kernelRadius: R } = input;\n const mmPerSite = input.sitePitchMicrometers / 1000;\n const index = new Map(wavelengthsNm.map((nm, i) => [nm, i]));\n const offsets = input.queryOffsetsSites ?? [{ x: 0, y: 0 }];\n const fraction = (value: number): number => { const f = value - Math.floor(value); return f > 1 - 1e-6 ? 0 : f < 1e-6 ? 0 : f; };\n const shifts: { x: number; y: number }[] = [];\n for (const o of offsets) {\n const f = { x: fraction(o.x), y: fraction(o.y) };\n if (!shifts.some((s) => Math.abs(s.x - f.x) <= 1e-6 && Math.abs(s.y - f.y) <= 1e-6)) shifts.push(f);\n }\n const M = Math.max(0, ...offsets.map((o) => Math.ceil(Math.max(Math.abs(o.x), Math.abs(o.y)) - 1e-6)));\n const LW = W + 2 * M, LH = H + 2 * M;\n const win = input.window ?? { x: 0, y: 0, width: W, height: H };\n const lx0 = Math.max(0, win.x), lx1 = Math.min(LW, win.x + win.width + 2 * M);\n const ly0 = Math.max(0, win.y), ly1 = Math.min(LH, win.y + win.height + 2 * M);\n if (!(lx0 < lx1 && ly0 < ly1)) throw new InvalidConfigurationError(\"Defocus window must overlap the native raster.\");\n const NW = lx1 - lx0, gridWidth = NW + 2 * R;\n const large = input.largeKernel;\n const kernels = large ? [] : wavelengthsNm.map((nm) => checkedSiteKernel(input.siteKernels(nm), R));\n const taps = kernels.map((kernel) => kernelTaps(kernel, R, gridWidth));\n const zonedGather = input.fieldZones ? createZonedGather(input.fieldZones, R, gridWidth, W, H, M) : undefined;\n const sharedKernel = !large && (zonedGather !== undefined || kernels.every((kernel) => kernel === kernels[0]));\n const scale = input.metresPerFrameUnit, distance = input.distanceM;\n const materialAt = base.chartMaterialAt?.bind(base), materialRadiance = base.materialRadiance?.bind(base);\n const now = (): number => globalThis.performance?.now() ?? Date.now();\n // Lattice point (li, lj) of shift s, as a native sensor point in mm (+Y down): site centre plus the shift.\n const xMmOf = (li: number, s: { x: number }): number => (li - M + 0.5 + s.x - W / 2) * mmPerSite;\n const yMmOf = (lj: number, s: { y: number }): number => (lj - M + 0.5 + s.y - H / 2) * mmPerSite;\n // Bands per time (LRU over (time, band)): values[shift][node] holds G_t / F at the band's own lattice points.\n const cache = new Map<string, Float64Array[][]>();\n const capacity = CACHED_BANDS * Math.max(1, input.timesPerBand ?? 1);\n // The last band read, so consecutive queries of one band skip the cache key (most queries).\n let lastBand = -1, lastTime = NaN, lastValues: Float64Array[][] | undefined;\n function band(b: number, time: number): Float64Array[][] {\n if (b === lastBand && time === lastTime) return lastValues!;\n const values = bandOf(b, time);\n lastBand = b; lastTime = time; lastValues = values;\n return values;\n }\n function bandOf(b: number, time: number): Float64Array[][] {\n const key = time + \":\" + b, cached = cache.get(key);\n if (cached) { cache.delete(key); cache.set(key, cached); return cached; }\n const started = input.onConvolution ? now() : 0;\n const y0 = ly0 + b * BAND_ROWS, rows = Math.min(BAND_ROWS, ly1 - y0), gridHeight = rows + 2 * R, size = gridWidth * gridHeight;\n const values = shifts.map((shift) => {\n // Each grid point's field factor and plane point (or material), shared by the spectral nodes.\n const factor = new Float64Array(size), u = new Float64Array(size), v = new Float64Array(size);\n const material = materialAt && materialRadiance ? new Int32Array(size) : undefined;\n for (let gy = 0; gy < gridHeight; gy++) {\n const yMm = yMmOf(y0 + gy - R, shift);\n for (let gx = 0; gx < gridWidth; gx++) {\n const k = gy * gridWidth + gx, look = geometry.lookOf(xMmOf(lx0 + gx - R, shift), yMm, time);\n if (!(look.z > 0)) throw new InvalidConfigurationError(\"lens.defocus: a lattice point's ray does not point toward the scene plane.\");\n // The base provider's own plane-point arithmetic for the outgoing direction −look.\n const t = distance / look.z;\n factor[k] = look.factor; u[k] = look.x * t / scale; v[k] = look.y * t / scale;\n if (material) material[k] = materialAt!(u[k]!, v[k]!);\n }\n }\n // The band's own lattice points' factors, to answer each query with G / F.\n const own = new Float64Array(rows * NW);\n for (let y = 0; y < rows; y++) for (let x = 0; x < NW; x++) own[y * NW + x] = factor[(y + R) * gridWidth + x + R]!;\n // One kernel for every node (the disc without diffraction) and fewer materials than nodes: the convolution is linear, so\n // G_λ = Σ_m L_m(λ)·(K ⊛ F·[material = m]); one convolution per material instead of one per node, the same sum regrouped.\n if (material && sharedKernel) {\n const present = [...new Set(material)];\n if (present.length < wavelengthsNm.length) {\n const perMaterial = present.map((m) => {\n const samples = new Float64Array(size);\n for (let k = 0; k < size; k++) if (material[k] === m) samples[k] = factor[k]!;\n return zonedGather ? zonedGather(samples, lx0, y0, NW, rows) : gatherInterior(samples, taps[0]!, gridWidth, NW, rows, R);\n });\n return wavelengthsNm.map((nm) => {\n const radiance = present.map((m) => materialRadiance!(m, nm)), out = new Float64Array(rows * NW);\n for (const value of radiance) if (!(value >= 0 && value <= 2 ** 100)) throw new InvalidConfigurationError(\"Irradiance samples must be finite, non-negative and within the declared magnitude.\");\n for (let k = 0; k < out.length; k++) {\n let sum = 0;\n for (let i = 0; i < present.length; i++) sum += radiance[i]! * perMaterial[i]![k]!;\n out[k] = sum / own[k]!;\n }\n return out;\n });\n }\n }\n return wavelengthsNm.map((nm, w) => {\n const samples = new Float64Array(size);\n if (material) {\n const radiance = new Map<number, number>();\n for (let k = 0; k < size; k++) {\n const m = material[k]!;\n let value = radiance.get(m);\n if (value === undefined) { value = materialRadiance!(m, nm); radiance.set(m, value); }\n samples[k] = factor[k]! * value;\n }\n } else for (let k = 0; k < size; k++) samples[k] = factor[k]! * base.radianceAt(u[k]!, v[k]!, nm);\n const gathered = zonedGather ? zonedGather(samples, lx0, y0, NW, rows) : gatherInterior(samples, taps[w]!, gridWidth, NW, rows, R);\n for (let k = 0; k < gathered.length; k++) gathered[k] = gathered[k]! / own[k]!;\n return gathered;\n });\n });\n cache.set(key, values);\n if (cache.size > capacity) cache.delete(cache.keys().next().value!);\n if (input.onConvolution) input.onConvolution(now() - started);\n return values;\n }\n /** The lattice key ((shift·LH + lj)·LW + li) of a look direction at time t, or undefined off the lattices or outside the window. */\n function keyOf(look: { x: number; y: number; z: number }, t: number): number | undefined {\n const point = geometry.sensorPointOf(look, t);\n if (point === undefined) return undefined;\n const fi = point.x / mmPerSite + W / 2 - 0.5, fj = point.y / mmPerSite + H / 2 - 0.5;\n for (let s = 0; s < shifts.length; s++) {\n const shift = shifts[s]!, i = Math.round(fi - shift.x), j = Math.round(fj - shift.y);\n if (Math.abs(fi - shift.x - i) > LATTICE_TOLERANCE_SITES || Math.abs(fj - shift.y - j) > LATTICE_TOLERANCE_SITES) continue;\n const li = i + M, lj = j + M;\n if (li < lx0 || lj < ly0 || li >= lx1 || lj >= ly1) return undefined;\n return (s * LH + lj) * LW + li;\n }\n return undefined;\n }\n function valueOf(key: number, t: number, nm: number): number {\n const w = index.get(nm);\n if (w === undefined) throw new InvalidConfigurationError(\"Defocus query is off the sensor site lattice; the image-space convolution does not apply.\");\n const li = key % LW, rest = (key - li) / LW, lj = rest % LH, s = (rest - lj) / LH;\n if (large) return largeValue(s, t, w, li, lj);\n return band(Math.floor((lj - ly0) / BAND_ROWS), t)[s]![w]![((lj - ly0) % BAND_ROWS) * NW + li - lx0]!;\n }\n // #564: one run lattice per (time, shift) of the samples F·L at the lattice points, and the own field factors F by tile, so a\n // query is answered with (K ⊛ D ⊛ F·L) / F as on the band path.\n const largeLattices = new Map<string, { lattice: LargeDefocusNodeLattice; own: Map<number, Float64Array> }>();\n const largeLatticeCount = shifts.length * Math.max(1, input.timesPerBand ?? 1);\n // Lattice points at most `reach` beyond the lattice feed queried values: the defocus kernel's radius plus the diffraction kernel's.\n const reach = large ? large.runs.radius + (large.diffraction ? large.diffraction.radius : 0) : 0;\n function largeValue(s: number, time: number, w: number, li: number, lj: number): number {\n const key = time + \":\" + s;\n let entry = largeLattices.get(key);\n if (!entry) {\n const shift = shifts[s]!;\n const lattice = createLargeDefocusNodeLattice({ kernel: large!, wavelengthsNm, capacityBytes: LARGE_DEFOCUS_CACHE_BYTES / largeLatticeCount, ...(input.onConvolution ? { onTile: input.onConvolution } : {}),\n source: (x0, y0, width, height) => {\n const size = width * height, factor = new Float64Array(size), u = new Float64Array(size), v = new Float64Array(size);\n const material = materialAt && materialRadiance ? new Int32Array(size) : undefined, beyond = new Uint8Array(size);\n for (let y = 0; y < height; y++) {\n const yMm = yMmOf(y0 + y, shift);\n for (let x = 0; x < width; x++) {\n const k = y * width + x;\n // A fixed tile's source reaches past the lattice: points beyond its reach feed no queried value, so they are 0 and never\n // mapped (the lens profiles are checked only up to the reach).\n if (x0 + x < -reach || x0 + x >= LW + reach || y0 + y < -reach || y0 + y >= LH + reach) { beyond[k] = 1; continue; }\n const look = geometry.lookOf(xMmOf(x0 + x, shift), yMm, time);\n if (!(look.z > 0)) throw new InvalidConfigurationError(\"lens.defocus: a lattice point's ray does not point toward the scene plane.\");\n const t = distance / look.z;\n factor[k] = look.factor; u[k] = look.x * t / scale; v[k] = look.y * t / scale;\n if (material) material[k] = materialAt!(u[k]!, v[k]!);\n }\n }\n return (node: number): Float64Array => {\n const nm = wavelengthsNm[node]!, samples = new Float64Array(size);\n if (material) {\n const radiance = new Map<number, number>();\n for (let k = 0; k < size; k++) {\n if (beyond[k]) continue;\n const m = material[k]!;\n let value = radiance.get(m);\n if (value === undefined) { value = materialRadiance!(m, nm); radiance.set(m, value); }\n samples[k] = factor[k]! * value;\n }\n } else for (let k = 0; k < size; k++) if (!beyond[k]) samples[k] = factor[k]! * base.radianceAt(u[k]!, v[k]!, nm);\n return samples;\n };\n } });\n entry = { lattice, own: new Map() };\n largeLattices.set(key, entry);\n if (largeLattices.size > largeLatticeCount) largeLattices.delete(largeLattices.keys().next().value!);\n }\n // The own factor of the lattice point, by 64-point tiles (kept for the request: 8 bytes per lattice point read).\n const T = 64, tx = Math.floor(li / T), ty = Math.floor(lj / T), tileKey = ty * 1048576 + tx;\n let own = entry.own.get(tileKey);\n if (!own) {\n own = new Float64Array(T * T);\n const shift = shifts[s]!;\n // Only the lattice's own points are queried; the rest of the tile is never read (and may lie beyond the lens profiles).\n for (let y = 0; y < T && ty * T + y < LH; y++) { const yMm = yMmOf(ty * T + y, shift); for (let x = 0; x < T && tx * T + x < LW; x++) own[y * T + x] = geometry.lookOf(xMmOf(tx * T + x, shift), yMm, time).factor; }\n entry.own.set(tileKey, own);\n }\n return entry.lattice.valueAt(w, li, lj) / own[(lj - ty * T) * T + li - tx * T]!;\n }\n function blurredAt(look: { x: number; y: number; z: number }, time: number, nm: number): number {\n const t = geometry.timeDependent ? time : 0, key = keyOf(look, t);\n if (key === undefined) throw new InvalidConfigurationError(\"Defocus query is off the sensor site lattice; the image-space convolution does not apply.\");\n return valueOf(key, t, nm);\n }\n const baseEvaluate = base.evaluateRadiance;\n const evaluateRadiance = (request: Readonly<SceneRadianceEvaluationRequest>): SceneRadianceEvaluationResult => {\n const result = baseEvaluate.call(base, request), o = (request.target as { outgoingDirectionUnitVector: { x: number; y: number; z: number } }).outgoingDirectionUnitVector;\n return { ...result, spectralRadianceWattsPerSquareMeterSteradianNanometer: blurredAt({ x: -o.x, y: -o.y, z: -o.z }, request.timeSecondsFromExposureStart, request.wavelengthNanometers) };\n };\n // The result is the base result with only its radiance replaced, so an engine-built base evaluator keeps its mark. Its radiance is\n // a pure function of the lattice key (and, with rotation, the request time) and the wavelength, so the lean executor may read it by\n // key, as for the diffraction provider.\n if (isInternalSceneRadianceEvaluator(baseEvaluate)) {\n markInternalSceneRadianceEvaluator(evaluateRadiance);\n // With rotation the key also carries the request time, as an index into the distinct times seen (one per temporal midpoint).\n const times: number[] = [], timeIndex = new Map<number, number>(), latticeKeys = shifts.length * LH * LW;\n registerInternalRadianceAccess(evaluateRadiance, {\n tabulated: false,\n keyOfDirection(o, time): number | undefined {\n const t = geometry.timeDependent ? time : 0, key = keyOf({ x: -o.x, y: -o.y, z: -o.z }, t);\n if (key === undefined) return undefined;\n let index = timeIndex.get(t);\n if (index === undefined) { index = times.length; times.push(t); timeIndex.set(t, index); }\n return index * latticeKeys + key;\n },\n radianceOfKey(key, nm): number {\n const index = Math.floor(key / latticeKeys);\n return valueOf(key - index * latticeKeys, times[index]!, nm);\n }\n });\n }\n return {\n sceneId: base.sceneId, providerProfileId: base.providerProfileId, radianceAt: base.radianceAt,\n evaluateRadiance,\n evaluateApertureRadiance(): SceneRadianceEvaluationResult {\n throw new InvalidConfigurationError(\"Defocus by image-space convolution does not take pupil rays.\");\n }\n };\n}\n\n/** Field-variation bounds of the image-space disc for one request (#548), recorded in the `lens.defocus` assumption. */\nexport interface DefocusFieldVariation {\n /** Sensor points the bounds were evaluated at: a grid of this many points per side over the native raster, edges included. */\n gridPointsPerSide: number;\n /**\n * Camera rotation (pitch or yaw tilts the scene plane in the camera frame): the largest change of the disc diameter, in\n * sites, between the axial depth of each scene point in the rotated camera frame and the subject distance, over the grid and\n * the rendered temporal midpoints. 0 for roll only; null without rotation.\n */\n rotationMaximumDiameterChangeSites: number | null;\n /**\n * Distortion: the largest deviation from 1 of the local scale of the distortion map (singular values of d distorted / d ideal)\n * over the grid: the relative disc-size difference to a model that blurs the ideal image and then distorts it. Null without distortion.\n */\n distortionMaximumLocalScaleDeviation: number | null;\n /**\n * A non-rectilinear projection: the largest change of the disc diameter, in sites, between the distance along each scene\n * point's ray and its axial depth (the thin-lens model uses the axial depth). Null for the rectilinear projection.\n */\n projectionMaximumDiameterChangeSites: number | null;\n}\n\n/** Internal: {@link DefocusFieldVariation} on a 9 × 9 grid of sensor points (the extremes of these smooth maps lie on the frame's edges). */\nexport function calculateDefocusFieldVariation(input: { geometry: PreparedDefocusImageSpaceGeometry; lensMapping?: PreparedEnvironmentLensFieldMapping;\n focalLengthMm: number; fNumber: number; focusDistanceM: number; subjectDistanceM: number; pitchMicrometers: number; nativeWidth: number; nativeHeight: number;\n angularVelocityRadPerSec: CameraAngularVelocityRadPerSec; temporalMidpointsSeconds: readonly number[]; diameterSites: number;\n discAt: (subjectDistanceM: number) => number }): DefocusFieldVariation {\n const { geometry, lensMapping, pitchMicrometers: pitch, nativeWidth: W, nativeHeight: H, subjectDistanceM: d, diameterSites, discAt } = input;\n const G = 9, points: { x: number; y: number }[] = [];\n for (let j = 0; j < G; j++) for (let i = 0; i < G; i++) points.push({ x: (i / (G - 1) - 0.5) * W * pitch / 1000, y: (j / (G - 1) - 0.5) * H * pitch / 1000 });\n let rotation: number | null = null;\n if (geometry.timeDependent) {\n rotation = 0;\n const omega = input.angularVelocityRadPerSec;\n for (const t of input.temporalMidpointsSeconds) {\n // The camera's optical axis at t in the reference axes; a scene point's axial depth in the rotated camera is P·axis.\n const axis = applyPhysicalCameraRotation({ x: 0, y: 0, z: 1 }, { pitch: omega.pitch * t, yaw: omega.yaw * t, roll: omega.roll * t }, \"camera-to-reference\");\n for (const p of points) {\n const look = geometry.lookOf(p.x, p.y, t), reach = d / look.z;\n const depth = reach * (look.x * axis.x + look.y * axis.y + look.z * axis.z);\n rotation = Math.max(rotation, Math.abs(discAt(depth) - diameterSites));\n }\n }\n }\n let distortion: number | null = null;\n if (lensMapping && lensMapping.mapping.distortion.kind !== \"none\") {\n distortion = 0;\n for (const p of points) {\n const scales = distortedImagePoint(lensMapping, undistortedImagePoint(lensMapping, { x: p.x, y: -p.y }).ideal);\n distortion = Math.max(distortion, scales.largestScale - 1, 1 - scales.smallestScale);\n }\n }\n let projection: number | null = null;\n if (lensMapping && lensMapping.mapping.projectionModel !== \"rectilinear\") {\n projection = 0;\n for (const p of points) {\n const look = geometry.lookOf(p.x, p.y, 0);\n projection = Math.max(projection, Math.abs(discAt(d / look.z) - diameterSites));\n }\n }\n return { gridPointsPerSide: G, rotationMaximumDiameterChangeSites: rotation, distortionMaximumLocalScaleDeviation: distortion, projectionMaximumDiameterChangeSites: projection };\n}\n"]}
@@ -1,5 +1,26 @@
1
1
  import type { PreparedDefocusImageSpaceGeometry } from "./defocus-image-space-provider.js";
2
- import { type DisplayViewExpectedSignal, type DisplayViewExpectedSignalInput } from "./expected-signal.js";
2
+ import { type ResolveLensSampledPsfInput } from "../optics/lens-psf-profile.js";
3
+ import { type DisplayViewExpectedSignal, type DisplayViewExpectedSignalInput, type GroupTables } from "./expected-signal.js";
4
+ /** #569: field zones along the native raster's longer side. */
5
+ export declare const DISPLAY_VIEW_LENS_PSF_ZONES = 64;
6
+ /** #569: a field-dependent PSF for the display view (see the module comment). */
7
+ export interface DisplayViewLensPsf {
8
+ /** Kernel radius and zone side, in sites. */
9
+ readonly radius: number;
10
+ readonly zoneSites: number;
11
+ /** The kernels at the frame centre's zone, for the expected-signal input's lattice groups and reach. */
12
+ axisKernels(wavelengthsNm: readonly number[]): {
13
+ radius: number;
14
+ perNode: Float64Array[];
15
+ };
16
+ /** The combined kernels of the zone of native site (x, y), for an input whose kernels are the axis kernels. */
17
+ tables(input: DisplayViewExpectedSignalInput): (x: number, y: number) => readonly GroupTables[];
18
+ }
19
+ /**
20
+ * #569: the field-dependent PSF of a display view from the sampled PSF the capture resolves (everything but the field point and wavelength),
21
+ * of kernel radius R, on the W × H native raster of `pitch` µm.
22
+ */
23
+ export declare function createDisplayViewLensPsf(psf: Omit<ResolveLensSampledPsfInput, "fieldPointMm" | "wavelengthNm">, R: number, W: number, H: number, pitch: number): DisplayViewLensPsf;
3
24
  /** What the lens signal needs from the resolved request. */
4
25
  export interface DisplayViewLensSetup {
5
26
  geometry: PreparedDefocusImageSpaceGeometry;
@@ -21,6 +42,16 @@ export interface DisplayViewLensSetup {
21
42
  y: number;
22
43
  };
23
44
  }[];
45
+ /**
46
+ * #569: a field-dependent lens PSF (`lens.catalogue`, {@link createDisplayViewLensPsf}): each site reads its field zone's kernels
47
+ * instead of the input's. The input's kernels (the axis zone's) set the lattice groups and the reach; absent, every site reads them.
48
+ */
49
+ psf?: DisplayViewLensPsf | undefined;
50
+ /**
51
+ * #569 (catalogue fisheyes): a ray that does not point toward the scene plane sees no scene (zero radiance), as the capture's provider
52
+ * with `zeroBeyondHorizon` gives it, instead of failing.
53
+ */
54
+ zeroBeyondHorizon?: boolean | undefined;
24
55
  }
25
56
  /**
26
57
  * Checks that the mapping and the vignetting profile cover the farthest source point the view reads, (W/2 + reachSites, H/2 + reachSites)
@@ -26,6 +26,15 @@
26
26
  * ring tagged with the point, sized from the window and capped at LATTICE_CACHE_LIMIT entries (beyond it, points are
27
27
  * evaluated as they are read).
28
28
  *
29
+ * Field-dependent PSF (#569, `lens.catalogue`; {@link createDisplayViewLensPsf}). The capture's environment PSF quadrature resolves the
30
+ * catalogue lens's sampled PSF at each query point's own field position. The view cuts the native raster into square zones of
31
+ * Z = ⌈max(W, H) / DISPLAY_VIEW_LENS_PSF_ZONES⌉ sites (one site on frames of at most that many sites a side) and every site of a zone
32
+ * takes the PSF the capture's own resolver gives at the zone's centre, at each spectral node (an approximation: the PSF's change
33
+ * across half a zone). A profile kernel's rows run with image +Y (up) and its tap (i, j) reads (x − (i − c)·p, y + (j − c)·p) in
34
+ * native coordinates (`sensorPsfSourcePoint`), so the view's kernel (reading in(x − t)) is the profile kernel flipped vertically.
35
+ * Each zone's combined kernels are the expected signal's own tables (`buildTables`) with the zone's kernels, built when a site of
36
+ * the zone is first read and kept per input in a least-recently-used cache of at most 64 MB (at least four zones).
37
+ *
29
38
  * Large defocus kernels (#564, `input.largeKernel`, radius above 64 sites). The image-space disc D is the same at every lattice
30
39
  * group, spectral node and temporal midpoint, so it commutes with those sums as in the rectilinear signal (`expected-signal.ts`):
31
40
  * μ_c(x) = Σ_s D(s)·E_c(x − s), with E_c(x) the sum above through the in-focus kernels (each node's diffraction kernel, or a unit
@@ -35,7 +44,62 @@
35
44
  */
36
45
  import { InvalidConfigurationError } from "../core/configuration-error.js";
37
46
  import { createSiteKernelRunsLattice } from "../optics/site-kernel-runs.js";
38
- import { displayViewSignalTables } from "./expected-signal.js";
47
+ import { resolveLensSampledPsfKernel } from "../optics/lens-psf-profile.js";
48
+ import { buildTables, displayViewSignalTables } from "./expected-signal.js";
49
+ /** #569: field zones along the native raster's longer side. */
50
+ export const DISPLAY_VIEW_LENS_PSF_ZONES = 64;
51
+ /**
52
+ * #569: the field-dependent PSF of a display view from the sampled PSF the capture resolves (everything but the field point and wavelength),
53
+ * of kernel radius R, on the W × H native raster of `pitch` µm.
54
+ */
55
+ export function createDisplayViewLensPsf(psf, R, W, H, pitch) {
56
+ const Z = Math.ceil(Math.max(W, H) / DISPLAY_VIEW_LENS_PSF_ZONES), zonesX = Math.ceil(W / Z), w = 2 * R + 1;
57
+ const zoneOf = (x, y) => Math.floor(y / Z) * zonesX + Math.floor(x / Z);
58
+ const kernelsOf = (zone, wavelengthsNm) => {
59
+ // The zone's centre in sites from the top-left corner (an edge zone may be narrower), in image millimetres (+Y up).
60
+ const zx = zone % zonesX, zy = (zone - zx) / zonesX, fieldPointMm = { x: ((zx * Z + Math.min(W, zx * Z + Z)) / 2 - W / 2) * pitch / 1000,
61
+ y: (H / 2 - (zy * Z + Math.min(H, zy * Z + Z)) / 2) * pitch / 1000 };
62
+ return wavelengthsNm.map((wavelengthNm) => {
63
+ // Every node of the engine-built profile has the same (2R + 1)² window, so every resolved kernel has it too.
64
+ const values = resolveLensSampledPsfKernel({ ...psf, fieldPointMm, wavelengthNm }).normalizedIntensity, out = new Float64Array(w * w);
65
+ for (let j = 0; j < w; j++)
66
+ for (let i = 0; i < w; i++)
67
+ out[(w - 1 - j) * w + i] = values[j * w + i];
68
+ return out;
69
+ });
70
+ };
71
+ const caches = new WeakMap();
72
+ return { radius: R, zoneSites: Z,
73
+ axisKernels: (wavelengthsNm) => ({ radius: R, perNode: kernelsOf(zoneOf(W >> 1, H >> 1), wavelengthsNm) }),
74
+ tables(input) {
75
+ let read = caches.get(input);
76
+ if (read)
77
+ return read;
78
+ const cache = new Map();
79
+ let kept = 0, last = -1, lastTables = [];
80
+ read = (x, y) => {
81
+ const zone = zoneOf(x, y);
82
+ if (zone === last)
83
+ return lastTables;
84
+ let tables = cache.get(zone);
85
+ if (tables)
86
+ cache.delete(zone);
87
+ else {
88
+ tables = buildTables({ ...input, kernels: { radius: R, perNode: kernelsOf(zone, input.wavelengthsNm) } }).groups;
89
+ // Zones kept: at least 4, and at most 64 MB of them (every zone's tables have the same size).
90
+ kept ||= Math.max(4, (1 << 23) / tables.reduce((n, g) => n + g.cw * g.ch * (g.neutral.length + g.spectral.flat().length + g.perNode.flat().length), 0));
91
+ if (cache.size >= kept)
92
+ cache.delete(cache.keys().next().value);
93
+ }
94
+ cache.set(zone, tables);
95
+ last = zone;
96
+ lastTables = tables;
97
+ return tables;
98
+ };
99
+ caches.set(input, read);
100
+ return read;
101
+ } };
102
+ }
39
103
  /** Largest lattice cache, in entries over all lattice groups and temporal midpoints (times the spectral nodes for radiance scenes). */
40
104
  const LATTICE_CACHE_LIMIT = 1 << 22;
41
105
  const pow2 = (n) => { let p = 1; while (p < n)
@@ -50,7 +114,7 @@ export function prepareDisplayViewLensSignal(lens, nativeWidth, nativeHeight, re
50
114
  for (const t of lens.times)
51
115
  for (const [x, y] of [[-xMm, -yMm], [xMm, -yMm], [-xMm, yMm], [xMm, yMm]]) {
52
116
  try {
53
- if (!(lens.geometry.lookOf(x, y, t).z > 0))
117
+ if (!(lens.geometry.lookOf(x, y, t).z > 0) && !lens.zeroBeyondHorizon)
54
118
  throw new InvalidConfigurationError("its ray does not point toward the scene plane.");
55
119
  }
56
120
  catch (error) {
@@ -67,14 +131,25 @@ function createLensSignal(lens, input, spanColumns) {
67
131
  const materials = scene.kind === "materials" ? scene : undefined, radianceAt = scene.kind === "radiance" ? scene.radianceAt : undefined;
68
132
  const { reflectance, spectralIndex, neutralDirect, spectralDirect, groups } = displayViewSignalTables(input);
69
133
  const kernels = input.kernels, R = kernels ? kernels.radius : 0;
134
+ /** #569: the combined kernels of the zone of site (x, y), or the input's own without a field-dependent PSF. */
135
+ const zoneTables = lens.psf ? lens.psf.tables(input) : () => groups;
70
136
  let lookups = 0;
71
137
  // The plane point (frame units) and field factor of native sensor point (x, y) mm at time t: the environment's mapping (lookOf) and
72
138
  // the planar provider's own arithmetic for the outgoing direction −look.
73
- let pu = 0, pv = 0, pf = 0;
139
+ // #569: with zeroBeyondHorizon, a ray at or beyond 90° reads the plane's origin with a zero factor (zero radiance; `beyond` is set).
140
+ let pu = 0, pv = 0, pf = 0, beyond = false;
141
+ const zeroBeyond = lens.zeroBeyondHorizon === true;
74
142
  const map = (xMm, yMm, t) => {
75
143
  const look = geometry.lookOf(xMm, yMm, t);
76
- if (!(look.z > 0))
77
- throw new InvalidConfigurationError("simulateDisplayView: a query ray does not point toward the scene plane.");
144
+ beyond = !(look.z > 0);
145
+ if (beyond) {
146
+ if (!zeroBeyond || !Number.isFinite(look.z))
147
+ throw new InvalidConfigurationError("simulateDisplayView: a query ray does not point toward the scene plane.");
148
+ pu = 0;
149
+ pv = 0;
150
+ pf = 0;
151
+ return;
152
+ }
78
153
  const s = distance / look.z;
79
154
  pu = look.x * s / scale;
80
155
  pv = look.y * s / scale;
@@ -157,14 +232,14 @@ function createLensSignal(lens, input, spanColumns) {
157
232
  }
158
233
  }
159
234
  function kernelSite(x, y) {
160
- const c = channelAt(x, y), rowMask = cacheRows - 1, colMask = cacheCols - 1;
235
+ const c = channelAt(x, y), rowMask = cacheRows - 1, colMask = cacheCols - 1, zone = zoneTables(x, y);
161
236
  let total = 0;
162
237
  for (let ti = 0; ti < T; ti++) {
163
238
  let sum = 0;
164
239
  for (let g = 0; g < G; g++) {
165
- const group = groups[g], p0 = x + group.minIx - R, q0 = y + group.minIy - R, cw = group.cw, ch = group.ch;
240
+ const group = groups[g], p0 = x + group.minIx - R, q0 = y + group.minIy - R, cw = group.cw, ch = group.ch, weights = zone[g];
166
241
  if (materials) {
167
- const nk = group.neutral[c], sk = group.spectral[c];
242
+ const nk = weights.neutral[c], sk = weights.spectral[c];
168
243
  for (let dy = 0, t = 0; dy < ch; dy++) {
169
244
  // The cache row of lattice row q (read inline: the common case is a hit).
170
245
  const q = q0 + dy, row = cacheRows > 0 ? ((g * T + ti) * cacheRows + (q & rowMask)) * cacheCols : -1;
@@ -187,7 +262,7 @@ function createLensSignal(lens, input, spanColumns) {
187
262
  lattice(g, ti, p0 + dx, q0 + dy);
188
263
  let value = 0;
189
264
  for (let n = 0; n < nodes; n++)
190
- value += group.perNode[n][c][t] * radiance[n];
265
+ value += weights.perNode[n][c][t] * radiance[n];
191
266
  sum += lf * value;
192
267
  }
193
268
  }
@@ -358,7 +433,7 @@ function createLensSignal(lens, input, spanColumns) {
358
433
  try {
359
434
  for (let ti = 0; ti < T; ti++) {
360
435
  map(xMm, yMm, times[ti]);
361
- const value = materials ? materials.materialAt(pu, pv) : radianceAt(pu, pv, pilotNode);
436
+ const value = beyond ? -1 : materials ? materials.materialAt(pu, pv) : radianceAt(pu, pv, pilotNode);
362
437
  lookups++;
363
438
  if (ti === 0)
364
439
  first = value;