@photivra/engine 2.19.0 → 2.21.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.
- package/CHANGELOG.md +289 -1
- package/CITATION.cff +1 -1
- package/NODE_SUPPORT.md +7 -5
- package/README.md +7 -6
- package/SECURITY.md +1 -1
- package/THIRD_PARTY.md +21 -10
- package/dist/capture/dng-lens-correction-opcodes.d.ts +32 -0
- package/dist/capture/dng-lens-correction-opcodes.js +119 -0
- package/dist/capture/dng-lens-correction-opcodes.js.map +1 -0
- package/dist/capture/exposure-build-up-stage.d.ts +16 -0
- package/dist/capture/exposure-build-up-stage.js +4 -0
- package/dist/capture/exposure-build-up-stage.js.map +1 -0
- package/dist/capture/native-environment-lean.d.ts +2 -1
- package/dist/capture/native-environment-lean.js +42 -78
- package/dist/capture/native-environment-lean.js.map +1 -1
- package/dist/capture/native-environment-tabulated.js +4 -3
- package/dist/capture/native-environment-tabulated.js.map +1 -1
- package/dist/capture/native-raw-dng.d.ts +6 -0
- package/dist/capture/native-raw-dng.js +16 -2
- package/dist/capture/native-raw-dng.js.map +1 -1
- package/dist/capture/native-raw.d.ts +3 -2
- package/dist/capture/native-raw.js +5 -4
- package/dist/capture/native-raw.js.map +1 -1
- package/dist/capture/sensor-raw-producer.d.ts +4 -1
- package/dist/capture/sensor-raw-producer.js +15 -8
- package/dist/capture/sensor-raw-producer.js.map +1 -1
- package/dist/core/shared-helpers.d.ts +2 -0
- package/dist/core/shared-helpers.js +4 -0
- package/dist/core/shared-helpers.js.map +1 -1
- package/dist/core/version.d.ts +1 -1
- package/dist/core/version.js +1 -1
- package/dist/core/version.js.map +1 -1
- package/dist/equipment/generic-lens-catalogue.d.ts +11 -4
- package/dist/equipment/generic-lens-catalogue.js +49 -7
- package/dist/equipment/generic-lens-catalogue.js.map +1 -1
- package/dist/equipment/generic-tier-assets.d.ts +32 -0
- package/dist/equipment/generic-tier-assets.js +18 -14
- package/dist/equipment/generic-tier-assets.js.map +1 -1
- package/dist/equipment/generic-tier-presets.js +2 -3
- package/dist/equipment/generic-tier-presets.js.map +1 -1
- package/dist/equipment/sensor-profile-body.d.ts +78 -0
- package/dist/equipment/sensor-profile-body.js +77 -0
- package/dist/equipment/sensor-profile-body.js.map +1 -0
- package/dist/equipment/sensor-profiles.d.ts +8 -0
- package/dist/equipment/sensor-profiles.js +82 -0
- package/dist/equipment/sensor-profiles.js.map +1 -0
- package/dist/facade/catalogue-lens-signal.d.ts +2 -2
- package/dist/facade/catalogue-lens-signal.js +58 -71
- package/dist/facade/catalogue-lens-signal.js.map +1 -1
- package/dist/facade/chart-radiance-batch.js +2 -1
- package/dist/facade/chart-radiance-batch.js.map +1 -1
- package/dist/facade/defocus-image-space-provider.d.ts +7 -0
- package/dist/facade/defocus-image-space-provider.js +64 -76
- package/dist/facade/defocus-image-space-provider.js.map +1 -1
- package/dist/facade/display-view-gpu-session.js +2 -0
- package/dist/facade/display-view-gpu-session.js.map +1 -1
- package/dist/facade/display-view-gpu.d.ts +13 -5
- package/dist/facade/display-view-gpu.js +4 -4
- package/dist/facade/display-view-gpu.js.map +1 -1
- package/dist/facade/display-view-lens-signal.d.ts +1 -1
- package/dist/facade/display-view-lens-signal.js +30 -26
- package/dist/facade/display-view-lens-signal.js.map +1 -1
- package/dist/facade/display-view.d.ts +3 -1
- package/dist/facade/display-view.js +6 -24
- package/dist/facade/display-view.js.map +1 -1
- package/dist/facade/expected-signal-setup.d.ts +3 -1
- package/dist/facade/expected-signal-setup.js +1 -1
- package/dist/facade/expected-signal-setup.js.map +1 -1
- package/dist/facade/expected-signal.d.ts +47 -14
- package/dist/facade/expected-signal.js +117 -112
- package/dist/facade/expected-signal.js.map +1 -1
- package/dist/facade/exposure-build-up.d.ts +70 -0
- package/dist/facade/exposure-build-up.js +164 -0
- package/dist/facade/exposure-build-up.js.map +1 -0
- package/dist/facade/fast-methods.d.ts +50 -0
- package/dist/facade/fast-methods.js +58 -0
- package/dist/facade/fast-methods.js.map +1 -0
- package/dist/facade/fast-resolution.d.ts +12 -0
- package/dist/facade/fast-resolution.js +18 -0
- package/dist/facade/fast-resolution.js.map +1 -0
- package/dist/facade/generic-lens-capture.d.ts +5 -4
- package/dist/facade/generic-lens-capture.js +5 -4
- package/dist/facade/generic-lens-capture.js.map +1 -1
- package/dist/facade/image-plane-enable.d.ts +7 -0
- package/dist/facade/image-plane-enable.js +17 -0
- package/dist/facade/image-plane-enable.js.map +1 -0
- package/dist/facade/image-plane-lattice-data.d.ts +6 -0
- package/dist/facade/image-plane-lattice-data.js +10 -0
- package/dist/facade/image-plane-lattice-data.js.map +1 -0
- package/dist/facade/image-plane-support.d.ts +33 -0
- package/dist/facade/image-plane-support.js +11 -0
- package/dist/facade/image-plane-support.js.map +1 -0
- package/dist/facade/image-plane.d.ts +36 -0
- package/dist/facade/image-plane.js +353 -0
- package/dist/facade/image-plane.js.map +1 -0
- package/dist/facade/mixed-illumination.d.ts +108 -0
- package/dist/facade/mixed-illumination.js +174 -0
- package/dist/facade/mixed-illumination.js.map +1 -0
- package/dist/facade/representative-light-sources.d.ts +72 -0
- package/dist/facade/representative-light-sources.js +124 -0
- package/dist/facade/representative-light-sources.js.map +1 -0
- package/dist/facade/scene-radiance.d.ts +129 -4
- package/dist/facade/scene-radiance.js +48 -13
- package/dist/facade/scene-radiance.js.map +1 -1
- package/dist/facade/simulate-capture.d.ts +88 -19
- package/dist/facade/simulate-capture.js +374 -145
- package/dist/facade/simulate-capture.js.map +1 -1
- package/dist/facade/simulate-display-view.d.ts +3 -2
- package/dist/facade/simulate-display-view.js +36 -18
- package/dist/facade/simulate-display-view.js.map +1 -1
- package/dist/gpu/chart-composite-gpu.d.ts +13 -1
- package/dist/gpu/chart-composite-gpu.js +48 -9
- package/dist/gpu/chart-composite-gpu.js.map +1 -1
- package/dist/gpu/chart-radiance-gpu.js +4 -30
- package/dist/gpu/chart-radiance-gpu.js.map +1 -1
- package/dist/gpu/display-view-composite-material-module.d.ts +10 -4
- package/dist/gpu/display-view-composite-material-module.js +39 -13
- package/dist/gpu/display-view-composite-material-module.js.map +1 -1
- package/dist/gpu/display-view-image-material-module.d.ts +86 -0
- package/dist/gpu/display-view-image-material-module.js +339 -0
- package/dist/gpu/display-view-image-material-module.js.map +1 -0
- package/dist/gpu/display-view-image-quality.d.ts +45 -0
- package/dist/gpu/display-view-image-quality.js +380 -0
- package/dist/gpu/display-view-image-quality.js.map +1 -0
- package/dist/gpu/display-view-quality-gpu.d.ts +67 -1
- package/dist/gpu/display-view-quality-gpu.js +136 -205
- package/dist/gpu/display-view-quality-gpu.js.map +1 -1
- package/dist/gpu/display-view-speed-gpu.d.ts +51 -3
- package/dist/gpu/display-view-speed-gpu.js +131 -93
- package/dist/gpu/display-view-speed-gpu.js.map +1 -1
- package/dist/gpu/wgsl-display-view-quality-kernel.d.ts +29 -15
- package/dist/gpu/wgsl-display-view-quality-kernel.js +58 -36
- package/dist/gpu/wgsl-display-view-quality-kernel.js.map +1 -1
- package/dist/gpu/wgsl-display-view-speed-kernel.d.ts +21 -6
- package/dist/gpu/wgsl-display-view-speed-kernel.js +46 -11
- package/dist/gpu/wgsl-display-view-speed-kernel.js.map +1 -1
- package/dist/gpu/wgsl-exact-sum.d.ts +20 -0
- package/dist/gpu/wgsl-exact-sum.js +42 -0
- package/dist/gpu/wgsl-exact-sum.js.map +1 -0
- package/dist/index.d.ts +18 -3
- package/dist/index.js +12 -1
- package/dist/index.js.map +1 -1
- package/dist/motion/subject-motion.d.ts +66 -0
- package/dist/motion/subject-motion.js +52 -0
- package/dist/motion/subject-motion.js.map +1 -0
- package/dist/optics/aperture-diameter.d.ts +47 -0
- package/dist/optics/aperture-diameter.js +50 -0
- package/dist/optics/aperture-diameter.js.map +1 -0
- package/dist/optics/detail-limit.d.ts +182 -0
- package/dist/optics/detail-limit.js +336 -0
- package/dist/optics/detail-limit.js.map +1 -0
- package/dist/optics/generic-lens-lateral-color.d.ts +83 -0
- package/dist/optics/generic-lens-lateral-color.js +77 -0
- package/dist/optics/generic-lens-lateral-color.js.map +1 -0
- package/dist/optics/generic-lens-psf.d.ts +18 -2
- package/dist/optics/generic-lens-psf.js +79 -48
- package/dist/optics/generic-lens-psf.js.map +1 -1
- package/dist/optics/lens-psf-profile.d.ts +7 -0
- package/dist/optics/lens-psf-profile.js +2 -1
- package/dist/optics/lens-psf-profile.js.map +1 -1
- package/dist/optics/scene-to-sensor-irradiance.d.ts +13 -0
- package/dist/optics/scene-to-sensor-irradiance.js +7 -0
- package/dist/optics/scene-to-sensor-irradiance.js.map +1 -1
- package/dist/output/crop-to-match-focal-length.d.ts +62 -0
- package/dist/output/crop-to-match-focal-length.js +63 -0
- package/dist/output/crop-to-match-focal-length.js.map +1 -0
- package/dist/output/developed-lens-corrections.d.ts +19 -5
- package/dist/output/developed-lens-corrections.js +30 -11
- package/dist/output/developed-lens-corrections.js.map +1 -1
- package/dist/output/generic-lens-corrections.d.ts +41 -3
- package/dist/output/generic-lens-corrections.js +57 -9
- package/dist/output/generic-lens-corrections.js.map +1 -1
- package/dist/output/lens-corrections.d.ts +12 -2
- package/dist/output/lens-corrections.js +22 -7
- package/dist/output/lens-corrections.js.map +1 -1
- package/dist/output/print-contrast-reference.js +1 -1
- package/dist/output/print-contrast-reference.js.map +1 -1
- package/dist/output/print-plan.d.ts +41 -5
- package/dist/output/print-plan.js +59 -14
- package/dist/output/print-plan.js.map +1 -1
- package/dist/output/print-size-blur-noise.d.ts +110 -0
- package/dist/output/print-size-blur-noise.js +138 -0
- package/dist/output/print-size-blur-noise.js.map +1 -0
- package/dist/sensor/binomial-sample.d.ts +3 -0
- package/dist/sensor/binomial-sample.js +86 -0
- package/dist/sensor/binomial-sample.js.map +1 -0
- package/dist/sensor/eqe-electron-rate.js +1 -7
- package/dist/sensor/eqe-electron-rate.js.map +1 -1
- package/dist/sensor/exposure-window.d.ts +2 -0
- package/dist/sensor/exposure-window.js +2 -2
- package/dist/sensor/exposure-window.js.map +1 -1
- package/dist/sensor/readout-timing.js +2 -23
- package/dist/sensor/readout-timing.js.map +1 -1
- package/dist/sensor/response-application-compatibility.js +1 -6
- package/dist/sensor/response-application-compatibility.js.map +1 -1
- package/dist/sensor/responsivity-photocurrent.js +1 -7
- package/dist/sensor/responsivity-photocurrent.js.map +1 -1
- package/dist/sensor/sensor-characteristics.d.ts +147 -0
- package/dist/sensor/sensor-characteristics.js +126 -0
- package/dist/sensor/sensor-characteristics.js.map +1 -0
- package/dist/sensor/spatial-sample-reduction.js +1 -5
- package/dist/sensor/spatial-sample-reduction.js.map +1 -1
- package/dist/sensor/spectral-quadrature.js +1 -6
- package/dist/sensor/spectral-quadrature.js.map +1 -1
- package/dist/sensor/temporal-photo-signal.d.ts +3 -0
- package/dist/sensor/temporal-photo-signal.js +5 -2
- package/dist/sensor/temporal-photo-signal.js.map +1 -1
- package/dist/stabilization/system.d.ts +9 -0
- package/dist/stabilization/system.js +5 -6
- package/dist/stabilization/system.js.map +1 -1
- package/docs/AGENT_GUIDE.md +5 -0
- package/docs/API_REFERENCE.md +173 -2
- package/docs/QUICK_START.md +213 -6
- package/docs/USAGE.md +157 -3
- package/docs/api/capture-native-raw-dng.md +6 -0
- package/docs/api/core-version.md +1 -1
- package/docs/api/equipment-generic-lens-catalogue.md +17 -7
- package/docs/api/equipment-sensor-profile-body.md +64 -0
- package/docs/api/equipment-sensor-profiles.md +86 -0
- package/docs/api/exports.json +357 -2
- package/docs/api/facade-display-view-gpu.md +5 -2
- package/docs/api/facade-exposure-build-up.md +105 -0
- package/docs/api/facade-fast-methods.md +99 -0
- package/docs/api/facade-image-plane-enable.md +16 -0
- package/docs/api/facade-mixed-illumination.md +67 -0
- package/docs/api/facade-representative-light-sources.md +131 -0
- package/docs/api/facade-scene-radiance.md +54 -3
- package/docs/api/facade-simulate-capture.md +60 -15
- package/docs/api/facade-simulate-display-view.md +3 -2
- package/docs/api/motion-subject-motion.md +23 -0
- package/docs/api/optics-aperture-diameter.md +51 -0
- package/docs/api/optics-detail-limit.md +203 -0
- package/docs/api/optics-generic-lens-lateral-color.md +79 -0
- package/docs/api/output-crop-to-match-focal-length.md +67 -0
- package/docs/api/output-developed-lens-corrections.md +10 -1
- package/docs/api/output-generic-lens-corrections.md +40 -2
- package/docs/api/output-lens-corrections.md +11 -1
- package/docs/api/output-print-plan.md +35 -1
- package/docs/api/output-print-size-blur-noise.md +115 -0
- package/docs/api/sensor-sensor-characteristics.md +105 -0
- package/llms.txt +6 -0
- package/package.json +1 -1
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# facade/exposure-build-up.ts public contracts
|
|
2
|
+
|
|
3
|
+
The package and root API versions are recorded once in [Navigation](../API_REFERENCE.md) · [Developer guide](https://github.com/Photivra/photivra/blob/main/docs/DEVELOPERS.md). Generated signatures retain independent schema/model versions. Only the exports listed here are root-package contracts; module-local helpers are not supported deep imports.
|
|
4
|
+
|
|
5
|
+
## EXPOSURE_BUILD_UP_MAXIMUM_FRACTIONS
|
|
6
|
+
|
|
7
|
+
The most fractions one build-up takes.
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
EXPOSURE_BUILD_UP_MAXIMUM_FRACTIONS = 64
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## EXPOSURE_BUILD_UP_STREAM_BASE
|
|
14
|
+
|
|
15
|
+
The first stream ID of the build-up's per-site random streams (`deriveNativeSiteStreamSeedUint32`): fraction j's photo split,
|
|
16
|
+
dark split and readout use streams base + 3j, + 3j + 1 and + 3j + 2 (j = 0 … 63). The whole exposure keeps the ordinary
|
|
17
|
+
streams 0 (charge) and 1 (read noise).
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
EXPOSURE_BUILD_UP_STREAM_BASE = 0x42550000
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## simulateExposureBuildUp
|
|
24
|
+
|
|
25
|
+
Renders fractions of one exposure as one accumulating process (#534), the way a camera's live readout of a long exposure
|
|
26
|
+
would show the light building up. Each fraction is read out and developed as its own photo.
|
|
27
|
+
|
|
28
|
+
The model: photon and dark-charge arrivals at a site are Poisson processes (photon shot noise: EMVA 1288 Release 4.0,
|
|
29
|
+
section 2, free), with any rate over time. Given the count n over [0, t] of a Poisson process with mean Λ(t), its arrival
|
|
30
|
+
times are n independent times with distribution Λ(s)/Λ(t) on [0, t], so its count over [0, s] is Binomial(n, Λ(s)/Λ(t))
|
|
31
|
+
(R. G. Gallager, Discrete Stochastic Processes, chapter 2, sections 2.4 and 2.5, MIT OpenCourseWare 6.262, free).
|
|
32
|
+
|
|
33
|
+
The method: the whole exposure is `simulateCapture(options)` itself, with its ordinary draws and seeds. Each earlier fraction
|
|
34
|
+
fⱼ is a capture of the same request in manual mode at the whole exposure's resolved f-number and ISO and the shutter fⱼ·t,
|
|
35
|
+
so its expected signal at every site is integrated from the spectrum over the window [0, fⱼ·t] by the capture itself (the
|
|
36
|
+
camera rotation, `motion.subject` and mixed lighting included, and each row's own window with a rolling shutter). Its
|
|
37
|
+
counts are not drawn anew: going down the fractions, each site's photo and dark counts are N(fⱼ) ~ Binomial(N(fⱼ₊₁), λ(fⱼ) /
|
|
38
|
+
λ(fⱼ₊₁)), with λ the site's expected mean in each render (after PRNU and DSNU). So every fraction's counts are Poisson with
|
|
39
|
+
that fraction's own mean (the mean and variance of `simulateCapture` at fⱼ·t), they never decrease from one fraction to the
|
|
40
|
+
next, and two fractions' counts covary by the earlier one's mean. Fixed-pattern noise is the sensor's own and the same in
|
|
41
|
+
every fraction. Each fraction's charge is clipped at the full well, then read once: its own read noise (dual gain as the ISO
|
|
42
|
+
selects), pre-ADC and ADC saturation and quantization at the ADC bit depth.
|
|
43
|
+
|
|
44
|
+
The windows are nested, so the true means never decrease; the capture's temporal midpoint quadrature can still put an
|
|
45
|
+
earlier fraction's estimate above a later one's at a site (motion blur). There the split takes probability 1 (the count is
|
|
46
|
+
kept), and the `exposure.buildUp` assumption counts those sites (`nonMonotoneSites`): an approximation of the quadrature,
|
|
47
|
+
not of the binomial law. Raise `sensor.temporalSampleCount` to remove them.
|
|
48
|
+
|
|
49
|
+
Cost: one capture per fraction, plus about 64 bytes per native site for the chain. Exact or fast: the request's own `fast`
|
|
50
|
+
(and the format default) applies to every fraction; the build-up adds no fast method, so with `fast: false` (the calculator's
|
|
51
|
+
setting) every fraction is an exact capture. On screen only: formats "srgb-8" and "srgb-16" (a fraction's JPEG, PNG or DNG
|
|
52
|
+
is refused). A fraction's realization depends on the whole `fractions` list (each step of the chain has its own streams);
|
|
53
|
+
the same request and list always give the same frames.
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
export async function simulateExposureBuildUp(options: SimulateCaptureOptions, buildUp: SimulateExposureBuildUpOptions): Promise<SimulateExposureBuildUpResult>;
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
This call is asynchronous; byte hashing uses the caller runtime's Web Crypto.
|
|
60
|
+
|
|
61
|
+
## SimulateExposureBuildUpFrame
|
|
62
|
+
|
|
63
|
+
One readout of a build-up.
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
export interface SimulateExposureBuildUpFrame {
|
|
67
|
+
/** The fraction of the exposure collected. */
|
|
68
|
+
fraction: number;
|
|
69
|
+
/** fraction × the request's shutter time, in s. */
|
|
70
|
+
elapsedSeconds: number;
|
|
71
|
+
/**
|
|
72
|
+
* The fraction developed as its own photo. At fraction 1 it is `simulateCapture(options)` itself, byte for byte. Below 1 it is
|
|
73
|
+
* the result of the fraction's capture (manual, the whole exposure's f-number and ISO, shutter fraction·t: its `image`, `raw`,
|
|
74
|
+
* `plan` and `request`), with the build-up's counts, the `exposure.buildUp` assumption, and the whole exposure's `exposure` and
|
|
75
|
+
* `sensor` reports (the camera's settings and noise figure, not the elapsed part's).
|
|
76
|
+
*/
|
|
77
|
+
result: SimulateCaptureResult;
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## SimulateExposureBuildUpOptions
|
|
82
|
+
|
|
83
|
+
The build-up to render with {@link simulateExposureBuildUp}.
|
|
84
|
+
|
|
85
|
+
```ts
|
|
86
|
+
export interface SimulateExposureBuildUpOptions {
|
|
87
|
+
/**
|
|
88
|
+
* Fractions of `exposure.shutterSeconds` to read out, strictly increasing, each above 0 and at most 1 (1 to 64 of them), for
|
|
89
|
+
* example `[0.2, 0.4, 0.6, 0.8, 1]`. A fraction of 1 is the whole exposure: `simulateCapture` of the request.
|
|
90
|
+
*/
|
|
91
|
+
fractions: readonly number[];
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## SimulateExposureBuildUpResult
|
|
96
|
+
|
|
97
|
+
The readouts of {@link simulateExposureBuildUp}, in the order of `fractions`.
|
|
98
|
+
|
|
99
|
+
```ts
|
|
100
|
+
export interface SimulateExposureBuildUpResult {
|
|
101
|
+
/** The whole exposure's shutter time, in s. */
|
|
102
|
+
shutterSeconds: number;
|
|
103
|
+
frames: readonly SimulateExposureBuildUpFrame[];
|
|
104
|
+
}
|
|
105
|
+
```
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# facade/fast-methods.ts public contracts
|
|
2
|
+
|
|
3
|
+
The package and root API versions are recorded once in [Navigation](../API_REFERENCE.md) · [Developer guide](https://github.com/Photivra/photivra/blob/main/docs/DEVELOPERS.md). Generated signatures retain independent schema/model versions. Only the exports listed here are root-package contracts; module-local helpers are not supported deep imports.
|
|
4
|
+
|
|
5
|
+
## SIMULATE_CAPTURE_FAST_METHODS
|
|
6
|
+
|
|
7
|
+
2.20.0: every speed-versus-accuracy choice of the capture facade and the display view (see the module comment).
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
SIMULATE_CAPTURE_FAST_METHODS: readonly SimulateCaptureFastMethod[] = Object.freeze([
|
|
11
|
+
{ id: "lens.catalogue/field-grid", override: "lens.catalogue", methods: "fast-and-exact", runs: ["simulateCapture"],
|
|
12
|
+
fast: "#568: the PSF blended over a field grid and tabulated expected electrons, verified per CFA phase against the exact chain",
|
|
13
|
+
exact: "the environment PSF quadrature with the PSF resolved at each query point", followsFormatDefault: true,
|
|
14
|
+
resolver: { file: CAPTURE, call: "resolveFast(catalogueFast, fastTop)" }, report: { applied: "lens.catalogue", assumption: "fast.lens.catalogue" } },
|
|
15
|
+
{ id: "lens.catalogue/cats-eye", override: "lens.catalogue", methods: "fast-and-exact", runs: ["simulateCapture", "simulateDisplayView", "prepareDisplayView"],
|
|
16
|
+
fast: "#567: with lens.defocus, the lens's bokeh without its cat's eye (the axis kernel everywhere)",
|
|
17
|
+
exact: "the cat's eye shaped at each field point (fast wides and normals)", followsFormatDefault: true,
|
|
18
|
+
resolver: { file: CAPTURE, call: "resolveFast(catalogueFast, fastTop)" }, report: { applied: "lens.catalogue", assumption: "fast.lens.catalogue.catsEye" } },
|
|
19
|
+
{ id: "lens.catalogue/view-psf-zones", override: "lens.catalogue", methods: "fast-and-exact", runs: ["simulateDisplayView", "prepareDisplayView"],
|
|
20
|
+
fast: "#569 (H1): 64 field zones along the longer side, each with the PSF at its centre",
|
|
21
|
+
exact: "one zone per site: the PSF at each site centre", followsFormatDefault: true,
|
|
22
|
+
resolver: { file: CAPTURE, call: "resolveFast(catalogueFast, fastTop)" }, report: { applied: "lens.catalogue", assumption: "view.lensPsf" } },
|
|
23
|
+
{ id: "lens.diffraction/rolling-shutter-taps", override: "lens.diffraction", methods: "fast-and-exact", runs: ["simulateCapture"],
|
|
24
|
+
fast: "#565: under rolling-shutter rotation (#551: or subject motion), each PSF tap reads the scene at its own source point",
|
|
25
|
+
exact: "each tap reads the scene at its site-lattice point (ties on chart boundaries resolve as on the lattice)", followsFormatDefault: true,
|
|
26
|
+
resolver: { file: CAPTURE, call: "resolveFast(diffractionFast, fastTop)" }, report: { applied: "lens.diffraction", assumption: "fast.lens.diffraction" } },
|
|
27
|
+
{ id: "lens.catalogue/rolling-shutter-taps", override: "lens.catalogue", methods: "fast-and-exact", runs: ["simulateCapture"],
|
|
28
|
+
fast: "#588: under rolling-shutter rotation, each catalogue PSF tap reads the scene at its own source point",
|
|
29
|
+
exact: "each tap reads the scene at its site-lattice point (ties on chart boundaries resolve as on the lattice)", followsFormatDefault: true,
|
|
30
|
+
resolver: { file: CAPTURE, call: "resolveFast(catalogueFast, fastTop)" }, report: { applied: "lens.catalogue", assumption: "fast.lens.catalogue" } },
|
|
31
|
+
{ id: "output.demosaic.ahd/view-low-signal-correction", override: "output.demosaic", methods: "fast-and-exact", runs: ["simulateDisplayView", "prepareDisplayView"],
|
|
32
|
+
fast: "(H3) 2048 draws per correction state, applied where a pixel's linear noise exceeds 0.01",
|
|
33
|
+
exact: "8192 draws per state, at the same 0.01 threshold", followsFormatDefault: true,
|
|
34
|
+
resolver: { file: CAPTURE, call: "resolveFast(demosaicFast, fastTop)" }, report: { applied: "output.demosaic.ahd", assumption: "view.demosaic" } },
|
|
35
|
+
{ id: "view.uniform-pixel-sampling", override: "fast", methods: "fast-and-exact", runs: ["simulateDisplayView", "prepareDisplayView"],
|
|
36
|
+
fast: "(H2) a quarter of the samples per axis in display pixels whose pilot finds no detail",
|
|
37
|
+
exact: "the full samples per axis in every display pixel", followsFormatDefault: true,
|
|
38
|
+
resolver: { file: CAPTURE, call: "uniformSampling: fastTop" }, report: { assumption: "view.estimation" } },
|
|
39
|
+
{ id: "prepareDisplayView.gpu", override: "fast", methods: "fast-and-exact", runs: ["prepareDisplayView"],
|
|
40
|
+
fast: "gpu \"auto\": WebGPU float32 where a conforming device supports the request (a bounded approximation), else the CPU reference",
|
|
41
|
+
exact: "gpu \"off\": the CPU reference; an explicit gpu wins", followsFormatDefault: true,
|
|
42
|
+
resolver: { file: VIEW, call: "parsePrepareDisplayViewOptions(prepareOptions, (options as { fast?: unknown } | null | undefined)?.fast !== false)" },
|
|
43
|
+
report: { field: "diagnostics.fast.execution" } },
|
|
44
|
+
{ id: "sensor.midGrey", override: "fast", methods: "fast-and-exact", runs: ["simulateCapture", "simulateDisplayView", "prepareDisplayView"],
|
|
45
|
+
fast: "#535: the mid-gray noise figure is not computed (about 0.3 ms)", exact: "result.sensor.midGrey is computed", followsFormatDefault: true,
|
|
46
|
+
resolver: { file: CAPTURE, call: "fastTop ? undefined : 0" }, report: { field: "sensor.midGrey" } },
|
|
47
|
+
{ id: "motion.subject/temporal-midpoints", override: "motion.subject", methods: "fast-and-exact", runs: ["simulateCapture", "simulateDisplayView", "prepareDisplayView"],
|
|
48
|
+
fast: "#551: with the default count and a still camera, one temporal midpoint per site of the subject's streak plus one, when that is fewer than 8",
|
|
49
|
+
exact: "the default 8 temporal midpoints (an explicit sensor.temporalSampleCount always wins)", followsFormatDefault: true,
|
|
50
|
+
resolver: { file: CAPTURE, call: "resolveFast(subjectFast, fastTop)" }, report: { applied: "motion.subject", assumption: "fast.motion.subject" } },
|
|
51
|
+
{ id: "lens.diffraction", override: "lens.diffraction", methods: "exact-only", runs: ["simulateCapture", "simulateDisplayView", "prepareDisplayView"],
|
|
52
|
+
fast: "", exact: "the diffraction kernels (a fast method only under rolling-shutter rotation, above)", followsFormatDefault: true,
|
|
53
|
+
resolver: { file: CAPTURE, call: "resolveFast(diffractionFast, fastTop)" }, report: { applied: "lens.diffraction" } },
|
|
54
|
+
{ id: "sensor.antiAliasing", override: "sensor.antiAliasing", methods: "exact-only", runs: ["simulateCapture", "simulateDisplayView", "prepareDisplayView"],
|
|
55
|
+
fast: "", exact: "the point-splitting filter", followsFormatDefault: true,
|
|
56
|
+
resolver: { file: CAPTURE, call: "fastInUse" }, report: { applied: "sensor.antiAliasing" } },
|
|
57
|
+
{ id: "sensor.pixelAperture.box", override: "sensor.pixelAperture", methods: "exact-only", runs: ["simulateCapture", "simulateDisplayView", "prepareDisplayView"],
|
|
58
|
+
fast: "", exact: "the N × N midpoint rule", followsFormatDefault: true,
|
|
59
|
+
resolver: { file: CAPTURE, call: "fastInUse" }, report: { applied: "sensor.pixelAperture.box" } },
|
|
60
|
+
{ id: "output.demosaic.ahd", override: "output.demosaic", methods: "exact-only", runs: ["simulateCapture"],
|
|
61
|
+
fast: "", exact: "the AHD demosaic of the capture (a fast method only in the display view's correction, above)", followsFormatDefault: true,
|
|
62
|
+
resolver: { file: CAPTURE, call: "resolveFast(demosaicFast, fastTop)" }, report: { applied: "output.demosaic.ahd" } }
|
|
63
|
+
] as const satisfies readonly SimulateCaptureFastMethod[])
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## SimulateCaptureFastMethod
|
|
67
|
+
|
|
68
|
+
One speed-versus-accuracy choice of {@link SIMULATE_CAPTURE_FAST_METHODS} (2.20.0).
|
|
69
|
+
|
|
70
|
+
```ts
|
|
71
|
+
export interface SimulateCaptureFastMethod {
|
|
72
|
+
/** A short id: the option path and, where one option has several fast methods, the method. */
|
|
73
|
+
id: string;
|
|
74
|
+
/**
|
|
75
|
+
* The request path whose record takes the `fast` override (`allowKeys` path in simulate-capture.ts), or "fast" when only the
|
|
76
|
+
* top-level flag sets it (a choice with no option record of its own).
|
|
77
|
+
*/
|
|
78
|
+
override: string;
|
|
79
|
+
/** "fast-and-exact": both methods exist; "exact-only": the record takes `fast`, but there is no fast method yet (reports false). */
|
|
80
|
+
methods: "fast-and-exact" | "exact-only";
|
|
81
|
+
/** Where it applies. */
|
|
82
|
+
runs: readonly ("simulateCapture" | "simulateDisplayView" | "prepareDisplayView")[];
|
|
83
|
+
/** The fast method and the exact one, in words (empty for exact-only). */
|
|
84
|
+
fast: string;
|
|
85
|
+
exact: string;
|
|
86
|
+
/** Always true: no choice keeps its own default (the test checks it). */
|
|
87
|
+
followsFormatDefault: true;
|
|
88
|
+
/**
|
|
89
|
+
* The resolver call in the source (`resolveFast(<record flag>, fastTop)`, or `fastTop` itself for a top-level choice), which the
|
|
90
|
+
* test finds in the named file.
|
|
91
|
+
*/
|
|
92
|
+
resolver: { file: string; call: string };
|
|
93
|
+
/**
|
|
94
|
+
* How the result reports it: the `diagnostics.fast.applied` key (true where the fast method ran), an assumption id the fast
|
|
95
|
+
* method adds, or another result field. At least one; the test finds each assumption id in the source.
|
|
96
|
+
*/
|
|
97
|
+
report: { applied?: string; assumption?: string; field?: string };
|
|
98
|
+
}
|
|
99
|
+
```
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# facade/image-plane-enable.ts public contracts
|
|
2
|
+
|
|
3
|
+
The package and root API versions are recorded once in [Navigation](../API_REFERENCE.md) · [Developer guide](https://github.com/Photivra/photivra/blob/main/docs/DEVELOPERS.md). Generated signatures retain independent schema/model versions. Only the exports listed here are root-package contracts; module-local helpers are not supported deep imports.
|
|
4
|
+
|
|
5
|
+
## prepareImagePlaneScenes
|
|
6
|
+
|
|
7
|
+
2.21 (#581): enables `{ kind: "image-plane" }` scenes (a photo as a flat print, docs/IMAGE_PLANE.md) in this JavaScript realm by
|
|
8
|
+
loading their module (a lazy chunk of about 14 KB gzip with its lattice data). Call it once, in the worker that captures, before
|
|
9
|
+
the first request with such a scene; later calls resolve at once. A request with an image-plane scene before it fails with a
|
|
10
|
+
message saying so.
|
|
11
|
+
|
|
12
|
+
```ts
|
|
13
|
+
export async function prepareImagePlaneScenes(): Promise<void>;
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
This call is asynchronous; byte hashing uses the caller runtime's Web Crypto.
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# facade/mixed-illumination.ts public contracts
|
|
2
|
+
|
|
3
|
+
The package and root API versions are recorded once in [Navigation](../API_REFERENCE.md) · [Developer guide](https://github.com/Photivra/photivra/blob/main/docs/DEVELOPERS.md). Generated signatures retain independent schema/model versions. Only the exports listed here are root-package contracts; module-local helpers are not supported deep imports.
|
|
4
|
+
|
|
5
|
+
## MixedIllumination
|
|
6
|
+
|
|
7
|
+
2.22 (#550), `simulateCapture` `illumination`: sources blended across the chart and point sources with inverse-square falloff
|
|
8
|
+
(docs/MIXED_ILLUMINATION.md). It replaces `illuminant` and `illuminanceLux`. `sources` lists 1 to 8 sources (with two or more, a
|
|
9
|
+
`blend` is required; one lights the whole plane); `points` lists 1 to 8 point sources; a request needs two or more sources or at least one point. Blend
|
|
10
|
+
coordinates are chart-local with `chartSize` and frame units without it; (0, 0) is the frame center.
|
|
11
|
+
|
|
12
|
+
```ts
|
|
13
|
+
export interface MixedIllumination {
|
|
14
|
+
sources?: readonly MixedIlluminationSource[];
|
|
15
|
+
blend?: MixedIlluminationBlend;
|
|
16
|
+
points?: readonly MixedIlluminationPointSource[];
|
|
17
|
+
}
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## MixedIlluminationBlend
|
|
21
|
+
|
|
22
|
+
How the sources blend across the chart. `linear-gradient` and `radial` map a point to a position t in [0, 1] (its projection
|
|
23
|
+
onto `from` → `to`, clamped; or its distance from `center` over `radius`, clamped) and crossfade linearly between consecutive
|
|
24
|
+
sources at their `stops` (one per source, non-decreasing in [0, 1]; default evenly spaced from 0 to 1): source 0 alone up to
|
|
25
|
+
stops[0], the last source alone from its stop on, and two equal stops a hard edge (the later source from the stop on).
|
|
26
|
+
`regions` gives each point the source of the first rectangle that contains it (bounds inclusive) and `outsideSource` elsewhere.
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
export type MixedIlluminationBlend =
|
|
30
|
+
| { kind: "linear-gradient"; from: MixedIlluminationPoint; to: MixedIlluminationPoint; stops?: readonly number[] }
|
|
31
|
+
| { kind: "radial"; center?: MixedIlluminationPoint; radius: number; stops?: readonly number[] }
|
|
32
|
+
| { kind: "regions"; regions: readonly { source: number; uMin: number; uMax: number; vMin: number; vMax: number }[]; outsideSource: number };
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## MixedIlluminationPoint
|
|
36
|
+
|
|
37
|
+
A point in chart coordinates (see {@link MixedIllumination}).
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
export interface MixedIlluminationPoint { u: number; v: number }
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## MixedIlluminationPointSource
|
|
44
|
+
|
|
45
|
+
2.22 (#550): a point light on the scene plane's front side: an illuminant spectrum, a position in metres (`xM`, `yM` on the plane
|
|
46
|
+
from the optical axis, +x right and +y up as seen from the camera; `heightM` > 0 in front of the plane, toward the camera) and an
|
|
47
|
+
intensity, either in candela or as the illuminance it gives at normal incidence at a reference distance (I = E·r²).
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
export interface MixedIlluminationPointSource {
|
|
51
|
+
illuminant: CaptureIlluminant;
|
|
52
|
+
position: { xM: number; yM: number; heightM: number };
|
|
53
|
+
intensity: { candela: number } | { illuminanceLux: number; distanceM: number };
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## MixedIlluminationSource
|
|
58
|
+
|
|
59
|
+
One light source of a mixed illumination: an illuminant (as `simulateCapture` `illuminant` takes it) at an illuminance.
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
export interface MixedIlluminationSource {
|
|
63
|
+
illuminant: CaptureIlluminant;
|
|
64
|
+
/** Illuminance this source alone gives where its weight is 1, lux, (0, 1e7]. */
|
|
65
|
+
illuminanceLux: number;
|
|
66
|
+
}
|
|
67
|
+
```
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# facade/representative-light-sources.ts public contracts
|
|
2
|
+
|
|
3
|
+
The package and root API versions are recorded once in [Navigation](../API_REFERENCE.md) · [Developer guide](https://github.com/Photivra/photivra/blob/main/docs/DEVELOPERS.md). Generated signatures retain independent schema/model versions. Only the exports listed here are root-package contracts; module-local helpers are not supported deep imports.
|
|
4
|
+
|
|
5
|
+
## createRepresentativeLightSourceIlluminant
|
|
6
|
+
|
|
7
|
+
A capture illuminant for a source: `{ kind: "spectrum", spectrum, label }` with the spectrum of
|
|
8
|
+
{@link createRepresentativeLightSourceSpectrum} and the label "<name> (representative, not a named product)".
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
export function createRepresentativeLightSourceIlluminant(input: { sourceId: RepresentativeLightSourceId }): Extract<CaptureIlluminant, { kind: "spectrum" }>;
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
This call is synchronous; any supplied provider must follow its explicit synchronous contract.
|
|
15
|
+
|
|
16
|
+
## createRepresentativeLightSourceSpectrum
|
|
17
|
+
|
|
18
|
+
A source's relative spectral power distribution S(λ) = b + Σ aₖ·exp(−½((λ − μₖ)/σₖ)²) as a function spectrum on
|
|
19
|
+
360–830 nm (relative units; values memoized per wavelength). Pass it to a capture as
|
|
20
|
+
`illuminant: { kind: "spectrum", spectrum }`; for color work use `sensor.spectralStepNanometers: 5` or finer
|
|
21
|
+
(docs/LIGHT_SOURCES.md, "Quadrature"). Throws `InvalidScientificInputError` outside 360–830 nm.
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
export function createRepresentativeLightSourceSpectrum(input: { sourceId: RepresentativeLightSourceId }): ColorimetricSpectrum;
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
This call is synchronous; any supplied provider must follow its explicit synchronous contract.
|
|
28
|
+
|
|
29
|
+
## getRepresentativeLightSourceSet
|
|
30
|
+
|
|
31
|
+
The built-in representative light sources: Photivra's own parametric spectra of a tri-phosphor fluorescent tube and
|
|
32
|
+
three white LEDs (low and high color rendering at 4000 K, warm at 2700 K). A static, deeply frozen engine contract.
|
|
33
|
+
Each is "representative, not a named product"; docs/LIGHT_SOURCES.md gives every formula and the reasons for it.
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
export function getRepresentativeLightSourceSet(): RepresentativeLightSourceSet;
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
This call is synchronous; any supplied provider must follow its explicit synchronous contract.
|
|
40
|
+
|
|
41
|
+
## REPRESENTATIVE_LIGHT_SOURCE_IDS
|
|
42
|
+
|
|
43
|
+
The source ids, in set order.
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
REPRESENTATIVE_LIGHT_SOURCE_IDS = Object.freeze([
|
|
47
|
+
"tri-phosphor-fluorescent-4000k", "white-led-low-rendering-4000k", "white-led-high-rendering-4000k", "warm-white-led-2700k"
|
|
48
|
+
] as const)
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## REPRESENTATIVE_LIGHT_SOURCE_SET_ID
|
|
52
|
+
|
|
53
|
+
Identity of the built-in light-source set.
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
REPRESENTATIVE_LIGHT_SOURCE_SET_ID = "photivra-representative-light-sources"
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## REPRESENTATIVE_LIGHT_SOURCE_SET_VERSION
|
|
60
|
+
|
|
61
|
+
Version of the set's spectra; a change to any spectrum changes it.
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
REPRESENTATIVE_LIGHT_SOURCE_SET_VERSION = "1.0.0"
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## REPRESENTATIVE_LIGHT_SOURCE_WAVELENGTH_RANGE_NANOMETERS
|
|
68
|
+
|
|
69
|
+
Domain of every spectrum, nm (the CIE 1931 observer's domain; the capture facade uses 380–780 nm of it).
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
REPRESENTATIVE_LIGHT_SOURCE_WAVELENGTH_RANGE_NANOMETERS = Object.freeze({ minimum: 360, maximum: 830 })
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## RepresentativeLightSource
|
|
76
|
+
|
|
77
|
+
One built-in source: its id, name, design reason and spectrum definition.
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
export interface RepresentativeLightSource {
|
|
81
|
+
sourceId: RepresentativeLightSourceId;
|
|
82
|
+
/** Photivra's descriptive name, for example "White LED, high color rendering, 4000 K". */
|
|
83
|
+
name: string;
|
|
84
|
+
family: "fluorescent" | "led";
|
|
85
|
+
/** The CCT the spectrum was designed for, K (its computed CCT is within 1 K of it, Duv within 0.0001; docs/LIGHT_SOURCES.md). */
|
|
86
|
+
nominalCorrelatedColorTemperatureKelvin: number;
|
|
87
|
+
/** Always "representative, not a named product". */
|
|
88
|
+
label: "representative, not a named product";
|
|
89
|
+
/** One sentence: what the source represents and why it is built this way. */
|
|
90
|
+
reason: string;
|
|
91
|
+
/** The constant b (a low continuum), relative units. */
|
|
92
|
+
base: number;
|
|
93
|
+
bands: readonly RepresentativeLightSourceBand[];
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## RepresentativeLightSourceBand
|
|
98
|
+
|
|
99
|
+
One Gaussian band a·exp(−½((λ − μ)/σ)²) of a source spectrum.
|
|
100
|
+
|
|
101
|
+
```ts
|
|
102
|
+
export interface RepresentativeLightSourceBand {
|
|
103
|
+
kind: "gaussian";
|
|
104
|
+
/** What the band represents, for example "blue pump" or "green phosphor line". */
|
|
105
|
+
role: string;
|
|
106
|
+
amplitude: number;
|
|
107
|
+
centerNanometers: number;
|
|
108
|
+
standardDeviationNanometers: number;
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## RepresentativeLightSourceId
|
|
113
|
+
|
|
114
|
+
The exact contract is declared below; use the domain guide for assumptions and staged integration.
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
export type RepresentativeLightSourceId = (typeof REPRESENTATIVE_LIGHT_SOURCE_IDS)[number];
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## RepresentativeLightSourceSet
|
|
121
|
+
|
|
122
|
+
The exact contract is declared below; use the domain guide for assumptions and staged integration.
|
|
123
|
+
|
|
124
|
+
```ts
|
|
125
|
+
export interface RepresentativeLightSourceSet {
|
|
126
|
+
setId: typeof REPRESENTATIVE_LIGHT_SOURCE_SET_ID;
|
|
127
|
+
setVersion: typeof REPRESENTATIVE_LIGHT_SOURCE_SET_VERSION;
|
|
128
|
+
wavelengthRangeNanometers: { readonly minimum: number; readonly maximum: number };
|
|
129
|
+
sources: readonly RepresentativeLightSource[];
|
|
130
|
+
}
|
|
131
|
+
```
|
|
@@ -91,7 +91,8 @@ provider `providerProfileId`.
|
|
|
91
91
|
|
|
92
92
|
```ts
|
|
93
93
|
export function createPlanarSceneRadianceProvider(input: {
|
|
94
|
-
scene:
|
|
94
|
+
/** An `image-plane` scene (#581) is refused: it is taken by the facade's capture and display-view functions, which load its module. */
|
|
95
|
+
scene: ChartScene | ChartMaterialLayerScene | CallerReflectanceScene | CallerRadianceScene | CallerMaterialScene | ImagePlaneScene;
|
|
95
96
|
illuminant: CaptureIlluminant;
|
|
96
97
|
illuminanceLux: number;
|
|
97
98
|
distanceM: number;
|
|
@@ -110,6 +111,47 @@ export function createPlanarSceneRadianceProvider(input: {
|
|
|
110
111
|
|
|
111
112
|
This call is synchronous; any supplied provider must follow its explicit synchronous contract.
|
|
112
113
|
|
|
114
|
+
## ImagePlaneImage
|
|
115
|
+
|
|
116
|
+
2.21 (#581): an image the caller supplies, for an {@link ImagePlaneScene}. `data` holds `width × height` pixels row by row
|
|
117
|
+
from the top, `channels` (3: RGB, 4: RGBA) samples each, in the encoding's type: `srgb-8` Uint8Array or Uint8ClampedArray
|
|
118
|
+
(canvas `ImageData.data`), `srgb-16` Uint16Array, `linear-srgb` Float32Array. sRGB primaries and white (IEC 61966-2-1) in
|
|
119
|
+
every encoding; `srgb-8` and `srgb-16` are decoded with the sRGB transfer function, `linear-srgb` is already linear and is
|
|
120
|
+
clipped to [0, 1] (the clipped samples are counted). Alpha is linear coverage over the paper. The array is read, never
|
|
121
|
+
changed or kept beyond the call.
|
|
122
|
+
|
|
123
|
+
```ts
|
|
124
|
+
export interface ImagePlaneImage {
|
|
125
|
+
width: number;
|
|
126
|
+
height: number;
|
|
127
|
+
channels: 3 | 4;
|
|
128
|
+
encoding: "srgb-8" | "srgb-16" | "linear-srgb";
|
|
129
|
+
data: Uint8Array | Uint8ClampedArray | Uint16Array | Float32Array;
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## ImagePlaneScene
|
|
134
|
+
|
|
135
|
+
2.21 (#581): a photo as a flat matte print on the scene plane, lit by the request's illuminant like a chart. Each pixel's
|
|
136
|
+
color becomes a reflectance spectrum through the engine's print reflectance lattice (docs/IMAGE_PLANE.md): an
|
|
137
|
+
approximation, a print of an image that was already processed, clipped and blurred by the camera that took it. The print's
|
|
138
|
+
physical size is `chartSize` (its height defaults to the image's aspect); without it the print is fitted inside the frame,
|
|
139
|
+
centered, on the 18 % surround.
|
|
140
|
+
|
|
141
|
+
```ts
|
|
142
|
+
export interface ImagePlaneScene {
|
|
143
|
+
kind: "image-plane";
|
|
144
|
+
sceneId: string;
|
|
145
|
+
image: ImagePlaneImage;
|
|
146
|
+
/** The paper and the deepest ink: reflectances of sRGB white and black, 0 ≤ black < white ≤ 1. Defaults 0.90 and 0.01. */
|
|
147
|
+
paper?: { whiteReflectance?: number; blackReflectance?: number };
|
|
148
|
+
/** How the print is reconstructed between pixel centers. Default `bilinear` (the pixels' spectra, bilinearly weighted). */
|
|
149
|
+
interpolation?: "bilinear" | "nearest";
|
|
150
|
+
/** Opt-in raised pixel limit: an integer up to the full-resolution ceiling. Default 24 000 000 pixels. */
|
|
151
|
+
maximumPixels?: number;
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
113
155
|
## PHOTOPIC_MAXIMUM_LUMINOUS_EFFICACY_LM_PER_W
|
|
114
156
|
|
|
115
157
|
CIE maximum luminous efficacy for photopic vision, lm/W.
|
|
@@ -128,8 +170,11 @@ export interface PlanarSceneRadianceProvider {
|
|
|
128
170
|
providerProfileId: string;
|
|
129
171
|
evaluateRadiance(request: Readonly<SceneRadianceEvaluationRequest>): SceneRadianceEvaluationResult;
|
|
130
172
|
evaluateApertureRadiance(request: Readonly<SceneRadianceEvaluationRequest>, ray: Readonly<SensorApertureRay>): SceneRadianceEvaluationResult;
|
|
131
|
-
/**
|
|
132
|
-
|
|
173
|
+
/**
|
|
174
|
+
* Spectral radiance at a plane point (frame units), the same value the callbacks return. #551: a moving subject's provider
|
|
175
|
+
* reads it at time `t` (seconds from the first opening, default 0); a still scene ignores it.
|
|
176
|
+
*/
|
|
177
|
+
radianceAt(u: number, v: number, wavelengthNanometers: number, t?: number): number;
|
|
133
178
|
/**
|
|
134
179
|
* 2.3, chart scenes only: the chart material at a plane point (frame units), or `materials.length` for the
|
|
135
180
|
* surround of a fixed-size chart; `materialRadiance` gives that material's spectral radiance, the same value
|
|
@@ -137,6 +182,12 @@ export interface PlanarSceneRadianceProvider {
|
|
|
137
182
|
*/
|
|
138
183
|
chartMaterialAt?(u: number, v: number): number;
|
|
139
184
|
materialRadiance?(material: number, wavelengthNanometers: number): number;
|
|
185
|
+
/**
|
|
186
|
+
* 2.21 (#581), image-plane scenes only: the tabulated expected signal's scene at these spectral nodes and channel responses, its
|
|
187
|
+
* radiance per node and, for the direct path, Σ_n A_c(λ_n)·L(λ_n) integrated from each pixel's reconstructed spectrum
|
|
188
|
+
* (`ResolvedImagePlaneScene.pixelSignals`, the surround's reflectance times the neutral signal outside the print).
|
|
189
|
+
*/
|
|
190
|
+
imageSignalScene?(wavelengths: readonly number[], perNode: readonly Float64Array[]): ImagePlaneSignalScene;
|
|
140
191
|
}
|
|
141
192
|
```
|
|
142
193
|
|