@photivra/engine 2.2.0 → 2.3.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 (47) hide show
  1. package/CHANGELOG.md +25 -1
  2. package/CITATION.cff +1 -1
  3. package/README.md +6 -6
  4. package/SECURITY.md +1 -1
  5. package/dist/capture/native-environment-raw.d.ts +18 -0
  6. package/dist/capture/native-environment-raw.js +17 -1
  7. package/dist/capture/native-environment-raw.js.map +1 -1
  8. package/dist/capture/native-raw.d.ts +3 -0
  9. package/dist/capture/native-raw.js +8 -5
  10. package/dist/capture/native-raw.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/generic-prime-lenses.d.ts +46 -0
  15. package/dist/equipment/generic-prime-lenses.js +59 -0
  16. package/dist/equipment/generic-prime-lenses.js.map +1 -0
  17. package/dist/facade/chart-scenes.d.ts +270 -1
  18. package/dist/facade/chart-scenes.js +443 -17
  19. package/dist/facade/chart-scenes.js.map +1 -1
  20. package/dist/facade/scene-radiance.d.ts +47 -0
  21. package/dist/facade/scene-radiance.js +65 -5
  22. package/dist/facade/scene-radiance.js.map +1 -1
  23. package/dist/facade/simulate-capture.d.ts +152 -5
  24. package/dist/facade/simulate-capture.js +302 -57
  25. package/dist/facade/simulate-capture.js.map +1 -1
  26. package/dist/facade/subject-framing.d.ts +55 -0
  27. package/dist/facade/subject-framing.js +66 -0
  28. package/dist/facade/subject-framing.js.map +1 -0
  29. package/dist/gpu/chart-radiance-gpu.d.ts +8 -0
  30. package/dist/gpu/chart-radiance-gpu.js +20 -1
  31. package/dist/gpu/chart-radiance-gpu.js.map +1 -1
  32. package/dist/index.d.ts +5 -3
  33. package/dist/index.js +5 -3
  34. package/dist/index.js.map +1 -1
  35. package/dist/optics/lens-psf-kernels.d.ts +3 -1
  36. package/dist/optics/lens-psf-kernels.js +7 -2
  37. package/dist/optics/lens-psf-kernels.js.map +1 -1
  38. package/docs/API_REFERENCE.md +48 -1
  39. package/docs/QUICK_START.md +269 -4
  40. package/docs/api/core-version.md +1 -1
  41. package/docs/api/equipment-generic-prime-lenses.md +85 -0
  42. package/docs/api/exports.json +167 -2
  43. package/docs/api/facade-chart-scenes.md +280 -4
  44. package/docs/api/facade-scene-radiance.md +42 -0
  45. package/docs/api/facade-simulate-capture.md +108 -3
  46. package/docs/api/facade-subject-framing.md +72 -0
  47. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"scene-radiance.js","sourceRoot":"","sources":["../../src/facade/scene-radiance.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Turns a facade scene and an illuminant into a scene radiance provider for the existing native\n * environment RAW contract (`NativeEnvironmentRawProvider.evaluateRadiance` and, for pupil sampling,\n * `evaluateApertureRadiance`). The scene is an engine chart, a caller reflectance function or a caller\n * radiance function.\n *\n * Geometry: one plane perpendicular to the optical axis at `distanceM` in front of the camera. A query's\n * outgoing direction o (scene toward camera, see docs/SENSOR_ENVIRONMENT_QUERY.md) gives the look\n * direction l = -o; the plane point is l·distanceM/l.z. With a pupil ray, the plane point is the ray from\n * its lens origin to z = distanceM.\n *\n * Radiometry: a Lambertian reflector of reflectance ρ(λ) under irradiance E(λ) has radiance\n * L(λ) = ρ(λ)·E(λ)/π (W·m⁻²·sr⁻¹·nm⁻¹). The illuminant spectral shape S(λ) is scaled so that the\n * plane illuminance is E_v = K_m ∫ E(λ) V(λ) dλ with K_m = 683 lm/W (CIE photometric definition) and\n * V(λ) = ȳ(λ) from the engine's analytic CIE 1931 fit. The light is uniform\n * over the plane, with no shadows. Inter-reflection, gloss and fluorescence are not modelled.\n * @see docs/QUICK_START.md\n */\n\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\nimport { requireInputObject } from \"../core/record-validation.js\";\nimport { estimateCie1931ColorMatchingFunctions, prepareColorimetricSpectrum, type ColorimetricSpectrum,\n type PreparedColorimetricSpectrum } from \"../color/color-matching-functions.js\";\nimport { createCieIlluminantASpectrum, createCieDaylightSpectrum, createPlanckianSpectrum, type CieDaylightBasis } from \"../color/illuminants.js\";\nimport type { SceneRadianceEvaluationRequest, SceneRadianceEvaluationResult } from \"../schema/scene-radiance.js\";\nimport type { EvidenceProvenance } from \"../core/evidence-provenance.js\";\nimport type { SensorApertureRay } from \"../optics/sensor-aperture-rays.js\";\nimport { resolveChartScene, type ChartScene, type ResolvedChartScene } from \"./chart-scenes.js\";\n\n/** CIE maximum luminous efficacy for photopic vision, lm/W. */\nexport const PHOTOPIC_MAXIMUM_LUMINOUS_EFFICACY_LM_PER_W = 683;\n/** Wavelength range of every facade spectrum and of the facade sensor quadrature, nm. */\nexport const FACADE_SPECTRAL_RANGE_NANOMETERS = Object.freeze({ minimum: 380, maximum: 780 });\n\n/**\n * Illuminant choices. CIE D65 is not bundled: its S0/S1/S2 basis tables must come from the caller\n * (`daylight`). `planckian` is Planck's law; `cie-a` is CIE illuminant A from its defining formula.\n */\nexport type CaptureIlluminant =\n | \"cie-a\"\n | { kind: \"planckian\"; temperatureKelvin: number }\n | { kind: \"cie-a\" }\n | { kind: \"daylight\"; correlatedColorTemperatureKelvin: number; basis: CieDaylightBasis }\n | { kind: \"spectrum\"; spectrum: ColorimetricSpectrum; label?: string };\n\nexport interface ResolvedCaptureIlluminant {\n /** Short public description, for example \"planckian-6500K\". */\n id: string;\n description: string;\n /** Relative spectral shape (arbitrary scale) over at least 380-780 nm. */\n shape: PreparedColorimetricSpectrum;\n /** Original spectrum, for colorimetric white-balance calculations. */\n spectrum: ColorimetricSpectrum;\n}\n\nexport function resolveCaptureIlluminant(value: CaptureIlluminant): ResolvedCaptureIlluminant {\n if (value === \"cie-a\") return resolveCaptureIlluminant({ kind: \"cie-a\" });\n requireInputObject(value, \"illuminant\");\n const record = value as unknown as Record<string, unknown>;\n const allowed: Record<string, readonly string[]> = { planckian: [\"kind\", \"temperatureKelvin\"], \"cie-a\": [\"kind\"],\n daylight: [\"kind\", \"correlatedColorTemperatureKelvin\", \"basis\"], spectrum: [\"kind\", \"spectrum\", \"label\"] };\n const keys = typeof record.kind === \"string\" ? allowed[record.kind] : undefined;\n if (!keys) throw new InvalidConfigurationError(\"Unknown illuminant kind.\");\n for (const key of Object.keys(record)) if (!keys.includes(key)) throw new InvalidConfigurationError(\"Unknown illuminant field: \" + key + \".\");\n let spectrum: ColorimetricSpectrum, id: string, description: string;\n try {\n switch (value.kind) {\n case \"planckian\": {\n const t = value.temperatureKelvin;\n if (typeof t !== \"number\" || !Number.isFinite(t) || t < 1000 || t > 25000) throw new InvalidConfigurationError(\"Planckian temperature must be 1000-25000 K.\");\n spectrum = createPlanckianSpectrum({ temperatureKelvin: t, wavelengthRangeNanometers: { ...FACADE_SPECTRAL_RANGE_NANOMETERS } });\n id = \"planckian-\" + t + \"K\"; description = \"Planck blackbody spectrum at \" + t + \" K (Planck's law).\";\n break;\n }\n case \"cie-a\":\n spectrum = createCieIlluminantASpectrum(); id = \"cie-a\"; description = \"CIE standard illuminant A from its defining formula: Planck's law with c2 = 1.435e-2 m·K and T = 2848 K, 100 at 560 nm.\";\n break;\n case \"daylight\":\n spectrum = createCieDaylightSpectrum({ correlatedColorTemperatureKelvin: value.correlatedColorTemperatureKelvin, coefficientRounding: \"cie-three-decimals\", basis: value.basis });\n id = \"cie-daylight-\" + value.correlatedColorTemperatureKelvin + \"K\"; description = \"CIE daylight from the caller's S0/S1/S2 basis (\" + value.basis.datasetId + \").\";\n break;\n case \"spectrum\":\n spectrum = value.spectrum; id = \"caller-spectrum\";\n description = \"Caller illuminant spectrum\" + (typeof value.label === \"string\" ? \" (\" + value.label + \")\" : \"\") + \".\";\n break;\n }\n } catch (error) {\n if (error instanceof InvalidConfigurationError) throw error;\n throw new InvalidConfigurationError(\"Invalid illuminant: \" + (error instanceof Error ? error.message : \"invalid\"));\n }\n let shape: PreparedColorimetricSpectrum;\n try { shape = prepareColorimetricSpectrum(spectrum, \"illuminant\"); } catch (error) {\n throw new InvalidConfigurationError(\"Invalid illuminant spectrum: \" + (error instanceof Error ? error.message : \"invalid\"));\n }\n const range = shape.wavelengthRangeNanometers;\n if (range.minimum > FACADE_SPECTRAL_RANGE_NANOMETERS.minimum || range.maximum < FACADE_SPECTRAL_RANGE_NANOMETERS.maximum)\n throw new InvalidConfigurationError(\"The illuminant spectrum must cover 380-780 nm.\");\n for (let nm = FACADE_SPECTRAL_RANGE_NANOMETERS.minimum; nm <= FACADE_SPECTRAL_RANGE_NANOMETERS.maximum; nm += 1) {\n const s = shape.evaluate(nm);\n if (!(s >= 0)) throw new InvalidConfigurationError(\"The illuminant spectrum must be non-negative over 380-780 nm.\");\n }\n return Object.freeze({ id, description, shape, spectrum });\n}\n\n/**\n * Factor k such that k·S(λ) (W·m⁻²·nm⁻¹) gives `illuminanceLux` on the plane: E_v = 683 ∫ k S ȳ dλ,\n * integrated with the 1 nm trapezoid rule over 380-780 nm (ȳ outside this range is below 4e-5 of its peak).\n */\nexport function calculateIlluminantIrradianceScale(shape: PreparedColorimetricSpectrum, illuminanceLux: number): number {\n if (typeof shape !== \"object\" || shape === null || typeof shape.evaluate !== \"function\") throw new InvalidConfigurationError(\"A prepared illuminant spectrum is required.\");\n if (typeof illuminanceLux !== \"number\" || !Number.isFinite(illuminanceLux) || illuminanceLux <= 0 || illuminanceLux > 1e7)\n throw new InvalidConfigurationError(\"Illuminance must be a positive number of lux up to 1e7.\");\n let sum = 0;\n for (let nm = FACADE_SPECTRAL_RANGE_NANOMETERS.minimum; nm <= FACADE_SPECTRAL_RANGE_NANOMETERS.maximum; nm++) {\n const w = nm === FACADE_SPECTRAL_RANGE_NANOMETERS.minimum || nm === FACADE_SPECTRAL_RANGE_NANOMETERS.maximum ? 0.5 : 1;\n sum += w * shape.evaluate(nm) * estimateCie1931ColorMatchingFunctions(nm).y;\n }\n if (!(sum > 0)) throw new InvalidConfigurationError(\"The illuminant has no luminous power.\");\n return illuminanceLux / (PHOTOPIC_MAXIMUM_LUMINOUS_EFFICACY_LM_PER_W * sum);\n}\n\n/** A point of the scene plane passed to caller scene functions. */\nexport interface ScenePlanePoint {\n /** Metres on the plane, from the optical axis: +x right, +y up (as seen from the camera). */\n xM: number;\n yM: number;\n /** The same point in frame units (u = ±1 at the left/right frame edges, v up on the same scale). */\n u: number;\n v: number;\n wavelengthNanometers: number;\n}\n/** Caller Lambertian reflectance (in [0, 1]) lit by the facade illuminant. */\nexport interface CallerReflectanceScene { kind: \"reflectance-function\"; sceneId: string; evaluate(point: Readonly<ScenePlanePoint>): number }\n/** Caller absolute spectral radiance in W·m⁻²·sr⁻¹·nm⁻¹; the facade illuminant is not used. */\nexport interface CallerRadianceScene { kind: \"radiance-function\"; sceneId: string; evaluate(point: Readonly<ScenePlanePoint>): number }\n\nexport interface PlanarSceneGeometry {\n distanceM: number;\n /** Metres per frame unit on the plane (half the framed width). */\n metresPerFrameUnit: number;\n}\n\nexport interface PlanarSceneRadianceProvider {\n sceneId: string;\n providerProfileId: string;\n evaluateRadiance(request: Readonly<SceneRadianceEvaluationRequest>): SceneRadianceEvaluationResult;\n evaluateApertureRadiance(request: Readonly<SceneRadianceEvaluationRequest>, ray: Readonly<SensorApertureRay>): SceneRadianceEvaluationResult;\n /** Spectral radiance at a plane point (frame units), the same value the callbacks return. */\n radianceAt(u: number, v: number, wavelengthNanometers: number): number;\n}\n\nconst UNCERTAINTY = Object.freeze({ kind: \"not-quantified\" as const, limitation: \"Analytic planar Lambertian scene; no measured scene, BRDF or illumination.\" });\n\n/**\n * Wraps a chart or caller scene as a provider for the native environment RAW task. `irradianceScale` is\n * from {@link calculateIlluminantIrradianceScale}; caller radiance scenes ignore the illuminant.\n */\nexport function buildPlanarSceneRadianceProvider(input: {\n scene: ResolvedChartScene | CallerReflectanceScene | CallerRadianceScene;\n sceneId: string;\n providerProfileId: string;\n illuminant: ResolvedCaptureIlluminant;\n irradianceScale: number;\n geometry: PlanarSceneGeometry;\n evidence: readonly EvidenceProvenance[];\n limitations: readonly string[];\n}): PlanarSceneRadianceProvider {\n const { scene, illuminant, irradianceScale, geometry } = input;\n const scale = geometry.metresPerFrameUnit, distance = geometry.distanceM, sceneId = input.sceneId, providerProfileId = input.providerProfileId;\n const evidence = input.evidence, limitations = input.limitations;\n const caller = \"kind\" in scene ? scene : undefined, chart = caller ? undefined : scene as ResolvedChartScene;\n function radianceAt(u: number, v: number, nm: number): number {\n if (chart) return chart.reflectanceAt(u, v, nm) * irradianceScale * illuminant.shape.evaluate(nm) / Math.PI;\n const point = Object.freeze({ xM: u * scale, yM: v * scale, u, v, wavelengthNanometers: nm });\n const value = caller!.evaluate(point);\n if (caller!.kind === \"reflectance-function\") {\n if (typeof value !== \"number\" || !Number.isFinite(value) || value < 0 || value > 1) throw new InvalidConfigurationError(\"Scene reflectance function must return a value in [0, 1].\");\n return value * irradianceScale * illuminant.shape.evaluate(nm) / Math.PI;\n }\n if (typeof value !== \"number\" || !Number.isFinite(value) || value < 0) throw new InvalidConfigurationError(\"Scene radiance function must return a finite non-negative radiance.\");\n return value;\n }\n function result(request: Readonly<SceneRadianceEvaluationRequest>, radiance: number): SceneRadianceEvaluationResult {\n return { schemaVersion: \"0.1.0\", sampleId: request.sampleId, sceneId, providerProfileId, wavelengthNanometers: request.wavelengthNanometers,\n wavelengthBasis: request.wavelengthBasis as SceneRadianceEvaluationResult[\"wavelengthBasis\"], quantity: \"outgoing-spectral-radiance\", unit: \"W/m^2/sr/nm\",\n spectralRadianceWattsPerSquareMeterSteradianNanometer: radiance, scientificStatus: \"approximation\", uncertainty: UNCERTAINTY, evidence, limitations };\n }\n return {\n sceneId, providerProfileId, radianceAt,\n evaluateRadiance(request): SceneRadianceEvaluationResult {\n const target = request.target;\n if (target.kind !== \"environment-direction\") throw new InvalidConfigurationError(\"Planar scene provider needs environment-direction queries.\");\n const o = target.outgoingDirectionUnitVector, lz = -o.z;\n if (!(lz > 0)) throw new InvalidConfigurationError(\"Planar scene query does not point toward the scene plane.\");\n const t = distance / lz;\n return result(request, radianceAt(-o.x * t / scale, -o.y * t / scale, request.wavelengthNanometers));\n },\n evaluateApertureRadiance(request, ray): SceneRadianceEvaluationResult {\n const d = ray.directionUnitVector, origin = ray.originM;\n if (!(d.z > 0)) throw new InvalidConfigurationError(\"Planar scene pupil ray does not point toward the scene plane.\");\n const t = (distance - origin.z) / d.z;\n return result(request, radianceAt((origin.x + d.x * t) / scale, (origin.y + d.y * t) / scale, request.wavelengthNanometers));\n }\n };\n}\n\n/**\n * Public scene-preset provider. Places an engine chart (or a caller reflectance or radiance function) on\n * a plane `distanceM` in front of the camera and `framedWidthM` wide (frame units u = ±1 at its edges),\n * lit by `illuminant` at `illuminanceLux`. The returned `evaluateRadiance` and `evaluateApertureRadiance`\n * follow the native environment RAW provider contract. They answer requests for scene `sceneId` and\n * provider `providerProfileId`.\n */\nexport function createPlanarSceneRadianceProvider(input: {\n scene: ChartScene | CallerReflectanceScene | CallerRadianceScene;\n illuminant: CaptureIlluminant;\n illuminanceLux: number;\n distanceM: number;\n framedWidthM: number;\n /** Frame height / width. */\n aspect: number;\n sceneId: string;\n providerProfileId: string;\n}): PlanarSceneRadianceProvider & { chart: ResolvedChartScene | null } {\n requireInputObject(input, \"createPlanarSceneRadianceProvider input\");\n const keys = [\"scene\", \"illuminant\", \"illuminanceLux\", \"distanceM\", \"framedWidthM\", \"aspect\", \"sceneId\", \"providerProfileId\"];\n for (const key of Object.keys(input)) if (!keys.includes(key)) throw new InvalidConfigurationError(\"createPlanarSceneRadianceProvider input has unknown field \\\"\" + key + \"\\\".\");\n for (const key of [\"illuminanceLux\", \"distanceM\", \"framedWidthM\", \"aspect\"] as const) {\n const value = input[key];\n if (typeof value !== \"number\" || !Number.isFinite(value) || value <= 0) throw new InvalidConfigurationError(key + \" must be a positive finite number.\");\n }\n for (const key of [\"sceneId\", \"providerProfileId\"] as const) if (typeof input[key] !== \"string\" || !/^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/.test(input[key])) throw new InvalidConfigurationError(key + \" must be a public opaque ID.\");\n requireInputObject(input.scene, \"scene\");\n const caller = \"kind\" in input.scene ? requireCallerScene(input.scene) : undefined;\n const chart = caller ? null : resolveChartScene({ scene: input.scene as ChartScene, aspect: input.aspect });\n const illuminant = resolveCaptureIlluminant(input.illuminant);\n const provider = buildPlanarSceneRadianceProvider({ scene: chart ?? caller!, sceneId: input.sceneId, providerProfileId: input.providerProfileId, illuminant,\n irradianceScale: calculateIlluminantIrradianceScale(illuminant.shape, input.illuminanceLux),\n geometry: { distanceM: input.distanceM, metresPerFrameUnit: input.framedWidthM / 2 },\n evidence: [{ sourceOrigin: \"photivra\", sourceReference: \"photivra:planar-scene-provider\", reuseStatus: \"photivra-owned\" }],\n limitations: [\"Planar Lambertian scene under uniform illumination; no shadows, inter-reflection, gloss or fluorescence.\"] });\n return { ...provider, chart };\n}\n\n/** Validates a caller scene function record. */\nexport function requireCallerScene(value: unknown): CallerReflectanceScene | CallerRadianceScene {\n requireInputObject(value, \"scene\");\n const record = value as Record<string, unknown>;\n for (const key of Object.keys(record)) if (key !== \"kind\" && key !== \"sceneId\" && key !== \"evaluate\") throw new InvalidConfigurationError(\"Unknown scene field: \" + key + \".\");\n if ((record.kind !== \"reflectance-function\" && record.kind !== \"radiance-function\") || typeof record.evaluate !== \"function\" ||\n typeof record.sceneId !== \"string\" || !/^[A-Za-z0-9][A-Za-z0-9._:-]{0,63}$/.test(record.sceneId)) throw new InvalidConfigurationError(\"A caller scene needs kind, a public sceneId and an evaluate function.\");\n return record as unknown as CallerReflectanceScene | CallerRadianceScene;\n}\n"]}
1
+ {"version":3,"file":"scene-radiance.js","sourceRoot":"","sources":["../../src/facade/scene-radiance.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Turns a facade scene and an illuminant into a scene radiance provider for the existing native\n * environment RAW contract (`NativeEnvironmentRawProvider.evaluateRadiance` and, for pupil sampling,\n * `evaluateApertureRadiance`). The scene is an engine chart, a caller reflectance function or a caller\n * radiance function.\n *\n * Geometry: one plane perpendicular to the optical axis at `distanceM` in front of the camera. A query's\n * outgoing direction o (scene toward camera, see docs/SENSOR_ENVIRONMENT_QUERY.md) gives the look\n * direction l = -o; the plane point is l·distanceM/l.z. With a pupil ray, the plane point is the ray from\n * its lens origin to z = distanceM.\n *\n * Radiometry: a Lambertian reflector of reflectance ρ(λ) under irradiance E(λ) has radiance\n * L(λ) = ρ(λ)·E(λ)/π (W·m⁻²·sr⁻¹·nm⁻¹). The illuminant spectral shape S(λ) is scaled so that the\n * plane illuminance is E_v = K_m ∫ E(λ) V(λ) dλ with K_m = 683 lm/W (CIE photometric definition) and\n * V(λ) = ȳ(λ) from the engine's analytic CIE 1931 fit. The light is uniform\n * over the plane, with no shadows. Inter-reflection, gloss and fluorescence are not modelled.\n * @see docs/QUICK_START.md\n */\n\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\nimport { requireInputObject } from \"../core/record-validation.js\";\nimport { estimateCie1931ColorMatchingFunctions, prepareColorimetricSpectrum, type ColorimetricSpectrum,\n type PreparedColorimetricSpectrum } from \"../color/color-matching-functions.js\";\nimport { createCieIlluminantASpectrum, createCieDaylightSpectrum, createPlanckianSpectrum, type CieDaylightBasis } from \"../color/illuminants.js\";\nimport type { SceneRadianceEvaluationRequest, SceneRadianceEvaluationResult } from \"../schema/scene-radiance.js\";\nimport type { EvidenceProvenance } from \"../core/evidence-provenance.js\";\nimport type { SensorApertureRay } from \"../optics/sensor-aperture-rays.js\";\nimport { resolveChartScene, type ChartScene, type ResolvedChartScene } from \"./chart-scenes.js\";\n\n/** CIE maximum luminous efficacy for photopic vision, lm/W. */\nexport const PHOTOPIC_MAXIMUM_LUMINOUS_EFFICACY_LM_PER_W = 683;\n/** Wavelength range of every facade spectrum and of the facade sensor quadrature, nm. */\nexport const FACADE_SPECTRAL_RANGE_NANOMETERS = Object.freeze({ minimum: 380, maximum: 780 });\n\n/**\n * Illuminant choices. CIE D65 is not bundled: its S0/S1/S2 basis tables must come from the caller\n * (`daylight`). `planckian` is Planck's law; `cie-a` is CIE illuminant A from its defining formula.\n */\nexport type CaptureIlluminant =\n | \"cie-a\"\n | { kind: \"planckian\"; temperatureKelvin: number }\n | { kind: \"cie-a\" }\n | { kind: \"daylight\"; correlatedColorTemperatureKelvin: number; basis: CieDaylightBasis }\n | { kind: \"spectrum\"; spectrum: ColorimetricSpectrum; label?: string };\n\nexport interface ResolvedCaptureIlluminant {\n /** Short public description, for example \"planckian-6500K\". */\n id: string;\n description: string;\n /** Relative spectral shape (arbitrary scale) over at least 380-780 nm. */\n shape: PreparedColorimetricSpectrum;\n /** Original spectrum, for colorimetric white-balance calculations. */\n spectrum: ColorimetricSpectrum;\n}\n\nexport function resolveCaptureIlluminant(value: CaptureIlluminant): ResolvedCaptureIlluminant {\n if (value === \"cie-a\") return resolveCaptureIlluminant({ kind: \"cie-a\" });\n requireInputObject(value, \"illuminant\");\n const record = value as unknown as Record<string, unknown>;\n const allowed: Record<string, readonly string[]> = { planckian: [\"kind\", \"temperatureKelvin\"], \"cie-a\": [\"kind\"],\n daylight: [\"kind\", \"correlatedColorTemperatureKelvin\", \"basis\"], spectrum: [\"kind\", \"spectrum\", \"label\"] };\n const keys = typeof record.kind === \"string\" ? allowed[record.kind] : undefined;\n if (!keys) throw new InvalidConfigurationError(\"Unknown illuminant kind.\");\n for (const key of Object.keys(record)) if (!keys.includes(key)) throw new InvalidConfigurationError(\"Unknown illuminant field: \" + key + \".\");\n let spectrum: ColorimetricSpectrum, id: string, description: string;\n try {\n switch (value.kind) {\n case \"planckian\": {\n const t = value.temperatureKelvin;\n if (typeof t !== \"number\" || !Number.isFinite(t) || t < 1000 || t > 25000) throw new InvalidConfigurationError(\"Planckian temperature must be 1000-25000 K.\");\n spectrum = createPlanckianSpectrum({ temperatureKelvin: t, wavelengthRangeNanometers: { ...FACADE_SPECTRAL_RANGE_NANOMETERS } });\n id = \"planckian-\" + t + \"K\"; description = \"Planck blackbody spectrum at \" + t + \" K (Planck's law).\";\n break;\n }\n case \"cie-a\":\n spectrum = createCieIlluminantASpectrum(); id = \"cie-a\"; description = \"CIE standard illuminant A from its defining formula: Planck's law with c2 = 1.435e-2 m·K and T = 2848 K, 100 at 560 nm.\";\n break;\n case \"daylight\":\n spectrum = createCieDaylightSpectrum({ correlatedColorTemperatureKelvin: value.correlatedColorTemperatureKelvin, coefficientRounding: \"cie-three-decimals\", basis: value.basis });\n id = \"cie-daylight-\" + value.correlatedColorTemperatureKelvin + \"K\"; description = \"CIE daylight from the caller's S0/S1/S2 basis (\" + value.basis.datasetId + \").\";\n break;\n case \"spectrum\":\n spectrum = value.spectrum; id = \"caller-spectrum\";\n description = \"Caller illuminant spectrum\" + (typeof value.label === \"string\" ? \" (\" + value.label + \")\" : \"\") + \".\";\n break;\n }\n } catch (error) {\n if (error instanceof InvalidConfigurationError) throw error;\n throw new InvalidConfigurationError(\"Invalid illuminant: \" + (error instanceof Error ? error.message : \"invalid\"));\n }\n let shape: PreparedColorimetricSpectrum;\n try { shape = prepareColorimetricSpectrum(spectrum, \"illuminant\"); } catch (error) {\n throw new InvalidConfigurationError(\"Invalid illuminant spectrum: \" + (error instanceof Error ? error.message : \"invalid\"));\n }\n const range = shape.wavelengthRangeNanometers;\n if (range.minimum > FACADE_SPECTRAL_RANGE_NANOMETERS.minimum || range.maximum < FACADE_SPECTRAL_RANGE_NANOMETERS.maximum)\n throw new InvalidConfigurationError(\"The illuminant spectrum must cover 380-780 nm.\");\n for (let nm = FACADE_SPECTRAL_RANGE_NANOMETERS.minimum; nm <= FACADE_SPECTRAL_RANGE_NANOMETERS.maximum; nm += 1) {\n const s = shape.evaluate(nm);\n if (!(s >= 0)) throw new InvalidConfigurationError(\"The illuminant spectrum must be non-negative over 380-780 nm.\");\n }\n return Object.freeze({ id, description, shape, spectrum });\n}\n\n/**\n * Factor k such that k·S(λ) (W·m⁻²·nm⁻¹) gives `illuminanceLux` on the plane: E_v = 683 ∫ k S ȳ dλ,\n * integrated with the 1 nm trapezoid rule over 380-780 nm (ȳ outside this range is below 4e-5 of its peak).\n */\nexport function calculateIlluminantIrradianceScale(shape: PreparedColorimetricSpectrum, illuminanceLux: number): number {\n if (typeof shape !== \"object\" || shape === null || typeof shape.evaluate !== \"function\") throw new InvalidConfigurationError(\"A prepared illuminant spectrum is required.\");\n if (typeof illuminanceLux !== \"number\" || !Number.isFinite(illuminanceLux) || illuminanceLux <= 0 || illuminanceLux > 1e7)\n throw new InvalidConfigurationError(\"Illuminance must be a positive number of lux up to 1e7.\");\n let sum = 0;\n for (let nm = FACADE_SPECTRAL_RANGE_NANOMETERS.minimum; nm <= FACADE_SPECTRAL_RANGE_NANOMETERS.maximum; nm++) {\n const w = nm === FACADE_SPECTRAL_RANGE_NANOMETERS.minimum || nm === FACADE_SPECTRAL_RANGE_NANOMETERS.maximum ? 0.5 : 1;\n sum += w * shape.evaluate(nm) * estimateCie1931ColorMatchingFunctions(nm).y;\n }\n if (!(sum > 0)) throw new InvalidConfigurationError(\"The illuminant has no luminous power.\");\n return illuminanceLux / (PHOTOPIC_MAXIMUM_LUMINOUS_EFFICACY_LM_PER_W * sum);\n}\n\n/** A point of the scene plane passed to caller scene functions. */\nexport interface ScenePlanePoint {\n /** Metres on the plane, from the optical axis: +x right, +y up (as seen from the camera). */\n xM: number;\n yM: number;\n /** The same point in frame units (u = ±1 at the left/right frame edges, v up on the same scale). */\n u: number;\n v: number;\n wavelengthNanometers: number;\n /**\n * 2.3, only with a fixed-size chart (`chartSize`): the point in chart-local frame units (±1 at the chart's\n * left/right edges, v up on the same scale, ±chart height/width at its top/bottom). The function is then\n * called only for points on the chart; the surround is the placement's surround reflectance.\n */\n chartU?: number;\n chartV?: number;\n}\n/** Caller Lambertian reflectance (in [0, 1]) lit by the facade illuminant. */\nexport interface CallerReflectanceScene { kind: \"reflectance-function\"; sceneId: string; evaluate(point: Readonly<ScenePlanePoint>): number }\n/** Caller absolute spectral radiance in W·m⁻²·sr⁻¹·nm⁻¹; the facade illuminant is not used. */\nexport interface CallerRadianceScene { kind: \"radiance-function\"; sceneId: string; evaluate(point: Readonly<ScenePlanePoint>): number }\n\nexport interface PlanarSceneGeometry {\n distanceM: number;\n /** Metres per frame unit on the plane (half the framed width). */\n metresPerFrameUnit: number;\n /**\n * 2.3, opt-in fixed-size chart: the chart is `widthM` × `heightM` on the plane, centred on the optical axis;\n * outside it the plane is a neutral Lambertian surround of `surroundReflectance`, lit by the same illuminant.\n * A chart preset is then resolved in its own frame (aspect heightM / widthM). Without it the chart fills the frame.\n */\n chart?: { widthM: number; heightM: number; surroundReflectance: number };\n}\n\nexport interface PlanarSceneRadianceProvider {\n sceneId: string;\n providerProfileId: string;\n evaluateRadiance(request: Readonly<SceneRadianceEvaluationRequest>): SceneRadianceEvaluationResult;\n evaluateApertureRadiance(request: Readonly<SceneRadianceEvaluationRequest>, ray: Readonly<SensorApertureRay>): SceneRadianceEvaluationResult;\n /** Spectral radiance at a plane point (frame units), the same value the callbacks return. */\n radianceAt(u: number, v: number, wavelengthNanometers: number): number;\n /**\n * 2.3, chart scenes only: the chart material at a plane point (frame units), or `materials.length` for the\n * surround of a fixed-size chart; `materialRadiance` gives that material's spectral radiance, the same value\n * `radianceAt` returns at its points.\n */\n chartMaterialAt?(u: number, v: number): number;\n materialRadiance?(material: number, wavelengthNanometers: number): number;\n}\n\nconst UNCERTAINTY = Object.freeze({ kind: \"not-quantified\" as const, limitation: \"Analytic planar Lambertian scene; no measured scene, BRDF or illumination.\" });\n\n/**\n * Wraps a chart or caller scene as a provider for the native environment RAW task. `irradianceScale` is\n * from {@link calculateIlluminantIrradianceScale}; caller radiance scenes ignore the illuminant.\n */\nexport function buildPlanarSceneRadianceProvider(input: {\n scene: ResolvedChartScene | CallerReflectanceScene | CallerRadianceScene;\n sceneId: string;\n providerProfileId: string;\n illuminant: ResolvedCaptureIlluminant;\n irradianceScale: number;\n geometry: PlanarSceneGeometry;\n evidence: readonly EvidenceProvenance[];\n limitations: readonly string[];\n}): PlanarSceneRadianceProvider {\n const { scene, illuminant, irradianceScale, geometry } = input;\n const scale = geometry.metresPerFrameUnit, distance = geometry.distanceM, sceneId = input.sceneId, providerProfileId = input.providerProfileId;\n const evidence = input.evidence, limitations = input.limitations;\n const caller = \"kind\" in scene ? scene : undefined, chart = caller ? undefined : scene as ResolvedChartScene;\n const placed = geometry.chart, half = placed ? placed.widthM / 2 : 0, chartAspect = placed ? placed.heightM / placed.widthM : 0;\n function radianceAt(u: number, v: number, nm: number): number {\n if (placed) {\n // Fixed-size chart (2.3): chart-local frame units from the plane point in metres.\n const xM = u * scale, yM = v * scale, cu = xM / half, cv = yM / half;\n if (!(Math.abs(cu) <= 1 && Math.abs(cv) <= chartAspect)) return placed.surroundReflectance * irradianceScale * illuminant.shape.evaluate(nm) / Math.PI;\n if (chart) return chart.reflectanceAt(cu, cv, nm) * irradianceScale * illuminant.shape.evaluate(nm) / Math.PI;\n return callerValue(Object.freeze({ xM, yM, u, v, wavelengthNanometers: nm, chartU: cu, chartV: cv }), nm);\n }\n if (chart) return chart.reflectanceAt(u, v, nm) * irradianceScale * illuminant.shape.evaluate(nm) / Math.PI;\n return callerValue(Object.freeze({ xM: u * scale, yM: v * scale, u, v, wavelengthNanometers: nm }), nm);\n }\n function callerValue(point: Readonly<ScenePlanePoint>, nm: number): number {\n const value = caller!.evaluate(point);\n if (caller!.kind === \"reflectance-function\") {\n if (typeof value !== \"number\" || !Number.isFinite(value) || value < 0 || value > 1) throw new InvalidConfigurationError(\"Scene reflectance function must return a value in [0, 1].\");\n return value * irradianceScale * illuminant.shape.evaluate(nm) / Math.PI;\n }\n if (typeof value !== \"number\" || !Number.isFinite(value) || value < 0) throw new InvalidConfigurationError(\"Scene radiance function must return a finite non-negative radiance.\");\n return value;\n }\n function result(request: Readonly<SceneRadianceEvaluationRequest>, radiance: number): SceneRadianceEvaluationResult {\n return { schemaVersion: \"0.1.0\", sampleId: request.sampleId, sceneId, providerProfileId, wavelengthNanometers: request.wavelengthNanometers,\n wavelengthBasis: request.wavelengthBasis as SceneRadianceEvaluationResult[\"wavelengthBasis\"], quantity: \"outgoing-spectral-radiance\", unit: \"W/m^2/sr/nm\",\n spectralRadianceWattsPerSquareMeterSteradianNanometer: radiance, scientificStatus: \"approximation\", uncertainty: UNCERTAINTY, evidence, limitations };\n }\n const chartAccess = chart ? {\n chartMaterialAt(u: number, v: number): number {\n if (!placed) return chart.materialAt(u, v);\n const cu = u * scale / half, cv = v * scale / half;\n return Math.abs(cu) <= 1 && Math.abs(cv) <= chartAspect ? chart.materialAt(cu, cv) : chart.materials.length;\n },\n materialRadiance(material: number, nm: number): number {\n const m = chart.materials[material];\n let value: number;\n if (m === undefined) value = placed ? placed.surroundReflectance : NaN;\n else if (m.kind === \"neutral\") value = m.reflectance;\n else {\n value = m.spectrum.evaluate(nm);\n if (!(value >= 0 && value <= 1)) throw new InvalidConfigurationError(\"Chart reflectance spectrum left [0, 1].\");\n }\n if (!(value >= 0)) throw new InvalidConfigurationError(\"Unknown chart material.\");\n return value * irradianceScale * illuminant.shape.evaluate(nm) / Math.PI;\n }\n } : {};\n return {\n sceneId, providerProfileId, radianceAt, ...chartAccess,\n evaluateRadiance(request): SceneRadianceEvaluationResult {\n const target = request.target;\n if (target.kind !== \"environment-direction\") throw new InvalidConfigurationError(\"Planar scene provider needs environment-direction queries.\");\n const o = target.outgoingDirectionUnitVector, lz = -o.z;\n if (!(lz > 0)) throw new InvalidConfigurationError(\"Planar scene query does not point toward the scene plane.\");\n const t = distance / lz;\n return result(request, radianceAt(-o.x * t / scale, -o.y * t / scale, request.wavelengthNanometers));\n },\n evaluateApertureRadiance(request, ray): SceneRadianceEvaluationResult {\n const d = ray.directionUnitVector, origin = ray.originM;\n if (!(d.z > 0)) throw new InvalidConfigurationError(\"Planar scene pupil ray does not point toward the scene plane.\");\n const t = (distance - origin.z) / d.z;\n return result(request, radianceAt((origin.x + d.x * t) / scale, (origin.y + d.y * t) / scale, request.wavelengthNanometers));\n }\n };\n}\n\n/** 2.3: a chart's physical size on the scene plane (`simulateCapture` `chartSize`, `createPlanarSceneRadianceProvider` `chartSize`). */\nexport interface ChartSizeOption {\n /** Chart width in metres, (0, 10 000]. */\n widthM: number;\n /** Chart height in metres. Default: widthM × the frame aspect (height / width), so the chart has the frame's shape. */\n heightM?: number;\n /** Neutral reflectance of the plane around the chart, lit by the same illuminant. Default 0.18. */\n surroundReflectance?: number;\n}\n/** Default surround of a fixed-size chart: an 18 % grey plane. */\nexport const CHART_SIZE_DEFAULT_SURROUND_REFLECTANCE = 0.18;\n/** Internal: validates a chart size and fills its defaults; `defaulted` names the fields taken from defaults. */\nexport function resolveChartSizeOption(value: unknown, frameAspect: number): { widthM: number; heightM: number; surroundReflectance: number; defaulted: (\"heightM\" | \"surroundReflectance\")[] } {\n requireInputObject(value, \"chartSize\");\n const record = value as Record<string, unknown>;\n for (const key of Object.keys(record)) if (![\"widthM\", \"heightM\", \"surroundReflectance\"].includes(key)) throw new InvalidConfigurationError(\"Unknown chartSize field: \" + key + \".\");\n const size = (x: unknown, name: string): number => {\n if (typeof x !== \"number\" || !Number.isFinite(x) || x <= 0 || x > 10_000) throw new InvalidConfigurationError(\"chartSize.\" + name + \" must be a positive number of metres up to 10000.\");\n return x;\n };\n const defaulted: (\"heightM\" | \"surroundReflectance\")[] = [];\n const widthM = size(record.widthM, \"widthM\");\n const heightM = record.heightM === undefined ? (defaulted.push(\"heightM\"), widthM * frameAspect) : size(record.heightM, \"heightM\");\n const surround = record.surroundReflectance === undefined ? (defaulted.push(\"surroundReflectance\"), CHART_SIZE_DEFAULT_SURROUND_REFLECTANCE) : record.surroundReflectance;\n if (typeof surround !== \"number\" || !Number.isFinite(surround) || surround < 0 || surround > 1) throw new InvalidConfigurationError(\"chartSize.surroundReflectance must be a reflectance in [0, 1].\");\n return { widthM, heightM, surroundReflectance: surround, defaulted };\n}\n\n/**\n * Public scene-preset provider. Places an engine chart (or a caller reflectance or radiance function) on\n * a plane `distanceM` in front of the camera and `framedWidthM` wide (frame units u = ±1 at its edges),\n * lit by `illuminant` at `illuminanceLux`. The returned `evaluateRadiance` and `evaluateApertureRadiance`\n * follow the native environment RAW provider contract. They answer requests for scene `sceneId` and\n * provider `providerProfileId`.\n */\nexport function createPlanarSceneRadianceProvider(input: {\n scene: ChartScene | CallerReflectanceScene | CallerRadianceScene;\n illuminant: CaptureIlluminant;\n illuminanceLux: number;\n distanceM: number;\n framedWidthM: number;\n /** Frame height / width. */\n aspect: number;\n sceneId: string;\n providerProfileId: string;\n /**\n * 2.3, opt-in: place the chart at this physical size, centred, instead of filling the frame; the chart preset\n * is resolved with aspect heightM / widthM and the rest of the plane is the surround.\n */\n chartSize?: ChartSizeOption;\n}): PlanarSceneRadianceProvider & { chart: ResolvedChartScene | null } {\n requireInputObject(input, \"createPlanarSceneRadianceProvider input\");\n const keys = [\"scene\", \"illuminant\", \"illuminanceLux\", \"distanceM\", \"framedWidthM\", \"aspect\", \"sceneId\", \"providerProfileId\", \"chartSize\"];\n for (const key of Object.keys(input)) if (!keys.includes(key)) throw new InvalidConfigurationError(\"createPlanarSceneRadianceProvider input has unknown field \\\"\" + key + \"\\\".\");\n for (const key of [\"illuminanceLux\", \"distanceM\", \"framedWidthM\", \"aspect\"] as const) {\n const value = input[key];\n if (typeof value !== \"number\" || !Number.isFinite(value) || value <= 0) throw new InvalidConfigurationError(key + \" must be a positive finite number.\");\n }\n for (const key of [\"sceneId\", \"providerProfileId\"] as const) if (typeof input[key] !== \"string\" || !/^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/.test(input[key])) throw new InvalidConfigurationError(key + \" must be a public opaque ID.\");\n requireInputObject(input.scene, \"scene\");\n const caller = \"kind\" in input.scene ? requireCallerScene(input.scene) : undefined;\n const size = input.chartSize === undefined ? undefined : resolveChartSizeOption(input.chartSize, input.aspect);\n const chart = caller ? null : resolveChartScene({ scene: input.scene as ChartScene, aspect: size ? size.heightM / size.widthM : input.aspect });\n const illuminant = resolveCaptureIlluminant(input.illuminant);\n const provider = buildPlanarSceneRadianceProvider({ scene: chart ?? caller!, sceneId: input.sceneId, providerProfileId: input.providerProfileId, illuminant,\n irradianceScale: calculateIlluminantIrradianceScale(illuminant.shape, input.illuminanceLux),\n geometry: { distanceM: input.distanceM, metresPerFrameUnit: input.framedWidthM / 2,\n ...(size ? { chart: { widthM: size.widthM, heightM: size.heightM, surroundReflectance: size.surroundReflectance } } : {}) },\n evidence: [{ sourceOrigin: \"photivra\", sourceReference: \"photivra:planar-scene-provider\", reuseStatus: \"photivra-owned\" }],\n limitations: [\"Planar Lambertian scene under uniform illumination; no shadows, inter-reflection, gloss or fluorescence.\"] });\n return { ...provider, chart };\n}\n\n/** Validates a caller scene function record. */\nexport function requireCallerScene(value: unknown): CallerReflectanceScene | CallerRadianceScene {\n requireInputObject(value, \"scene\");\n const record = value as Record<string, unknown>;\n for (const key of Object.keys(record)) if (key !== \"kind\" && key !== \"sceneId\" && key !== \"evaluate\") throw new InvalidConfigurationError(\"Unknown scene field: \" + key + \".\");\n if ((record.kind !== \"reflectance-function\" && record.kind !== \"radiance-function\") || typeof record.evaluate !== \"function\" ||\n typeof record.sceneId !== \"string\" || !/^[A-Za-z0-9][A-Za-z0-9._:-]{0,63}$/.test(record.sceneId)) throw new InvalidConfigurationError(\"A caller scene needs kind, a public sceneId and an evaluate function.\");\n return record as unknown as CallerReflectanceScene | CallerRadianceScene;\n}\n"]}
@@ -15,7 +15,7 @@ import type { CalculateEnvironmentSensorPhotoSignalInput } from "../sensor/envir
15
15
  import { type DiffractionLimitedPsfProfile } from "../optics/diffraction-psf-profile.js";
16
16
  import { type AntiAliasingPointSplitComponent } from "../sensor/optical-stack.js";
17
17
  import { type ChartScene } from "./chart-scenes.js";
18
- import { type CaptureIlluminant, type CallerRadianceScene, type CallerReflectanceScene } from "./scene-radiance.js";
18
+ import { type ChartSizeOption, type CaptureIlluminant, type CallerRadianceScene, type CallerReflectanceScene } from "./scene-radiance.js";
19
19
  /** Version of how the facade builds requests. It changes whenever the same input would build a different request. */
20
20
  export declare const SIMULATE_CAPTURE_FACADE_VERSION: "1.0.0";
21
21
  export type SimulateCaptureExposureMode = "manual" | "aperture-priority" | "shutter-priority" | "program";
@@ -85,6 +85,13 @@ export type SimulateCaptureSensorAntiAliasing = {
85
85
  kind: "point-splitting";
86
86
  components: readonly AntiAliasingPointSplitComponent[];
87
87
  };
88
+ /** Pixel aperture (2.3): centre sampling, or the square photosite integrated with an N × N midpoint rule. */
89
+ export type SimulateCapturePixelAperture = "point" | "box" | {
90
+ kind: "box";
91
+ samplesPerAxis?: number;
92
+ };
93
+ /** Default midpoint samples per axis of `sensor.pixelAperture: "box"`. */
94
+ export declare const SIMULATE_CAPTURE_BOX_APERTURE_DEFAULT_SAMPLES = 4;
88
95
  export interface SimulateCaptureMotion {
89
96
  /** Constant camera angular velocity, rad/s, in the engine's pitch/yaw/roll convention. Missing axes are 0. */
90
97
  angularVelocityRadPerSec?: {
@@ -103,6 +110,14 @@ export interface SimulateCaptureOptions {
103
110
  lens?: {
104
111
  /** Must lie in the lens capability (the generic primes are 50 mm). Default: the lens's shortest focal length. */
105
112
  focalLengthMm?: number;
113
+ /**
114
+ * Opt-in (2.3): a lens of the generic prime family by its full-frame-equivalent focal length
115
+ * (`GENERIC_PRIME_EQUIVALENT_FOCAL_LENGTHS_MM`). Its physical focal length is the equivalent ÷ the diagonal crop
116
+ * factor of the simulated frame (output width × height × pixel pitch); it replaces the tier lens's focal length and
117
+ * f-number range (the tier lens's transmission is kept). An f-number outside the prime's range, or a subject or
118
+ * focus distance below its minimum focus distance, is rejected. Not combinable with `focalLengthMm`.
119
+ */
120
+ prime?: number;
106
121
  /** Aperture for manual and aperture-priority modes. Default 8. */
107
122
  fNumber?: number;
108
123
  /** Focus distance in metres. Default: the subject distance. */
@@ -129,7 +144,7 @@ export interface SimulateCaptureOptions {
129
144
  * Opt-in (2.1) diffraction blur of an ideal, aberration-free, in-focus lens with a circular pupil at the
130
145
  * capture's resolved f-number: the engine builds the Airy kernels (`createDiffractionLimitedPsfProfile`)
131
146
  * on the site pitch. `kernelRadiusSamples` (0–32) sets the kernel window; default: the third dark ring at
132
- * the longest spectral node. Not combinable with `psf` or `pupilSampling`. Default off.
147
+ * the longest spectral node, capped at 32 sites. Not combinable with `psf` or `pupilSampling`. Default off.
133
148
  */
134
149
  diffraction?: SimulateCaptureLensDiffraction;
135
150
  };
@@ -147,6 +162,14 @@ export interface SimulateCaptureOptions {
147
162
  scene: ChartScene | CallerReflectanceScene | CallerRadianceScene;
148
163
  /** Distance from the camera to the scene plane in metres. Default 5. */
149
164
  subjectDistanceM?: number;
165
+ /**
166
+ * Opt-in (2.3) fixed-size chart: place the scene at this physical size on the plane at the subject distance,
167
+ * centred on the optical axis, instead of sizing it to fill the frame. Outside it the plane is a neutral surround
168
+ * (default 18 %). Chart presets are resolved in the chart's own frame (aspect heightM / widthM); caller functions
169
+ * are called only on the chart and receive chart-local `chartU`, `chartV`. `result.scene.chart` reports the
170
+ * framed width, the fraction of the frame the chart covers and the thin-lens magnification.
171
+ */
172
+ chartSize?: ChartSizeOption;
150
173
  /** Default: Planckian 6500 K (a blackbody stand-in for daylight; CIE D65 is not bundled). */
151
174
  illuminant?: CaptureIlluminant;
152
175
  /** Illuminance on the scene plane, lux. Default about 21 481 lux (see `SIMULATE_CAPTURE_DEFAULT_ILLUMINANCE_LUX` and the assumptions). */
@@ -191,6 +214,20 @@ export interface SimulateCaptureOptions {
191
214
  * memory grow with the pixel count (see "Large images" in the quick start); browsers may fail at large sizes.
192
215
  */
193
216
  maximumPixels?: number;
217
+ /**
218
+ * Opt-in (2.3) region rendering: render only this rectangle, in output-pixel coordinates of the whole frame
219
+ * `width` × `height` (x right, y down from its top-left). The pixels are byte-identical to the same pixels of
220
+ * the whole render: framing, metering, exposure, noise seeds (absolute native site indices), rolling-shutter row
221
+ * timing, diffraction and demosaic all use the whole frame. Use it to tile a large frame across workers or to
222
+ * render a 100 % crop. `result.image` is the region; `result.region` reports it. Not combinable with
223
+ * `whiteBalance: "auto"`, whose statistics would come from the region only.
224
+ */
225
+ region?: {
226
+ x: number;
227
+ y: number;
228
+ width: number;
229
+ height: number;
230
+ };
194
231
  };
195
232
  /** Camera motion and shutter type. Default: still camera, global electronic shutter. */
196
233
  motion?: SimulateCaptureMotion;
@@ -208,6 +245,13 @@ export interface SimulateCaptureOptions {
208
245
  * Multiplies the scene queries by the number of split points. Default off (the tiers declare no filter).
209
246
  */
210
247
  antiAliasing?: SimulateCaptureSensorAntiAliasing;
248
+ /**
249
+ * Opt-in (2.3) pixel aperture. `"point"` (default): each site samples the irradiance at its centre.
250
+ * `"box"`: each site integrates the irradiance over its whole square photosite (fill factor 1) with an
251
+ * N × N midpoint rule, N = `samplesPerAxis` (1–16, default 4), so detail finer than a pixel averages out as
252
+ * on a real sensor (pixel MTF |sinc(f·p)|) instead of aliasing. Multiplies the scene queries by N².
253
+ */
254
+ pixelAperture?: SimulateCapturePixelAperture;
211
255
  };
212
256
  /** Aborting cancels the running task; the promise rejects with a domain error and returns no partial image. */
213
257
  signal?: AbortSignal;
@@ -218,7 +262,7 @@ export interface SimulateCaptureOptions {
218
262
  * Options reported in `diagnostics.options` (2.1), in this order, when they ran: the ones that change how much work
219
263
  * a capture does. `motion.rotation` is a non-zero angular velocity; `sensor.temporalSampleCount` a count above 1.
220
264
  */
221
- export declare const SIMULATE_CAPTURE_COST_OPTIONS: readonly ["lens.pupilSampling", "lens.projection", "lens.distortion", "lens.vignetting", "lens.psf", "lens.diffraction", "sensor.antiAliasing", "sensor.temporalSampleCount", "motion.rotation", "motion.shutter.rolling", "output.borderHandling.mirror", "output.whiteBalance.auto", "output.demosaic.ahd", "output.highlightMode.reconstruct", "output.colorEncoding.wide-gamut", "output.gamutMapping.perceptual", "output.format.jpeg", "output.format.png", "output.format.dng"];
265
+ export declare const SIMULATE_CAPTURE_COST_OPTIONS: readonly ["lens.pupilSampling", "lens.projection", "lens.distortion", "lens.vignetting", "lens.psf", "lens.diffraction", "sensor.antiAliasing", "sensor.pixelAperture.box", "sensor.temporalSampleCount", "motion.rotation", "motion.shutter.rolling", "output.borderHandling.mirror", "output.region", "output.whiteBalance.auto", "output.demosaic.ahd", "output.highlightMode.reconstruct", "output.colorEncoding.wide-gamut", "output.gamutMapping.perceptual", "output.format.jpeg", "output.format.png", "output.format.dng"];
222
266
  export type SimulateCaptureCostOption = typeof SIMULATE_CAPTURE_COST_OPTIONS[number];
223
267
  export interface SimulateCaptureProgress {
224
268
  stage: "raw" | "white-balance" | "development" | "jpeg";
@@ -251,9 +295,32 @@ export interface SimulateCaptureResult {
251
295
  /** Lossless uncompressed CFA DNG of the packed RAW when format is "dng" (`serializeNativeRawDng`); `samples` are then sRGB 8-bit. */
252
296
  dng?: Uint8Array;
253
297
  };
254
- /** Packed native RAW (codes, black levels, saturation flags) as produced by the native environment RAW task. */
298
+ /**
299
+ * Packed native RAW (codes, black levels, saturation flags) as produced by the native environment RAW task. With
300
+ * `output.region` (2.3): the region's native sites only, with `plan` describing that raster (its active area is the
301
+ * region); `request.environmentRaw` and `request.siteInput` stay those of the whole frame.
302
+ */
255
303
  raw: NativeRawOutput;
256
304
  plan: NativeRawPlan;
305
+ /**
306
+ * 2.3, present with `output.region`: the rendered rectangle in output pixels of the whole `frameWidth` × `frameHeight`
307
+ * frame, and the native sites rendered for it (`nativeRect`, in the whole frame's native raster: the region, the
308
+ * demosaic reach on each side clipped to the raster, and its origin rounded down to the 2 × 2 CFA repeat).
309
+ */
310
+ region?: {
311
+ x: number;
312
+ y: number;
313
+ width: number;
314
+ height: number;
315
+ frameWidth: number;
316
+ frameHeight: number;
317
+ nativeRect: {
318
+ x: number;
319
+ y: number;
320
+ width: number;
321
+ height: number;
322
+ };
323
+ };
257
324
  /** The complete underlying request. */
258
325
  request: {
259
326
  environmentRaw: NativeEnvironmentRawInput;
@@ -301,6 +368,24 @@ export interface SimulateCaptureResult {
301
368
  /** Physical size of the framed scene plane, metres. */
302
369
  framedWidthM: number;
303
370
  framedHeightM: number;
371
+ /**
372
+ * 2.3, present with `chartSize`: the chart's physical size and surround, the fraction of the frame width and
373
+ * height it covers (above 1 when it is larger than the frame and cropped), the thin-lens magnification
374
+ * v/d (image distance over subject distance, the scale the facade's framing uses) and the chart's size on the
375
+ * sensor in millimetres and output pixels.
376
+ */
377
+ chart?: {
378
+ widthM: number;
379
+ heightM: number;
380
+ surroundReflectance: number;
381
+ frameWidthFraction: number;
382
+ frameHeightFraction: number;
383
+ magnification: number;
384
+ imageWidthMm: number;
385
+ imageHeightMm: number;
386
+ imageWidthPixels: number;
387
+ imageHeightPixels: number;
388
+ };
304
389
  /**
305
390
  * SHA-256 of the canonical scene description, recorded as the capture source digest. Caller spectra (a
306
391
  * `spectrum` or `daylight` illuminant, chart reflectance spectra) are part of the description: tabulated
@@ -366,5 +451,67 @@ export declare const SIMULATE_CAPTURE_DEFAULT_ILLUMINANCE_LUX: number;
366
451
  * underlying request/plan, provenance and every assumption made. See docs/QUICK_START.md.
367
452
  */
368
453
  export declare function simulateCapture(options: SimulateCaptureOptions): Promise<SimulateCaptureResult>;
454
+ /**
455
+ * The ideal reference of a capture request (2.3): the same scene, framing, chart size, output size, region and pixel
456
+ * grid as `simulateCapture(options)` would use, rendered with no camera effects (no lens blur, diffraction, defocus,
457
+ * distortion, vignetting, anti-aliasing filter, mosaic or demosaic, noise, dark signal or motion), at the capture's
458
+ * own exposure and developed with its white balance, colour matrices, tone curve and encoding (the
459
+ * `reference.exposure` assumption). Deterministic and cheap: no RAW is simulated. Formats srgb-8, srgb-16 and png.
460
+ * The result is labelled `kind: "ideal-reference"`; it is not a capture.
461
+ * @see docs/QUICK_START.md, "Ideal reference".
462
+ */
463
+ export declare function simulateIdealReference(options: SimulateCaptureOptions): Promise<IdealReferenceResult>;
464
+ /** Result of {@link simulateIdealReference}: an ideal reference image, not a capture (no RAW, plan or request). */
465
+ export interface IdealReferenceResult {
466
+ kind: "ideal-reference";
467
+ /** Human-readable label for a user interface. */
468
+ label: string;
469
+ facadeVersion: typeof SIMULATE_CAPTURE_FACADE_VERSION;
470
+ engineApiVersion: string;
471
+ image: {
472
+ width: number;
473
+ height: number;
474
+ format: SimulateCaptureOutputFormat;
475
+ samples: Uint8Array | Uint16Array;
476
+ png?: Uint8Array;
477
+ colorEncoding?: SimulateCaptureColorEncoding;
478
+ };
479
+ /** The resolved exposure of the capture this reference matches. */
480
+ exposure: {
481
+ mode: SimulateCaptureExposureMode;
482
+ settings: {
483
+ fNumber: number;
484
+ shutterSeconds: number;
485
+ iso: number;
486
+ };
487
+ ev100: number;
488
+ };
489
+ scene: SimulateCaptureResult["scene"];
490
+ region?: {
491
+ x: number;
492
+ y: number;
493
+ width: number;
494
+ height: number;
495
+ frameWidth: number;
496
+ frameHeight: number;
497
+ };
498
+ diagnostics: {
499
+ sampleCount: number;
500
+ timingsMs: {
501
+ reference: number;
502
+ total: number;
503
+ };
504
+ };
505
+ provenance: {
506
+ scientificStatus: "approximation";
507
+ cameraPresetId: string;
508
+ cameraPresetVersion: string;
509
+ evidence: readonly EvidenceProvenance[];
510
+ composedContracts: readonly string[];
511
+ limitations: readonly string[];
512
+ };
513
+ /** The capture request's assumptions, then `reference.kind`, `reference.excludes`, `reference.exposure` and `reference.sampling`. */
514
+ assumptions: readonly SimulateCaptureAssumption[];
515
+ }
369
516
  /** Chart preset ids accepted by `simulateCapture({ scene: { preset } })`. */
370
- export declare const SIMULATE_CAPTURE_CHART_PRESETS: readonly ("uniform" | "patches" | "slanted-edge" | "siemens-star" | "step-wedge" | "grey-ramp" | "checkerboard" | "point-grid")[];
517
+ export declare const SIMULATE_CAPTURE_CHART_PRESETS: readonly ("composite" | "uniform" | "patches" | "slanted-edge" | "siemens-star" | "step-wedge" | "grey-ramp" | "checkerboard" | "point-grid" | "dead-leaves" | "bar-groups" | "hyperbolic-wedge" | "zone-plate" | "slanted-squares" | "line-grid" | "fiducial")[];