@woosh/meep-engine 3.63.3 → 3.64.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 +51 -0
- package/package.json +1 -1
- package/src/core/color/xyz/m3_chromatic_adaptation_bradford.d.ts +14 -0
- package/src/core/color/xyz/m3_chromatic_adaptation_bradford.d.ts.map +1 -0
- package/src/core/color/xyz/m3_chromatic_adaptation_bradford.js +51 -0
- package/src/core/math/linalg/eigen/matrix_symmetric_3x3_eigen.d.ts +2 -1
- package/src/core/math/linalg/eigen/matrix_symmetric_3x3_eigen.d.ts.map +1 -1
- package/src/core/math/linalg/eigen/matrix_symmetric_3x3_eigen.js +51 -70
- package/src/core/math/linalg/eigen/matrix_symmetric_4x4_eigen.d.ts.map +1 -1
- package/src/core/math/linalg/eigen/matrix_symmetric_4x4_eigen.js +8 -64
- package/src/core/math/linalg/eigen/matrix_symmetric_jacobi_rotate_in_place.d.ts +17 -0
- package/src/core/math/linalg/eigen/matrix_symmetric_jacobi_rotate_in_place.d.ts.map +1 -0
- package/src/core/math/linalg/eigen/matrix_symmetric_jacobi_rotate_in_place.js +64 -0
- package/src/core/math/linalg/solve_box_constrained_qp.d.ts +30 -0
- package/src/core/math/linalg/solve_box_constrained_qp.d.ts.map +1 -0
- package/src/core/math/linalg/solve_box_constrained_qp.js +205 -0
- package/src/engine/physics/constraint/soft_spring_coefficients.d.ts +24 -0
- package/src/engine/physics/constraint/soft_spring_coefficients.d.ts.map +1 -0
- package/src/engine/physics/constraint/soft_spring_coefficients.js +38 -0
- package/src/engine/physics/constraint/solve_constraints.d.ts.map +1 -1
- package/src/engine/physics/constraint/solve_constraints.js +16 -8
- package/src/engine/physics/ecs/PhysicsSystem.d.ts +54 -0
- package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
- package/src/engine/physics/ecs/PhysicsSystem.js +192 -7
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
- package/src/engine/physics/inertia/world_inverse_inertia.d.ts +3 -5
- package/src/engine/physics/inertia/world_inverse_inertia.d.ts.map +1 -1
- package/src/engine/physics/inertia/world_inverse_inertia.js +3 -5
- package/src/engine/physics/vehicle/RaycastVehicle.d.ts +183 -12
- package/src/engine/physics/vehicle/RaycastVehicle.d.ts.map +1 -1
- package/src/engine/physics/vehicle/RaycastVehicle.js +1046 -121
- package/src/shade/playground/tonemap_sdr/README.md +11 -8
- package/src/shade/playground/tonemap_sdr/ToneMapCompare.js +2 -2
- package/src/shade/renderer/Renderer.d.ts +5 -6
- package/src/shade/renderer/Renderer.d.ts.map +1 -1
- package/src/shade/renderer/Renderer.js +15 -88
- package/src/shade/renderer/animation/chunk_animation_curve_evaluate_keys.d.ts +14 -0
- package/src/shade/renderer/animation/chunk_animation_curve_evaluate_keys.d.ts.map +1 -0
- package/src/shade/renderer/animation/chunk_animation_curve_evaluate_keys.js +62 -0
- package/src/shade/renderer/deferred/tonemap/ColorGrade.d.ts +158 -0
- package/src/shade/renderer/deferred/tonemap/ColorGrade.d.ts.map +1 -0
- package/src/shade/renderer/deferred/tonemap/ColorGrade.js +337 -0
- package/src/shade/renderer/deferred/tonemap/SAMPLER_TONEMAP_LUT.d.ts +9 -0
- package/src/shade/renderer/deferred/tonemap/SAMPLER_TONEMAP_LUT.d.ts.map +1 -0
- package/src/shade/renderer/deferred/tonemap/SAMPLER_TONEMAP_LUT.js +15 -0
- package/src/shade/renderer/deferred/tonemap/TONE_MAP_OPERATOR_ACES.d.ts +6 -0
- package/src/shade/renderer/deferred/tonemap/TONE_MAP_OPERATOR_ACES.d.ts.map +1 -0
- package/src/shade/renderer/deferred/tonemap/TONE_MAP_OPERATOR_ACES.js +84 -0
- package/src/shade/renderer/deferred/tonemap/TONE_MAP_OPERATOR_GT7.d.ts +10 -0
- package/src/shade/renderer/deferred/tonemap/TONE_MAP_OPERATOR_GT7.d.ts.map +1 -0
- package/src/shade/renderer/deferred/tonemap/TONE_MAP_OPERATOR_GT7.js +25 -0
- package/src/shade/renderer/deferred/tonemap/TONE_MAP_OPERATOR_NONE.d.ts +9 -0
- package/src/shade/renderer/deferred/tonemap/TONE_MAP_OPERATOR_NONE.d.ts.map +1 -0
- package/src/shade/renderer/deferred/tonemap/TONE_MAP_OPERATOR_NONE.js +20 -0
- package/src/shade/renderer/deferred/tonemap/TONE_MAP_OPERATOR_PBR_NEUTRAL.d.ts +14 -0
- package/src/shade/renderer/deferred/tonemap/TONE_MAP_OPERATOR_PBR_NEUTRAL.d.ts.map +1 -0
- package/src/shade/renderer/deferred/tonemap/TONE_MAP_OPERATOR_PBR_NEUTRAL.js +30 -0
- package/src/shade/renderer/deferred/tonemap/ToneMapOperator.d.ts +54 -0
- package/src/shade/renderer/deferred/tonemap/ToneMapOperator.d.ts.map +1 -0
- package/src/shade/renderer/deferred/tonemap/ToneMapOperator.js +63 -0
- package/src/shade/renderer/deferred/tonemap/ToneMapper.d.ts +106 -0
- package/src/shade/renderer/deferred/tonemap/ToneMapper.d.ts.map +1 -0
- package/src/shade/renderer/deferred/tonemap/ToneMapper.js +474 -0
- package/src/shade/renderer/deferred/tonemap/TonemapAces2Tables.d.ts +5 -13
- package/src/shade/renderer/deferred/tonemap/TonemapAces2Tables.d.ts.map +1 -1
- package/src/shade/renderer/deferred/tonemap/TonemapAces2Tables.js +5 -44
- package/src/shade/renderer/deferred/tonemap/TonemapDisplaySettings.d.ts +7 -25
- package/src/shade/renderer/deferred/tonemap/TonemapDisplaySettings.d.ts.map +1 -1
- package/src/shade/renderer/deferred/tonemap/TonemapDisplaySettings.js +11 -51
- package/src/shade/renderer/deferred/tonemap/m3_white_balance_rec709.d.ts +20 -0
- package/src/shade/renderer/deferred/tonemap/m3_white_balance_rec709.d.ts.map +1 -0
- package/src/shade/renderer/deferred/tonemap/m3_white_balance_rec709.js +103 -0
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_lut.d.ts +9 -0
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_lut.d.ts.map +1 -0
- package/src/shade/renderer/deferred/tonemap/{shader_tonemap_HDR_none.js → shader_tonemap_HDR_lut.js} +22 -18
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_lut.d.ts +9 -0
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_lut.d.ts.map +1 -0
- package/src/shade/renderer/deferred/tonemap/{shader_tonemap_LDR_aces.js → shader_tonemap_LDR_lut.js} +24 -24
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_lut_bake.d.ts +23 -0
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_lut_bake.d.ts.map +1 -0
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_lut_bake.js +92 -0
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_lut_sdr_from_hdr.d.ts +15 -0
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_lut_sdr_from_hdr.d.ts.map +1 -0
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_lut_sdr_from_hdr.js +73 -0
- package/src/shade/renderer/fluid/GPUFluidCascade.d.ts +3 -3
- package/src/shade/renderer/fluid/GPUFluidCascadeStack.d.ts +1 -1
- package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts +6 -6
- package/src/shade/renderer/fluid/pressure/GPUFluidPressureSolve.d.ts +1 -1
- package/src/shade/renderer/fluid/query/GPUFluidQueries.d.ts +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts +1 -1
- package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
- package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
- package/src/shade/renderer/shader/chunk/color/conversion/chunk_CRM_REC709_AP1.d.ts +22 -0
- package/src/shade/renderer/shader/chunk/color/conversion/chunk_CRM_REC709_AP1.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/color/conversion/chunk_CRM_REC709_AP1.js +62 -0
- package/src/shade/renderer/shader/chunk/color/grade/chunk_color_grade.d.ts +13 -0
- package/src/shade/renderer/shader/chunk/color/grade/chunk_color_grade.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/color/grade/chunk_color_grade.js +140 -0
- package/src/shade/renderer/shader/chunk/color/oklab/chunk_oklab_compute_max_saturation.d.ts +11 -0
- package/src/shade/renderer/shader/chunk/color/oklab/chunk_oklab_compute_max_saturation.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/color/oklab/chunk_oklab_compute_max_saturation.js +65 -0
- package/src/shade/renderer/shader/chunk/color/tonemap/chunk_bt2390_eetf.d.ts +14 -0
- package/src/shade/renderer/shader/chunk/color/tonemap/chunk_bt2390_eetf.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/color/tonemap/chunk_bt2390_eetf.js +38 -0
- package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_lut.d.ts +16 -0
- package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_lut.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_lut.js +41 -0
- package/src/shade/renderer/water/query/GPUWaterQueries.d.ts +1 -1
- package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +8 -8
- package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts.map +1 -1
- package/src/shade/wgsl/emulator/WGSLLanguageCore.js +2 -0
- package/src/shade/renderer/ShadeToneMappingMode.d.ts +0 -15
- package/src/shade/renderer/ShadeToneMappingMode.d.ts.map +0 -1
- package/src/shade/renderer/ShadeToneMappingMode.js +0 -41
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR.d.ts +0 -9
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR.d.ts.map +0 -1
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR.js +0 -79
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_aces.d.ts +0 -17
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_aces.d.ts.map +0 -1
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_aces.js +0 -101
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_none.d.ts +0 -9
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_none.d.ts.map +0 -1
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_pbr_neutral.d.ts +0 -10
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_pbr_neutral.d.ts.map +0 -1
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_pbr_neutral.js +0 -80
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR.d.ts +0 -9
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR.d.ts.map +0 -1
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR.js +0 -80
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_aces.d.ts +0 -10
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_aces.d.ts.map +0 -1
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_none.d.ts +0 -9
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_none.d.ts.map +0 -1
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_none.js +0 -71
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_pbr_neutral.d.ts +0 -10
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_pbr_neutral.d.ts.map +0 -1
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_pbr_neutral.js +0 -76
- package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_hdr_bt2390.d.ts +0 -3
- package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_hdr_bt2390.d.ts.map +0 -1
- package/src/shade/renderer/shader/chunk/color/tonemap/chunk_tonemap_hdr_bt2390.js +0 -44
|
@@ -7,18 +7,18 @@ import {
|
|
|
7
7
|
import { PAPER_WHITE_NITS } from "../../shader/chunk/color/tonemap/chunk_PAPER_WHITE_NITS.js";
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
|
-
* What
|
|
10
|
+
* What the ACES tone-map operator binds as `aces2_tables`: two ACES 2.0 output transforms, each its parameters and
|
|
11
11
|
* gamut tables, both limited to Rec.709, the gamut of the SDR picture they expand.
|
|
12
12
|
*
|
|
13
|
-
* 1. An SDR display, 100 cd/m². The
|
|
13
|
+
* 1. An SDR display, 100 cd/m². The operator runs it backwards, from the SDR picture to the scene.
|
|
14
14
|
* 2. This display: the peak over the paper white, times 100 cd/m². A display at or under the paper white gets
|
|
15
|
-
* 100 cd/m², which the
|
|
15
|
+
* 100 cd/m², which the operator does not read.
|
|
16
16
|
*
|
|
17
17
|
* Both take SDR white for 100 cd/m², ACES 2.0's reference, so an SDR picture expanded for a display keeps SDR white
|
|
18
18
|
* where the paper white puts it.
|
|
19
19
|
*
|
|
20
|
-
* Building one transform takes 7 to 13 ms, so the tables are built on the first {@link update}
|
|
21
|
-
*
|
|
20
|
+
* Building one transform takes 7 to 13 ms, so the tables are built on the first {@link update}, and again only when
|
|
21
|
+
* the display's peak changes.
|
|
22
22
|
*/
|
|
23
23
|
export class TonemapAces2Tables {
|
|
24
24
|
/**
|
|
@@ -29,13 +29,6 @@ export class TonemapAces2Tables {
|
|
|
29
29
|
|
|
30
30
|
#peak_nits = NaN;
|
|
31
31
|
|
|
32
|
-
/**
|
|
33
|
-
* @type {GPUBuffer|null}
|
|
34
|
-
*/
|
|
35
|
-
#buffer = null;
|
|
36
|
-
|
|
37
|
-
#uploaded = false;
|
|
38
|
-
|
|
39
32
|
/**
|
|
40
33
|
* Build the tables for a display, if they are not built for it already.
|
|
41
34
|
*
|
|
@@ -59,39 +52,7 @@ export class TonemapAces2Tables {
|
|
|
59
52
|
aces2_transform_block_write(this.data, ACES2_BLOCK_FLOATS, 100 * headroom, ACES2_LIMITING_REC709);
|
|
60
53
|
|
|
61
54
|
this.#peak_nits = peak_nits;
|
|
62
|
-
this.#uploaded = false;
|
|
63
55
|
|
|
64
56
|
return true;
|
|
65
57
|
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* The tables on the device, written if they changed since the last call.
|
|
69
|
-
*
|
|
70
|
-
* @param {GPUDevice} device
|
|
71
|
-
* @returns {GPUBuffer}
|
|
72
|
-
*/
|
|
73
|
-
gpu_buffer(device) {
|
|
74
|
-
if (this.#buffer === null) {
|
|
75
|
-
this.#buffer = device.createBuffer({
|
|
76
|
-
label: "tonemap/aces2 tables",
|
|
77
|
-
size: this.data.byteLength,
|
|
78
|
-
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,
|
|
79
|
-
});
|
|
80
|
-
this.#uploaded = false;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
if (!this.#uploaded) {
|
|
84
|
-
device.queue.writeBuffer(this.#buffer, 0, this.data);
|
|
85
|
-
this.#uploaded = true;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
return this.#buffer;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
destroy() {
|
|
92
|
-
if (this.#buffer !== null) {
|
|
93
|
-
this.#buffer.destroy();
|
|
94
|
-
this.#buffer = null;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
58
|
}
|
|
@@ -1,22 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* What the tone mapper is told about the display: the colour space the canvas actually shows, and the display's peak.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* `peak_nits`. So one instance serves whichever pass is current.
|
|
4
|
+
* The apply passes read the matrix from linear Rec.2020, the LUT's output, to the canvas's linear primaries, as
|
|
5
|
+
* {@link TONEMAP_SETTINGS}. The peak is what an HDR LUT is baked for.
|
|
7
6
|
*
|
|
8
|
-
*
|
|
7
|
+
* The matrix is three columns, not a `mat3x3f`: a `mat3x3f` pads each column to 16 bytes and the immediate
|
|
9
8
|
* serialiser writes its nine floats end to end.
|
|
10
9
|
*/
|
|
11
10
|
export class TonemapDisplaySettings {
|
|
12
|
-
display_from_rec709_c0: Float32Array;
|
|
13
|
-
display_from_rec709_c1: Float32Array;
|
|
14
|
-
display_from_rec709_c2: Float32Array;
|
|
15
11
|
display_from_rec2020_c0: Float32Array;
|
|
16
12
|
display_from_rec2020_c1: Float32Array;
|
|
17
13
|
display_from_rec2020_c2: Float32Array;
|
|
18
14
|
/**
|
|
19
|
-
* The display's peak, cd/m².
|
|
15
|
+
* The display's peak, cd/m². An HDR LUT is baked for it.
|
|
20
16
|
* @type {number}
|
|
21
17
|
*/
|
|
22
18
|
peak_nits: number;
|
|
@@ -29,22 +25,8 @@ export class TonemapDisplaySettings {
|
|
|
29
25
|
set_canvas_color_space(color_space: PredefinedColorSpace | string): void;
|
|
30
26
|
}
|
|
31
27
|
/**
|
|
32
|
-
* Immediate data of
|
|
28
|
+
* Immediate data of the tone mapper's apply passes. Filled by {@link TonemapDisplaySettings}.
|
|
33
29
|
*/
|
|
34
|
-
export const
|
|
35
|
-
/**
|
|
36
|
-
* Immediate data of a pass that works in Rec.709 and is told the display's peak. Filled by {@link
|
|
37
|
-
* TonemapDisplaySettings}.
|
|
38
|
-
*/
|
|
39
|
-
export const TONEMAP_SETTINGS_REC709_PEAK: WebGPUStruct;
|
|
40
|
-
/**
|
|
41
|
-
* Immediate data of a pass that works in Rec.2020. Filled by {@link TonemapDisplaySettings}.
|
|
42
|
-
*/
|
|
43
|
-
export const TONEMAP_SETTINGS_REC2020: WebGPUStruct;
|
|
44
|
-
/**
|
|
45
|
-
* Immediate data of a pass that works in Rec.2020 and is told the display's peak. Filled by {@link
|
|
46
|
-
* TonemapDisplaySettings}.
|
|
47
|
-
*/
|
|
48
|
-
export const TONEMAP_SETTINGS_REC2020_PEAK: WebGPUStruct;
|
|
30
|
+
export const TONEMAP_SETTINGS: WebGPUStruct;
|
|
49
31
|
import { WebGPUStruct } from "../../shader/type/WebGPUStruct.js";
|
|
50
32
|
//# sourceMappingURL=TonemapDisplaySettings.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TonemapDisplaySettings.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/deferred/tonemap/TonemapDisplaySettings.js"],"names":[],"mappings":"AAiDA
|
|
1
|
+
{"version":3,"file":"TonemapDisplaySettings.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/deferred/tonemap/TonemapDisplaySettings.js"],"names":[],"mappings":"AAiDA;;;;;;;;GAQG;AACH;IACI,sCAA8C;IAC9C,sCAA8C;IAC9C,sCAA8C;IAE9C;;;OAGG;IACH,WAFU,MAAM,CAEC;IAMjB;;;;;OAKG;IACH,oCAHW,oBAAoB,GAAC,MAAM,QAcrC;CACJ;AAED;;GAEG;AACH,4CAKG;6BAjG0B,mCAAmC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { m3_rgb_to_xyz_from_primaries } from "../../../../core/color/xyz/m3_rgb_to_xyz_from_primaries.js";
|
|
2
2
|
import { m3_invert } from "../../../../core/geom/mat3/m3_invert.js";
|
|
3
3
|
import { m3_multiply } from "../../../../core/geom/mat3/m3_multiply.js";
|
|
4
|
-
import {
|
|
4
|
+
import { vec3f } from "../../shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
|
|
5
5
|
import { WebGPUStruct } from "../../shader/type/WebGPUStruct.js";
|
|
6
6
|
|
|
7
7
|
// chromaticities of red, green and blue; every space here has a D65 white, so none needs chromatic adaptation
|
|
@@ -48,26 +48,21 @@ function write_columns(c0, c1, c2, from, to) {
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
/**
|
|
51
|
-
*
|
|
51
|
+
* What the tone mapper is told about the display: the colour space the canvas actually shows, and the display's peak.
|
|
52
52
|
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
* `peak_nits`. So one instance serves whichever pass is current.
|
|
53
|
+
* The apply passes read the matrix from linear Rec.2020, the LUT's output, to the canvas's linear primaries, as
|
|
54
|
+
* {@link TONEMAP_SETTINGS}. The peak is what an HDR LUT is baked for.
|
|
56
55
|
*
|
|
57
|
-
*
|
|
56
|
+
* The matrix is three columns, not a `mat3x3f`: a `mat3x3f` pads each column to 16 bytes and the immediate
|
|
58
57
|
* serialiser writes its nine floats end to end.
|
|
59
58
|
*/
|
|
60
59
|
export class TonemapDisplaySettings {
|
|
61
|
-
display_from_rec709_c0 = new Float32Array([1, 0, 0]);
|
|
62
|
-
display_from_rec709_c1 = new Float32Array([0, 1, 0]);
|
|
63
|
-
display_from_rec709_c2 = new Float32Array([0, 0, 1]);
|
|
64
|
-
|
|
65
60
|
display_from_rec2020_c0 = new Float32Array(3);
|
|
66
61
|
display_from_rec2020_c1 = new Float32Array(3);
|
|
67
62
|
display_from_rec2020_c2 = new Float32Array(3);
|
|
68
63
|
|
|
69
64
|
/**
|
|
70
|
-
* The display's peak, cd/m².
|
|
65
|
+
* The display's peak, cd/m². An HDR LUT is baked for it.
|
|
71
66
|
* @type {number}
|
|
72
67
|
*/
|
|
73
68
|
peak_nits = 1000;
|
|
@@ -89,10 +84,6 @@ export class TonemapDisplaySettings {
|
|
|
89
84
|
throw new Error(`Canvas colorSpace '${color_space}' is not one the tonemap passes can write`);
|
|
90
85
|
}
|
|
91
86
|
|
|
92
|
-
write_columns(
|
|
93
|
-
this.display_from_rec709_c0, this.display_from_rec709_c1, this.display_from_rec709_c2,
|
|
94
|
-
PRIMARIES_REC709, display
|
|
95
|
-
);
|
|
96
87
|
write_columns(
|
|
97
88
|
this.display_from_rec2020_c0, this.display_from_rec2020_c1, this.display_from_rec2020_c2,
|
|
98
89
|
PRIMARIES_REC2020, display
|
|
@@ -100,43 +91,12 @@ export class TonemapDisplaySettings {
|
|
|
100
91
|
}
|
|
101
92
|
}
|
|
102
93
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
display_from_rec709_c2: vec3f,
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
const display_from_rec2020 = {
|
|
94
|
+
/**
|
|
95
|
+
* Immediate data of the tone mapper's apply passes. Filled by {@link TonemapDisplaySettings}.
|
|
96
|
+
*/
|
|
97
|
+
export const TONEMAP_SETTINGS = WebGPUStruct.from({
|
|
111
98
|
/** column 0 of the matrix from linear Rec.2020 to the canvas's linear primaries */
|
|
112
99
|
display_from_rec2020_c0: vec3f,
|
|
113
100
|
display_from_rec2020_c1: vec3f,
|
|
114
101
|
display_from_rec2020_c2: vec3f,
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* The display's peak, cd/m². The paper white is not a setting: it is PAPER_WHITE_NITS on both outputs.
|
|
119
|
-
*/
|
|
120
|
-
const peak = { peak_nits: f32 };
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* Immediate data of a pass that works in Rec.709. Filled by {@link TonemapDisplaySettings}.
|
|
124
|
-
*/
|
|
125
|
-
export const TONEMAP_SETTINGS_REC709 = WebGPUStruct.from({ ...display_from_rec709 });
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* Immediate data of a pass that works in Rec.709 and is told the display's peak. Filled by {@link
|
|
129
|
-
* TonemapDisplaySettings}.
|
|
130
|
-
*/
|
|
131
|
-
export const TONEMAP_SETTINGS_REC709_PEAK = WebGPUStruct.from({ ...display_from_rec709, ...peak });
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* Immediate data of a pass that works in Rec.2020. Filled by {@link TonemapDisplaySettings}.
|
|
135
|
-
*/
|
|
136
|
-
export const TONEMAP_SETTINGS_REC2020 = WebGPUStruct.from({ ...display_from_rec2020 });
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* Immediate data of a pass that works in Rec.2020 and is told the display's peak. Filled by {@link
|
|
140
|
-
* TonemapDisplaySettings}.
|
|
141
|
-
*/
|
|
142
|
-
export const TONEMAP_SETTINGS_REC2020_PEAK = WebGPUStruct.from({ ...display_from_rec2020, ...peak });
|
|
102
|
+
});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unreal's temperature white balance (`WhiteBalance` in `TonemapCommon.ush`, the default "White Balance" mode) on
|
|
3
|
+
* linear Rec.709, as a matrix. Light from a white at `temperature` K, moved along its isotherm by `tint`, becomes
|
|
4
|
+
* neutral: a lower temperature cools the picture.
|
|
5
|
+
*
|
|
6
|
+
* The source white is on the Planckian locus below 4000 K and on the CIE daylight locus from there, as Unreal's is,
|
|
7
|
+
* and the adaptation to D65 is Bradford. At 6500 K and no tint, where Unreal skips the stage, the matrix is the
|
|
8
|
+
* identity.
|
|
9
|
+
*
|
|
10
|
+
* @param {Float32Array|Float64Array|number[]} out 9 elements, row-major
|
|
11
|
+
* @param {number} temperature K
|
|
12
|
+
* @param {number} tint offset along the isotherm, in units of 0.05 in CIE 1960 uv; Unreal's range is -1 to 1
|
|
13
|
+
*/
|
|
14
|
+
export function m3_white_balance_rec709(out: Float32Array | Float64Array | number[], temperature: number, tint: number): void;
|
|
15
|
+
/**
|
|
16
|
+
* The temperature white balance is neutral at these, and Unreal skips it there.
|
|
17
|
+
*/
|
|
18
|
+
export const WHITE_BALANCE_NEUTRAL_TEMPERATURE: 6500;
|
|
19
|
+
export const WHITE_BALANCE_NEUTRAL_TINT: 0;
|
|
20
|
+
//# sourceMappingURL=m3_white_balance_rec709.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"m3_white_balance_rec709.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/deferred/tonemap/m3_white_balance_rec709.js"],"names":[],"mappings":"AAqCA;;;;;;;;;;;;GAYG;AACH,6CAJW,YAAY,GAAC,YAAY,GAAC,MAAM,EAAE,eAClC,MAAM,QACN,MAAM,QAsDhB;AAxFD;;GAEG;AACH,qDAAsD;AACtD,2CAA4C"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { m3_chromatic_adaptation_bradford } from "../../../../core/color/xyz/m3_chromatic_adaptation_bradford.js";
|
|
2
|
+
import { m3_rgb_to_xyz_from_primaries } from "../../../../core/color/xyz/m3_rgb_to_xyz_from_primaries.js";
|
|
3
|
+
import { m3_invert } from "../../../../core/geom/mat3/m3_invert.js";
|
|
4
|
+
import { m3_multiply } from "../../../../core/geom/mat3/m3_multiply.js";
|
|
5
|
+
|
|
6
|
+
const D65_X = 0.3127;
|
|
7
|
+
const D65_Y = 0.3290;
|
|
8
|
+
|
|
9
|
+
const REC709_TO_XYZ = new Float64Array(9);
|
|
10
|
+
m3_rgb_to_xyz_from_primaries(REC709_TO_XYZ, [0.640, 0.330, 0.300, 0.600, 0.150, 0.060], D65_X, D65_Y);
|
|
11
|
+
|
|
12
|
+
const XYZ_TO_REC709 = new Float64Array(9);
|
|
13
|
+
m3_invert(XYZ_TO_REC709, REC709_TO_XYZ);
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* The temperature white balance is neutral at these, and Unreal skips it there.
|
|
17
|
+
*/
|
|
18
|
+
export const WHITE_BALANCE_NEUTRAL_TEMPERATURE = 6500;
|
|
19
|
+
export const WHITE_BALANCE_NEUTRAL_TINT = 0;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Chromaticity of the Planckian locus at `temperature` K, Krystek's rational fit in CIE 1960 uv, as Unreal's
|
|
23
|
+
* `PlanckianLocusChromaticity`.
|
|
24
|
+
*
|
|
25
|
+
* @param {number[]} out [x, y]
|
|
26
|
+
* @param {number} temperature
|
|
27
|
+
*/
|
|
28
|
+
function planckian_locus_uv(out, temperature) {
|
|
29
|
+
const t = temperature;
|
|
30
|
+
out[0] = (0.860117757 + 1.54118254e-4 * t + 1.28641212e-7 * t * t) / (1 + 8.42420235e-4 * t + 7.08145163e-7 * t * t);
|
|
31
|
+
out[1] = (0.317398726 + 4.22806245e-5 * t + 4.20481691e-8 * t * t) / (1 - 2.89741816e-5 * t + 1.61456053e-7 * t * t);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const scratch_uv = [0, 0];
|
|
35
|
+
const scratch_cat = new Float64Array(9);
|
|
36
|
+
const scratch_m = new Float64Array(9);
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Unreal's temperature white balance (`WhiteBalance` in `TonemapCommon.ush`, the default "White Balance" mode) on
|
|
40
|
+
* linear Rec.709, as a matrix. Light from a white at `temperature` K, moved along its isotherm by `tint`, becomes
|
|
41
|
+
* neutral: a lower temperature cools the picture.
|
|
42
|
+
*
|
|
43
|
+
* The source white is on the Planckian locus below 4000 K and on the CIE daylight locus from there, as Unreal's is,
|
|
44
|
+
* and the adaptation to D65 is Bradford. At 6500 K and no tint, where Unreal skips the stage, the matrix is the
|
|
45
|
+
* identity.
|
|
46
|
+
*
|
|
47
|
+
* @param {Float32Array|Float64Array|number[]} out 9 elements, row-major
|
|
48
|
+
* @param {number} temperature K
|
|
49
|
+
* @param {number} tint offset along the isotherm, in units of 0.05 in CIE 1960 uv; Unreal's range is -1 to 1
|
|
50
|
+
*/
|
|
51
|
+
export function m3_white_balance_rec709(out, temperature, tint) {
|
|
52
|
+
if (temperature === WHITE_BALANCE_NEUTRAL_TEMPERATURE && tint === WHITE_BALANCE_NEUTRAL_TINT) {
|
|
53
|
+
out.fill(0);
|
|
54
|
+
out[0] = 1;
|
|
55
|
+
out[4] = 1;
|
|
56
|
+
out[8] = 1;
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
let x, y;
|
|
61
|
+
|
|
62
|
+
if (temperature < 4000) {
|
|
63
|
+
planckian_locus_uv(scratch_uv, temperature);
|
|
64
|
+
const [u, v] = scratch_uv;
|
|
65
|
+
const d = 2 * u - 8 * v + 4;
|
|
66
|
+
x = 3 * u / d;
|
|
67
|
+
y = 2 * v / d;
|
|
68
|
+
} else {
|
|
69
|
+
// the CIE daylight locus, with the temperature corrected for the revision of Planck's c2, so 6500 is D65
|
|
70
|
+
const t = temperature * 1.4388 / 1.438;
|
|
71
|
+
const r = 1 / t;
|
|
72
|
+
|
|
73
|
+
x = t <= 7000
|
|
74
|
+
? 0.244063 + (0.09911e3 + (2.9678e6 - 4.6070e9 * r) * r) * r
|
|
75
|
+
: 0.237040 + (0.24748e3 + (1.9018e6 - 2.0064e9 * r) * r) * r;
|
|
76
|
+
y = -3 * x * x + 2.87 * x - 0.275;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
{
|
|
80
|
+
// along the isotherm, the normal to the Planckian locus in uv, by the tint
|
|
81
|
+
const t = temperature;
|
|
82
|
+
planckian_locus_uv(scratch_uv, t);
|
|
83
|
+
const [u, v] = scratch_uv;
|
|
84
|
+
|
|
85
|
+
const ud = (-1.13758118e9 - 1.91615621e6 * t - 1.53177 * t * t) / ((1.41213984e6 + 1189.62 * t + t * t) ** 2);
|
|
86
|
+
const vd = (1.97471536e9 - 705674.0 * t - 308.607 * t * t) / ((6.19363586e6 - 179.456 * t + t * t) ** 2);
|
|
87
|
+
const length = Math.hypot(ud, vd);
|
|
88
|
+
|
|
89
|
+
const iu = u + vd / length * tint * 0.05;
|
|
90
|
+
const iv = v - ud / length * tint * 0.05;
|
|
91
|
+
|
|
92
|
+
const d0 = 2 * u - 8 * v + 4;
|
|
93
|
+
const d1 = 2 * iu - 8 * iv + 4;
|
|
94
|
+
|
|
95
|
+
x += 3 * iu / d1 - 3 * u / d0;
|
|
96
|
+
y += 2 * iv / d1 - 2 * v / d0;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
m3_chromatic_adaptation_bradford(scratch_cat, x, y, D65_X, D65_Y);
|
|
100
|
+
|
|
101
|
+
m3_multiply(scratch_m, scratch_cat, REC709_TO_XYZ);
|
|
102
|
+
m3_multiply(out, XYZ_TO_REC709, scratch_m);
|
|
103
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The HDR output of {@link ToneMapper}: exposure, then the HDR LUT, written in the canvas's primaries, extended, where
|
|
3
|
+
* 1.0 is SDR white.
|
|
4
|
+
*
|
|
5
|
+
* @type {ImageShader}
|
|
6
|
+
*/
|
|
7
|
+
export const shader_tonemap_HDR_lut: ImageShader;
|
|
8
|
+
import { ImageShader } from "../../shader/ImageShader.js";
|
|
9
|
+
//# sourceMappingURL=shader_tonemap_HDR_lut.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shader_tonemap_HDR_lut.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_lut.js"],"names":[],"mappings":"AAmDA;;;;;GAKG;AACH,qCAFU,WAAW,CAclB;4BAlEyB,6BAA6B"}
|
package/src/shade/renderer/deferred/tonemap/{shader_tonemap_HDR_none.js → shader_tonemap_HDR_lut.js}
RENAMED
|
@@ -1,16 +1,21 @@
|
|
|
1
|
-
import { F32_CONTAINER_STRUCT } from "../../shader/type/F32_CONTAINER_STRUCT.js";
|
|
2
|
-
import { TONEMAP_SETTINGS_REC709 } from "./TonemapDisplaySettings.js";
|
|
3
1
|
import { chunk_sRGBTransferOETF } from "../../shader/chunk/color/sRGB/chunk_sRGBTransferOETF.js";
|
|
2
|
+
import { chunk_tonemap_lut } from "../../shader/chunk/color/tonemap/chunk_tonemap_lut.js";
|
|
4
3
|
import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
|
|
5
4
|
import { ImageShader } from "../../shader/ImageShader.js";
|
|
6
5
|
import { ShaderResourceSetDescriptor } from "../../shader/resource/ShaderResourceSetDescriptor.js";
|
|
7
6
|
import { ShaderDescriptor } from "../../shader/ShaderDescriptor.js";
|
|
7
|
+
import { F32_CONTAINER_STRUCT } from "../../shader/type/F32_CONTAINER_STRUCT.js";
|
|
8
|
+
import { SAMPLER_TONEMAP_LUT } from "./SAMPLER_TONEMAP_LUT.js";
|
|
9
|
+
import { TONEMAP_SETTINGS } from "./TonemapDisplaySettings.js";
|
|
8
10
|
|
|
9
11
|
const resources = new ShaderResourceSetDescriptor();
|
|
10
|
-
|
|
12
|
+
|
|
13
|
+
resources.setImmediate("settings", TONEMAP_SETTINGS);
|
|
11
14
|
resources.createGroup()
|
|
12
15
|
.addTexture("input_color", "float")
|
|
13
16
|
.addUniform("exposure", F32_CONTAINER_STRUCT)
|
|
17
|
+
.addTexture("lut", "float", "3d")
|
|
18
|
+
.addSampler("lut_sampler", "filtering", SAMPLER_TONEMAP_LUT)
|
|
14
19
|
|
|
15
20
|
const body = CodeChunk.from(
|
|
16
21
|
//language=WGSL
|
|
@@ -21,39 +26,38 @@ fn main(
|
|
|
21
26
|
) -> @location(0) vec4<f32> {
|
|
22
27
|
|
|
23
28
|
// scene color in linear Rec. 709
|
|
24
|
-
|
|
29
|
+
let color = textureLoad(input_color, vec2i(coord.xy), 0).rgb * exposure.value;
|
|
25
30
|
|
|
26
|
-
color
|
|
31
|
+
let uvw = tonemap_lut_coordinate(color, f32(textureDimensions(lut).x));
|
|
32
|
+
let color_2020 = tonemap_lut_pq_decode(textureSampleLevel(lut, lut_sampler, uvw, 0.0).rgb);
|
|
27
33
|
|
|
28
|
-
//
|
|
34
|
+
// into the primaries the canvas reports it was configured with (Renderer#configure_context)
|
|
35
|
+
let color_display = mat3x3<f32>(
|
|
36
|
+
settings.display_from_rec2020_c0,
|
|
37
|
+
settings.display_from_rec2020_c1,
|
|
38
|
+
settings.display_from_rec2020_c2
|
|
39
|
+
) * color_2020;
|
|
29
40
|
|
|
30
41
|
// NOTE: no dithering, colorspace is wide
|
|
31
42
|
|
|
32
|
-
// into the primaries the canvas reports it was configured with (Renderer#configure_context): Display P3, or
|
|
33
|
-
// sRGB where the browser would not configure P3
|
|
34
|
-
let color_display = mat3x3<f32>(
|
|
35
|
-
settings.display_from_rec709_c0,
|
|
36
|
-
settings.display_from_rec709_c1,
|
|
37
|
-
settings.display_from_rec709_c2
|
|
38
|
-
) * color;
|
|
39
|
-
|
|
40
43
|
// apply gamma. Note that gamma is the same for "Display P3" and "sRGB"
|
|
41
44
|
return vec4(sRGBTransferOETF(color_display), 1.0);
|
|
42
45
|
}
|
|
43
46
|
`, [
|
|
47
|
+
chunk_tonemap_lut,
|
|
44
48
|
chunk_sRGBTransferOETF,
|
|
45
49
|
]
|
|
46
50
|
);
|
|
47
51
|
|
|
48
52
|
/**
|
|
49
|
-
* The HDR output
|
|
50
|
-
* SDR white
|
|
53
|
+
* The HDR output of {@link ToneMapper}: exposure, then the HDR LUT, written in the canvas's primaries, extended, where
|
|
54
|
+
* 1.0 is SDR white.
|
|
51
55
|
*
|
|
52
56
|
* @type {ImageShader}
|
|
53
57
|
*/
|
|
54
|
-
export const
|
|
58
|
+
export const shader_tonemap_HDR_lut = new ImageShader({
|
|
55
59
|
descriptor: ShaderDescriptor.from({
|
|
56
|
-
label: "Tonemap/HDR
|
|
60
|
+
label: "Tonemap/HDR",
|
|
57
61
|
resources,
|
|
58
62
|
body
|
|
59
63
|
}),
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The SDR output of {@link ToneMapper}: exposure, then the SDR LUT, the canvas's primaries, the sRGB transfer curve
|
|
3
|
+
* and an 8-bit dither. The 8-bit target clips anything the LUT puts past SDR white.
|
|
4
|
+
*
|
|
5
|
+
* @type {ImageShader}
|
|
6
|
+
*/
|
|
7
|
+
export const shader_tonemap_LDR_lut: ImageShader;
|
|
8
|
+
import { ImageShader } from "../../shader/ImageShader.js";
|
|
9
|
+
//# sourceMappingURL=shader_tonemap_LDR_lut.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shader_tonemap_LDR_lut.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_lut.js"],"names":[],"mappings":"AA0DA;;;;;GAKG;AACH,qCAFU,WAAW,CAclB;4BAtEyB,6BAA6B"}
|
package/src/shade/renderer/deferred/tonemap/{shader_tonemap_LDR_aces.js → shader_tonemap_LDR_lut.js}
RENAMED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import { F32_CONTAINER_STRUCT } from "../../shader/type/F32_CONTAINER_STRUCT.js";
|
|
2
|
-
import { TONEMAP_SETTINGS_REC709 } from "./TonemapDisplaySettings.js";
|
|
3
1
|
import { chunk_sRGBTransferOETF } from "../../shader/chunk/color/sRGB/chunk_sRGBTransferOETF.js";
|
|
4
|
-
import {
|
|
2
|
+
import { chunk_tonemap_lut } from "../../shader/chunk/color/tonemap/chunk_tonemap_lut.js";
|
|
5
3
|
import {
|
|
6
4
|
chunk_dither_color_8bit_triangle_noise
|
|
7
5
|
} from "../../shader/chunk/texture/dither/chunk_dither_color_8bit_triangle_noise.js";
|
|
@@ -9,12 +7,18 @@ import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
|
|
|
9
7
|
import { ImageShader } from "../../shader/ImageShader.js";
|
|
10
8
|
import { ShaderResourceSetDescriptor } from "../../shader/resource/ShaderResourceSetDescriptor.js";
|
|
11
9
|
import { ShaderDescriptor } from "../../shader/ShaderDescriptor.js";
|
|
10
|
+
import { F32_CONTAINER_STRUCT } from "../../shader/type/F32_CONTAINER_STRUCT.js";
|
|
11
|
+
import { SAMPLER_TONEMAP_LUT } from "./SAMPLER_TONEMAP_LUT.js";
|
|
12
|
+
import { TONEMAP_SETTINGS } from "./TonemapDisplaySettings.js";
|
|
12
13
|
|
|
13
14
|
const resources = new ShaderResourceSetDescriptor();
|
|
14
|
-
|
|
15
|
+
|
|
16
|
+
resources.setImmediate("settings", TONEMAP_SETTINGS);
|
|
15
17
|
resources.createGroup()
|
|
16
18
|
.addTexture("input_color", "float")
|
|
17
19
|
.addUniform("exposure", F32_CONTAINER_STRUCT)
|
|
20
|
+
.addTexture("lut", "float", "3d")
|
|
21
|
+
.addSampler("lut_sampler", "filtering", SAMPLER_TONEMAP_LUT)
|
|
18
22
|
|
|
19
23
|
const body = CodeChunk.from(
|
|
20
24
|
//language=WGSL
|
|
@@ -25,46 +29,42 @@ fn main(
|
|
|
25
29
|
) -> @location(0) vec4<f32> {
|
|
26
30
|
|
|
27
31
|
// scene color in linear Rec. 709
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
color *= exposure.value;
|
|
32
|
+
let color = textureLoad(input_color, vec2i(coord.xy), 0).rgb * exposure.value;
|
|
31
33
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
+
let uvw = tonemap_lut_coordinate(color, f32(textureDimensions(lut).x));
|
|
35
|
+
let color_2020 = tonemap_lut_pq_decode(textureSampleLevel(lut, lut_sampler, uvw, 0.0).rgb);
|
|
34
36
|
|
|
35
|
-
// into the primaries the canvas reports it was configured with (Renderer#configure_context)
|
|
36
|
-
// sRGB where the browser would not configure P3. A Rec.709 colour sits inside both.
|
|
37
|
+
// into the primaries the canvas reports it was configured with (Renderer#configure_context)
|
|
37
38
|
let color_display = mat3x3<f32>(
|
|
38
|
-
settings.
|
|
39
|
-
settings.
|
|
40
|
-
settings.
|
|
41
|
-
) *
|
|
39
|
+
settings.display_from_rec2020_c0,
|
|
40
|
+
settings.display_from_rec2020_c1,
|
|
41
|
+
settings.display_from_rec2020_c2
|
|
42
|
+
) * color_2020;
|
|
42
43
|
|
|
43
44
|
// apply gamma. Note that gamma is the same for "Display P3" and "sRGB"
|
|
44
|
-
|
|
45
|
+
var color_gamma = sRGBTransferOETF(color_display);
|
|
45
46
|
|
|
46
47
|
// apply dither to remove color banding
|
|
47
|
-
|
|
48
|
+
color_gamma += dither_color_8bit_triangle_noise(coord.xy);
|
|
48
49
|
|
|
49
|
-
return vec4(
|
|
50
|
+
return vec4(color_gamma, 1.0);
|
|
50
51
|
}
|
|
51
52
|
`, [
|
|
52
|
-
|
|
53
|
+
chunk_tonemap_lut,
|
|
53
54
|
chunk_dither_color_8bit_triangle_noise,
|
|
54
55
|
chunk_sRGBTransferOETF,
|
|
55
56
|
]
|
|
56
57
|
);
|
|
57
58
|
|
|
58
59
|
/**
|
|
59
|
-
* The SDR output
|
|
60
|
-
*
|
|
61
|
-
* picture into an HDR display's headroom.
|
|
60
|
+
* The SDR output of {@link ToneMapper}: exposure, then the SDR LUT, the canvas's primaries, the sRGB transfer curve
|
|
61
|
+
* and an 8-bit dither. The 8-bit target clips anything the LUT puts past SDR white.
|
|
62
62
|
*
|
|
63
63
|
* @type {ImageShader}
|
|
64
64
|
*/
|
|
65
|
-
export const
|
|
65
|
+
export const shader_tonemap_LDR_lut = new ImageShader({
|
|
66
66
|
descriptor: ShaderDescriptor.from({
|
|
67
|
-
label: "Tonemap/LDR
|
|
67
|
+
label: "Tonemap/LDR",
|
|
68
68
|
resources,
|
|
69
69
|
body
|
|
70
70
|
}),
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The compute shader that bakes `operator` into a LUT, `lut`, one texel a thread: the texel's PQ signal decoded to
|
|
3
|
+
* exposed scene colour, through the colour grade and the operator, and encoded again, as {@link chunk_tonemap_lut}
|
|
4
|
+
* describes. The grade is `grade`, a {@link COLOR_GRADE_STRUCT}, and `grade_keys`, its curves' keyframes; see
|
|
5
|
+
* `ColorGrade#pack`. Built on first use and kept for the operator.
|
|
6
|
+
*
|
|
7
|
+
* Dispatch `ceil(resolution / TONEMAP_LUT_BAKE_GROUP)` workgroups along each axis.
|
|
8
|
+
*
|
|
9
|
+
* @param {ToneMapOperator} operator
|
|
10
|
+
* @returns {ComputeShader}
|
|
11
|
+
*/
|
|
12
|
+
export function shader_tonemap_lut_bake(operator: ToneMapOperator): ComputeShader;
|
|
13
|
+
/**
|
|
14
|
+
* Immediate data of a bake: the peak the operator is evaluated for, `PAPER_WHITE_NITS` for an SDR LUT.
|
|
15
|
+
*/
|
|
16
|
+
export const TONEMAP_LUT_BAKE_SETTINGS: WebGPUStruct;
|
|
17
|
+
/**
|
|
18
|
+
* Edge of the cube of LUT texels one workgroup bakes.
|
|
19
|
+
*/
|
|
20
|
+
export const TONEMAP_LUT_BAKE_GROUP: 4;
|
|
21
|
+
import { ComputeShader } from "../../shader/ComputeShader.js";
|
|
22
|
+
import { WebGPUStruct } from "../../shader/type/WebGPUStruct.js";
|
|
23
|
+
//# sourceMappingURL=shader_tonemap_lut_bake.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shader_tonemap_lut_bake.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/deferred/tonemap/shader_tonemap_lut_bake.js"],"names":[],"mappings":"AA2BA;;;;;;;;;;GAUG;AACH,oEAFa,aAAa,CAuDzB;AA/ED;;GAEG;AACH,qDAA+E;AAE/E;;GAEG;AACH,uCAAwC;8BAfV,+BAA+B;6BAIhC,mCAAmC"}
|