@woosh/meep-engine 3.51.0 → 3.52.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/package.json +1 -1
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
- package/src/shade/playground/tonemap_sdr/README.md +5 -3
- package/src/shade/renderer/Renderer.d.ts +1 -1
- package/src/shade/renderer/Renderer.d.ts.map +1 -1
- package/src/shade/renderer/Renderer.js +43 -15
- package/src/shade/renderer/ShadeToneMappingMode.d.ts +3 -2
- package/src/shade/renderer/ShadeToneMappingMode.js +15 -4
- package/src/shade/renderer/deferred/tonemap/TonemapAces2Tables.d.ts +38 -0
- package/src/shade/renderer/deferred/tonemap/TonemapAces2Tables.d.ts.map +1 -0
- package/src/shade/renderer/deferred/tonemap/TonemapAces2Tables.js +97 -0
- package/src/shade/renderer/deferred/{TonemapDisplaySettings.d.ts → tonemap/TonemapDisplaySettings.d.ts} +1 -1
- package/src/shade/renderer/deferred/tonemap/TonemapDisplaySettings.d.ts.map +1 -0
- package/src/shade/renderer/deferred/{TonemapDisplaySettings.js → tonemap/TonemapDisplaySettings.js} +5 -5
- package/src/shade/renderer/deferred/{shader_tonemap_HDR.d.ts → tonemap/shader_tonemap_HDR.d.ts} +1 -1
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR.d.ts.map +1 -0
- package/src/shade/renderer/deferred/{shader_tonemap_HDR.js → tonemap/shader_tonemap_HDR.js} +9 -9
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_aces.d.ts +17 -0
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_aces.d.ts.map +1 -0
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_aces.js +101 -0
- package/src/shade/renderer/deferred/{shader_tonemap_HDR_none.d.ts → tonemap/shader_tonemap_HDR_none.d.ts} +1 -1
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_none.d.ts.map +1 -0
- package/src/shade/renderer/deferred/{shader_tonemap_HDR_none.js → tonemap/shader_tonemap_HDR_none.js} +6 -6
- package/src/shade/renderer/deferred/{shader_tonemap_HDR_pbr_neutral.d.ts → tonemap/shader_tonemap_HDR_pbr_neutral.d.ts} +1 -1
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_pbr_neutral.d.ts.map +1 -0
- package/src/shade/renderer/deferred/{shader_tonemap_HDR_pbr_neutral.js → tonemap/shader_tonemap_HDR_pbr_neutral.js} +8 -8
- package/src/shade/renderer/deferred/{shader_tonemap_LDR.d.ts → tonemap/shader_tonemap_LDR.d.ts} +1 -1
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR.d.ts.map +1 -0
- package/src/shade/renderer/deferred/{shader_tonemap_LDR.js → tonemap/shader_tonemap_LDR.js} +10 -10
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_aces.d.ts +10 -0
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_aces.d.ts.map +1 -0
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_aces.js +77 -0
- package/src/shade/renderer/deferred/{shader_tonemap_LDR_none.d.ts → tonemap/shader_tonemap_LDR_none.d.ts} +1 -1
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_none.d.ts.map +1 -0
- package/src/shade/renderer/deferred/{shader_tonemap_LDR_none.js → tonemap/shader_tonemap_LDR_none.js} +7 -7
- package/src/shade/renderer/deferred/{shader_tonemap_LDR_pbr_neutral.d.ts → tonemap/shader_tonemap_LDR_pbr_neutral.d.ts} +1 -1
- package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_pbr_neutral.d.ts.map +1 -0
- package/src/shade/renderer/deferred/{shader_tonemap_LDR_pbr_neutral.js → tonemap/shader_tonemap_LDR_pbr_neutral.js} +8 -8
- 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/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/tonemap/ACES_TONE_MAPPING_BRIEF_2026_10_17.md +160 -0
- package/src/shade/renderer/shader/chunk/color/tonemap/HDR_TONE_MAPPING_FORMS_BRIEF_2026_10_16.md +5 -1
- package/src/shade/renderer/shader/chunk/color/tonemap/SDR_TONE_MAPPING_BRIEF_2026_10_16.md +15 -5
- package/src/shade/renderer/shader/chunk/color/tonemap/aces/aces2_transform_block.d.ts +41 -0
- package/src/shade/renderer/shader/chunk/color/tonemap/aces/aces2_transform_block.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/color/tonemap/aces/aces2_transform_block.js +692 -0
- package/src/shade/renderer/shader/chunk/color/tonemap/aces/chunk_aces2_output_transform.d.ts +25 -0
- package/src/shade/renderer/shader/chunk/color/tonemap/aces/chunk_aces2_output_transform.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/color/tonemap/aces/chunk_aces2_output_transform.js +446 -0
- package/src/shade/renderer/shader/chunk/color/tonemap/aces/chunk_aces_ue_matrices.d.ts +22 -0
- package/src/shade/renderer/shader/chunk/color/tonemap/aces/chunk_aces_ue_matrices.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/color/tonemap/aces/chunk_aces_ue_matrices.js +68 -0
- package/src/shade/renderer/shader/chunk/color/tonemap/aces/chunk_tonemap_ue_filmic.d.ts +32 -0
- package/src/shade/renderer/shader/chunk/color/tonemap/aces/chunk_tonemap_ue_filmic.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/color/tonemap/aces/chunk_tonemap_ue_filmic.js +163 -0
- package/src/shade/renderer/shader/chunk/color/tonemap/chunk_PAPER_WHITE_NITS.d.ts +10 -3
- package/src/shade/renderer/shader/chunk/color/tonemap/chunk_PAPER_WHITE_NITS.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/color/tonemap/chunk_PAPER_WHITE_NITS.js +12 -4
- package/src/shade/renderer/deferred/TonemapDisplaySettings.d.ts.map +0 -1
- package/src/shade/renderer/deferred/shader_tonemap_HDR.d.ts.map +0 -1
- package/src/shade/renderer/deferred/shader_tonemap_HDR_none.d.ts.map +0 -1
- package/src/shade/renderer/deferred/shader_tonemap_HDR_pbr_neutral.d.ts.map +0 -1
- package/src/shade/renderer/deferred/shader_tonemap_LDR.d.ts.map +0 -1
- package/src/shade/renderer/deferred/shader_tonemap_LDR_none.d.ts.map +0 -1
- package/src/shade/renderer/deferred/shader_tonemap_LDR_pbr_neutral.d.ts.map +0 -1
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { F32_CONTAINER_STRUCT } from "
|
|
1
|
+
import { F32_CONTAINER_STRUCT } from "../../shader/type/F32_CONTAINER_STRUCT.js";
|
|
2
2
|
import { TONEMAP_SETTINGS_REC709_PEAK } from "./TonemapDisplaySettings.js";
|
|
3
|
-
import { chunk_sRGBTransferOETF } from "
|
|
4
|
-
import { chunk_PAPER_WHITE_NITS } from "
|
|
5
|
-
import { chunk_tonemap_khronos_pbr } from "
|
|
6
|
-
import { CodeChunk } from "
|
|
7
|
-
import { ImageShader } from "
|
|
8
|
-
import { ShaderResourceSetDescriptor } from "
|
|
9
|
-
import { ShaderDescriptor } from "
|
|
3
|
+
import { chunk_sRGBTransferOETF } from "../../shader/chunk/color/sRGB/chunk_sRGBTransferOETF.js";
|
|
4
|
+
import { chunk_PAPER_WHITE_NITS } from "../../shader/chunk/color/tonemap/chunk_PAPER_WHITE_NITS.js";
|
|
5
|
+
import { chunk_tonemap_khronos_pbr } from "../../shader/chunk/color/tonemap/chunk_tonemap_khronos_pbr.js";
|
|
6
|
+
import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
|
|
7
|
+
import { ImageShader } from "../../shader/ImageShader.js";
|
|
8
|
+
import { ShaderResourceSetDescriptor } from "../../shader/resource/ShaderResourceSetDescriptor.js";
|
|
9
|
+
import { ShaderDescriptor } from "../../shader/ShaderDescriptor.js";
|
|
10
10
|
|
|
11
11
|
const resources = new ShaderResourceSetDescriptor();
|
|
12
12
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shader_tonemap_LDR.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/deferred/tonemap/shader_tonemap_LDR.js"],"names":[],"mappings":"AA6DA;;;;;GAKG;AACH,iCAFU,WAAW,CAclB;4BArEyB,6BAA6B"}
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { F32_CONTAINER_STRUCT } from "
|
|
1
|
+
import { F32_CONTAINER_STRUCT } from "../../shader/type/F32_CONTAINER_STRUCT.js";
|
|
2
2
|
import { TONEMAP_SETTINGS_REC2020 } from "./TonemapDisplaySettings.js";
|
|
3
|
-
import { chunk_CRM_FROM_REC709_TO_REC2020 } from "
|
|
4
|
-
import { chunk_sRGBTransferOETF } from "
|
|
5
|
-
import { chunk_PAPER_WHITE_NITS } from "
|
|
6
|
-
import { chunk_tonemap_gt7 } from "
|
|
3
|
+
import { chunk_CRM_FROM_REC709_TO_REC2020 } from "../../shader/chunk/color/conversion/chunk_CRM_FROM_REC709_TO_REC2020.js";
|
|
4
|
+
import { chunk_sRGBTransferOETF } from "../../shader/chunk/color/sRGB/chunk_sRGBTransferOETF.js";
|
|
5
|
+
import { chunk_PAPER_WHITE_NITS } from "../../shader/chunk/color/tonemap/chunk_PAPER_WHITE_NITS.js";
|
|
6
|
+
import { chunk_tonemap_gt7 } from "../../shader/chunk/color/tonemap/gt7/chunk_tonemap_gt7.js";
|
|
7
7
|
import {
|
|
8
8
|
chunk_dither_color_8bit_triangle_noise
|
|
9
|
-
} from "
|
|
10
|
-
import { CodeChunk } from "
|
|
11
|
-
import { ImageShader } from "
|
|
12
|
-
import { ShaderResourceSetDescriptor } from "
|
|
13
|
-
import { ShaderDescriptor } from "
|
|
9
|
+
} from "../../shader/chunk/texture/dither/chunk_dither_color_8bit_triangle_noise.js";
|
|
10
|
+
import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
|
|
11
|
+
import { ImageShader } from "../../shader/ImageShader.js";
|
|
12
|
+
import { ShaderResourceSetDescriptor } from "../../shader/resource/ShaderResourceSetDescriptor.js";
|
|
13
|
+
import { ShaderDescriptor } from "../../shader/ShaderDescriptor.js";
|
|
14
14
|
|
|
15
15
|
const resources = new ShaderResourceSetDescriptor();
|
|
16
16
|
resources.setImmediate("settings", TONEMAP_SETTINGS_REC2020);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The SDR output with {@link ShadeToneMappingMode.ACES}: exposure, Unreal Engine's default "Filmic" tone mapping, the
|
|
3
|
+
* canvas's primaries, the sRGB transfer curve and an 8-bit dither. {@link shader_tonemap_HDR_aces} expands the same
|
|
4
|
+
* picture into an HDR display's headroom.
|
|
5
|
+
*
|
|
6
|
+
* @type {ImageShader}
|
|
7
|
+
*/
|
|
8
|
+
export const shader_tonemap_LDR_aces: ImageShader;
|
|
9
|
+
import { ImageShader } from "../../shader/ImageShader.js";
|
|
10
|
+
//# sourceMappingURL=shader_tonemap_LDR_aces.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shader_tonemap_LDR_aces.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_aces.js"],"names":[],"mappings":"AAyDA;;;;;;GAMG;AACH,sCAFU,WAAW,CAclB;4BApEyB,6BAA6B"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { F32_CONTAINER_STRUCT } from "../../shader/type/F32_CONTAINER_STRUCT.js";
|
|
2
|
+
import { TONEMAP_SETTINGS_REC709 } from "./TonemapDisplaySettings.js";
|
|
3
|
+
import { chunk_sRGBTransferOETF } from "../../shader/chunk/color/sRGB/chunk_sRGBTransferOETF.js";
|
|
4
|
+
import { chunk_tonemap_ue_filmic } from "../../shader/chunk/color/tonemap/aces/chunk_tonemap_ue_filmic.js";
|
|
5
|
+
import {
|
|
6
|
+
chunk_dither_color_8bit_triangle_noise
|
|
7
|
+
} from "../../shader/chunk/texture/dither/chunk_dither_color_8bit_triangle_noise.js";
|
|
8
|
+
import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
|
|
9
|
+
import { ImageShader } from "../../shader/ImageShader.js";
|
|
10
|
+
import { ShaderResourceSetDescriptor } from "../../shader/resource/ShaderResourceSetDescriptor.js";
|
|
11
|
+
import { ShaderDescriptor } from "../../shader/ShaderDescriptor.js";
|
|
12
|
+
|
|
13
|
+
const resources = new ShaderResourceSetDescriptor();
|
|
14
|
+
resources.setImmediate("settings", TONEMAP_SETTINGS_REC709);
|
|
15
|
+
resources.createGroup()
|
|
16
|
+
.addTexture("input_color", "float")
|
|
17
|
+
.addUniform("exposure", F32_CONTAINER_STRUCT)
|
|
18
|
+
|
|
19
|
+
const body = CodeChunk.from(
|
|
20
|
+
//language=WGSL
|
|
21
|
+
`
|
|
22
|
+
@fragment
|
|
23
|
+
fn main(
|
|
24
|
+
@builtin(position) coord : vec4<f32>,
|
|
25
|
+
) -> @location(0) vec4<f32> {
|
|
26
|
+
|
|
27
|
+
// scene color in linear Rec. 709
|
|
28
|
+
var color = textureLoad(input_color, vec2i(coord.xy), 0).rgb;
|
|
29
|
+
|
|
30
|
+
color *= exposure.value;
|
|
31
|
+
|
|
32
|
+
// Unreal's default SDR rendering, in Rec.709 and within it
|
|
33
|
+
color = tonemap_ue_filmic(color);
|
|
34
|
+
|
|
35
|
+
// into the primaries the canvas reports it was configured with (Renderer#configure_context): Display P3, or
|
|
36
|
+
// sRGB where the browser would not configure P3. A Rec.709 colour sits inside both.
|
|
37
|
+
let color_display = mat3x3<f32>(
|
|
38
|
+
settings.display_from_rec709_c0,
|
|
39
|
+
settings.display_from_rec709_c1,
|
|
40
|
+
settings.display_from_rec709_c2
|
|
41
|
+
) * color;
|
|
42
|
+
|
|
43
|
+
// apply gamma. Note that gamma is the same for "Display P3" and "sRGB"
|
|
44
|
+
color = sRGBTransferOETF(color_display);
|
|
45
|
+
|
|
46
|
+
// apply dither to remove color banding
|
|
47
|
+
color += dither_color_8bit_triangle_noise(coord.xy);
|
|
48
|
+
|
|
49
|
+
return vec4(color, 1.0);
|
|
50
|
+
}
|
|
51
|
+
`, [
|
|
52
|
+
chunk_tonemap_ue_filmic,
|
|
53
|
+
chunk_dither_color_8bit_triangle_noise,
|
|
54
|
+
chunk_sRGBTransferOETF,
|
|
55
|
+
]
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* The SDR output with {@link ShadeToneMappingMode.ACES}: exposure, Unreal Engine's default "Filmic" tone mapping, the
|
|
60
|
+
* canvas's primaries, the sRGB transfer curve and an 8-bit dither. {@link shader_tonemap_HDR_aces} expands the same
|
|
61
|
+
* picture into an HDR display's headroom.
|
|
62
|
+
*
|
|
63
|
+
* @type {ImageShader}
|
|
64
|
+
*/
|
|
65
|
+
export const shader_tonemap_LDR_aces = new ImageShader({
|
|
66
|
+
descriptor: ShaderDescriptor.from({
|
|
67
|
+
label: "Tonemap/LDR/aces",
|
|
68
|
+
resources,
|
|
69
|
+
body
|
|
70
|
+
}),
|
|
71
|
+
targets: [
|
|
72
|
+
{
|
|
73
|
+
label: "tone-mapped",
|
|
74
|
+
format: "rgba8unorm"
|
|
75
|
+
}
|
|
76
|
+
]
|
|
77
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shader_tonemap_LDR_none.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_none.js"],"names":[],"mappings":"AAoDA;;;;;GAKG;AACH,sCAFU,WAAW,CAclB;4BA/DyB,6BAA6B"}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { F32_CONTAINER_STRUCT } from "
|
|
1
|
+
import { F32_CONTAINER_STRUCT } from "../../shader/type/F32_CONTAINER_STRUCT.js";
|
|
2
2
|
import { TONEMAP_SETTINGS_REC709 } from "./TonemapDisplaySettings.js";
|
|
3
|
-
import { chunk_sRGBTransferOETF } from "
|
|
3
|
+
import { chunk_sRGBTransferOETF } from "../../shader/chunk/color/sRGB/chunk_sRGBTransferOETF.js";
|
|
4
4
|
import {
|
|
5
5
|
chunk_dither_color_8bit_triangle_noise
|
|
6
|
-
} from "
|
|
7
|
-
import { CodeChunk } from "
|
|
8
|
-
import { ImageShader } from "
|
|
9
|
-
import { ShaderResourceSetDescriptor } from "
|
|
10
|
-
import { ShaderDescriptor } from "
|
|
6
|
+
} from "../../shader/chunk/texture/dither/chunk_dither_color_8bit_triangle_noise.js";
|
|
7
|
+
import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
|
|
8
|
+
import { ImageShader } from "../../shader/ImageShader.js";
|
|
9
|
+
import { ShaderResourceSetDescriptor } from "../../shader/resource/ShaderResourceSetDescriptor.js";
|
|
10
|
+
import { ShaderDescriptor } from "../../shader/ShaderDescriptor.js";
|
|
11
11
|
|
|
12
12
|
const resources = new ShaderResourceSetDescriptor();
|
|
13
13
|
resources.setImmediate("settings", TONEMAP_SETTINGS_REC709);
|
|
@@ -6,5 +6,5 @@
|
|
|
6
6
|
* @type {ImageShader}
|
|
7
7
|
*/
|
|
8
8
|
export const shader_tonemap_LDR_pbr_neutral: ImageShader;
|
|
9
|
-
import { ImageShader } from "
|
|
9
|
+
import { ImageShader } from "../../shader/ImageShader.js";
|
|
10
10
|
//# sourceMappingURL=shader_tonemap_LDR_pbr_neutral.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shader_tonemap_LDR_pbr_neutral.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_pbr_neutral.js"],"names":[],"mappings":"AAwDA;;;;;;GAMG;AACH,6CAFU,WAAW,CAclB;4BAnEyB,6BAA6B"}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { F32_CONTAINER_STRUCT } from "
|
|
1
|
+
import { F32_CONTAINER_STRUCT } from "../../shader/type/F32_CONTAINER_STRUCT.js";
|
|
2
2
|
import { TONEMAP_SETTINGS_REC709 } from "./TonemapDisplaySettings.js";
|
|
3
|
-
import { chunk_sRGBTransferOETF } from "
|
|
4
|
-
import { chunk_tonemap_khronos_pbr } from "
|
|
3
|
+
import { chunk_sRGBTransferOETF } from "../../shader/chunk/color/sRGB/chunk_sRGBTransferOETF.js";
|
|
4
|
+
import { chunk_tonemap_khronos_pbr } from "../../shader/chunk/color/tonemap/chunk_tonemap_khronos_pbr.js";
|
|
5
5
|
import {
|
|
6
6
|
chunk_dither_color_8bit_triangle_noise
|
|
7
|
-
} from "
|
|
8
|
-
import { CodeChunk } from "
|
|
9
|
-
import { ImageShader } from "
|
|
10
|
-
import { ShaderResourceSetDescriptor } from "
|
|
11
|
-
import { ShaderDescriptor } from "
|
|
7
|
+
} from "../../shader/chunk/texture/dither/chunk_dither_color_8bit_triangle_noise.js";
|
|
8
|
+
import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
|
|
9
|
+
import { ImageShader } from "../../shader/ImageShader.js";
|
|
10
|
+
import { ShaderResourceSetDescriptor } from "../../shader/resource/ShaderResourceSetDescriptor.js";
|
|
11
|
+
import { ShaderDescriptor } from "../../shader/ShaderDescriptor.js";
|
|
12
12
|
|
|
13
13
|
const resources = new ShaderResourceSetDescriptor();
|
|
14
14
|
resources.setImmediate("settings", TONEMAP_SETTINGS_REC709);
|
|
@@ -136,7 +136,7 @@ export class GPUFluidCascade {
|
|
|
136
136
|
* @param {*} _resources
|
|
137
137
|
* @param {{encoder: ShadeGPUCommandContext}} context
|
|
138
138
|
*/
|
|
139
|
-
static "__#
|
|
139
|
+
static "__#264@#execute_restrict"(record: object, _resources: any, context: {
|
|
140
140
|
encoder: ShadeGPUCommandContext;
|
|
141
141
|
}): void;
|
|
142
142
|
/**
|
|
@@ -144,7 +144,7 @@ export class GPUFluidCascade {
|
|
|
144
144
|
* @param {*} _resources
|
|
145
145
|
* @param {{encoder: ShadeGPUCommandContext}} context
|
|
146
146
|
*/
|
|
147
|
-
static "__#
|
|
147
|
+
static "__#264@#execute_fill"(record: object, _resources: any, context: {
|
|
148
148
|
encoder: ShadeGPUCommandContext;
|
|
149
149
|
}): void;
|
|
150
150
|
/**
|
|
@@ -152,7 +152,7 @@ export class GPUFluidCascade {
|
|
|
152
152
|
* @param {import("../../../engine/graphics/render/frame_graph/FramePassResources.js").FramePassResources} resources
|
|
153
153
|
* @param {{encoder: ShadeGPUCommandContext}} context
|
|
154
154
|
*/
|
|
155
|
-
static "__#
|
|
155
|
+
static "__#264@#execute"(record: object, resources: import("../../../engine/graphics/render/frame_graph/FramePassResources.js").FramePassResources, context: {
|
|
156
156
|
encoder: ShadeGPUCommandContext;
|
|
157
157
|
}): void;
|
|
158
158
|
/**
|
|
@@ -56,7 +56,7 @@ export class GPUFluidCascadeStack {
|
|
|
56
56
|
* @param {*} _resources
|
|
57
57
|
* @param {{encoder: import("../../device/ShadeGPUCommandContext.js").ShadeGPUCommandContext}} context
|
|
58
58
|
*/
|
|
59
|
-
static "__#
|
|
59
|
+
static "__#266@#execute_publish"(pass: object, _resources: any, context: {
|
|
60
60
|
encoder: import("../../device/ShadeGPUCommandContext.js").ShadeGPUCommandContext;
|
|
61
61
|
}): void;
|
|
62
62
|
/**
|
|
@@ -90,19 +90,19 @@ export class GPUFluidForcing {
|
|
|
90
90
|
* @param {number} clear_size bytes cleared from 0 when the pool reuses the buffer
|
|
91
91
|
* @returns {BufferResourceDescriptor}
|
|
92
92
|
*/
|
|
93
|
-
static "__#
|
|
93
|
+
static "__#267@#descriptor"(kept: BufferResourceDescriptor[], role: number, size: number, usage: number, clear_size: number): BufferResourceDescriptor;
|
|
94
94
|
/**
|
|
95
95
|
* @param {object} record
|
|
96
96
|
* @param {FramePassResources} resources
|
|
97
97
|
* @param {{encoder: ShadeGPUCommandContext}} context
|
|
98
98
|
*/
|
|
99
|
-
static "__#
|
|
99
|
+
static "__#267@#execute_extract"(record: object, resources: FramePassResources, context: {
|
|
100
100
|
encoder: ShadeGPUCommandContext;
|
|
101
101
|
}): void;
|
|
102
|
-
static "__#
|
|
103
|
-
static "__#
|
|
104
|
-
static "__#
|
|
105
|
-
static "__#
|
|
102
|
+
static "__#267@#execute_clear"(record: any, _resources: any, context: any): void;
|
|
103
|
+
static "__#267@#execute_query"(record: any, resources: any, context: any): void;
|
|
104
|
+
static "__#267@#execute_command"(record: any, resources: any, context: any): void;
|
|
105
|
+
static "__#267@#execute_apply"(record: any, resources: any, context: any): void;
|
|
106
106
|
/**
|
|
107
107
|
* @param {object} options
|
|
108
108
|
* @param {GPUDevice} options.device
|
|
@@ -34,7 +34,7 @@ export class GPUFluidPressureSolve {
|
|
|
34
34
|
* @param {*} _resources
|
|
35
35
|
* @param {{encoder: ShadeGPUCommandContext}} context
|
|
36
36
|
*/
|
|
37
|
-
static "__#
|
|
37
|
+
static "__#263@#execute"(data: {
|
|
38
38
|
solve: GPUFluidPressureSolve;
|
|
39
39
|
arm: number;
|
|
40
40
|
count: number;
|
|
@@ -49,7 +49,7 @@ export class GPUFluidQueries {
|
|
|
49
49
|
* @param {import("../../../../engine/graphics/render/frame_graph/FramePassResources.js").FramePassResources} resources
|
|
50
50
|
* @param {{encoder: import("../../../device/ShadeGPUCommandContext.js").ShadeGPUCommandContext}} context
|
|
51
51
|
*/
|
|
52
|
-
static "__#
|
|
52
|
+
static "__#268@#execute"(pass: object, resources: import("../../../../engine/graphics/render/frame_graph/FramePassResources.js").FramePassResources, context: {
|
|
53
53
|
encoder: import("../../../device/ShadeGPUCommandContext.js").ShadeGPUCommandContext;
|
|
54
54
|
}): void;
|
|
55
55
|
/**
|
|
@@ -13,7 +13,7 @@ export class TinyGltf {
|
|
|
13
13
|
* @readonly
|
|
14
14
|
* @type {TextureFormat}
|
|
15
15
|
*/
|
|
16
|
-
static readonly "__#
|
|
16
|
+
static readonly "__#287@#UNCOMPRESSED_TARGET": TextureFormat;
|
|
17
17
|
/**
|
|
18
18
|
* @param {AssetManager} assetManager
|
|
19
19
|
* @param {AssetRequestScope} [scope]
|
|
@@ -53,7 +53,7 @@ export class NSS {
|
|
|
53
53
|
* @returns {number}
|
|
54
54
|
*/
|
|
55
55
|
static recommended_jitter_sequence_size(upscale_ratio: number): number;
|
|
56
|
-
static "__#
|
|
56
|
+
static "__#201@#preprocess_tensor_descriptor"(render_w: any, render_h: any): TextureResourceDescriptor;
|
|
57
57
|
/**
|
|
58
58
|
* @param {GraphicsContext} graphics
|
|
59
59
|
*/
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# ACES tone mapping, Unreal's default look: a brief (2026-10-17)
|
|
2
|
+
|
|
3
|
+
**Status: built.** `ShadeToneMappingMode.ACES` is the default. It is added beside GT7, PBR Neutral and NONE, and
|
|
4
|
+
replaces none of them. Alex asked for a close match to Unreal Engine's current default look, on SDR and HDR alike,
|
|
5
|
+
as fixed-function tone mapping: no settings and no LUTs.
|
|
6
|
+
|
|
7
|
+
## 1. What it is
|
|
8
|
+
|
|
9
|
+
- **SDR is Unreal's "Filmic" tone mapper at its default settings.** It is a line-for-line port of UE 5.4's
|
|
10
|
+
`CombineLUTsCommon` (PostProcessCombineLUTs.usf, the sRGB output device) and `FilmToneMap` (TonemapCommon.ush), in
|
|
11
|
+
`chunk_tonemap_ue_filmic`, evaluated per pixel where UE bakes it into a 32³ LUT:
|
|
12
|
+
1. ACEScg from UE's default sRGB working space;
|
|
13
|
+
2. Expand Gamut at 1.0;
|
|
14
|
+
3. the colour corrections at their defaults, which only clamp at zero;
|
|
15
|
+
4. Blue Correction at 0.6;
|
|
16
|
+
5. the curve at Slope 0.88, Toe 0.55, Shoulder 0.26, Black Clip 0 and White Clip 0.04 (`FPostProcessSettings`,
|
|
17
|
+
Scene.cpp);
|
|
18
|
+
6. the inverse blue correction, then Rec.709 clipped to [0, 1].
|
|
19
|
+
- **HDR is what Unreal 5.8 does with Filmic on a display past 100 cd/m²:** the SDR picture, taken back to the scene
|
|
20
|
+
through the inverse ACES 2.0 output transform for a 100 cd/m² display, and rendered again with the ACES 2.0 output
|
|
21
|
+
transform for this display's headroom, both limited to Rec.709. The ACES 2.0 part is OpenColorIO 2.6.0's
|
|
22
|
+
implementation, in `chunk_aces2_output_transform`, with three limits on its inverse (D5). Its per-display parameters
|
|
23
|
+
and gamut tables are built on the CPU in `aces2_transform_block.js` and owned by `TonemapAces2Tables`.
|
|
24
|
+
|
|
25
|
+
| | SDR | HDR, 1000 cd/m² | HDR, 2000 cd/m² | HDR, 4000 cd/m² |
|
|
26
|
+
|---|---|---|---|---|
|
|
27
|
+
| exposed 0.18 shows at, × SDR white | 0.180 | 0.257 | 0.287 | 0.313 |
|
|
28
|
+
| white reaches, × SDR white | 1.0 at +6 EV | 4.90 | 9.62 | 18.64 |
|
|
29
|
+
|
|
30
|
+
HDR columns are 1015, 2030 and 4060 cd/m² displays, whose headroom over the 203 cd/m² paper white puts ACES 2.0 at
|
|
31
|
+
500, 1000 and 2000 cd/m². The values are OpenColorIO's.
|
|
32
|
+
|
|
33
|
+
Mid-grey rises with the display's peak. That is ACES 2.0's design, and Unreal 5.8 keeps it: 10 cd/m² at a 100 cd/m²
|
|
34
|
+
display, plus 14% of that for every doubling of the peak. A display with no headroom shows the SDR picture exactly.
|
|
35
|
+
|
|
36
|
+
## 2. Sources
|
|
37
|
+
|
|
38
|
+
- **UE 5.4 source, installed** (H:/Program Files/Epic Games/UE_5.4): PostProcessCombineLUTs.usf, TonemapCommon.ush,
|
|
39
|
+
ACES.ush, GammaCorrectionCommon.ush, PostProcessCommon.ush, PostProcessTonemap.usf; PostProcessCombineLUTs.cpp,
|
|
40
|
+
PostProcessTonemap.cpp, RenderCore.cpp, HDRHelper.h, Scene.cpp. Every default above was read there.
|
|
41
|
+
- **UE after 5.4, release notes** (Epic, verified):
|
|
42
|
+
- 5.6 adds ACES 2.0 for HDR as an option (`r.HDR.Aces.Version=2`).
|
|
43
|
+
- 5.8 adds "support for ACES 2.0 in SDR", moves ACES into a secondary LUT, and drops the HDR UI paper white from 300
|
|
44
|
+
to 203 cd/m² to match BT.2408.
|
|
45
|
+
- 5.8's `TonemappingMethod` is FILMIC = 0 or STANDARD_ACES = 1.
|
|
46
|
+
- **UE 5.8's behaviour, Epic staff** (Yutaro Sawada, forums.unrealengine.com/t/tonemappingmethod/2747218, 2026-07-30,
|
|
47
|
+
in Japanese):
|
|
48
|
+
- `r.HDR.Aces.Version` now defaults to 2.
|
|
49
|
+
- Filmic, the default, aims at one look on SDR and HDR. Past 100 cd/m² it is "applied, converted back to linear
|
|
50
|
+
through the inverse ACES 2.0, then output again through ACES 2.0 at the target luminance".
|
|
51
|
+
- `r.HDR.Aces.SceneColorMultiplier` applies to Standard ACES only.
|
|
52
|
+
- The peak comes from the hardware, and mid and minimum luminance derive from it.
|
|
53
|
+
- **ACES 2.0:**
|
|
54
|
+
- ampas/aces-core, Lib.Academy.OutputTransform.ctl and Lib.Academy.Tonescale.ctl;
|
|
55
|
+
- OpenColorIO v2.6.0, ops/fixedfunction/ACES2/Transform.cpp, FixedFunctionOpCPU.cpp and transforms/builtins/ACES.cpp,
|
|
56
|
+
which this ports.
|
|
57
|
+
- **The UE 5.8 source is not public**, so the glue between Filmic and ACES 2.0 (§3, D2) is inferred from the staff
|
|
58
|
+
description, not read.
|
|
59
|
+
|
|
60
|
+
The state of the art elsewhere, for context:
|
|
61
|
+
|
|
62
|
+
- Godot defaults to Linear, three.js to none, and Unity HDRP to none; Filament defaults to a legacy ACES fit.
|
|
63
|
+
- Blender added ACES 1.3 and 2.0 views in 5.0, with AgX the default since 4.0.
|
|
64
|
+
- No real-time engine but Unreal ships ACES 2.0 by default.
|
|
65
|
+
|
|
66
|
+
## 3. Decisions
|
|
67
|
+
|
|
68
|
+
- **D1. SDR is Filmic exactly, Unreal's pass excepted.** Left out because they are not tone mapping:
|
|
69
|
+
- vignette (UE's default intensity 0.4), grain, sharpening and bloom;
|
|
70
|
+
- the LUT itself: UE interpolates a 32³ table, where this evaluates the function;
|
|
71
|
+
- the LUT's input range: UE's log encoding stops at 43.7, so it shades anything brighter as 43.7. This does not,
|
|
72
|
+
which moves saturated highlights past 43.7 by a few codes.
|
|
73
|
+
- **D2. HDR, the glue I inferred:**
|
|
74
|
+
- The inverse runs at 100 cd/m² with Rec.709 limiting primaries, because Filmic's output is a Rec.709 SDR picture.
|
|
75
|
+
- The forward runs at 100 × the display's peak over the paper white, also limited to Rec.709. So both transforms
|
|
76
|
+
take SDR white for 100 cd/m², and SDR white lands on the paper white, as in every other mode.
|
|
77
|
+
- Rec.709 rather than the canvas's Display P3, because the review measured what P3 does: just past the paper white
|
|
78
|
+
(203.01 cd/m²) saturated colours jumped up to 67 codes from the SDR picture, 213 of 512 by more than 2. Limited
|
|
79
|
+
to the SDR picture's own gamut, the HDR picture becomes the SDR one as the headroom shrinks to none. HDR gives up
|
|
80
|
+
colours outside Rec.709, which the SDR picture never had either. Unreal may limit to the display's gamut; its
|
|
81
|
+
source would say.
|
|
82
|
+
- A display at or under the paper white shows the SDR picture, Unreal's "past 100 cd/m²" rule in this engine's
|
|
83
|
+
units.
|
|
84
|
+
- Unreal sets the HDR level with `HDRPaperWhiteNits` and runs the forward transform at the display's absolute
|
|
85
|
+
peak. If its paper white scales the SDR picture onto the paper white, which its default of 203, BT.2408 and ours
|
|
86
|
+
suggest, the two agree.
|
|
87
|
+
- **D3. No scene colour multiplier.** UE applies its 1.5 to Standard ACES only.
|
|
88
|
+
- **D4. Tables are built on the CPU, per display.** ACES 2.0 needs a reach table, a hue table and a gamut-cusp
|
|
89
|
+
table with an upper-hull gamma per hue. They are found by searches no pixel can afford.
|
|
90
|
+
- Built in 7–13 ms in JS, on the first HDR frame and then on a change of peak, not every frame and not with the
|
|
91
|
+
renderer.
|
|
92
|
+
- Bound as one 15 KB storage buffer: two blocks of 1,893 floats.
|
|
93
|
+
- These are the algorithm's own data, not a grading LUT.
|
|
94
|
+
- **D5. The inverse is limited where OCIO's is ill-conditioned.** Filmic clips channels onto the Rec.709 cube's
|
|
95
|
+
surface, and ACES 2.0's estimate of the gamut boundary lies a hair inside that surface. So a bright tinted highlight,
|
|
96
|
+
SDR (0.981, 1, 1) say, sits on or past the boundary, where OCIO's inverse extrapolates. The review measured it as a
|
|
97
|
+
jump of 0.24 × SDR white between neighbouring scene values on a smooth ramp, which a picture shows as speckle or a
|
|
98
|
+
ring. Three limits, only in the inverse, and only where it is ill-conditioned:
|
|
99
|
+
- colourfulness past the estimated boundary is clamped to it, so it comes back as the reach boundary, which the
|
|
100
|
+
forward transform takes back to the boundary;
|
|
101
|
+
- the decompression's gain is held to 5. Below the last unit of J it stays under 4.9 for 3,000 Filmic outputs, and
|
|
102
|
+
within that unit it reaches 600 to 11,700, which multiplies float32 rounding by as much;
|
|
103
|
+
- over that last unit of J the decompression fades to none, so a near-white colour meets the neutral that white,
|
|
104
|
+
past J_max, is sent to.
|
|
105
|
+
|
|
106
|
+
A colour whose SDR picture is not in that region is untouched and matches OCIO. Two more departures are where OCIO
|
|
107
|
+
gives NaN: the gamut boundary's power takes a base clamped at zero, and an achromatic response at or under zero
|
|
108
|
+
tone-maps to zero, which is where OCIO's `max(0, NaN)` lands it.
|
|
109
|
+
|
|
110
|
+
## 4. Measured
|
|
111
|
+
|
|
112
|
+
**Against the references**, in `shader_tonemap_aces.spec.js`, under the WGSL emulator, in Display P3:
|
|
113
|
+
|
|
114
|
+
- SDR is within the dither of a float64 Python port of UE's HLSL, at 29 colours from black to 1000.
|
|
115
|
+
- HDR is within 1e-4 (encoded) of OpenColorIO 2.6.0 at four display peaks: its builtin inverse at 100 cd/m², then its
|
|
116
|
+
ACES 2.0 fixed function limited to Rec.709 between its builtins' clamps.
|
|
117
|
+
- The exceptions are three bright saturated colours whose SDR picture is near white, where D5's limits apply, and
|
|
118
|
+
a grey at +4 EV on 8120 cd/m², where OCIO's float32 inverse drifts by more than that. These four are held to a
|
|
119
|
+
float64 Python port with the same limits instead.
|
|
120
|
+
- A tinted highlight's HDR picture moves continuously: the largest step along a ramp shrinks when the interval is cut
|
|
121
|
+
ten times finer. Without D5's clamp and gain limit it does not, nor with P3 limiting at 203.01 cd/m² is an HDR
|
|
122
|
+
display within 2 codes of SDR; both tests failed before the change.
|
|
123
|
+
- Mutation testing: 110 mutants by an adversarial reviewer, then the survivors and every limit in D5 again. Three
|
|
124
|
+
survive, each unreachable or under the tolerance (the inverse's nd ≥ 1 branch, which the clamp makes unreachable;
|
|
125
|
+
the gain ≥ 1 escape; a looser cusp-search tolerance).
|
|
126
|
+
- The JS table builder matches a float64 Python port to 6e-8.
|
|
127
|
+
- That Python port matches OCIO's builtins to 2e-5, forward and inverse, at 100, 500 and 1000 cd/m².
|
|
128
|
+
|
|
129
|
+
**On the device** (RTX 4090, headless Chrome, volumetrics_froxel, 1258×646, exposure fixed). OKLab lightness and HSV
|
|
130
|
+
saturation are on the displayed frame:
|
|
131
|
+
|
|
132
|
+
| view | mode | L mean | L p05 | L p95 | saturation |
|
|
133
|
+
|---|---|---|---|---|---|
|
|
134
|
+
| overview | ACES | 0.434 | 0.141 | 0.655 | 0.323 |
|
|
135
|
+
| overview | GT7 | 0.445 | 0.180 | 0.635 | 0.281 |
|
|
136
|
+
| broadside | ACES | 0.512 | 0.224 | 0.868 | 0.263 |
|
|
137
|
+
| broadside | GT7 | 0.522 | 0.258 | 0.891 | 0.241 |
|
|
138
|
+
| volume edge | ACES | 0.472 | 0.256 | 0.725 | 0.342 |
|
|
139
|
+
| volume edge | GT7 | 0.480 | 0.288 | 0.699 | 0.300 |
|
|
140
|
+
|
|
141
|
+
- Mid-grey is where GT7 puts it, 0.18 in and 0.18 out.
|
|
142
|
+
- The mid-tone contrast is 1.36 against GT7's 1.05. Shadows sit deeper and highlights brighter, and saturation rises
|
|
143
|
+
12–15%.
|
|
144
|
+
|
|
145
|
+
The pass's cost, three interleaved rounds of 24 frames:
|
|
146
|
+
|
|
147
|
+
| pass | ACES | GT7 |
|
|
148
|
+
|---|---|---|
|
|
149
|
+
| SDR | 12–13 µs | 14–21 µs |
|
|
150
|
+
| HDR | 55–102 µs | 16–33 µs |
|
|
151
|
+
|
|
152
|
+
The HDR pass was forced through `matchMedia` and ran on the device with no validation errors and no non-finite output.
|
|
153
|
+
It has not been looked at on an HDR display.
|
|
154
|
+
|
|
155
|
+
## 5. Open, measured
|
|
156
|
+
|
|
157
|
+
- **The HDR pass costs three to four times GT7's**: two ACES 2.0 transforms a pixel, 55–102 µs at 0.8 MP on a 4090.
|
|
158
|
+
Unreal pays this once into a LUT, which was ruled out here.
|
|
159
|
+
- **The glue to Filmic is inferred** (D2, D5). Unreal evaluates this composite into a LUT, whose interpolation smooths
|
|
160
|
+
what D5 limits; its 5.8 source is the way to check.
|
package/src/shade/renderer/shader/chunk/color/tonemap/HDR_TONE_MAPPING_FORMS_BRIEF_2026_10_16.md
CHANGED
|
@@ -4,6 +4,10 @@
|
|
|
4
4
|
`ShadeToneMappingMode.PBR_NEUTRAL` runs `tonemap_khronos_pbr` with the peak form. The prototypes this brief measured
|
|
5
5
|
are gone from the playground `src/shade/playground/tonemap_sdr/`, which now compares GT7 and PBR Neutral.
|
|
6
6
|
|
|
7
|
+
**The paper white is 203 cd/m² since `5549db81f` (2026-10-17),** BT.2408's graphics white, not GT7's 250. Every
|
|
8
|
+
measurement below was taken at 250, so peak ×4 was a 1000 cd/m² display; at 203 it is 812 cd/m², and a 1000 cd/m²
|
|
9
|
+
display is ×4.93.
|
|
10
|
+
|
|
7
11
|
## 1. Recommendation
|
|
8
12
|
|
|
9
13
|
The question: does each operator have one form, parameterised by the display's peak, that serves an SDR peak and an HDR
|
|
@@ -249,7 +253,7 @@ SDR white, the means at ×4 are 0.2–9.2 codes for GT7, 0.8–14.2 for Neutral
|
|
|
249
253
|
- `chunk_tonemap_khronos_pbr` takes the peak. Its WGSL signature changes from `tonemap_khronos_pbr(c)` to
|
|
250
254
|
`tonemap_khronos_pbr(c, peak)`, a break for any WGSL caller outside the repo. The import path stays.
|
|
251
255
|
- **The paper white becomes a canvas convention, not GT7's.** Neutral's HDR pass divides the display's peak by the same
|
|
252
|
-
|
|
256
|
+
paper white that puts SDR white at the canvas's 1.0: 250 cd/m² then, 203 since `5549db81f`. So `chunk_GT7_PAPER_WHITE_NITS` moves out of `gt7/` under a
|
|
253
257
|
name of its own, which is an import-path change too.
|
|
254
258
|
- **Mid-grey sits lower.** Neutral puts an exposed 0.18 at 0.140 (the 0.04 Fresnel offset), where GT7 puts it at 0.179.
|
|
255
259
|
Switching modes darkens mid-grey by 0.36 EV. Auto-exposure meters the scene, not the output, so it will not
|
|
@@ -5,6 +5,14 @@ F3 landed with `ShadeToneMappingMode`, whose modes were then `GT7` and `NONE`. T
|
|
|
5
5
|
then added `PBR_NEUTRAL` and removed the ACES and AgX chunks. The playground `src/shade/playground/tonemap_sdr/`
|
|
6
6
|
compares GT7 and PBR Neutral.
|
|
7
7
|
|
|
8
|
+
**The paper white is 203 cd/m² since `5549db81f` (2026-10-17),** BT.2408's graphics white, where this brief chose the
|
|
9
|
+
sample code's 250. Every measurement below was taken at 250. At 203 the SDR pass is the sample code's SDR mode with
|
|
10
|
+
`GRAN_TURISMO_SDR_PAPER_WHITE` at 203, under the 250 its parameters were tuned on, so it is no longer the sample code
|
|
11
|
+
exactly. The curve's toe sits at a fixed 53.8 cd/m², so the change is not a scale: an exposed 0.18 comes out 0.176
|
|
12
|
+
(116) instead of 0.179 (117). Against the compiled sample code at 203, over the same 648 inputs, the ICtCp blend differs
|
|
13
|
+
by up to 0.33 codes in the mid-tones and 14.7 in saturated highlights, against 0.30 and 14.4 at 250.
|
|
14
|
+
`shader_tonemap_LDR.spec.js` pins the sample code's output at 203.
|
|
15
|
+
|
|
8
16
|
## 1. Recommendation
|
|
9
17
|
|
|
10
18
|
**Make GT7's SDR mode the SDR default, exactly as Polyphony's sample code defines it.** The curve's peak is the
|
|
@@ -205,13 +213,15 @@ renderer.tone_mapping_mode = ShadeToneMappingMode.NONE; // exposure only; SDR c
|
|
|
205
213
|
|
|
206
214
|
Each module lists its own chunks, so a mode's dependencies are visible. No `override`, no runtime branch on a
|
|
207
215
|
setting. If shader switches land, each pair can become one pass with a choice.
|
|
208
|
-
- **The paper white is a convention, not a setting.** `chunk_GT7_PAPER_WHITE_NITS` (250
|
|
209
|
-
|
|
210
|
-
|
|
216
|
+
- **The paper white is a convention, not a setting.** `chunk_GT7_PAPER_WHITE_NITS` (250; since the HDR forms brief
|
|
217
|
+
`chunk_PAPER_WHITE_NITS`, and 203 since `5549db81f`) is the paper white on both outputs, and SDR also uses it as the
|
|
218
|
+
peak. Below the SDR shoulder the two outputs therefore write the same colour: pinned in `shader_tonemap_HDR.spec.js`.
|
|
219
|
+
The HDR pass's only setting is the display's peak.
|
|
211
220
|
- **`tonemap_gt7` follows the sample code** in the curve, the relative chroma fade, the 0.6 untwisted weight and the
|
|
212
221
|
clamp at the target, and keeps the ICtCp blend (F2). Against the compiled sample code over 648 inputs it differs by up
|
|
213
|
-
to 0.3 sRGB codes in the mid-tones and up to 14 in saturated highlights
|
|
214
|
-
8", from four hand-picked cases; the full sweep
|
|
222
|
+
to 0.3 sRGB codes in the mid-tones and up to 14 in saturated highlights, at 250; at 203, against the sample code at
|
|
223
|
+
203, by 0.33 and 14.7. An earlier draft of this brief said "at most 8", from four hand-picked cases; the full sweep
|
|
224
|
+
says 14.
|
|
215
225
|
- **ACES, AgX and Neutral were unwired** here, kept for a look at HDR-aware variants of each.
|
|
216
226
|
`HDR_TONE_MAPPING_FORMS_BRIEF_2026_10_16.md` took that look: ACES and AgX are removed, and Neutral is
|
|
217
227
|
`ShadeToneMappingMode.PBR_NEUTRAL`, with the display's peak in place of the specification's 1 on HDR.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fill one block of the ACES 2.0 output transform for a display: its peak and the primaries it limits to.
|
|
3
|
+
*
|
|
4
|
+
* Matches OpenColorIO's `ACES_OUTPUT_TRANSFORM_20` set up with the same two values, and the builtin transforms' AP1
|
|
5
|
+
* clamp before it and clamp at the peak after it. Takes a few tens of milliseconds, so it is for a display that
|
|
6
|
+
* changed, not for a frame.
|
|
7
|
+
*
|
|
8
|
+
* @param {Float32Array} out
|
|
9
|
+
* @param {number} offset first float of the block
|
|
10
|
+
* @param {number} peak_nits the display's peak, cd/m², where 100 is what an exposed 1.0 shows at
|
|
11
|
+
* @param {number[]} limiting red, green, blue and white xy
|
|
12
|
+
*/
|
|
13
|
+
export function aces2_transform_block_write(out: Float32Array, offset: number, peak_nits: number, limiting: number[]): void;
|
|
14
|
+
/**
|
|
15
|
+
* Rec.709's red, green, blue and white xy: the limiting primaries the ACES tone mapping uses.
|
|
16
|
+
* @type {number[]}
|
|
17
|
+
*/
|
|
18
|
+
export const ACES2_LIMITING_REC709: number[];
|
|
19
|
+
/** limiting primaries to the CAM16 cone space, white-adapted */
|
|
20
|
+
export const ACES2_OUT_RGB_TO_CAM: 0;
|
|
21
|
+
export const ACES2_OUT_CAM_TO_RGB: 9;
|
|
22
|
+
/** ACES2065-1 (AP0) to the cone space and back */
|
|
23
|
+
export const ACES2_IN_RGB_TO_CAM: 18;
|
|
24
|
+
export const ACES2_IN_CAM_TO_RGB: 27;
|
|
25
|
+
/** compressed cone response to achromatic and opponent (A, a, b) and back; the same for every set of primaries */
|
|
26
|
+
export const ACES2_CONE_TO_AAB: 36;
|
|
27
|
+
export const ACES2_AAB_TO_CONE: 45;
|
|
28
|
+
/**
|
|
29
|
+
* scalars, in this order: limit_J_max, model_gamma_inv, mid_J, focus_dist, lower_hull_gamma_inv, s_2, m_2, g, t_1,
|
|
30
|
+
* n_r, inverse_limit, AP1 upper bound, sat, sat_thr, compr, chroma_compress_scale, peak / 100, F_L_n, cz, inv_cz,
|
|
31
|
+
* A_w_J, inv_A_w_J, the hue search range's lower and upper offsets
|
|
32
|
+
*/
|
|
33
|
+
export const ACES2_SCALARS: 54;
|
|
34
|
+
export const ACES2_SCALAR_COUNT: 24;
|
|
35
|
+
/** TOTAL entries of (hue, cusp J, cusp M, upper hull inverse gamma) */
|
|
36
|
+
export const ACES2_CUSP_TABLE: number;
|
|
37
|
+
/** TOTAL entries of the reach gamut's M at limit_J_max, one per degree from the first nominal entry */
|
|
38
|
+
export const ACES2_REACH_TABLE: number;
|
|
39
|
+
/** floats in one block */
|
|
40
|
+
export const ACES2_BLOCK_FLOATS: number;
|
|
41
|
+
//# sourceMappingURL=aces2_transform_block.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aces2_transform_block.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/shade/renderer/shader/chunk/color/tonemap/aces/aces2_transform_block.js"],"names":[],"mappings":"AA6hBA;;;;;;;;;;;GAWG;AACH,iDALW,YAAY,UACZ,MAAM,aACN,MAAM,YACN,MAAM,EAAE,QA4IlB;AA7nBD;;;GAGG;AACH,oCAFU,MAAM,EAAE,CAEwE;AAK1F,gEAAgE;AAChE,qCAAsC;AACtC,qCAAsC;AACtC,kDAAkD;AAClD,qCAAsC;AACtC,qCAAsC;AACtC,kHAAkH;AAClH,mCAAoC;AACpC,mCAAoC;AACpC;;;;GAIG;AACH,+BAAgC;AAChC,oCAAqC;AACrC,uEAAuE;AACvE,sCAAmE;AACnE,uGAAuG;AACvG,uCAA8D;AAC9D,0BAA0B;AAC1B,wCAA4D"}
|