@photivra/engine 2.12.0 → 2.14.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 +144 -1
- package/CITATION.cff +1 -1
- package/README.md +7 -7
- package/SECURITY.md +1 -1
- package/THIRD_PARTY.md +3 -0
- package/dist/camera/lens-projection.js +2 -1
- package/dist/camera/lens-projection.js.map +1 -1
- package/dist/capture/dng-import.js +1 -1
- package/dist/capture/dng-import.js.map +1 -1
- package/dist/capture/export-jpeg.d.ts +1 -1
- package/dist/capture/export-jpeg.js +6 -4
- package/dist/capture/export-jpeg.js.map +1 -1
- package/dist/capture/host-yield-cadence.js +1 -1
- package/dist/capture/host-yield-cadence.js.map +1 -1
- package/dist/capture/native-environment-optical-stage.js +1 -1
- package/dist/capture/native-environment-optical-stage.js.map +1 -1
- package/dist/capture/native-raw.js +1 -1
- package/dist/capture/native-raw.js.map +1 -1
- package/dist/capture/packed-sensor-raw.js +3 -3
- package/dist/capture/packed-sensor-raw.js.map +1 -1
- package/dist/capture/sensor-raw-producer.js +1 -1
- package/dist/capture/sensor-raw-producer.js.map +1 -1
- package/dist/color/capture-color.js +3 -3
- package/dist/color/capture-color.js.map +1 -1
- package/dist/color/chromatic-adaptation.js +2 -2
- package/dist/color/chromatic-adaptation.js.map +1 -1
- package/dist/color/color-matching-functions.js +1 -1
- package/dist/color/color-matching-functions.js.map +1 -1
- package/dist/color/colorimetry-math.js +2 -2
- package/dist/color/colorimetry-math.js.map +1 -1
- package/dist/color/illuminants.js +3 -3
- package/dist/color/illuminants.js.map +1 -1
- package/dist/color/rgb-color-spaces.js +1 -1
- package/dist/color/rgb-color-spaces.js.map +1 -1
- package/dist/color/sensor-color-development.js +1 -1
- package/dist/color/sensor-color-development.js.map +1 -1
- package/dist/core/record-validation.js +3 -3
- package/dist/core/record-validation.js.map +1 -1
- package/dist/core/version.d.ts +1 -1
- package/dist/core/version.js +1 -1
- package/dist/core/version.js.map +1 -1
- package/dist/equipment/generic-prime-lenses.js +3 -3
- package/dist/equipment/generic-prime-lenses.js.map +1 -1
- package/dist/equipment/generic-tier-assets.d.ts +23 -1
- package/dist/equipment/generic-tier-assets.js +58 -30
- package/dist/equipment/generic-tier-assets.js.map +1 -1
- package/dist/equipment/generic-tier-presets.d.ts +6 -3
- package/dist/equipment/generic-tier-presets.js +26 -13
- package/dist/equipment/generic-tier-presets.js.map +1 -1
- package/dist/exposure/auto-iso-slowest-shutter.d.ts +120 -0
- package/dist/exposure/auto-iso-slowest-shutter.js +217 -0
- package/dist/exposure/auto-iso-slowest-shutter.js.map +1 -0
- package/dist/exposure/exposure-mode-resolver.d.ts +57 -1
- package/dist/exposure/exposure-mode-resolver.js +238 -33
- package/dist/exposure/exposure-mode-resolver.js.map +1 -1
- package/dist/exposure/flash-ttl.js +1 -1
- package/dist/exposure/flash-ttl.js.map +1 -1
- package/dist/exposure/flash.js +1 -1
- package/dist/exposure/flash.js.map +1 -1
- package/dist/facade/chart-material-layers.js +2 -2
- package/dist/facade/chart-material-layers.js.map +1 -1
- package/dist/facade/chart-radiance-batch.js +1 -1
- package/dist/facade/chart-radiance-batch.js.map +1 -1
- package/dist/facade/chart-scenes.d.ts +45 -8
- package/dist/facade/chart-scenes.js +101 -44
- package/dist/facade/chart-scenes.js.map +1 -1
- package/dist/facade/color-patches.d.ts +129 -0
- package/dist/facade/color-patches.js +209 -0
- package/dist/facade/color-patches.js.map +1 -0
- package/dist/facade/diffraction-provider.js +12 -13
- package/dist/facade/diffraction-provider.js.map +1 -1
- package/dist/facade/display-view-gpu.js +1 -1
- package/dist/facade/display-view-gpu.js.map +1 -1
- package/dist/facade/display-view.d.ts +27 -0
- package/dist/facade/display-view.js +234 -65
- package/dist/facade/display-view.js.map +1 -1
- package/dist/facade/scene-radiance.js +2 -2
- package/dist/facade/scene-radiance.js.map +1 -1
- package/dist/facade/simulate-capture.d.ts +139 -12
- package/dist/facade/simulate-capture.js +209 -36
- package/dist/facade/simulate-capture.js.map +1 -1
- package/dist/facade/simulate-display-view.js +2 -2
- package/dist/facade/simulate-display-view.js.map +1 -1
- package/dist/gpu/chart-composite-gpu.js +2 -2
- package/dist/gpu/chart-composite-gpu.js.map +1 -1
- package/dist/gpu/display-view-composite-material-module.js +1 -1
- package/dist/gpu/display-view-composite-material-module.js.map +1 -1
- package/dist/gpu/display-view-quality-gpu.d.ts +2 -1
- package/dist/gpu/display-view-quality-gpu.js +24 -14
- package/dist/gpu/display-view-quality-gpu.js.map +1 -1
- package/dist/gpu/image-kernel-execution.js +2 -2
- package/dist/gpu/image-kernel-execution.js.map +1 -1
- package/dist/gpu/temporal-sum-gpu.js +23 -23
- package/dist/gpu/webgpu-runtime.js +1 -1
- package/dist/gpu/webgpu-runtime.js.map +1 -1
- package/dist/gpu/wgsl-chart-composite-kernel.js +318 -318
- package/dist/gpu/wgsl-chart-composite-kernel.js.map +1 -1
- package/dist/gpu/wgsl-chart-kernel.js +117 -117
- package/dist/gpu/wgsl-chart-kernel.js.map +1 -1
- package/dist/gpu/wgsl-display-view-quality-kernel.d.ts +13 -1
- package/dist/gpu/wgsl-display-view-quality-kernel.js +522 -488
- package/dist/gpu/wgsl-display-view-quality-kernel.js.map +1 -1
- package/dist/gpu/wgsl-display-view-speed-kernel.js +248 -248
- package/dist/gpu/wgsl-display-view-speed-kernel.js.map +1 -1
- package/dist/gpu/wgsl-kernels.js +203 -203
- package/dist/gpu/wgsl-kernels.js.map +1 -1
- package/dist/gpu/wgsl-sensor-kernel.js +302 -302
- package/dist/gpu/wgsl-sensor-kernel.js.map +1 -1
- package/dist/index.d.ts +8 -5
- package/dist/index.js +6 -3
- package/dist/index.js.map +1 -1
- package/dist/motion/temporal-exposure-sum.js +1 -1
- package/dist/motion/temporal-exposure-sum.js.map +1 -1
- package/dist/optics/diffraction-psf-profile.js +4 -4
- package/dist/optics/diffraction-psf-profile.js.map +1 -1
- package/dist/optics/front-of-lens-filter.js +1 -1
- package/dist/optics/front-of-lens-filter.js.map +1 -1
- package/dist/optics/irradiance-convolution.d.ts +10 -0
- package/dist/optics/irradiance-convolution.js +49 -14
- package/dist/optics/irradiance-convolution.js.map +1 -1
- package/dist/output/native-capture-sdr.js +1 -1
- package/dist/output/native-capture-sdr.js.map +1 -1
- package/dist/output/png-encoder.js +2 -2
- package/dist/output/png-encoder.js.map +1 -1
- package/dist/output/print-jpeg.js +13 -10
- package/dist/output/print-jpeg.js.map +1 -1
- package/dist/output/text-metadata.d.ts +22 -2
- package/dist/output/text-metadata.js +58 -9
- package/dist/output/text-metadata.js.map +1 -1
- package/dist/sensor/fixed-pattern-noise.js +1 -1
- package/dist/sensor/fixed-pattern-noise.js.map +1 -1
- package/dist/sensor/readout-exposure-linkage.js +1 -1
- package/dist/sensor/readout-exposure-linkage.js.map +1 -1
- package/docs/API_REFERENCE.md +49 -1
- package/docs/QUICK_START.md +104 -9
- package/docs/USAGE.md +241 -2
- package/docs/api/core-version.md +1 -1
- package/docs/api/equipment-generic-tier-assets.md +41 -1
- package/docs/api/equipment-generic-tier-presets.md +11 -3
- package/docs/api/exports.json +172 -2
- package/docs/api/exposure-auto-iso-slowest-shutter.md +139 -0
- package/docs/api/exposure-exposure-mode-resolver.md +68 -0
- package/docs/api/facade-chart-scenes.md +36 -5
- package/docs/api/facade-color-patches.md +150 -0
- package/docs/api/facade-simulate-capture.md +140 -9
- package/docs/api/output-text-metadata.md +34 -0
- package/llms.txt +1 -0
- package/package.json +2 -2
|
@@ -20,7 +20,8 @@
|
|
|
20
20
|
* the footprint, the demosaic candidates (one bilinear, or AHD's two directional linear candidates, each with its full
|
|
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
|
-
* residual, AHD's choice variance ¼·Var(H − V),
|
|
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), and the low-signal correction interpolated trilinearly between the grid
|
|
24
25
|
* states of a table the host uploaded (the states themselves are computed on the host, #447; the kernel records every
|
|
25
26
|
* grid key it needs in a bitmap and flags a display pixel whose state the table lacks).
|
|
26
27
|
*
|
|
@@ -63,7 +64,7 @@ export const DISPLAY_VIEW_QUALITY_CANDIDATE_ENTRIES = 49;
|
|
|
63
64
|
export const DISPLAY_VIEW_QUALITY_CANDIDATE_FLOATS = 8;
|
|
64
65
|
const CANDIDATE_PHASE_STRIDE = 4 + DISPLAY_VIEW_QUALITY_CANDIDATE_ENTRIES * DISPLAY_VIEW_QUALITY_CANDIDATE_FLOATS;
|
|
65
66
|
/** Layout of the aux table (float32 words). */
|
|
66
|
-
export const DISPLAY_VIEW_QUALITY_AUX = Object.freeze({
|
|
67
|
+
export const DISPLAY_VIEW_QUALITY_AUX = /* @__PURE__ */ Object.freeze({
|
|
67
68
|
/** Per phase p, channel c, tap t: dx, dy, weight, 0 (the bilinear kernels, 4 taps; unused taps have weight 0). */
|
|
68
69
|
bilinear: 0,
|
|
69
70
|
/** Per phase p, channel c: 1 / Σ_t w_t² of the bilinear kernel (host float64). */
|
|
@@ -76,7 +77,7 @@ export const DISPLAY_VIEW_QUALITY_AUX = Object.freeze({
|
|
|
76
77
|
size: 240 + 4 * CANDIDATE_PHASE_STRIDE
|
|
77
78
|
});
|
|
78
79
|
/** Pixel flag bits of the output flag word. */
|
|
79
|
-
export const DISPLAY_VIEW_QUALITY_FLAG = Object.freeze({
|
|
80
|
+
export const DISPLAY_VIEW_QUALITY_FLAG = /* @__PURE__ */ Object.freeze({
|
|
80
81
|
/** A site the pixel read had an uncertain lattice material (recompute on the host). */
|
|
81
82
|
materialUncertain: 1,
|
|
82
83
|
/** A site the pixel read lies outside the band's site window (a host geometry error; recompute). */
|
|
@@ -87,9 +88,21 @@ export const DISPLAY_VIEW_QUALITY_FLAG = Object.freeze({
|
|
|
87
88
|
thresholdTie: 8,
|
|
88
89
|
/** Informational: the pixel's expected value includes the low-signal correction. */
|
|
89
90
|
corrected: 16,
|
|
91
|
+
/**
|
|
92
|
+
* #457: the reference takes AHD's choice on the noise-free mosaic (one candidate, or their average on a tie), which the kernel
|
|
93
|
+
* does not compute; it renders the average. The pixel is flagged (recompute) when Σ_j a_j·½|h(H) − h(V)| of some component
|
|
94
|
+
* exceeds `DISPLAY_VIEW_QUALITY_CHOICE_SIGMA` times the pixel's noise standard deviation.
|
|
95
|
+
*/
|
|
96
|
+
ahdChoice: 32,
|
|
90
97
|
/** The bits that require the host's recomputation. */
|
|
91
|
-
recompute:
|
|
98
|
+
recompute: 47
|
|
92
99
|
});
|
|
100
|
+
/**
|
|
101
|
+
* #457: the largest move, in units of the display pixel's own noise σ, that AHD's choice between its candidates may make to a pixel
|
|
102
|
+
* the kernel keeps (it renders the candidates' average and its bound carries the move); a larger one is recomputed on the host. A
|
|
103
|
+
* 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.
|
|
104
|
+
*/
|
|
105
|
+
export const DISPLAY_VIEW_QUALITY_CHOICE_SIGMA = 2 ** -10;
|
|
93
106
|
/** Words of the grid-key bitmap: one bit per grid key (AHD_KEY_LEVELS³ keys). */
|
|
94
107
|
export const DISPLAY_VIEW_QUALITY_BITMAP_WORDS = Math.ceil(AHD_KEY_LEVELS ** 3 / 32);
|
|
95
108
|
/**
|
|
@@ -125,20 +138,20 @@ const SITE: u32 = ${DISPLAY_VIEW_QUALITY_SITE_FLOATS}u;
|
|
|
125
138
|
const GROUP: u32 = ${DISPLAY_VIEW_QUALITY_GROUP_WORDS}u;
|
|
126
139
|
const TAP: u32 = ${DISPLAY_VIEW_QUALITY_TAP_WORDS}u;
|
|
127
140
|
struct Params {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
141
|
+
count: u32, row0: u32, region_w: u32, region_x: u32,
|
|
142
|
+
region_y: u32, margin: u32, native_w: u32, native_h: u32,
|
|
143
|
+
columns: u32, tone: u32, reach: u32, candidates: u32,
|
|
144
|
+
site_x0: i32, site_y0: i32, site_w: u32, site_h: u32,
|
|
145
|
+
correction: u32, state_count: u32, taps: u32, groups: u32,
|
|
146
|
+
lattice_total: u32, gain_at_clip0: u32, gain_at_clip1: u32, gain_at_clip2: u32,
|
|
147
|
+
k0: f32, k1: f32, k2: f32, reach2: f32,
|
|
148
|
+
dark0: f32, dark1: f32, dark2: f32, clip_level: f32,
|
|
149
|
+
c0_0: f32, c0_1: f32, c0_2: f32, threshold: f32,
|
|
150
|
+
g0: f32, g1: f32, g2: f32, scale_u: f32,
|
|
151
|
+
m00: f32, m01: f32, m02: f32, m10: f32,
|
|
152
|
+
m11: f32, m12: f32, m20: f32, m21: f32,
|
|
153
|
+
m22: f32, scale_v: f32, site_gamma: f32, site_first: u32,
|
|
154
|
+
site_tiny: f32, pad_f: f32, pad_g: f32, pad_h: f32,
|
|
142
155
|
};
|
|
143
156
|
@group(0) @binding(0) var<uniform> params: Params;
|
|
144
157
|
|
|
@@ -146,161 +159,161 @@ fn k_of(c: u32) -> f32 { if (c == 0u) { return params.k0; } if (c == 1u) { retur
|
|
|
146
159
|
fn dark_of(c: u32) -> f32 { if (c == 0u) { return params.dark0; } if (c == 1u) { return params.dark1; } return params.dark2; }
|
|
147
160
|
fn c0_of(c: u32) -> f32 { if (c == 0u) { return params.c0_0; } if (c == 1u) { return params.c0_1; } return params.c0_2; }
|
|
148
161
|
fn g_of(c: u32) -> f32 { if (c == 0u) { return params.g0; } if (c == 1u) { return params.g1; } return params.g2; }
|
|
149
|
-
|
|
162
|
+
|
|
150
163
|
fn gain_at_clip(c: u32) -> bool { if (c == 0u) { return params.gain_at_clip0 == 1u; } if (c == 1u) { return params.gain_at_clip1 == 1u; } return params.gain_at_clip2 == 1u; }
|
|
151
164
|
fn m_of(r: u32, c: u32) -> f32 {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
165
|
+
let i = r * 3u + c;
|
|
166
|
+
switch (i) {
|
|
167
|
+
case 0u: { return params.m00; } case 1u: { return params.m01; } case 2u: { return params.m02; }
|
|
168
|
+
case 3u: { return params.m10; } case 4u: { return params.m11; } case 5u: { return params.m12; }
|
|
169
|
+
case 6u: { return params.m20; } case 7u: { return params.m21; } default: { return params.m22; }
|
|
170
|
+
}
|
|
158
171
|
}
|
|
159
172
|
fn channel_of(x: i32, y: i32) -> u32 {
|
|
160
|
-
|
|
161
|
-
|
|
173
|
+
if ((y & 1) == 0) { return select(1u, 0u, (x & 1) == 0); }
|
|
174
|
+
return select(2u, 1u, (x & 1) == 0);
|
|
162
175
|
}
|
|
163
|
-
|
|
176
|
+
|
|
164
177
|
fn b_add(a: vec2<f32>, b: vec2<f32>) -> vec2<f32> { let v = a.x + b.x; return vec2<f32>(v, a.y + b.y + E * abs(v)); }
|
|
165
178
|
fn b_sub(a: vec2<f32>, b: vec2<f32>) -> vec2<f32> { let v = a.x - b.x; return vec2<f32>(v, a.y + b.y + E * abs(v)); }
|
|
166
179
|
fn b_mul(a: vec2<f32>, b: vec2<f32>) -> vec2<f32> { let v = a.x * b.x; return vec2<f32>(v, abs(a.x) * b.y + abs(b.x) * a.y + E * abs(v)); }
|
|
167
|
-
|
|
180
|
+
|
|
168
181
|
fn b_scale(a: vec2<f32>, k: f32) -> vec2<f32> { let v = a.x * k; return vec2<f32>(v, a.y * abs(k) + E * abs(v)); }
|
|
169
|
-
|
|
182
|
+
|
|
170
183
|
fn b_rounded(k: f32) -> vec2<f32> { return vec2<f32>(k, E * abs(k)); }
|
|
171
184
|
fn b_div(a: vec2<f32>, b: vec2<f32>) -> vec2<f32> { let v = a.x / b.x; return vec2<f32>(v, (a.y + abs(v) * b.y) / abs(b.x) + 2.5 * E * abs(v)); }
|
|
172
|
-
|
|
185
|
+
|
|
173
186
|
fn b_sqrt(a: vec2<f32>) -> vec2<f32> {
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
187
|
+
let s = sqrt(max(a.x, 0.0));
|
|
188
|
+
if (s > 0.0) { return vec2<f32>(s, min(a.y / (2.0 * s), sqrt(a.y)) + 4.5 * E * s); }
|
|
189
|
+
return vec2<f32>(0.0, sqrt(a.y));
|
|
177
190
|
}
|
|
178
|
-
|
|
191
|
+
|
|
179
192
|
fn phi(z: f32) -> f32 { return 0.3989422804014327 * exp(-0.5 * z * z); }
|
|
180
193
|
fn pq(z: f32) -> vec2<f32> {
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
194
|
+
let x = abs(z);
|
|
195
|
+
let t = 1.0 / (1.0 + 0.2316419 * x);
|
|
196
|
+
let q = phi(x) * t * (0.319381530 + t * (-0.356563782 + t * (1.781477937 + t * (-1.821255978 + t * 1.330274429))));
|
|
197
|
+
if (z >= 0.0) { return vec2<f32>(1.0 - q, q); }
|
|
198
|
+
return vec2<f32>(q, 1.0 - q);
|
|
186
199
|
}
|
|
187
200
|
struct Moments { mean: vec2<f32>, variance: vec2<f32>, slope: vec2<f32> }
|
|
188
|
-
|
|
201
|
+
|
|
189
202
|
fn upper_clip(m: vec2<f32>, v: vec2<f32>, top: f32) -> Moments {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
203
|
+
var out: Moments;
|
|
204
|
+
if (!(v.x > 0.0)) {
|
|
205
|
+
|
|
206
|
+
let decided = v.y == 0.0 && (m.x - m.y >= top || m.x + m.y < top);
|
|
207
|
+
out.mean = vec2<f32>(min(m.x, top), m.y); out.variance = vec2<f32>(0.0, v.y); out.slope = vec2<f32>(select(0.0, 1.0, m.x < top), select(1.0, 0.0, decided));
|
|
208
|
+
return out;
|
|
209
|
+
}
|
|
210
|
+
let s = b_sqrt(v);
|
|
211
|
+
let z = (top - m.x) / s.x;
|
|
212
|
+
if (z > CLIP_REACH) { out.mean = m; out.variance = v; out.slope = vec2<f32>(1.0, 0.0); return out; }
|
|
213
|
+
if (z < -CLIP_REACH) { out.mean = vec2<f32>(top, 0.0); out.variance = vec2<f32>(0.0, 0.0); out.slope = vec2<f32>(0.0, 0.0); return out; }
|
|
214
|
+
let p = pq(z);
|
|
215
|
+
let d = phi(z);
|
|
216
|
+
let delta = d - z * p.y;
|
|
217
|
+
let ratio = p.x - z * d + z * z * p.y - delta * delta;
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
let rho_z = 2.0 * p.y * (z + delta);
|
|
221
|
+
out.mean = vec2<f32>(m.x - s.x * delta, p.x * m.y + d * s.y + CLIP_MEAN_U * E * s.x);
|
|
222
|
+
out.variance = vec2<f32>(v.x * max(0.0, ratio), s.x * abs(rho_z) * m.y + s.x * abs(2.0 * ratio - z * rho_z) * s.y + CLIP_VARIANCE_U * E * v.x);
|
|
223
|
+
out.slope = vec2<f32>(p.x, min(1.0, (d * m.y + abs(z) * d * s.y) / s.x + CLIP_SLOPE_U * E));
|
|
224
|
+
return out;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
|
|
216
229
|
fn unit_clip(m: vec2<f32>, v: vec2<f32>, skew: vec2<f32>) -> Moments {
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
230
|
+
var out: Moments;
|
|
231
|
+
if (!(v.x > 0.0)) {
|
|
232
|
+
let decided = v.y == 0.0 && ((m.x - m.y > 0.0 && m.x + m.y < 1.0) || m.x + m.y <= 0.0 || m.x - m.y >= 1.0);
|
|
233
|
+
out.mean = vec2<f32>(clamp(m.x, 0.0, 1.0), m.y); out.variance = vec2<f32>(0.0, v.y); out.slope = vec2<f32>(select(0.0, 1.0, m.x > 0.0 && m.x < 1.0), select(1.0, 0.0, decided));
|
|
234
|
+
return out;
|
|
235
|
+
}
|
|
236
|
+
let s = b_sqrt(v);
|
|
237
|
+
let a = -m.x / s.x;
|
|
238
|
+
let b = (1.0 - m.x) / s.x;
|
|
239
|
+
if (a < -CLIP_REACH && b > CLIP_REACH) { out.mean = m; out.variance = v; out.slope = vec2<f32>(1.0, 0.0); return out; }
|
|
240
|
+
var pa = 0.0; var da = 0.0;
|
|
241
|
+
if (!(a < -CLIP_REACH)) { pa = pq(a).x; da = phi(a); }
|
|
242
|
+
var pb = 1.0; var qb = 0.0; var db = 0.0;
|
|
243
|
+
if (!(b > CLIP_REACH)) { let p = pq(b); pb = p.x; qb = p.y; db = phi(b); }
|
|
244
|
+
let inside = pb - pa;
|
|
245
|
+
let gamma = clamp(skew.x, -1.0, 1.0);
|
|
246
|
+
let aa = a * da;
|
|
247
|
+
let bb = b * db;
|
|
248
|
+
let eg = a * pa + (da - db) + b * qb;
|
|
249
|
+
let eg2 = a * a * pa + inside - (bb - aa) + b * b * qb;
|
|
250
|
+
let normal_mean = m.x + s.x * eg;
|
|
251
|
+
var mean = normal_mean;
|
|
252
|
+
var shift = 0.0;
|
|
253
|
+
if (gamma != 0.0) { shift = s.x * gamma / 6.0 * (aa - bb); mean = normal_mean + shift; }
|
|
254
|
+
|
|
255
|
+
let d_shift = 0.1 * s.x * min(2.0, skew.y) + 0.1 * abs(gamma) * s.y + E * abs(shift);
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
let rho = eg2 - eg * eg;
|
|
260
|
+
let rho_a = 2.0 * pa * (a - eg);
|
|
261
|
+
let rho_b = 2.0 * qb * (b - eg);
|
|
262
|
+
let d_mean = m.y * inside + abs(da - db) * s.y + 2.0 * CLIP_MEAN_U * E * s.x + d_shift;
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
let normal_variance = v.x * rho;
|
|
266
|
+
let d_normal = s.x * abs(rho_a + rho_b) * m.y + s.x * abs(2.0 * rho - a * rho_a - b * rho_b) * s.y + 2.0 * CLIP_VARIANCE_U * E * v.x;
|
|
267
|
+
let variance = max(0.0, normal_variance - shift * (2.0 * normal_mean + shift));
|
|
268
|
+
var d_var = d_normal + 2.0 * (d_shift * (abs(normal_mean) + abs(shift)) + abs(shift) * d_mean);
|
|
269
|
+
if (shift > d_shift) { d_var = min(d_var, max(variance, max(0.0, normal_variance) + d_normal)); }
|
|
270
|
+
out.mean = vec2<f32>(mean, d_mean);
|
|
271
|
+
out.variance = vec2<f32>(variance, d_var);
|
|
272
|
+
out.slope = vec2<f32>(inside, min(1.0, (abs(da - db) * m.y + abs(aa - bb) * s.y) / s.x + 2.0 * CLIP_SLOPE_U * E));
|
|
273
|
+
return out;
|
|
261
274
|
}
|
|
262
275
|
`;
|
|
263
276
|
/** The Gauss–Legendre Reinhard moments read the aux table, so they live in the pixel kernel. */
|
|
264
277
|
const REINHARD_WGSL = /* wgsl */ `
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
|
|
268
281
|
fn reinhard_moments(m: vec2<f32>, v: vec2<f32>) -> Moments {
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
282
|
+
var out: Moments;
|
|
283
|
+
if (!(v.x > 0.0)) {
|
|
284
|
+
if (m.x > 0.0) {
|
|
285
|
+
let h = m.x / (1.0 + m.x);
|
|
286
|
+
out.mean = vec2<f32>(h, m.y + 4.0 * E * h); out.variance = vec2<f32>(0.0, v.y); out.slope = vec2<f32>(1.0 / ((1.0 + m.x) * (1.0 + m.x)), min(1.0, 2.0 * m.y + 6.0 * E));
|
|
287
|
+
return out;
|
|
288
|
+
}
|
|
289
|
+
out.mean = vec2<f32>(0.0, m.y); out.variance = vec2<f32>(0.0, v.y); out.slope = vec2<f32>(0.0, 1.0);
|
|
290
|
+
return out;
|
|
291
|
+
}
|
|
292
|
+
let s = b_sqrt(v);
|
|
293
|
+
let zlo = max(-m.x / s.x, -CLIP_REACH);
|
|
294
|
+
if (!(CLIP_REACH > zlo)) { out.mean = vec2<f32>(0.0, m.y + s.y); out.variance = vec2<f32>(0.0, v.y); out.slope = vec2<f32>(0.0, 1.0); return out; }
|
|
295
|
+
let hm = select(0.0, m.x / (1.0 + m.x), m.x > 0.0);
|
|
296
|
+
var e1 = 0.0; var e2 = 0.0; var ed = 0.0;
|
|
297
|
+
let zwidth = (CLIP_REACH - zlo) / 4.0;
|
|
298
|
+
for (var p = 0u; p < 4u; p = p + 1u) {
|
|
299
|
+
let zc = zlo + (f32(p) + 0.5) * zwidth;
|
|
300
|
+
let zhalf = zwidth / 2.0;
|
|
301
|
+
for (var k = 0u; k < 16u; k = k + 1u) {
|
|
289
302
|
let z = zc + zhalf * aux[${DISPLAY_VIEW_QUALITY_AUX.gaussLegendre}u + k];
|
|
290
|
-
|
|
303
|
+
let x = m.x + s.x * z;
|
|
291
304
|
let weight = zhalf * aux[${DISPLAY_VIEW_QUALITY_AUX.gaussLegendre + 16}u + k] * phi(z);
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
305
|
+
let h = x / (1.0 + x);
|
|
306
|
+
e1 = e1 + weight * h;
|
|
307
|
+
e2 = e2 + weight * (h - hm) * (h - hm);
|
|
308
|
+
ed = ed + weight / ((1.0 + x) * (1.0 + x));
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
let shifted = e1 - hm;
|
|
312
|
+
let variance = max(0.0, e2 - shifted * shifted);
|
|
313
|
+
out.mean = vec2<f32>(e1, m.y + s.y + REINHARD_MEAN_U * E * abs(e1));
|
|
314
|
+
out.variance = vec2<f32>(variance, 2.0 * s.x * m.y + 2.0 * v.y + REINHARD_VARIANCE_U * E * variance);
|
|
315
|
+
out.slope = vec2<f32>(ed, min(1.0, 2.0 * m.y + 2.0 * s.y + REINHARD_SLOPE_U * E));
|
|
316
|
+
return out;
|
|
304
317
|
}
|
|
305
318
|
`;
|
|
306
319
|
/**
|
|
@@ -315,21 +328,21 @@ export const DISPLAY_VIEW_QUALITY_LATTICE_WGSL = /* wgsl */ `${COMMON_WGSL}
|
|
|
315
328
|
@compute @workgroup_size(${DISPLAY_VIEW_QUALITY_WORKGROUP_SIZE})
|
|
316
329
|
fn main(@builtin(global_invocation_id) gid: vec3<u32>, @builtin(num_workgroups) wg: vec3<u32>) {
|
|
317
330
|
let i = gid.x + gid.y * wg.x * ${DISPLAY_VIEW_QUALITY_WORKGROUP_SIZE}u;
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
331
|
+
if (i >= params.lattice_total) { return; }
|
|
332
|
+
var g = 0u;
|
|
333
|
+
for (var k = 1u; k < params.groups; k = k + 1u) { if (i >= groups[k * GROUP + 4u]) { g = k; } }
|
|
334
|
+
let base = g * GROUP;
|
|
335
|
+
let lx0 = bitcast<i32>(groups[base]);
|
|
336
|
+
let ly0 = bitcast<i32>(groups[base + 1u]);
|
|
337
|
+
let lw = groups[base + 2u];
|
|
338
|
+
let local = i - groups[base + 4u];
|
|
339
|
+
let q = ly0 + i32(local / lw);
|
|
340
|
+
let p = lx0 + i32(local % lw);
|
|
341
|
+
let u = (f32(p) + bitcast<f32>(groups[base + 6u])) * params.scale_u;
|
|
342
|
+
let v = (f32(q) + bitcast<f32>(groups[base + 7u])) * params.scale_v;
|
|
343
|
+
material_uncertain = false;
|
|
344
|
+
let m = material_at(vec2<f32>(u, v));
|
|
345
|
+
lattice_out[i] = m | select(0u, 0x80000000u, material_uncertain);
|
|
333
346
|
}
|
|
334
347
|
`;
|
|
335
348
|
/**
|
|
@@ -338,21 +351,21 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>, @builtin(num_workgroups)
|
|
|
338
351
|
*/
|
|
339
352
|
const SITE_TAIL_WGSL = /* wgsl */ `
|
|
340
353
|
fn write_site(i: u32, c: u32, e: f32, de: f32, flag: u32) {
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
354
|
+
let kc = k_of(c);
|
|
355
|
+
let mean = kc * e;
|
|
356
|
+
let variance = kc * kc * e + c0_of(c);
|
|
357
|
+
let third = kc * kc * kc * e;
|
|
358
|
+
var m = vec2<f32>(mean, kc * de + 2.0 * E * mean);
|
|
359
|
+
var v = vec2<f32>(variance, kc * kc * de + 4.0 * E * variance);
|
|
360
|
+
let gap = 1.0 - mean;
|
|
361
|
+
if (!(gap > 0.0 && gap * gap > params.reach2 * variance)) {
|
|
362
|
+
let clipped = upper_clip(m, v, 1.0);
|
|
363
|
+
m = clipped.mean; v = clipped.variance;
|
|
364
|
+
}
|
|
365
|
+
let o = i * SITE;
|
|
366
|
+
sites[o] = m.x; sites[o + 1u] = v.x; sites[o + 2u] = third;
|
|
367
|
+
sites[o + 3u] = m.y; sites[o + 4u] = v.y; sites[o + 5u] = kc * kc * kc * de + 5.0 * E * third;
|
|
368
|
+
sites[o + 6u] = bitcast<f32>(flag); sites[o + 7u] = e;
|
|
356
369
|
}
|
|
357
370
|
`;
|
|
358
371
|
/**
|
|
@@ -379,28 +392,28 @@ export const DISPLAY_VIEW_QUALITY_SITES_WGSL = /* wgsl */ `${COMMON_WGSL}${siteB
|
|
|
379
392
|
@compute @workgroup_size(${DISPLAY_VIEW_QUALITY_WORKGROUP_SIZE})
|
|
380
393
|
fn main(@builtin(global_invocation_id) gid: vec3<u32>, @builtin(num_workgroups) wg: vec3<u32>) {
|
|
381
394
|
let local = gid.x + gid.y * wg.x * ${DISPLAY_VIEW_QUALITY_WORKGROUP_SIZE}u;
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
395
|
+
if (local >= params.count) { return; }
|
|
396
|
+
let i = params.site_first + local;
|
|
397
|
+
let ii = i % params.site_w;
|
|
398
|
+
let jj = i / params.site_w;
|
|
399
|
+
let x = params.site_x0 + i32(ii);
|
|
400
|
+
let y = params.site_y0 + i32(jj);
|
|
401
|
+
let c = channel_of(x, y);
|
|
402
|
+
var sum = 0.0;
|
|
403
|
+
var uncertainty = 0.0;
|
|
404
|
+
let T = params.taps;
|
|
405
|
+
for (var t = 0u; t < T; t = t + 1u) {
|
|
406
|
+
let tb = t * TAP;
|
|
407
|
+
let g = taps[tb] * GROUP;
|
|
408
|
+
let index = groups[g + 4u] + (jj + taps[tb + 2u]) * groups[g + 2u] + ii + taps[tb + 1u];
|
|
409
|
+
let raw = lattice[index];
|
|
410
|
+
if ((raw >> 31u) != 0u) { uncertainty = uncertainty + spread[c * T + t]; }
|
|
411
|
+
sum = sum + table[((raw & 0x7fffffffu) * 3u + c) * T + t];
|
|
412
|
+
}
|
|
413
|
+
let e = sum + dark_of(c);
|
|
414
|
+
let flag = select(0u, 1u, uncertainty > UNCERTAINTY_LIMIT * e);
|
|
415
|
+
let de = params.site_gamma * e + uncertainty;
|
|
416
|
+
write_site(i, c, e, de, flag);
|
|
404
417
|
}
|
|
405
418
|
`;
|
|
406
419
|
/**
|
|
@@ -427,47 +440,47 @@ ${SITE_TAIL_WGSL}
|
|
|
427
440
|
@compute @workgroup_size(${DISPLAY_VIEW_QUALITY_WORKGROUP_SIZE})
|
|
428
441
|
fn main(@builtin(global_invocation_id) gid: vec3<u32>, @builtin(num_workgroups) wg: vec3<u32>) {
|
|
429
442
|
let local = gid.x + gid.y * wg.x * ${DISPLAY_VIEW_QUALITY_WORKGROUP_SIZE}u;
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
443
|
+
if (local >= params.count) { return; }
|
|
444
|
+
let i = params.site_first + local;
|
|
445
|
+
let ii = i % params.site_w;
|
|
446
|
+
let jj = i / params.site_w;
|
|
447
|
+
let x = params.site_x0 + i32(ii);
|
|
448
|
+
let y = params.site_y0 + i32(jj);
|
|
449
|
+
let c = channel_of(x, y);
|
|
450
|
+
let T = params.taps;
|
|
451
|
+
var sum = 0.0;
|
|
452
|
+
var uncertainty = 0.0;
|
|
453
|
+
for (var k = 0u; k < params.groups; k = k + 1u) {
|
|
454
|
+
let g = k * GROUP;
|
|
455
|
+
let lw = groups[g + 2u];
|
|
456
|
+
let cw = lw - params.site_w + 1u;
|
|
457
|
+
let ch = groups[g + 3u] - params.site_h + 1u;
|
|
458
|
+
let lattice0 = groups[g + 4u] + jj * lw + ii;
|
|
459
|
+
let tap0 = groups[g + 5u];
|
|
460
|
+
var group_sum = 0.0;
|
|
461
|
+
var group_uncertainty = 0.0;
|
|
462
|
+
for (var dy = 0u; dy < ch; dy = dy + 1u) {
|
|
463
|
+
let row = lattice0 + dy * lw;
|
|
464
|
+
let row_tap = tap0 + dy * cw;
|
|
465
|
+
var row_sum = 0.0;
|
|
466
|
+
var row_uncertainty = 0.0;
|
|
467
|
+
for (var dx = 0u; dx < cw; dx = dx + 1u) {
|
|
468
|
+
let raw = lattice[row + dx];
|
|
469
|
+
let t = row_tap + dx;
|
|
470
|
+
let m = 2u * (raw & 0x7fffffffu);
|
|
471
|
+
if ((raw >> 31u) != 0u) { row_uncertainty = row_uncertainty + spread[c * T + t]; }
|
|
472
|
+
row_sum = row_sum + bitcast<f32>(materials[m + 1u]) * table[(materials[m] * 3u + c) * T + t];
|
|
473
|
+
}
|
|
474
|
+
group_sum = group_sum + row_sum;
|
|
475
|
+
group_uncertainty = group_uncertainty + row_uncertainty;
|
|
476
|
+
}
|
|
477
|
+
sum = sum + group_sum;
|
|
478
|
+
uncertainty = uncertainty + group_uncertainty;
|
|
479
|
+
}
|
|
480
|
+
let e = sum + dark_of(c);
|
|
481
|
+
let flag = select(0u, 1u, uncertainty > UNCERTAINTY_LIMIT * e);
|
|
482
|
+
let de = params.site_gamma * e + uncertainty * (1.0 + params.site_gamma) + params.site_tiny;
|
|
483
|
+
write_site(i, c, e, de, flag);
|
|
471
484
|
}
|
|
472
485
|
`;
|
|
473
486
|
/** Pass 3: the display pixels (see the module comment). */
|
|
@@ -484,6 +497,8 @@ const FLAG_OUTSIDE: u32 = ${DISPLAY_VIEW_QUALITY_FLAG.siteOutsideWindow}u;
|
|
|
484
497
|
const FLAG_STATE: u32 = ${DISPLAY_VIEW_QUALITY_FLAG.stateMissing}u;
|
|
485
498
|
const FLAG_TIE: u32 = ${DISPLAY_VIEW_QUALITY_FLAG.thresholdTie}u;
|
|
486
499
|
const FLAG_CORRECTED: u32 = ${DISPLAY_VIEW_QUALITY_FLAG.corrected}u;
|
|
500
|
+
const FLAG_CHOICE: u32 = ${DISPLAY_VIEW_QUALITY_FLAG.ahdChoice}u;
|
|
501
|
+
const CHOICE_SIGMA: f32 = ${literal(DISPLAY_VIEW_QUALITY_CHOICE_SIGMA)};
|
|
487
502
|
@group(0) @binding(1) var<storage, read> aux: array<f32>;
|
|
488
503
|
@group(0) @binding(2) var<storage, read> geometry: array<f32>;
|
|
489
504
|
@group(0) @binding(3) var<storage, read> sites: array<f32>;
|
|
@@ -497,269 +512,288 @@ var<private> pixel_flags: u32;
|
|
|
497
512
|
${REINHARD_WGSL}
|
|
498
513
|
fn reflect_x(x: i32) -> i32 { if (x < 0) { return -x; } if (x >= i32(params.native_w)) { return 2 * i32(params.native_w) - 2 - x; } return x; }
|
|
499
514
|
fn reflect_y(y: i32) -> i32 { if (y < 0) { return -y; } if (y >= i32(params.native_h)) { return 2 * i32(params.native_h) - 2 - y; } return y; }
|
|
500
|
-
|
|
515
|
+
|
|
501
516
|
fn site_at(x: i32, y: i32) -> u32 {
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
}
|
|
509
|
-
|
|
517
|
+
let rx = reflect_x(x) - params.site_x0;
|
|
518
|
+
let ry = reflect_y(y) - params.site_y0;
|
|
519
|
+
if (rx < 0 || ry < 0 || rx >= i32(params.site_w) || ry >= i32(params.site_h)) { pixel_flags = pixel_flags | FLAG_OUTSIDE; return 0u; }
|
|
520
|
+
let o = (u32(ry) * params.site_w + u32(rx)) * SITE;
|
|
521
|
+
pixel_flags = pixel_flags | (bitcast<u32>(sites[o + 6u]) & 1u);
|
|
522
|
+
return o;
|
|
523
|
+
}
|
|
524
|
+
|
|
510
525
|
fn find_state(key: i32) -> u32 {
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
526
|
+
var lo = 0u; var hi = params.state_count;
|
|
527
|
+
while (lo < hi) {
|
|
528
|
+
let mid = (lo + hi) / 2u;
|
|
529
|
+
if (state_keys[mid] < key) { lo = mid + 1u; } else { hi = mid; }
|
|
530
|
+
}
|
|
531
|
+
if (lo < params.state_count && state_keys[lo] == key) { return lo; }
|
|
532
|
+
return params.state_count;
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
|
|
536
|
+
|
|
522
537
|
fn flat_correction(m0: vec2<f32>, m1: vec2<f32>, m2: vec2<f32>, corr: ptr<function, array<vec2<f32>, 3>>) {
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
538
|
+
var base: array<u32, 3>; var frac: array<f32, 3>; var dg: array<f32, 3>;
|
|
539
|
+
for (var i = 0u; i < 3u; i = i + 1u) {
|
|
540
|
+
var mi = m0; if (i == 1u) { mi = m1; } if (i == 2u) { mi = m2; }
|
|
541
|
+
let clamped = clamp(mi.x, KEY_FLOOR, 1.0);
|
|
542
|
+
let g = (log2(clamped) + KEY_OCTAVES) * KEY_STEPS;
|
|
543
|
+
let b = min(u32(max(floor(g), 0.0)), KEY_TOP);
|
|
544
|
+
base[i] = b; frac[i] = g - f32(b);
|
|
545
|
+
|
|
546
|
+
var slope = 0.0; if (mi.x > KEY_FLOOR && mi.x < 1.0) { slope = 1.4426950408889634 * mi.y / clamped; }
|
|
547
|
+
dg[i] = KEY_STEPS * (slope + 4.76837158203125e-7 + 36.0 * E) + 2.0 * E * (g + 1.0);
|
|
548
|
+
}
|
|
549
|
+
var values: array<f32, 24>;
|
|
550
|
+
var missing = false;
|
|
551
|
+
for (var corner = 0u; corner < 8u; corner = corner + 1u) {
|
|
552
|
+
let i0 = base[0] + (corner & 1u); let i1 = base[1] + ((corner >> 1u) & 1u); let i2 = base[2] + ((corner >> 2u) & 1u);
|
|
553
|
+
let key = i32((i0 * KEY_LEVELS + i1) * KEY_LEVELS + i2);
|
|
554
|
+
var weight = 1.0;
|
|
555
|
+
for (var i = 0u; i < 3u; i = i + 1u) { weight = weight * select(1.0 - frac[i], frac[i], ((corner >> i) & 1u) == 1u); }
|
|
556
|
+
if (weight == 0.0) { for (var c = 0u; c < 3u; c = c + 1u) { values[corner * 3u + c] = 0.0; } continue; }
|
|
557
|
+
atomicOr(&bitmap[u32(key) / 32u], 1u << (u32(key) % 32u));
|
|
558
|
+
let at = find_state(key);
|
|
559
|
+
if (at >= params.state_count) { missing = true; continue; }
|
|
560
|
+
for (var c = 0u; c < 3u; c = c + 1u) { values[corner * 3u + c] = state_values[at * 3u + c]; }
|
|
561
|
+
}
|
|
562
|
+
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; }
|
|
563
|
+
for (var c = 0u; c < 3u; c = c + 1u) {
|
|
564
|
+
var sum = 0.0; var mag = 0.0;
|
|
565
|
+
for (var corner = 0u; corner < 8u; corner = corner + 1u) {
|
|
566
|
+
var weight = 1.0;
|
|
567
|
+
for (var i = 0u; i < 3u; i = i + 1u) { weight = weight * select(1.0 - frac[i], frac[i], ((corner >> i) & 1u) == 1u); }
|
|
568
|
+
sum = sum + weight * values[corner * 3u + c];
|
|
569
|
+
mag = mag + abs(weight * values[corner * 3u + c]);
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
var slope_term = 0.0;
|
|
573
|
+
for (var i = 0u; i < 3u; i = i + 1u) {
|
|
574
|
+
var largest = 0.0;
|
|
575
|
+
for (var corner = 0u; corner < 8u; corner = corner + 1u) {
|
|
576
|
+
if (((corner >> i) & 1u) == 1u) { continue; }
|
|
577
|
+
largest = max(largest, abs(values[(corner | (1u << i)) * 3u + c] - values[corner * 3u + c]));
|
|
578
|
+
}
|
|
579
|
+
slope_term = slope_term + dg[i] * largest;
|
|
580
|
+
}
|
|
581
|
+
(*corr)[c] = vec2<f32>(sum, slope_term + 12.0 * E * mag);
|
|
582
|
+
}
|
|
568
583
|
}
|
|
569
584
|
@compute @workgroup_size(${DISPLAY_VIEW_QUALITY_WORKGROUP_SIZE})
|
|
570
585
|
fn main(@builtin(global_invocation_id) gid: vec3<u32>, @builtin(num_workgroups) wg: vec3<u32>) {
|
|
571
586
|
let i = gid.x + gid.y * wg.x * ${DISPLAY_VIEW_QUALITY_WORKGROUP_SIZE}u;
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
587
|
+
if (i >= params.count) { return; }
|
|
588
|
+
pixel_flags = 0u;
|
|
589
|
+
let rx = i % params.region_w;
|
|
590
|
+
let ry = params.row0 + i / params.region_w;
|
|
591
|
+
let col = rx * STRIDE;
|
|
592
|
+
let row = (params.columns + ry) * STRIDE;
|
|
593
|
+
let col_first = bitcast<i32>(geometry[col]);
|
|
594
|
+
let nx = bitcast<u32>(geometry[col + 1u]);
|
|
595
|
+
let row_first = bitcast<i32>(geometry[row]);
|
|
596
|
+
let ny = bitcast<u32>(geometry[row + 1u]);
|
|
597
|
+
let margin = i32(params.margin);
|
|
598
|
+
let reinhard = params.tone == 1u;
|
|
599
|
+
let count = params.candidates;
|
|
600
|
+
let share = select(1.0, 0.5, count == 2u);
|
|
601
|
+
|
|
602
|
+
let xb_even = geometry[col + 8u]; let xb_odd = geometry[col + 9u];
|
|
603
|
+
let xpp_even = geometry[col + 10u]; let xpp_odd = geometry[col + 11u];
|
|
604
|
+
let xqq_even = geometry[col + 12u]; let xqq_odd = geometry[col + 13u];
|
|
605
|
+
let xpq_even = geometry[col + 14u]; let xpq_odd = geometry[col + 15u];
|
|
606
|
+
let yb_even = geometry[row + 8u]; let yb_odd = geometry[row + 9u];
|
|
607
|
+
let ypp_even = geometry[row + 10u]; let ypp_odd = geometry[row + 11u];
|
|
608
|
+
let yqq_even = geometry[row + 12u]; let yqq_odd = geometry[row + 13u];
|
|
609
|
+
let ypq_even = geometry[row + 14u]; let ypq_odd = geometry[row + 15u];
|
|
610
|
+
let b0 = xb_even * yb_even;
|
|
611
|
+
let b1 = (xpp_odd * ypp_even + xqq_odd * ypp_even + xpp_odd * yqq_even + 2.0 * xpq_odd * ypp_even + 2.0 * xpp_odd * ypq_even + 2.0 * xpq_odd * ypq_even) +
|
|
612
|
+
(xpp_even * ypp_odd + xqq_even * ypp_odd + xpp_even * yqq_odd + 2.0 * xpq_even * ypp_odd + 2.0 * xpp_even * ypq_odd + 2.0 * xpq_even * ypq_odd);
|
|
613
|
+
let b2 = xb_odd * yb_odd;
|
|
614
|
+
var s = array<vec2<f32>, 3>(vec2<f32>(0.0), vec2<f32>(0.0), vec2<f32>(0.0));
|
|
615
|
+
var cov = array<vec2<f32>, 6>(vec2<f32>(0.0), vec2<f32>(0.0), vec2<f32>(0.0), vec2<f32>(0.0), vec2<f32>(0.0), vec2<f32>(0.0));
|
|
616
|
+
var res = array<vec2<f32>, 3>(vec2<f32>(0.0), vec2<f32>(0.0), vec2<f32>(0.0));
|
|
617
|
+
|
|
618
|
+
var choice = array<f32, 3>(0.0, 0.0, 0.0);
|
|
619
|
+
for (var j = 0u; j < ny; j = j + 1u) {
|
|
620
|
+
let ay = geometry[row + 2u + j];
|
|
621
|
+
for (var ii = 0u; ii < nx; ii = ii + 1u) {
|
|
622
|
+
|
|
623
|
+
let aj = vec2<f32>(geometry[col + 2u + ii] * ay, 3.0 * E * abs(geometry[col + 2u + ii] * ay));
|
|
624
|
+
let x = col_first + i32(ii) + margin;
|
|
625
|
+
let y = row_first + i32(j) + margin;
|
|
626
|
+
let phase = u32(y & 1) * 2u + u32(x & 1);
|
|
627
|
+
|
|
628
|
+
var csv: array<vec2<f32>, 3>;
|
|
629
|
+
for (var c = 0u; c < 3u; c = c + 1u) {
|
|
630
|
+
var variance = vec2<f32>(0.0, 0.0);
|
|
614
631
|
let tb = ${DISPLAY_VIEW_QUALITY_AUX.bilinear}u + (phase * 3u + c) * 16u;
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
632
|
+
for (var t = 0u; t < 4u; t = t + 1u) {
|
|
633
|
+
let w = aux[tb + 4u * t + 2u];
|
|
634
|
+
if (w == 0.0) { continue; }
|
|
635
|
+
let o = site_at(x + i32(aux[tb + 4u * t]), y + i32(aux[tb + 4u * t + 1u]));
|
|
636
|
+
variance = b_add(variance, b_scale(vec2<f32>(sites[o + 1u], sites[o + 4u]), w * w));
|
|
637
|
+
}
|
|
621
638
|
csv[c] = b_mul(variance, b_rounded(aux[${DISPLAY_VIEW_QUALITY_AUX.inverseW2}u + phase * 3u + c]));
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
639
|
+
}
|
|
640
|
+
let cb = CAND_BASE + phase * CAND_STRIDE;
|
|
641
|
+
let entries = bitcast<u32>(aux[cb]);
|
|
642
|
+
var e_mean = array<vec2<f32>, 3>(vec2<f32>(0.0), vec2<f32>(0.0), vec2<f32>(0.0));
|
|
643
|
+
var cm_average = array<vec2<f32>, 3>(vec2<f32>(0.0), vec2<f32>(0.0), vec2<f32>(0.0));
|
|
644
|
+
var pixel_variance = vec2<f32>(0.0, 0.0);
|
|
645
|
+
var bs: array<vec2<f32>, 3>; var hs: array<vec2<f32>, 3>;
|
|
646
|
+
var hv: array<vec2<f32>, 3>;
|
|
647
|
+
|
|
648
|
+
var h_cand = array<vec2<f32>, 6>(vec2<f32>(0.0), vec2<f32>(0.0), vec2<f32>(0.0), vec2<f32>(0.0), vec2<f32>(0.0), vec2<f32>(0.0));
|
|
649
|
+
for (var d = 0u; d < count; d = d + 1u) {
|
|
650
|
+
|
|
651
|
+
var cm: array<vec2<f32>, 3>;
|
|
652
|
+
var C: array<vec2<f32>, 6>;
|
|
653
|
+
|
|
654
|
+
|
|
655
|
+
var exact = array<bool, 3>(true, true, true);
|
|
656
|
+
for (var c = 0u; c < 3u; c = c + 1u) { cm[c] = vec2<f32>(0.0, 0.0); }
|
|
657
|
+
for (var k = 0u; k < 6u; k = k + 1u) { C[k] = vec2<f32>(0.0, 0.0); }
|
|
658
|
+
for (var n = 0u; n < entries; n = n + 1u) {
|
|
640
659
|
let eb = cb + 4u + n * ${DISPLAY_VIEW_QUALITY_CANDIDATE_FLOATS}u + 2u + d * 3u;
|
|
641
|
-
|
|
642
|
-
|
|
660
|
+
let w0 = aux[eb]; let w1 = aux[eb + 1u]; let w2 = aux[eb + 2u];
|
|
661
|
+
if (w0 == 0.0 && w1 == 0.0 && w2 == 0.0) { continue; }
|
|
643
662
|
let o = site_at(x + i32(aux[cb + 4u + n * ${DISPLAY_VIEW_QUALITY_CANDIDATE_FLOATS}u]), y + i32(aux[cb + 4u + n * ${DISPLAY_VIEW_QUALITY_CANDIDATE_FLOATS}u + 1u]));
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
663
|
+
let sm = vec2<f32>(sites[o], sites[o + 3u]);
|
|
664
|
+
let sv = vec2<f32>(sites[o + 1u], sites[o + 4u]);
|
|
665
|
+
let white = sm.y == 0.0 && sm.x == 1.0;
|
|
666
|
+
exact[0] = exact[0] && (white || w0 == 0.0); exact[1] = exact[1] && (white || w1 == 0.0); exact[2] = exact[2] && (white || w2 == 0.0);
|
|
667
|
+
cm[0] = b_add(cm[0], b_scale(sm, w0)); cm[1] = b_add(cm[1], b_scale(sm, w1)); cm[2] = b_add(cm[2], b_scale(sm, w2));
|
|
668
|
+
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));
|
|
669
|
+
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));
|
|
670
|
+
}
|
|
671
|
+
for (var c = 0u; c < 3u; c = c + 1u) { if (exact[c]) { cm[c].y = 0.0; } cm_average[c] = b_add(cm_average[c], b_scale(cm[c], share)); }
|
|
672
|
+
|
|
673
|
+
|
|
674
|
+
var bm: array<vec2<f32>, 3>; var bv: array<vec2<f32>, 3>;
|
|
675
|
+
for (var c = 0u; c < 3u; c = c + 1u) {
|
|
676
|
+
let gc = b_rounded(g_of(c));
|
|
677
|
+
var um = b_mul(gc, cm[c]);
|
|
678
|
+
if (exact[c] && cm[c].x == 1.0 && gain_at_clip(c)) { um = vec2<f32>(params.clip_level, 0.0); }
|
|
679
|
+
let uv = b_mul(b_mul(gc, gc), C[select(select(0u, 3u, c == 1u), 5u, c == 2u)]);
|
|
680
|
+
let gap = params.clip_level - um.x;
|
|
681
|
+
if (gap > 0.0 && gap * gap > params.reach2 * uv.x) { bm[c] = um; bv[c] = uv; bs[c] = gc; }
|
|
682
|
+
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); }
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
var hm: array<vec2<f32>, 3>;
|
|
686
|
+
for (var comp = 0u; comp < 3u; comp = comp + 1u) {
|
|
687
|
+
let r0 = b_rounded(m_of(comp, 0u)); let r1 = b_rounded(m_of(comp, 1u)); let r2 = b_rounded(m_of(comp, 2u));
|
|
688
|
+
let mean = b_add(b_add(b_mul(r0, bm[0]), b_mul(r1, bm[1])), b_mul(r2, bm[2]));
|
|
689
|
+
var variance = b_add(b_add(b_mul(b_mul(r0, r0), bv[0]), b_mul(b_mul(r1, r1), bv[1])), b_mul(b_mul(r2, r2), bv[2]));
|
|
690
|
+
let x01 = b_mul(b_mul(b_mul(r0, r1), b_mul(bs[0], bs[1])), C[1]);
|
|
691
|
+
let x02 = b_mul(b_mul(b_mul(r0, r2), b_mul(bs[0], bs[2])), C[2]);
|
|
692
|
+
let x12 = b_mul(b_mul(b_mul(r1, r2), b_mul(bs[1], bs[2])), C[4]);
|
|
693
|
+
variance = b_add(variance, b_scale(b_add(b_add(x01, x02), x12), 2.0));
|
|
694
|
+
var moments: Moments;
|
|
695
|
+
if (!reinhard && mean.x > 0.0 && mean.x < 1.0 && mean.x * mean.x > params.reach2 * variance.x && (1.0 - mean.x) * (1.0 - mean.x) > params.reach2 * variance.x) {
|
|
696
|
+
moments.mean = mean; moments.variance = variance; moments.slope = vec2<f32>(1.0, 0.0);
|
|
697
|
+
} else if (reinhard) {
|
|
698
|
+
moments = reinhard_moments(mean, variance);
|
|
699
|
+
} else {
|
|
700
|
+
|
|
701
|
+
var third = vec2<f32>(0.0, 0.0);
|
|
702
|
+
let k0 = b_mul(r0, bs[0]); let k1 = b_mul(r1, bs[1]); let k2 = b_mul(r2, bs[2]);
|
|
703
|
+
for (var n = 0u; n < entries; n = n + 1u) {
|
|
685
704
|
let eb = cb + 4u + n * ${DISPLAY_VIEW_QUALITY_CANDIDATE_FLOATS}u + 2u + d * 3u;
|
|
686
|
-
|
|
687
|
-
|
|
705
|
+
let w0 = aux[eb]; let w1 = aux[eb + 1u]; let w2 = aux[eb + 2u];
|
|
706
|
+
if (w0 == 0.0 && w1 == 0.0 && w2 == 0.0) { continue; }
|
|
688
707
|
let o = site_at(x + i32(aux[cb + 4u + n * ${DISPLAY_VIEW_QUALITY_CANDIDATE_FLOATS}u]), y + i32(aux[cb + 4u + n * ${DISPLAY_VIEW_QUALITY_CANDIDATE_FLOATS}u + 1u]));
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
708
|
+
let coefficient = b_add(b_add(b_scale(k0, w0), b_scale(k1, w1)), b_scale(k2, w2));
|
|
709
|
+
let cube = b_mul(b_mul(coefficient, coefficient), coefficient);
|
|
710
|
+
third = b_add(third, b_mul(cube, vec2<f32>(sites[o + 2u], sites[o + 5u])));
|
|
711
|
+
}
|
|
712
|
+
var skew = vec2<f32>(0.0, 0.0);
|
|
713
|
+
if (variance.x > 0.0) { skew = b_div(third, b_mul(variance, b_sqrt(variance))); }
|
|
714
|
+
moments = unit_clip(mean, variance, skew);
|
|
715
|
+
}
|
|
716
|
+
hm[comp] = moments.mean; hv[comp] = moments.variance; hs[comp] = moments.slope;
|
|
717
|
+
h_cand[d * 3u + comp] = moments.mean;
|
|
718
|
+
e_mean[comp] = b_add(e_mean[comp], b_scale(moments.mean, share));
|
|
719
|
+
pixel_variance = vec2<f32>(max(pixel_variance.x, moments.variance.x), max(pixel_variance.y, moments.variance.y));
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
var an: array<vec2<f32>, 9>;
|
|
723
|
+
for (var c = 0u; c < 3u; c = c + 1u) {
|
|
724
|
+
an[c] = b_mul(b_mul(hs[0], b_rounded(m_of(0u, c))), bs[c]);
|
|
725
|
+
an[3u + c] = b_mul(b_mul(hs[1], b_rounded(m_of(1u, c))), bs[c]);
|
|
726
|
+
an[6u + c] = b_mul(b_mul(hs[2], b_rounded(m_of(2u, c))), bs[c]);
|
|
727
|
+
var bc = b0; if (c == 1u) { bc = b1; } if (c == 2u) { bc = b2; }
|
|
728
|
+
let wgt = b_mul(b_mul(b_scale(aj, share), b_rounded(bc)), csv[c]);
|
|
729
|
+
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]));
|
|
730
|
+
cov[3] = b_add(cov[3], b_mul(b_mul(wgt, an[3u + c]), an[3u + c])); cov[4] = b_add(cov[4], b_mul(b_mul(wgt, an[3u + c]), an[6u + c])); cov[5] = b_add(cov[5], b_mul(b_mul(wgt, an[6u + c]), an[6u + c]));
|
|
731
|
+
}
|
|
732
|
+
for (var comp = 0u; comp < 3u; comp = comp + 1u) {
|
|
733
|
+
var l = vec2<f32>(0.0, 0.0);
|
|
734
|
+
for (var p = 0u; p < 3u; p = p + 1u) {
|
|
735
|
+
for (var q = 0u; q < 3u; q = q + 1u) {
|
|
736
|
+
var cij = C[0]; if (p + q == 1u) { cij = C[1]; } if ((p == 0u && q == 2u) || (p == 2u && q == 0u)) { cij = C[2]; } if (p == 1u && q == 1u) { cij = C[3]; }
|
|
737
|
+
if ((p == 1u && q == 2u) || (p == 2u && q == 1u)) { cij = C[4]; } if (p == 2u && q == 2u) { cij = C[5]; }
|
|
738
|
+
l = b_add(l, b_mul(b_mul(an[comp * 3u + p], an[comp * 3u + q]), cij));
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
let t = vec2<f32>(share * max(0.0, hv[comp].x - l.x), share * (hv[comp].y + l.y));
|
|
742
|
+
res[comp] = b_add(res[comp], b_mul(b_mul(aj, aj), t));
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
if (count == 2u) {
|
|
746
|
+
|
|
747
|
+
|
|
748
|
+
|
|
749
|
+
for (var comp = 0u; comp < 3u; comp = comp + 1u) {
|
|
750
|
+
let diff = abs(h_cand[comp].x - h_cand[3u + comp].x);
|
|
751
|
+
let both = h_cand[comp].y + h_cand[3u + comp].y;
|
|
752
|
+
choice[comp] = choice[comp] + aj.x * 0.5 * diff;
|
|
753
|
+
e_mean[comp].y = e_mean[comp].y + 0.5 * (diff + both);
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
for (var comp = 0u; comp < 3u; comp = comp + 1u) { s[comp] = b_add(s[comp], b_mul(aj, e_mean[comp])); }
|
|
757
|
+
if (count == 2u) {
|
|
758
|
+
|
|
759
|
+
var x0 = vec2<f32>(0.0, 0.0); var x1 = vec2<f32>(0.0, 0.0); var x2 = vec2<f32>(0.0, 0.0);
|
|
760
|
+
for (var n = 0u; n < entries; n = n + 1u) {
|
|
730
761
|
let eb = cb + 4u + n * ${DISPLAY_VIEW_QUALITY_CANDIDATE_FLOATS}u;
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
762
|
+
let o = site_at(x + i32(aux[eb]), y + i32(aux[eb + 1u]));
|
|
763
|
+
let d0 = b_scale(bs[0], aux[eb + 2u] - aux[eb + 5u]);
|
|
764
|
+
let d1 = b_scale(bs[1], aux[eb + 3u] - aux[eb + 6u]);
|
|
765
|
+
let d2 = b_scale(bs[2], aux[eb + 4u] - aux[eb + 7u]);
|
|
766
|
+
let sv = vec2<f32>(sites[o + 1u], sites[o + 4u]);
|
|
767
|
+
let 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)));
|
|
768
|
+
let 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)));
|
|
769
|
+
let 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)));
|
|
770
|
+
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));
|
|
771
|
+
}
|
|
772
|
+
let ajaj = b_mul(aj, aj);
|
|
773
|
+
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)));
|
|
774
|
+
}
|
|
775
|
+
if (params.correction == 1u) {
|
|
776
|
+
|
|
777
|
+
if (abs(pixel_variance.x - params.threshold) <= pixel_variance.y) { pixel_flags = pixel_flags | FLAG_TIE; }
|
|
778
|
+
if (pixel_variance.x > params.threshold) {
|
|
779
|
+
var corr: array<vec2<f32>, 3>;
|
|
780
|
+
flat_correction(cm_average[0], cm_average[1], cm_average[2], &corr);
|
|
781
|
+
for (var comp = 0u; comp < 3u; comp = comp + 1u) { s[comp] = b_add(s[comp], b_mul(aj, corr[comp])); }
|
|
782
|
+
pixel_flags = pixel_flags | FLAG_CORRECTED;
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
if (choice[0] > CHOICE_SIGMA * sqrt(max(cov[0].x + res[0].x, 0.0)) || choice[1] > CHOICE_SIGMA * sqrt(max(cov[3].x + res[1].x, 0.0)) ||
|
|
789
|
+
choice[2] > CHOICE_SIGMA * sqrt(max(cov[5].x + res[2].x, 0.0))) { pixel_flags = pixel_flags | FLAG_CHOICE; }
|
|
756
790
|
let o = i * ${DISPLAY_VIEW_QUALITY_OUTPUT_FLOATS}u;
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
791
|
+
out[o] = s[0].x; out[o + 1u] = s[1].x; out[o + 2u] = s[2].x;
|
|
792
|
+
out[o + 3u] = cov[0].x + res[0].x; out[o + 4u] = cov[3].x + res[1].x; out[o + 5u] = cov[5].x + res[2].x;
|
|
793
|
+
out[o + 6u] = cov[1].x; out[o + 7u] = cov[2].x; out[o + 8u] = cov[4].x;
|
|
794
|
+
out[o + 9u] = max(s[0].y, max(s[1].y, s[2].y));
|
|
795
|
+
out[o + 10u] = max(max(cov[0].y + res[0].y, cov[3].y + res[1].y), max(cov[5].y + res[2].y, max(cov[1].y, max(cov[2].y, cov[4].y))));
|
|
796
|
+
flags[i] = pixel_flags;
|
|
763
797
|
}
|
|
764
798
|
`;
|
|
765
799
|
/** The lattice pass with a material module appended (`fn material_at(p: vec2<f32>) -> u32`, `var<private> material_uncertain: bool`). */
|