@photivra/engine 2.20.0 → 2.22.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 +295 -1
- package/CITATION.cff +1 -1
- package/README.md +7 -6
- package/SECURITY.md +1 -1
- package/THIRD_PARTY.md +18 -0
- package/dist/capture/c2pa-embed.d.ts +116 -0
- package/dist/capture/c2pa-embed.js +493 -0
- package/dist/capture/c2pa-embed.js.map +1 -0
- package/dist/capture/dng-import.d.ts +73 -8
- package/dist/capture/dng-import.js +315 -80
- package/dist/capture/dng-import.js.map +1 -1
- package/dist/capture/dng-lens-correction-opcodes.d.ts +2 -2
- package/dist/capture/dng-lens-correction-opcodes.js +2 -2
- package/dist/capture/dng-lens-correction-opcodes.js.map +1 -1
- package/dist/capture/dng-opcodes.d.ts +96 -0
- package/dist/capture/dng-opcodes.js +391 -0
- package/dist/capture/dng-opcodes.js.map +1 -0
- package/dist/capture/dng-profile-maps.d.ts +99 -0
- package/dist/capture/dng-profile-maps.js +381 -0
- package/dist/capture/dng-profile-maps.js.map +1 -0
- package/dist/capture/dng-stage-image.d.ts +23 -0
- package/dist/capture/dng-stage-image.js +65 -0
- package/dist/capture/dng-stage-image.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/jpeg-xl-tiles.d.ts +22 -0
- package/dist/capture/jpeg-xl-tiles.js +151 -0
- package/dist/capture/jpeg-xl-tiles.js.map +1 -0
- package/dist/capture/lossy-jpeg.d.ts +17 -0
- package/dist/capture/lossy-jpeg.js +369 -0
- package/dist/capture/lossy-jpeg.js.map +1 -0
- package/dist/capture/native-environment-lean.d.ts +2 -1
- package/dist/capture/native-environment-lean.js +41 -73
- 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-development.d.ts +2 -1
- package/dist/capture/native-raw-development.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 +12 -3
- package/dist/capture/sensor-raw-producer.js.map +1 -1
- package/dist/color/neighbor-highlight-reconstruction.d.ts +66 -0
- package/dist/color/neighbor-highlight-reconstruction.js +234 -0
- package/dist/color/neighbor-highlight-reconstruction.js.map +1 -0
- package/dist/color/sensor-color-development.d.ts +5 -0
- package/dist/color/sensor-color-development.js +7 -1
- package/dist/color/sensor-color-development.js.map +1 -1
- package/dist/color/spectral-spikiness.d.ts +11 -0
- package/dist/color/spectral-spikiness.js +23 -0
- package/dist/color/spectral-spikiness.js.map +1 -0
- package/dist/core/execution-error.d.ts +21 -0
- package/dist/core/execution-error.js +12 -0
- package/dist/core/execution-error.js.map +1 -0
- 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 +3 -2
- package/dist/equipment/generic-lens-catalogue.js +18 -5
- 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 +16 -11
- package/dist/equipment/generic-tier-assets.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 +28 -3
- package/dist/facade/catalogue-lens-signal.js +83 -78
- 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/diffraction-provider.d.ts +1 -1
- package/dist/facade/diffraction-provider.js +4 -4
- package/dist/facade/diffraction-provider.js.map +1 -1
- package/dist/facade/display-view-gpu-session.js +39 -5
- package/dist/facade/display-view-gpu-session.js.map +1 -1
- package/dist/facade/display-view-gpu.d.ts +19 -6
- package/dist/facade/display-view-gpu.js.map +1 -1
- package/dist/facade/display-view-lens-signal.js +25 -23
- package/dist/facade/display-view-lens-signal.js.map +1 -1
- package/dist/facade/display-view-normal.d.ts +15 -0
- package/dist/facade/display-view-normal.js +44 -0
- package/dist/facade/display-view-normal.js.map +1 -0
- package/dist/facade/display-view-rendering.d.ts +97 -0
- package/dist/facade/display-view-rendering.js +598 -0
- package/dist/facade/display-view-rendering.js.map +1 -0
- package/dist/facade/display-view.d.ts +37 -65
- package/dist/facade/display-view.js +152 -499
- 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 +3 -3
- 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 +1 -1
- package/dist/facade/fast-methods.js +46 -9
- package/dist/facade/fast-methods.js.map +1 -1
- package/dist/facade/generic-lens-capture.d.ts +3 -3
- package/dist/facade/generic-lens-capture.js +3 -3
- 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 +384 -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/on-demand-kits.d.ts +14 -0
- package/dist/facade/on-demand-kits.js +36 -0
- package/dist/facade/on-demand-kits.js.map +1 -0
- package/dist/facade/opt-in-kit.d.ts +9 -0
- package/dist/facade/opt-in-kit.js +11 -0
- package/dist/facade/opt-in-kit.js.map +1 -0
- package/dist/facade/quality-kit.d.ts +21 -0
- package/dist/facade/quality-kit.js +23 -0
- package/dist/facade/quality-kit.js.map +1 -0
- package/dist/facade/quality-paths.d.ts +22 -0
- package/dist/facade/quality-paths.js +44 -0
- package/dist/facade/quality-paths.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 +145 -4
- package/dist/facade/scene-radiance.js +50 -13
- package/dist/facade/scene-radiance.js.map +1 -1
- package/dist/facade/simulate-capture.d.ts +68 -20
- package/dist/facade/simulate-capture.js +399 -146
- package/dist/facade/simulate-capture.js.map +1 -1
- package/dist/facade/simulate-display-view.d.ts +10 -12
- package/dist/facade/simulate-display-view.js +70 -53
- 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-gpu-renderer.d.ts +43 -0
- package/dist/gpu/display-view-gpu-renderer.js +134 -0
- package/dist/gpu/display-view-gpu-renderer.js.map +1 -0
- package/dist/gpu/display-view-image-material-module.d.ts +87 -0
- package/dist/gpu/display-view-image-material-module.js +361 -0
- package/dist/gpu/display-view-image-material-module.js.map +1 -0
- package/dist/gpu/display-view-image-quality.d.ts +87 -0
- package/dist/gpu/display-view-image-quality.js +625 -0
- package/dist/gpu/display-view-image-quality.js.map +1 -0
- package/dist/gpu/display-view-quality-gpu.d.ts +80 -65
- package/dist/gpu/display-view-quality-gpu.js +187 -445
- package/dist/gpu/display-view-quality-gpu.js.map +1 -1
- package/dist/gpu/display-view-speed-gpu.d.ts +67 -19
- package/dist/gpu/display-view-speed-gpu.js +181 -105
- package/dist/gpu/display-view-speed-gpu.js.map +1 -1
- package/dist/gpu/image-kernel-accelerator.js +3 -0
- package/dist/gpu/image-kernel-accelerator.js.map +1 -1
- package/dist/gpu/image-kernel-execution.d.ts +2 -13
- package/dist/gpu/image-kernel-execution.js +2 -10
- package/dist/gpu/image-kernel-execution.js.map +1 -1
- package/dist/gpu/wgsl-display-view-coupled-stub.d.ts +8 -0
- package/dist/gpu/wgsl-display-view-coupled-stub.js +21 -0
- package/dist/gpu/wgsl-display-view-coupled-stub.js.map +1 -0
- package/dist/gpu/wgsl-display-view-coupled.d.ts +88 -0
- package/dist/gpu/wgsl-display-view-coupled.js +353 -0
- package/dist/gpu/wgsl-display-view-coupled.js.map +1 -0
- package/dist/gpu/wgsl-display-view-quality-kernel.d.ts +33 -24
- package/dist/gpu/wgsl-display-view-quality-kernel.js +166 -146
- package/dist/gpu/wgsl-display-view-quality-kernel.js.map +1 -1
- package/dist/gpu/wgsl-display-view-speed-kernel.d.ts +19 -44
- package/dist/gpu/wgsl-display-view-speed-kernel.js +116 -18
- 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 +22 -6
- package/dist/index.js +16 -2
- 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/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.js +54 -46
- 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/output/camera-channel-response.d.ts +50 -0
- package/dist/output/camera-channel-response.js +69 -0
- package/dist/output/camera-channel-response.js.map +1 -0
- package/dist/output/developed-lens-corrections.d.ts +19 -5
- package/dist/output/developed-lens-corrections.js +28 -9
- package/dist/output/developed-lens-corrections.js.map +1 -1
- package/dist/output/generic-lens-corrections.d.ts +41 -5
- package/dist/output/generic-lens-corrections.js +52 -8
- package/dist/output/generic-lens-corrections.js.map +1 -1
- package/dist/output/native-capture-sdr.js +5 -2
- package/dist/output/native-capture-sdr.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/sdr-rendering.d.ts +18 -1
- package/dist/output/sdr-rendering.js +39 -2
- package/dist/output/sdr-rendering.js.map +1 -1
- 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/native-sensor-report.d.ts +10 -0
- package/dist/sensor/native-sensor-report.js +16 -0
- package/dist/sensor/native-sensor-report.js.map +1 -0
- package/dist/sensor/sensor-characteristics.d.ts +91 -13
- package/dist/sensor/sensor-characteristics.js +30 -15
- package/dist/sensor/sensor-characteristics.js.map +1 -1
- package/docs/AGENT_GUIDE.md +1 -0
- package/docs/API_REFERENCE.md +214 -4
- package/docs/QUICK_START.md +162 -8
- package/docs/USAGE.md +195 -22
- package/docs/api/capture-c2pa-embed.md +177 -0
- package/docs/api/capture-dng-import.md +86 -10
- package/docs/api/capture-dng-opcodes.md +93 -0
- package/docs/api/capture-dng-profile-maps.md +141 -0
- package/docs/api/capture-dng-stage-image.md +43 -0
- package/docs/api/capture-jpeg-xl-tiles.md +33 -0
- package/docs/api/capture-lossy-jpeg.md +41 -0
- package/docs/api/capture-native-raw-development.md +2 -1
- package/docs/api/core-execution-error.md +43 -0
- package/docs/api/core-version.md +1 -1
- package/docs/api/equipment-generic-lens-catalogue.md +10 -5
- package/docs/api/equipment-sensor-profile-body.md +64 -0
- package/docs/api/equipment-sensor-profiles.md +86 -0
- package/docs/api/exports.json +460 -5
- package/docs/api/facade-display-view-gpu.md +5 -2
- package/docs/api/facade-display-view.md +11 -15
- package/docs/api/facade-exposure-build-up.md +105 -0
- package/docs/api/facade-fast-methods.md +47 -10
- package/docs/api/facade-image-plane-enable.md +16 -0
- package/docs/api/facade-mixed-illumination.md +67 -0
- package/docs/api/facade-quality-paths.md +24 -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 +48 -11
- package/docs/api/facade-simulate-display-view.md +10 -12
- package/docs/api/gpu-image-kernel-execution.md +0 -36
- package/docs/api/motion-subject-motion.md +23 -0
- package/docs/api/optics-generic-lens-lateral-color.md +79 -0
- package/docs/api/output-camera-channel-response.md +55 -0
- package/docs/api/output-developed-lens-corrections.md +10 -1
- package/docs/api/output-generic-lens-corrections.md +40 -4
- package/docs/api/output-print-plan.md +35 -1
- package/docs/api/output-sdr-rendering.md +6 -1
- package/docs/api/sensor-sensor-characteristics.md +54 -2
- package/llms.txt +3 -0
- package/package.json +6 -5
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: Apache-2.0
|
|
2
2
|
/**
|
|
3
3
|
* WGSL kernels of the display view's Quality path on the GPU (#479): the exact area mean with diffraction kernels, the
|
|
4
|
-
* anti-aliasing filter's spots
|
|
4
|
+
* anti-aliasing filter's spots and the AHD candidates, in three passes over one band of display
|
|
5
5
|
* rows (docs/WEBGPU.md, "Display view (Quality) on the GPU"; the float64 reference is `renderDisplayView` with
|
|
6
6
|
* `createDisplayViewExpectedSignal`, facade/display-view.ts and facade/expected-signal.ts):
|
|
7
7
|
*
|
|
@@ -21,9 +21,7 @@
|
|
|
21
21
|
* camera-channel covariance), white balance and the highlight clip, the colour matrix, the tone curve and the clip to
|
|
22
22
|
* [0, 1] with the skewness term, the candidates' average, the Stein covariance with the closed-form B_c, the independent
|
|
23
23
|
* residual, AHD's choice variance ¼·Var(H − V), the flag for AHD's choice on the noise-free mosaic, which the reference takes and
|
|
24
|
-
* the kernel does not (#457)
|
|
25
|
-
* states of a table the host uploaded (the states themselves are computed on the host, #447; the kernel records every
|
|
26
|
-
* grid key it needs in a bitmap and flags a display pixel whose state the table lacks).
|
|
24
|
+
* the kernel does not (#457). 2.22.0: there is no low-signal correction (docs/DISPLAY_VIEW.md, "AHD at low signal").
|
|
27
25
|
*
|
|
28
26
|
* **Highlights (#533).** The site pass records whether each site is certainly below white, certainly at or above it, or
|
|
29
27
|
* undecided (`clip_state`, from the site's mean and variance and their running bounds: certain only beyond twice the reference's
|
|
@@ -50,10 +48,13 @@
|
|
|
50
48
|
* trigonometric built-in).
|
|
51
49
|
*/
|
|
52
50
|
import { DISPLAY_VIEW_CLIP_MEAN_U, DISPLAY_VIEW_CLIP_VARIANCE_U, DISPLAY_VIEW_REINHARD_MEAN_U, DISPLAY_VIEW_REINHARD_VARIANCE_U } from "./wgsl-display-view-speed-kernel.js";
|
|
53
|
-
import {
|
|
51
|
+
import { EXACT_SUM_WGSL } from "./wgsl-exact-sum.js";
|
|
52
|
+
import { DISPLAY_VIEW_COUPLED_STUB_WGSL } from "./wgsl-display-view-coupled-stub.js";
|
|
54
53
|
export const DISPLAY_VIEW_QUALITY_WORKGROUP_SIZE = 64;
|
|
55
54
|
/** Largest footprint per axis (real pixels), as the Speed kernel. */
|
|
56
55
|
export const DISPLAY_VIEW_QUALITY_MAXIMUM_PIXELS_PER_AXIS = 6;
|
|
56
|
+
/** Most spectral nodes the site passes integrate per site (2.21.0: the per-node partials are private arrays of this length). */
|
|
57
|
+
export const DISPLAY_VIEW_QUALITY_MAXIMUM_NODES = 96;
|
|
57
58
|
/** Uniform parameter words (see `Params`): 56 words, 224 bytes. */
|
|
58
59
|
export const DISPLAY_VIEW_QUALITY_PARAM_WORDS = 56;
|
|
59
60
|
/** Words per lattice-group record: lx0, ly0, lw, lh, lbase, first tap (the blocked site pass, #492), cu (f32), cv (f32). */
|
|
@@ -89,12 +90,7 @@ export const DISPLAY_VIEW_QUALITY_FLAG = /* @__PURE__ */ Object.freeze({
|
|
|
89
90
|
materialUncertain: 1,
|
|
90
91
|
/** A site the pixel read lies outside the band's site window (a host geometry error; recompute). */
|
|
91
92
|
siteOutsideWindow: 2,
|
|
92
|
-
|
|
93
|
-
stateMissing: 4,
|
|
94
|
-
/** A sample's pixel variance lies within its bound of the correction threshold (recompute). */
|
|
95
|
-
thresholdTie: 8,
|
|
96
|
-
/** Informational: the pixel's expected value includes the low-signal correction. */
|
|
97
|
-
corrected: 16,
|
|
93
|
+
// Bits 4, 8 and 16 (the low-signal correction's state, threshold and applied flags) are unused since 2.22.0.
|
|
98
94
|
/**
|
|
99
95
|
* #457: the reference takes AHD's choice on the noise-free mosaic (one candidate, or their average on a tie), which the kernel
|
|
100
96
|
* does not compute; it renders the average. The pixel is flagged (recompute) when Σ_j a_j·½|h(H) − h(V)| of some component
|
|
@@ -104,7 +100,7 @@ export const DISPLAY_VIEW_QUALITY_FLAG = /* @__PURE__ */ Object.freeze({
|
|
|
104
100
|
/** #533: a real pixel's saturation is undecided (the host computes the display pixel's count with the reference; its samples stay). */
|
|
105
101
|
highlightUndecided: 64,
|
|
106
102
|
/** The bits that require the host's recomputation. */
|
|
107
|
-
recompute:
|
|
103
|
+
recompute: 35
|
|
108
104
|
});
|
|
109
105
|
/** #533: flag words per display pixel: the flags, then the 36-bit mask of saturated real pixels. */
|
|
110
106
|
export const DISPLAY_VIEW_QUALITY_FLAG_WORDS = 3;
|
|
@@ -114,8 +110,6 @@ export const DISPLAY_VIEW_QUALITY_FLAG_WORDS = 3;
|
|
|
114
110
|
* design tolerance, not a measurement: 2^-10 σ is a tenth of the 0.01 σ to which the float32 tests hold the GPU to the reference.
|
|
115
111
|
*/
|
|
116
112
|
export const DISPLAY_VIEW_QUALITY_CHOICE_SIGMA = 2 ** -10;
|
|
117
|
-
/** Words of the grid-key bitmap: one bit per grid key (AHD_KEY_LEVELS³ keys). */
|
|
118
|
-
export const DISPLAY_VIEW_QUALITY_BITMAP_WORDS = Math.ceil(AHD_KEY_LEVELS ** 3 / 32);
|
|
119
113
|
/**
|
|
120
114
|
* A site whose uncertain lattice points (the material module's flag) could move its electrons by more than this fraction of
|
|
121
115
|
* their value is flagged for host recomputation; a smaller uncertainty enters the site's bound instead (the tap weights times
|
|
@@ -133,7 +127,7 @@ const literal = (value) => {
|
|
|
133
127
|
return /[.e]/u.test(text) ? text : `${text}.0`;
|
|
134
128
|
};
|
|
135
129
|
/** The parameter struct and the bound helpers shared by the three passes. */
|
|
136
|
-
const
|
|
130
|
+
export const DISPLAY_VIEW_QUALITY_COMMON_WGSL = /* wgsl */ `
|
|
137
131
|
const E: f32 = ${E_LITERAL};
|
|
138
132
|
const SLACK: f32 = 1e-14;
|
|
139
133
|
const CLIP_REACH: f32 = 8.5;
|
|
@@ -153,16 +147,16 @@ count: u32, row0: u32, region_w: u32, region_x: u32,
|
|
|
153
147
|
region_y: u32, margin: u32, native_w: u32, native_h: u32,
|
|
154
148
|
columns: u32, tone: u32, reach: u32, candidates: u32,
|
|
155
149
|
site_x0: i32, site_y0: i32, site_w: u32, site_h: u32,
|
|
156
|
-
|
|
150
|
+
unused_16: u32, unused_17: u32, taps: u32, groups: u32,
|
|
157
151
|
lattice_total: u32, gain_at_clip0: u32, gain_at_clip1: u32, gain_at_clip2: u32,
|
|
158
152
|
k0: f32, k1: f32, k2: f32, reach2: f32,
|
|
159
153
|
dark0: f32, dark1: f32, dark2: f32, clip_level: f32,
|
|
160
|
-
c0_0: f32, c0_1: f32, c0_2: f32,
|
|
154
|
+
c0_0: f32, c0_1: f32, c0_2: f32, unused_35: f32,
|
|
161
155
|
g0: f32, g1: f32, g2: f32, scale_u: f32,
|
|
162
156
|
m00: f32, m01: f32, m02: f32, m10: f32,
|
|
163
157
|
m11: f32, m12: f32, m20: f32, m21: f32,
|
|
164
158
|
m22: f32, scale_v: f32, site_gamma: f32, site_first: u32,
|
|
165
|
-
site_tiny: f32,
|
|
159
|
+
site_tiny: f32, nodes: u32, pad_g: f32, pad_h: f32,
|
|
166
160
|
};
|
|
167
161
|
@group(0) @binding(0) var<uniform> params: Params;
|
|
168
162
|
|
|
@@ -344,7 +338,7 @@ return out;
|
|
|
344
338
|
* records hold each group's lattice window (lx0, ly0, lw, lh), its first index in the lattice buffer and the point constants
|
|
345
339
|
* c_u = 0.5 + f_x − W/2 and c_v = 0.5 + f_y − H/2 (exact in float32, checked by the host).
|
|
346
340
|
*/
|
|
347
|
-
export const DISPLAY_VIEW_QUALITY_LATTICE_WGSL = /* wgsl */ `${
|
|
341
|
+
export const DISPLAY_VIEW_QUALITY_LATTICE_WGSL = /* wgsl */ `${DISPLAY_VIEW_QUALITY_COMMON_WGSL}
|
|
348
342
|
@group(0) @binding(1) var<storage, read> groups: array<u32>;
|
|
349
343
|
@group(0) @binding(2) var<storage, read_write> lattice_out: array<u32>;
|
|
350
344
|
@compute @workgroup_size(${DISPLAY_VIEW_QUALITY_WORKGROUP_SIZE})
|
|
@@ -371,7 +365,7 @@ lattice_out[i] = m | select(0u, 0x80000000u, material_uncertain);
|
|
|
371
365
|
* The end of pass 2, shared by both site passes: from the site's electrons e and their absolute bound de, the readout moments
|
|
372
366
|
* (mean k·e, variance k²e + c₀, third cumulant k³e), the clip at the white level and their bounds, written to site i.
|
|
373
367
|
*/
|
|
374
|
-
const
|
|
368
|
+
export const DISPLAY_VIEW_QUALITY_SITE_TAIL_WGSL = /* wgsl */ `
|
|
375
369
|
fn write_site(i: u32, c: u32, e: f32, de: f32, flag: u32) {
|
|
376
370
|
let kc = k_of(c);
|
|
377
371
|
let mean = kc * e;
|
|
@@ -404,16 +398,38 @@ const siteBindingsWgsl = (tapRecords) => /* wgsl */ `
|
|
|
404
398
|
@group(0) @binding(4) var<storage, read> lattice: array<u32>;
|
|
405
399
|
@group(0) @binding(5) var<storage, read_write> sites: array<f32>;
|
|
406
400
|
@group(0) @binding(6) var<storage, read> spread: array<f32>;
|
|
401
|
+
${EXACT_SUM_WGSL}
|
|
402
|
+
alias Nodes = array<f32, ${DISPLAY_VIEW_QUALITY_MAXIMUM_NODES}>;
|
|
403
|
+
fn add_tap(p: ptr<function, Nodes>, c: u32, t: u32, m: u32) {
|
|
404
|
+
let N = params.nodes;
|
|
405
|
+
for (var n = 0u; n < N; n = n + 1u) { (*p)[n] = (*p)[n] + table[(c * params.taps + t) * N + n] * table[(3u * params.taps + m) * N + n]; }
|
|
406
|
+
}
|
|
407
|
+
fn add_nodes(p: ptr<function, Nodes>, q: ptr<function, Nodes>) { for (var n = 0u; n < params.nodes; n = n + 1u) { (*p)[n] = (*p)[n] + (*q)[n]; (*q)[n] = 0.0; } }
|
|
408
|
+
fn node_total(p: ptr<function, Nodes>, dark: f32) -> f32 {
|
|
409
|
+
var anchor = exact_exponent(dark);
|
|
410
|
+
for (var k = 0u; k < params.nodes; k = k + 1u) { if ((*p)[k] > 0.0) { anchor = max(anchor, exact_exponent((*p)[k])); } }
|
|
411
|
+
var sum: ExactSum;
|
|
412
|
+
sum.anchor = anchor;
|
|
413
|
+
for (var k = 0u; k < params.nodes; k = k + 1u) { exact_add(&sum, (*p)[k]); }
|
|
414
|
+
exact_add(&sum, dark);
|
|
415
|
+
return exact_round(&sum);
|
|
416
|
+
}
|
|
407
417
|
`;
|
|
408
418
|
/**
|
|
409
419
|
* Pass 2: the expected electrons, readout moments and white clip of every native site of the band's window, with their bounds.
|
|
410
|
-
*
|
|
411
|
-
*
|
|
420
|
+
* 2.21.0 (signals integrated from the material spectrum per site): the site's electrons are Σ_t Σ_n C_c(t, n)·L_{m_t}(λ_n) +
|
|
421
|
+
* dark_c, from the channel's per-node kernel values and the spectrum of the material each tap reads (`table`: C at
|
|
422
|
+
* (c·T + t)·N + n, the spectra from 3·T·N), accumulated per node over the taps, then the node partials and the dark electrons
|
|
423
|
+
* summed in integer arithmetic and rounded once (EXACT_SUM_WGSL). Every term is non-negative and carries two host roundings (E/2
|
|
424
|
+
* each), its product (E) and at most T − 1 additions, then the final rounding (E), and the dark electrons their host rounding
|
|
425
|
+
* (E/2), so the sum carries at most (T + 2.5)·E, inside (T + 3)·E
|
|
426
|
+
* (`params.site_gamma`),
|
|
427
|
+
* plus `params.site_tiny`, the host's absolute bound on what a device that flushes below the float32 normal range can drop. An uncertain lattice point adds the tap's value spread
|
|
412
428
|
* over the materials (`spread`, host float64) to the site's uncertainty, which enters its bounds, or flags the site when it
|
|
413
429
|
* exceeds UNCERTAINTY_LIMIT of the electrons. One dispatch covers the `params.count` sites from `params.site_first` (#492: the
|
|
414
430
|
* host splits a band's sites over several dispatches so that no dispatch gathers more than its tap budget).
|
|
415
431
|
*/
|
|
416
|
-
export const DISPLAY_VIEW_QUALITY_SITES_WGSL = /* wgsl */ `${
|
|
432
|
+
export const DISPLAY_VIEW_QUALITY_SITES_WGSL = /* wgsl */ `${DISPLAY_VIEW_QUALITY_COMMON_WGSL}${siteBindingsWgsl(true)}${DISPLAY_VIEW_QUALITY_SITE_TAIL_WGSL}
|
|
417
433
|
@compute @workgroup_size(${DISPLAY_VIEW_QUALITY_WORKGROUP_SIZE})
|
|
418
434
|
fn main(@builtin(global_invocation_id) gid: vec3<u32>, @builtin(num_workgroups) wg: vec3<u32>) {
|
|
419
435
|
let local = gid.x + gid.y * wg.x * ${DISPLAY_VIEW_QUALITY_WORKGROUP_SIZE}u;
|
|
@@ -424,44 +440,42 @@ let jj = i / params.site_w;
|
|
|
424
440
|
let x = params.site_x0 + i32(ii);
|
|
425
441
|
let y = params.site_y0 + i32(jj);
|
|
426
442
|
let c = channel_of(x, y);
|
|
427
|
-
var sum = 0.0;
|
|
428
443
|
var uncertainty = 0.0;
|
|
429
444
|
let T = params.taps;
|
|
445
|
+
var partial: Nodes;
|
|
430
446
|
for (var t = 0u; t < T; t = t + 1u) {
|
|
431
447
|
let tb = t * TAP;
|
|
432
448
|
let g = taps[tb] * GROUP;
|
|
433
449
|
let index = groups[g + 4u] + (jj + taps[tb + 2u]) * groups[g + 2u] + ii + taps[tb + 1u];
|
|
434
450
|
let raw = lattice[index];
|
|
435
451
|
if ((raw >> 31u) != 0u) { uncertainty = uncertainty + spread[c * T + t]; }
|
|
436
|
-
|
|
452
|
+
add_tap(&partial, c, t, raw & 0x7fffffffu);
|
|
437
453
|
}
|
|
438
|
-
let e =
|
|
454
|
+
let e = node_total(&partial, dark_of(c));
|
|
439
455
|
let flag = select(0u, 1u, uncertainty > UNCERTAINTY_LIMIT * e);
|
|
440
|
-
let de = params.site_gamma * e + uncertainty;
|
|
456
|
+
let de = params.site_gamma * e + uncertainty + params.site_tiny;
|
|
441
457
|
write_site(i, c, e, de, flag);
|
|
442
458
|
}
|
|
443
459
|
`;
|
|
444
460
|
/**
|
|
445
|
-
* Pass 2 with the defocus disc (#492): the same site electrons
|
|
461
|
+
* Pass 2 with the defocus disc (#492): the same site electrons, summed in blocks.
|
|
446
462
|
*
|
|
447
|
-
* - **
|
|
448
|
-
*
|
|
449
|
-
* `materials` holds per material its row (0 for neutral, 1 + s for spectral material s) and its reflectance as float32 bits
|
|
450
|
-
* (1 for a spectral material, an exact product). A scene of thousands of neutral materials (#491's composite: 4 143) then
|
|
451
|
-
* needs 3·T values instead of 3·T per material.
|
|
463
|
+
* - **Spectral table.** The pass reads the tap-list pass's table (2.21.0): the channel's per-node kernel values C_c(t, n) and each
|
|
464
|
+
* material's spectrum, so the signal of each tap is integrated from its material's spectrum when the site is read.
|
|
452
465
|
* - **Blocked sum.** Every group's taps form a dense cw × ch rectangle (the combined kernel's window, row-major from the group's
|
|
453
|
-
* first tap, `groups[g + 5]`), so a site sums each row of a group into a row partial, the rows into a group partial
|
|
454
|
-
* groups into the total. No tap records are read: the tap's lattice offset
|
|
466
|
+
* first tap, `groups[g + 5]`), so a site sums each row of a group into a row partial per node, the rows into a group partial
|
|
467
|
+
* and the groups into the total, then the nodes in integer arithmetic. No tap records are read: the tap's lattice offset
|
|
468
|
+
* within its group is its (dx, dy).
|
|
455
469
|
*
|
|
456
|
-
* Every term is non-negative and carries two host roundings (u each, u = E/2: the
|
|
457
|
-
* (E) and at most cw + ch + G additions,
|
|
458
|
-
*
|
|
459
|
-
*
|
|
460
|
-
*
|
|
470
|
+
* Every term is non-negative and carries two host roundings (u each, u = E/2: the kernel value and the spectrum), one product
|
|
471
|
+
* (E) and at most cw − 1 + ch − 1 + G − 1 inexact additions, then the integer sum of the node partials and the dark electrons,
|
|
472
|
+
* rounded once (E), and the dark electrons' host rounding (E/2), so the electrons carry at most (cw_max + ch_max + G + 0.5)·E, inside (cw_max + ch_max + G + 3)·E (`params.site_gamma`;
|
|
473
|
+
* recursive summation of the up to 4·(2·96 + 2)² = 150 544 taps of a combined radius of 96 would carry (T + 3)·E ≈ 1.8 %
|
|
474
|
+
* instead). The uncertainty, summed the same way, is scaled by 1 + site_gamma, and `params.site_tiny` (host float64, rounded up)
|
|
475
|
+
* bounds what a device that flushes results below the float32 normal range can drop (the tap-list pass adds it too).
|
|
461
476
|
*/
|
|
462
|
-
export const DISPLAY_VIEW_QUALITY_SITES_BLOCKED_WGSL = /* wgsl */ `${
|
|
463
|
-
|
|
464
|
-
${SITE_TAIL_WGSL}
|
|
477
|
+
export const DISPLAY_VIEW_QUALITY_SITES_BLOCKED_WGSL = /* wgsl */ `${DISPLAY_VIEW_QUALITY_COMMON_WGSL}${siteBindingsWgsl(false)}
|
|
478
|
+
${DISPLAY_VIEW_QUALITY_SITE_TAIL_WGSL}
|
|
465
479
|
@compute @workgroup_size(${DISPLAY_VIEW_QUALITY_WORKGROUP_SIZE})
|
|
466
480
|
fn main(@builtin(global_invocation_id) gid: vec3<u32>, @builtin(num_workgroups) wg: vec3<u32>) {
|
|
467
481
|
let local = gid.x + gid.y * wg.x * ${DISPLAY_VIEW_QUALITY_WORKGROUP_SIZE}u;
|
|
@@ -473,7 +487,9 @@ let x = params.site_x0 + i32(ii);
|
|
|
473
487
|
let y = params.site_y0 + i32(jj);
|
|
474
488
|
let c = channel_of(x, y);
|
|
475
489
|
let T = params.taps;
|
|
476
|
-
var
|
|
490
|
+
var total: Nodes;
|
|
491
|
+
var group_sum: Nodes;
|
|
492
|
+
var row_sum: Nodes;
|
|
477
493
|
var uncertainty = 0.0;
|
|
478
494
|
for (var k = 0u; k < params.groups; k = k + 1u) {
|
|
479
495
|
let g = k * GROUP;
|
|
@@ -482,57 +498,50 @@ let cw = lw - params.site_w + 1u;
|
|
|
482
498
|
let ch = groups[g + 3u] - params.site_h + 1u;
|
|
483
499
|
let lattice0 = groups[g + 4u] + jj * lw + ii;
|
|
484
500
|
let tap0 = groups[g + 5u];
|
|
485
|
-
var group_sum = 0.0;
|
|
486
501
|
var group_uncertainty = 0.0;
|
|
487
502
|
for (var dy = 0u; dy < ch; dy = dy + 1u) {
|
|
488
503
|
let row = lattice0 + dy * lw;
|
|
489
504
|
let row_tap = tap0 + dy * cw;
|
|
490
|
-
var row_sum = 0.0;
|
|
491
505
|
var row_uncertainty = 0.0;
|
|
492
506
|
for (var dx = 0u; dx < cw; dx = dx + 1u) {
|
|
493
507
|
let raw = lattice[row + dx];
|
|
494
508
|
let t = row_tap + dx;
|
|
495
|
-
let m = 2u * (raw & 0x7fffffffu);
|
|
496
509
|
if ((raw >> 31u) != 0u) { row_uncertainty = row_uncertainty + spread[c * T + t]; }
|
|
497
|
-
row_sum
|
|
510
|
+
add_tap(&row_sum, c, t, raw & 0x7fffffffu);
|
|
498
511
|
}
|
|
499
|
-
group_sum
|
|
512
|
+
add_nodes(&group_sum, &row_sum);
|
|
500
513
|
group_uncertainty = group_uncertainty + row_uncertainty;
|
|
501
514
|
}
|
|
502
|
-
|
|
515
|
+
add_nodes(&total, &group_sum);
|
|
503
516
|
uncertainty = uncertainty + group_uncertainty;
|
|
504
517
|
}
|
|
505
|
-
let e =
|
|
518
|
+
let e = node_total(&total, dark_of(c));
|
|
506
519
|
let flag = select(0u, 1u, uncertainty > UNCERTAINTY_LIMIT * e);
|
|
507
520
|
let de = params.site_gamma * e + uncertainty * (1.0 + params.site_gamma) + params.site_tiny;
|
|
508
521
|
write_site(i, c, e, de, flag);
|
|
509
522
|
}
|
|
510
523
|
`;
|
|
511
524
|
/** Pass 3: the display pixels (see the module comment). */
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
const
|
|
525
|
+
/*
|
|
526
|
+
* 2.22.0: in the luminance branch the nested loops read the colour matrix rows from one local array (`mm`) instead of calling
|
|
527
|
+
* `m_of` (a `switch`): SwiftShader's compiler ended the GPU process on the `switch` inside those loops (after about 44 s). The
|
|
528
|
+
* values are the same (docs/WEBGPU.md, "Coupled rendering steps").
|
|
529
|
+
*/
|
|
530
|
+
export const DISPLAY_VIEW_QUALITY_PIXELS_BODY_WGSL = /* wgsl */ `${DISPLAY_VIEW_QUALITY_COMMON_WGSL}
|
|
518
531
|
const CAND_BASE: u32 = ${DISPLAY_VIEW_QUALITY_AUX.candidates}u;
|
|
519
532
|
const CAND_STRIDE: u32 = ${CANDIDATE_PHASE_STRIDE}u;
|
|
520
533
|
const FLAG_UNCERTAIN: u32 = ${DISPLAY_VIEW_QUALITY_FLAG.materialUncertain}u;
|
|
521
534
|
const FLAG_OUTSIDE: u32 = ${DISPLAY_VIEW_QUALITY_FLAG.siteOutsideWindow}u;
|
|
522
|
-
const FLAG_STATE: u32 = ${DISPLAY_VIEW_QUALITY_FLAG.stateMissing}u;
|
|
523
|
-
const FLAG_TIE: u32 = ${DISPLAY_VIEW_QUALITY_FLAG.thresholdTie}u;
|
|
524
|
-
const FLAG_CORRECTED: u32 = ${DISPLAY_VIEW_QUALITY_FLAG.corrected}u;
|
|
525
535
|
const FLAG_CHOICE: u32 = ${DISPLAY_VIEW_QUALITY_FLAG.ahdChoice}u;
|
|
526
536
|
const FLAG_HIGHLIGHT: u32 = ${DISPLAY_VIEW_QUALITY_FLAG.highlightUndecided}u;
|
|
527
537
|
const CHOICE_SIGMA: f32 = ${literal(DISPLAY_VIEW_QUALITY_CHOICE_SIGMA)};
|
|
528
538
|
@group(0) @binding(1) var<storage, read> aux: array<f32>;
|
|
529
539
|
@group(0) @binding(2) var<storage, read> geometry: array<f32>;
|
|
530
540
|
@group(0) @binding(3) var<storage, read> sites: array<f32>;
|
|
531
|
-
@group(0) @binding(4) var<storage,
|
|
532
|
-
@group(0) @binding(5) var<storage,
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
@group(0) @binding(8) var<storage, read_write> flags: array<u32>;
|
|
541
|
+
@group(0) @binding(4) var<storage, read_write> out: array<f32>;
|
|
542
|
+
@group(0) @binding(5) var<storage, read_write> flags: array<u32>;
|
|
543
|
+
|
|
544
|
+
fn cp_k(i: u32) -> f32 { return aux[${DISPLAY_VIEW_QUALITY_AUX.size}u + i]; }
|
|
536
545
|
|
|
537
546
|
var<private> pixel_flags: u32;
|
|
538
547
|
${REINHARD_WGSL}
|
|
@@ -549,66 +558,6 @@ return o;
|
|
|
549
558
|
}
|
|
550
559
|
|
|
551
560
|
fn clip_bits(o: u32) -> u32 { return (bitcast<u32>(sites[o + 6u]) >> 1u) & 3u; }
|
|
552
|
-
|
|
553
|
-
fn find_state(key: i32) -> u32 {
|
|
554
|
-
var lo = 0u; var hi = params.state_count;
|
|
555
|
-
while (lo < hi) {
|
|
556
|
-
let mid = (lo + hi) / 2u;
|
|
557
|
-
if (state_keys[mid] < key) { lo = mid + 1u; } else { hi = mid; }
|
|
558
|
-
}
|
|
559
|
-
if (lo < params.state_count && state_keys[lo] == key) { return lo; }
|
|
560
|
-
return params.state_count;
|
|
561
|
-
}
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
fn flat_correction(m0: vec2<f32>, m1: vec2<f32>, m2: vec2<f32>, corr: ptr<function, array<vec2<f32>, 3>>) {
|
|
566
|
-
var base: array<u32, 3>; var frac: array<f32, 3>; var dg: array<f32, 3>;
|
|
567
|
-
for (var i = 0u; i < 3u; i = i + 1u) {
|
|
568
|
-
var mi = m0; if (i == 1u) { mi = m1; } if (i == 2u) { mi = m2; }
|
|
569
|
-
let clamped = clamp(mi.x, KEY_FLOOR, 1.0);
|
|
570
|
-
let g = (log2(clamped) + KEY_OCTAVES) * KEY_STEPS;
|
|
571
|
-
let b = min(u32(max(floor(g), 0.0)), KEY_TOP);
|
|
572
|
-
base[i] = b; frac[i] = g - f32(b);
|
|
573
|
-
|
|
574
|
-
var slope = 0.0; if (mi.x > KEY_FLOOR && mi.x < 1.0) { slope = 1.4426950408889634 * mi.y / clamped; }
|
|
575
|
-
dg[i] = KEY_STEPS * (slope + 4.76837158203125e-7 + 36.0 * E) + 2.0 * E * (g + 1.0);
|
|
576
|
-
}
|
|
577
|
-
var values: array<f32, 24>;
|
|
578
|
-
var missing = false;
|
|
579
|
-
for (var corner = 0u; corner < 8u; corner = corner + 1u) {
|
|
580
|
-
let i0 = base[0] + (corner & 1u); let i1 = base[1] + ((corner >> 1u) & 1u); let i2 = base[2] + ((corner >> 2u) & 1u);
|
|
581
|
-
let key = i32((i0 * KEY_LEVELS + i1) * KEY_LEVELS + i2);
|
|
582
|
-
var weight = 1.0;
|
|
583
|
-
for (var i = 0u; i < 3u; i = i + 1u) { weight = weight * select(1.0 - frac[i], frac[i], ((corner >> i) & 1u) == 1u); }
|
|
584
|
-
if (weight == 0.0) { for (var c = 0u; c < 3u; c = c + 1u) { values[corner * 3u + c] = 0.0; } continue; }
|
|
585
|
-
atomicOr(&bitmap[u32(key) / 32u], 1u << (u32(key) % 32u));
|
|
586
|
-
let at = find_state(key);
|
|
587
|
-
if (at >= params.state_count) { missing = true; continue; }
|
|
588
|
-
for (var c = 0u; c < 3u; c = c + 1u) { values[corner * 3u + c] = state_values[at * 3u + c]; }
|
|
589
|
-
}
|
|
590
|
-
if (missing) { pixel_flags = pixel_flags | FLAG_STATE; for (var c = 0u; c < 3u; c = c + 1u) { (*corr)[c] = vec2<f32>(0.0, 0.0); } return; }
|
|
591
|
-
for (var c = 0u; c < 3u; c = c + 1u) {
|
|
592
|
-
var sum = 0.0; var mag = 0.0;
|
|
593
|
-
for (var corner = 0u; corner < 8u; corner = corner + 1u) {
|
|
594
|
-
var weight = 1.0;
|
|
595
|
-
for (var i = 0u; i < 3u; i = i + 1u) { weight = weight * select(1.0 - frac[i], frac[i], ((corner >> i) & 1u) == 1u); }
|
|
596
|
-
sum = sum + weight * values[corner * 3u + c];
|
|
597
|
-
mag = mag + abs(weight * values[corner * 3u + c]);
|
|
598
|
-
}
|
|
599
|
-
|
|
600
|
-
var slope_term = 0.0;
|
|
601
|
-
for (var i = 0u; i < 3u; i = i + 1u) {
|
|
602
|
-
var largest = 0.0;
|
|
603
|
-
for (var corner = 0u; corner < 8u; corner = corner + 1u) {
|
|
604
|
-
if (((corner >> i) & 1u) == 1u) { continue; }
|
|
605
|
-
largest = max(largest, abs(values[(corner | (1u << i)) * 3u + c] - values[corner * 3u + c]));
|
|
606
|
-
}
|
|
607
|
-
slope_term = slope_term + dg[i] * largest;
|
|
608
|
-
}
|
|
609
|
-
(*corr)[c] = vec2<f32>(sum, slope_term + 12.0 * E * mag);
|
|
610
|
-
}
|
|
611
|
-
}
|
|
612
561
|
@compute @workgroup_size(${DISPLAY_VIEW_QUALITY_WORKGROUP_SIZE})
|
|
613
562
|
fn main(@builtin(global_invocation_id) gid: vec3<u32>, @builtin(num_workgroups) wg: vec3<u32>) {
|
|
614
563
|
let i = gid.x + gid.y * wg.x * ${DISPLAY_VIEW_QUALITY_WORKGROUP_SIZE}u;
|
|
@@ -625,6 +574,9 @@ let ny = bitcast<u32>(geometry[row + 1u]);
|
|
|
625
574
|
let margin = i32(params.margin);
|
|
626
575
|
let reinhard = params.tone == 1u;
|
|
627
576
|
let count = params.candidates;
|
|
577
|
+
|
|
578
|
+
var cp_used = false;
|
|
579
|
+
var cp_a: array<vec2<f32>, 9>;
|
|
628
580
|
let share = select(1.0, 0.5, count == 2u);
|
|
629
581
|
|
|
630
582
|
let xb_even = geometry[col + 8u]; let xb_odd = geometry[col + 9u];
|
|
@@ -689,8 +641,6 @@ let bit = j * nx + ii;
|
|
|
689
641
|
if (bit < 32u) { mask0 = mask0 | (1u << bit); } else { mask1 = mask1 | (1u << (bit - 32u)); }
|
|
690
642
|
} else if ((clip_any & 2u) != 0u) { undecided = true; }
|
|
691
643
|
var e_mean = array<vec2<f32>, 3>(vec2<f32>(0.0), vec2<f32>(0.0), vec2<f32>(0.0));
|
|
692
|
-
var cm_average = array<vec2<f32>, 3>(vec2<f32>(0.0), vec2<f32>(0.0), vec2<f32>(0.0));
|
|
693
|
-
var pixel_variance = vec2<f32>(0.0, 0.0);
|
|
694
644
|
var bs: array<vec2<f32>, 3>; var hs: array<vec2<f32>, 3>;
|
|
695
645
|
var hv: array<vec2<f32>, 3>;
|
|
696
646
|
|
|
@@ -717,17 +667,26 @@ cm[0] = b_add(cm[0], b_scale(sm, w0)); cm[1] = b_add(cm[1], b_scale(sm, w1)); cm
|
|
|
717
667
|
C[0] = b_add(C[0], b_scale(sv, w0 * w0)); C[1] = b_add(C[1], b_scale(sv, w0 * w1)); C[2] = b_add(C[2], b_scale(sv, w0 * w2));
|
|
718
668
|
C[3] = b_add(C[3], b_scale(sv, w1 * w1)); C[4] = b_add(C[4], b_scale(sv, w1 * w2)); C[5] = b_add(C[5], b_scale(sv, w2 * w2));
|
|
719
669
|
}
|
|
720
|
-
for (var c = 0u; c < 3u; c = c + 1u) { if (exact[c]) { cm[c].y = 0.0; }
|
|
670
|
+
for (var c = 0u; c < 3u; c = c + 1u) { if (exact[c]) { cm[c].y = 0.0; } }
|
|
671
|
+
|
|
672
|
+
|
|
673
|
+
var cp_chain_run = false;
|
|
674
|
+
if (cp_on() && cp_reconstruct()) {
|
|
675
|
+
let reach = cp_reconstruct_reach(vec3<f32>(cm[0].x, cm[1].x, cm[2].x), vec3<f32>(C[0].x, C[3].x, C[5].x));
|
|
676
|
+
if (reach == 2u) { pixel_flags = pixel_flags | FLAG_UNCERTAIN; }
|
|
677
|
+
cp_chain_run = reach >= 1u;
|
|
678
|
+
}
|
|
679
|
+
let cp_unclipped = cp_on() && cp_reconstruct();
|
|
721
680
|
|
|
722
681
|
|
|
723
682
|
var bm: array<vec2<f32>, 3>; var bv: array<vec2<f32>, 3>;
|
|
724
683
|
for (var c = 0u; c < 3u; c = c + 1u) {
|
|
725
684
|
let gc = b_rounded(g_of(c));
|
|
726
685
|
var um = b_mul(gc, cm[c]);
|
|
727
|
-
if (exact[c] && cm[c].x == 1.0 && gain_at_clip(c)) { um = vec2<f32>(params.clip_level, 0.0); }
|
|
686
|
+
if (exact[c] && cm[c].x == 1.0 && gain_at_clip(c) && !cp_unclipped) { um = vec2<f32>(params.clip_level, 0.0); }
|
|
728
687
|
let uv = b_mul(b_mul(gc, gc), C[select(select(0u, 3u, c == 1u), 5u, c == 2u)]);
|
|
729
688
|
let gap = params.clip_level - um.x;
|
|
730
|
-
if (gap > 0.0 && gap * gap > params.reach2 * uv.x) { bm[c] = um; bv[c] = uv; bs[c] = gc; }
|
|
689
|
+
if (cp_unclipped || (gap > 0.0 && gap * gap > params.reach2 * uv.x)) { bm[c] = um; bv[c] = uv; bs[c] = gc; }
|
|
731
690
|
else { let clipped = upper_clip(um, uv, params.clip_level); bm[c] = clipped.mean; bv[c] = clipped.variance; bs[c] = b_mul(gc, clipped.slope); }
|
|
732
691
|
}
|
|
733
692
|
|
|
@@ -763,16 +722,75 @@ if (variance.x > 0.0) { skew = b_div(third, b_mul(variance, b_sqrt(variance)));
|
|
|
763
722
|
moments = unit_clip(mean, variance, skew);
|
|
764
723
|
}
|
|
765
724
|
hm[comp] = moments.mean; hv[comp] = moments.variance; hs[comp] = moments.slope;
|
|
766
|
-
h_cand[d * 3u + comp] = moments.mean;
|
|
767
|
-
e_mean[comp] = b_add(e_mean[comp], b_scale(moments.mean, share));
|
|
768
|
-
pixel_variance = vec2<f32>(max(pixel_variance.x, moments.variance.x), max(pixel_variance.y, moments.variance.y));
|
|
769
725
|
}
|
|
770
726
|
|
|
771
727
|
var an: array<vec2<f32>, 9>;
|
|
728
|
+
cp_used = false;
|
|
729
|
+
if (cp_on()) {
|
|
730
|
+
if (!cp_chain_run && cp_luminance()) {
|
|
731
|
+
var mu = vec3<f32>(0.0); var dmu = vec3<f32>(0.0); var dsv = vec3<f32>(0.0);
|
|
732
|
+
var srow = array<vec3<f32>, 3>(vec3<f32>(0.0), vec3<f32>(0.0), vec3<f32>(0.0));
|
|
733
|
+
var cc = array<f32, 9>(C[0].x, C[1].x, C[2].x, C[1].x, C[3].x, C[4].x, C[2].x, C[4].x, C[5].x);
|
|
734
|
+
var mm = array<vec3<f32>, 3>(vec3<f32>(params.m00, params.m01, params.m02), vec3<f32>(params.m10, params.m11, params.m12), vec3<f32>(params.m20, params.m21, params.m22));
|
|
735
|
+
for (var r = 0u; r < 3u; r = r + 1u) {
|
|
736
|
+
mu[r] = mm[r][0] * bm[0].x + mm[r][1] * bm[1].x + mm[r][2] * bm[2].x;
|
|
737
|
+
dmu[r] = abs(mm[r][0]) * bm[0].y + abs(mm[r][1]) * bm[1].y + abs(mm[r][2]) * bm[2].y;
|
|
738
|
+
dsv[r] = mm[r][0] * mm[r][0] * bv[0].y + mm[r][1] * mm[r][1] * bv[1].y + mm[r][2] * mm[r][2] * bv[2].y;
|
|
739
|
+
for (var q = 0u; q < 3u; q = q + 1u) {
|
|
740
|
+
var v = 0.0;
|
|
741
|
+
for (var a = 0u; a < 3u; a = a + 1u) { for (var b = 0u; b < 3u; b = b + 1u) {
|
|
742
|
+
var bab = bv[a].x; if (a != b) { bab = bs[a].x * bs[b].x * cc[a * 3u + b]; }
|
|
743
|
+
v = v + mm[r][a] * mm[q][b] * bab;
|
|
744
|
+
} }
|
|
745
|
+
srow[r][q] = v;
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
let t = cp_tone(mu, srow[0], srow[1], srow[2], dmu, dsv);
|
|
749
|
+
if (t.flag) { pixel_flags = pixel_flags | FLAG_UNCERTAIN; }
|
|
750
|
+
if (cp_desaturate() && t.top) { cp_chain_run = true; }
|
|
751
|
+
else {
|
|
752
|
+
let rows = array<vec3<f32>, 3>(t.a0, t.a1, t.a2);
|
|
753
|
+
for (var comp = 0u; comp < 3u; comp = comp + 1u) {
|
|
754
|
+
hm[comp] = vec2<f32>(t.hm[comp], t.bm[comp]); hv[comp] = vec2<f32>(t.hv[comp], t.bv[comp]);
|
|
772
755
|
for (var c = 0u; c < 3u; c = c + 1u) {
|
|
756
|
+
let jmc = rows[comp].x * m_of(0u, c) + rows[comp].y * m_of(1u, c) + rows[comp].z * m_of(2u, c);
|
|
757
|
+
let ajm = abs(rows[comp].x * m_of(0u, c)) + abs(rows[comp].y * m_of(1u, c)) + abs(rows[comp].z * m_of(2u, c));
|
|
758
|
+
let value = jmc * bs[c].x;
|
|
759
|
+
an[comp * 3u + c] = vec2<f32>(value, ajm * bs[c].y + abs(value) * (t.ju + 4.0 * E));
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
cp_used = true;
|
|
763
|
+
}
|
|
764
|
+
} else if (!cp_chain_run && cp_desaturate() && !reinhard) {
|
|
765
|
+
for (var comp = 0u; comp < 3u; comp = comp + 1u) {
|
|
766
|
+
let top = hm[comp].x + CLIP_REACH * sqrt(hv[comp].x);
|
|
767
|
+
if (hm[comp].x > 0.0 && top >= 0.999) { cp_chain_run = true; }
|
|
768
|
+
if (hm[comp].x > 0.0 && hm[comp].x - 2.0 * hm[comp].y < 0.999 && abs(top - 0.999) <= 2.0 * (hm[comp].y + CLIP_REACH * min(sqrt(hv[comp].y), hv[comp].y / (2.0 * sqrt(hv[comp].x)))) + 64.0 * E) { pixel_flags = pixel_flags | FLAG_UNCERTAIN; }
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
if (cp_chain_run) {
|
|
772
|
+
let t = cp_chain(vec3<f32>(cm[0].x, cm[1].x, cm[2].x), C[0].x, C[1].x, C[2].x, C[3].x, C[4].x, C[5].x, vec3<f32>(cm[0].y, cm[1].y, cm[2].y), vec3<f32>(C[0].y, C[3].y, C[5].y));
|
|
773
|
+
if (t.flag) { pixel_flags = pixel_flags | FLAG_UNCERTAIN; }
|
|
774
|
+
let rows = array<vec3<f32>, 3>(t.a0, t.a1, t.a2);
|
|
775
|
+
for (var comp = 0u; comp < 3u; comp = comp + 1u) {
|
|
776
|
+
hm[comp] = vec2<f32>(t.hm[comp], t.bm[comp]); hv[comp] = vec2<f32>(t.hv[comp], t.bv[comp]);
|
|
777
|
+
for (var c = 0u; c < 3u; c = c + 1u) { an[comp * 3u + c] = vec2<f32>(rows[comp][c], abs(rows[comp][c]) * t.ju); }
|
|
778
|
+
}
|
|
779
|
+
cp_used = true;
|
|
780
|
+
}
|
|
781
|
+
if (cp_used) { for (var k = 0u; k < 9u; k = k + 1u) { cp_a[k] = an[k]; } }
|
|
782
|
+
}
|
|
783
|
+
for (var comp = 0u; comp < 3u; comp = comp + 1u) {
|
|
784
|
+
h_cand[d * 3u + comp] = hm[comp];
|
|
785
|
+
e_mean[comp] = b_add(e_mean[comp], b_scale(hm[comp], share));
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
for (var c = 0u; c < 3u; c = c + 1u) {
|
|
789
|
+
if (!cp_used) {
|
|
773
790
|
an[c] = b_mul(b_mul(hs[0], b_rounded(m_of(0u, c))), bs[c]);
|
|
774
791
|
an[3u + c] = b_mul(b_mul(hs[1], b_rounded(m_of(1u, c))), bs[c]);
|
|
775
792
|
an[6u + c] = b_mul(b_mul(hs[2], b_rounded(m_of(2u, c))), bs[c]);
|
|
793
|
+
}
|
|
776
794
|
var bc = b0; if (c == 1u) { bc = b1; } if (c == 2u) { bc = b2; }
|
|
777
795
|
let wgt = b_mul(b_mul(b_scale(aj, share), b_rounded(bc)), csv[c]);
|
|
778
796
|
cov[0] = b_add(cov[0], b_mul(b_mul(wgt, an[c]), an[c])); cov[1] = b_add(cov[1], b_mul(b_mul(wgt, an[c]), an[3u + c])); cov[2] = b_add(cov[2], b_mul(b_mul(wgt, an[c]), an[6u + c]));
|
|
@@ -813,24 +831,21 @@ let d0 = b_scale(bs[0], aux[eb + 2u] - aux[eb + 5u]);
|
|
|
813
831
|
let d1 = b_scale(bs[1], aux[eb + 3u] - aux[eb + 6u]);
|
|
814
832
|
let d2 = b_scale(bs[2], aux[eb + 4u] - aux[eb + 7u]);
|
|
815
833
|
let sv = vec2<f32>(sites[o + 1u], sites[o + 4u]);
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
834
|
+
var a = b_mul(hs[0], b_add(b_add(b_mul(b_rounded(params.m00), d0), b_mul(b_rounded(params.m01), d1)), b_mul(b_rounded(params.m02), d2)));
|
|
835
|
+
var b = b_mul(hs[1], b_add(b_add(b_mul(b_rounded(params.m10), d0), b_mul(b_rounded(params.m11), d1)), b_mul(b_rounded(params.m12), d2)));
|
|
836
|
+
var c = b_mul(hs[2], b_add(b_add(b_mul(b_rounded(params.m20), d0), b_mul(b_rounded(params.m21), d1)), b_mul(b_rounded(params.m22), d2)));
|
|
837
|
+
if (cp_used) {
|
|
838
|
+
|
|
839
|
+
let e0 = aux[eb + 2u] - aux[eb + 5u]; let e1 = aux[eb + 3u] - aux[eb + 6u]; let e2 = aux[eb + 4u] - aux[eb + 7u];
|
|
840
|
+
a = b_add(b_add(b_scale(cp_a[0], e0), b_scale(cp_a[1], e1)), b_scale(cp_a[2], e2));
|
|
841
|
+
b = b_add(b_add(b_scale(cp_a[3], e0), b_scale(cp_a[4], e1)), b_scale(cp_a[5], e2));
|
|
842
|
+
c = b_add(b_add(b_scale(cp_a[6], e0), b_scale(cp_a[7], e1)), b_scale(cp_a[8], e2));
|
|
843
|
+
}
|
|
819
844
|
x0 = b_add(x0, b_mul(b_mul(a, a), sv)); x1 = b_add(x1, b_mul(b_mul(b, b), sv)); x2 = b_add(x2, b_mul(b_mul(c, c), sv));
|
|
820
845
|
}
|
|
821
846
|
let ajaj = b_mul(aj, aj);
|
|
822
847
|
res[0] = b_add(res[0], b_mul(ajaj, b_scale(x0, 0.25))); res[1] = b_add(res[1], b_mul(ajaj, b_scale(x1, 0.25))); res[2] = b_add(res[2], b_mul(ajaj, b_scale(x2, 0.25)));
|
|
823
848
|
}
|
|
824
|
-
if (params.correction == 1u) {
|
|
825
|
-
|
|
826
|
-
if (abs(pixel_variance.x - params.threshold) <= pixel_variance.y) { pixel_flags = pixel_flags | FLAG_TIE; }
|
|
827
|
-
if (pixel_variance.x > params.threshold) {
|
|
828
|
-
var corr: array<vec2<f32>, 3>;
|
|
829
|
-
flat_correction(cm_average[0], cm_average[1], cm_average[2], &corr);
|
|
830
|
-
for (var comp = 0u; comp < 3u; comp = comp + 1u) { s[comp] = b_add(s[comp], b_mul(aj, corr[comp])); }
|
|
831
|
-
pixel_flags = pixel_flags | FLAG_CORRECTED;
|
|
832
|
-
}
|
|
833
|
-
}
|
|
834
849
|
}
|
|
835
850
|
}
|
|
836
851
|
|
|
@@ -847,6 +862,11 @@ flags[3u * i + 1u] = mask0;
|
|
|
847
862
|
flags[3u * i + 2u] = mask1;
|
|
848
863
|
}
|
|
849
864
|
`;
|
|
865
|
+
/** The pixel pass (`DISPLAY_VIEW_QUALITY_PIXELS_BODY_WGSL`) with the coupled steps' text: the stub by default, the coupled steps on demand (#593). */
|
|
866
|
+
export function assembleDisplayViewQualityPixelsWgsl(coupledWgsl = DISPLAY_VIEW_COUPLED_STUB_WGSL) {
|
|
867
|
+
return DISPLAY_VIEW_QUALITY_PIXELS_BODY_WGSL + "\n" + coupledWgsl;
|
|
868
|
+
}
|
|
869
|
+
export const DISPLAY_VIEW_QUALITY_PIXELS_WGSL = /* @__PURE__ */ assembleDisplayViewQualityPixelsWgsl();
|
|
850
870
|
/** The lattice pass with a material module appended (`fn material_at(p: vec2<f32>) -> u32`, `var<private> material_uncertain: bool`). */
|
|
851
871
|
export function assembleDisplayViewQualityLatticeWgsl(materialModuleWgsl) {
|
|
852
872
|
return DISPLAY_VIEW_QUALITY_LATTICE_WGSL + "\n" + materialModuleWgsl + "\n";
|