@woosh/meep-engine 3.50.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/graphics3/make_default_environment.d.ts.map +1 -1
- package/src/engine/graphics3/make_default_environment.js +11 -5
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
- package/src/shade/playground/particle_ecs/moonlit_environment.d.ts.map +1 -1
- package/src/shade/playground/particle_ecs/moonlit_environment.js +11 -5
- package/src/shade/playground/sh_exponential/sh_exp_playground_shaders.d.ts.map +1 -1
- package/src/shade/playground/sh_exponential/sh_exp_playground_shaders.js +3 -1
- 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/atmosphere/chunk_sample_environment_color.d.ts +3 -0
- package/src/shade/renderer/atmosphere/chunk_sample_environment_color.d.ts.map +1 -1
- package/src/shade/renderer/atmosphere/chunk_sample_environment_color.js +11 -8
- package/src/shade/renderer/atmosphere/shader_sky_irradiance_lut.d.ts +6 -0
- package/src/shade/renderer/atmosphere/shader_sky_irradiance_lut.d.ts.map +1 -1
- package/src/shade/renderer/atmosphere/shader_sky_irradiance_lut.js +227 -215
- package/src/shade/renderer/deferred/SHADING_LIGHT_RESOURCE_GROUP.d.ts.map +1 -1
- package/src/shade/renderer/deferred/SHADING_LIGHT_RESOURCE_GROUP.js +2 -0
- package/src/shade/renderer/deferred/indirect/chunk_get_ibl_irradiance.d.ts.map +1 -1
- package/src/shade/renderer/deferred/indirect/chunk_get_ibl_irradiance.js +4 -2
- package/src/shade/renderer/deferred/indirect/chunk_get_ibl_radiance.d.ts.map +1 -1
- package/src/shade/renderer/deferred/indirect/chunk_get_ibl_radiance.js +4 -2
- package/src/shade/renderer/deferred/shader_background.d.ts.map +1 -1
- package/src/shade/renderer/deferred/shader_background.js +4 -2
- 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/global_illumination/brick4/gpu/bake/shader_brick4_bake_probes.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/brick4/gpu/bake/shader_brick4_bake_probes.js +3 -1
- package/src/shade/renderer/global_illumination/ibl/shader_diffuse_IBL.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/ibl/shader_diffuse_IBL.js +3 -1
- package/src/shade/renderer/global_illumination/ibl/shader_specular_IBL.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/ibl/shader_specular_IBL.js +3 -1
- package/src/shade/renderer/global_illumination/lpv/deprecated/probe_trace_compute_shader_code.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/lpv/deprecated/probe_trace_compute_shader_code.js +3 -1
- package/src/shade/renderer/global_illumination/probe/octahedral/shader_lpv_build_gbuffer.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe/octahedral/shader_lpv_build_gbuffer.js +4 -2
- package/src/shade/renderer/light/GPULightCollection.d.ts.map +1 -1
- package/src/shade/renderer/light/GPULightCollection.js +44 -0
- package/src/shade/renderer/light/environment/ENVIRONMENT_MAP_RESOURCE.d.ts +2 -1
- package/src/shade/renderer/light/environment/ENVIRONMENT_MAP_RESOURCE.d.ts.map +1 -1
- package/src/shade/renderer/light/environment/ENVIRONMENT_MAP_RESOURCE.js +3 -2
- package/src/shade/renderer/light/environment/ENVIRONMENT_MAP_SAMPLER_RESOURCE.d.ts +14 -0
- package/src/shade/renderer/light/environment/ENVIRONMENT_MAP_SAMPLER_RESOURCE.d.ts.map +1 -0
- package/src/shade/renderer/light/environment/ENVIRONMENT_MAP_SAMPLER_RESOURCE.js +25 -0
- package/src/shade/renderer/light/environment/execute_filter_environment_map.d.ts.map +1 -1
- package/src/shade/renderer/light/environment/execute_filter_environment_map.js +3 -4
- package/src/shade/renderer/light/environment/octahedral_skirt_matches.d.ts +19 -0
- package/src/shade/renderer/light/environment/octahedral_skirt_matches.d.ts.map +1 -0
- package/src/shade/renderer/light/environment/octahedral_skirt_matches.js +67 -0
- package/src/shade/renderer/light/environment/octahedral_skirt_source_texel.d.ts +16 -0
- package/src/shade/renderer/light/environment/octahedral_skirt_source_texel.d.ts.map +1 -0
- package/src/shade/renderer/light/environment/octahedral_skirt_source_texel.js +35 -0
- package/src/shade/renderer/light/environment/resample_cube_to_octahedral.d.ts +7 -2
- package/src/shade/renderer/light/environment/resample_cube_to_octahedral.d.ts.map +1 -1
- package/src/shade/renderer/light/environment/resample_cube_to_octahedral.js +23 -7
- package/src/shade/renderer/light/environment/resample_equirectangular_to_octahedral.d.ts +8 -2
- package/src/shade/renderer/light/environment/resample_equirectangular_to_octahedral.d.ts.map +1 -1
- package/src/shade/renderer/light/environment/resample_equirectangular_to_octahedral.js +24 -7
- package/src/shade/renderer/light/environment/sampler2d_octahedral_skirt_fill.d.ts +12 -0
- package/src/shade/renderer/light/environment/sampler2d_octahedral_skirt_fill.d.ts.map +1 -0
- package/src/shade/renderer/light/environment/sampler2d_octahedral_skirt_fill.js +54 -0
- package/src/shade/renderer/light/environment/sh_exponential/shader_sh_exp_environment_cells.d.ts +2 -2
- package/src/shade/renderer/light/environment/sh_exponential/shader_sh_exp_environment_cells.d.ts.map +1 -1
- package/src/shade/renderer/light/environment/sh_exponential/shader_sh_exp_environment_cells.js +5 -4
- package/src/shade/renderer/light/environment/shader_convolve_reflection_map.d.ts.map +1 -1
- package/src/shade/renderer/light/environment/shader_convolve_reflection_map.js +13 -9
- package/src/shade/renderer/light/environment/shader_project_environment_sh.d.ts.map +1 -1
- package/src/shade/renderer/light/environment/shader_project_environment_sh.js +3 -1
- package/src/shade/renderer/lightmap/bake/shader_lightmap_viz_to_irradiance_flat.d.ts.map +1 -1
- package/src/shade/renderer/lightmap/bake/shader_lightmap_viz_to_irradiance_flat.js +3 -1
- package/src/shade/renderer/lightmap/bake/shader_lightmap_viz_to_sh.d.ts.map +1 -1
- package/src/shade/renderer/lightmap/bake/shader_lightmap_viz_to_sh.js +3 -1
- package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
- package/src/shade/renderer/path_tracer/accumulating/shader_accumulating_path_tracer.d.ts.map +1 -1
- package/src/shade/renderer/path_tracer/accumulating/shader_accumulating_path_tracer.js +3 -1
- package/src/shade/renderer/path_tracer/graph_path_trace_scene.d.ts.map +1 -1
- package/src/shade/renderer/path_tracer/graph_path_trace_scene.js +3 -1
- package/src/shade/renderer/path_tracer/shader/chunk_render_trace_path.js +1 -1
- package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
- package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader.js +3 -1
- package/src/shade/renderer/rasterize/native/avboit/AVBOIT_CONSTANTS.d.ts +0 -5
- package/src/shade/renderer/rasterize/native/avboit/AVBOIT_CONSTANTS.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/native/avboit/AVBOIT_CONSTANTS.js +0 -6
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_counts_to_extinction.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_counts_to_extinction.js +4 -1
- package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.js +3 -0
- package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.js +3 -0
- 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/shader/chunk/texture/octahedral/chunk_texture_octahedral_skirt_texel_uv.d.ts +15 -0
- package/src/shade/renderer/shader/chunk/texture/octahedral/chunk_texture_octahedral_skirt_texel_uv.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/texture/octahedral/chunk_texture_octahedral_skirt_texel_uv.js +27 -0
- package/src/shade/renderer/shader/chunk/texture/octahedral/chunk_texture_octahedral_skirt_uv.d.ts +18 -0
- package/src/shade/renderer/shader/chunk/texture/octahedral/chunk_texture_octahedral_skirt_uv.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/texture/octahedral/chunk_texture_octahedral_skirt_uv.js +24 -0
- package/src/shade/renderer/shader/chunk/texture/sample/chunk_sample_environment_map.d.ts +18 -1
- package/src/shade/renderer/shader/chunk/texture/sample/chunk_sample_environment_map.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/texture/sample/chunk_sample_environment_map.js +45 -27
- package/src/shade/renderer/view/GPUViewSkyContext.js +169 -169
- package/src/shade/renderer/volumetrics/NOTES.md +209 -0
- package/src/shade/renderer/volumetrics/VOLUMETRICS_METADATA_STRUCT.d.ts.map +1 -1
- package/src/shade/renderer/volumetrics/VOLUMETRICS_METADATA_STRUCT.js +1 -1
- package/src/shade/renderer/volumetrics/chunk_volumetrics_media_group_list.d.ts +36 -0
- package/src/shade/renderer/volumetrics/chunk_volumetrics_media_group_list.d.ts.map +1 -0
- package/src/shade/renderer/volumetrics/chunk_volumetrics_media_group_list.js +129 -0
- package/src/shade/renderer/volumetrics/graph_build_volumetrics.d.ts.map +1 -1
- package/src/shade/renderer/volumetrics/graph_build_volumetrics.js +75 -0
- package/src/shade/renderer/volumetrics/shader_volumetrics_bin_participating_media.d.ts +26 -0
- package/src/shade/renderer/volumetrics/shader_volumetrics_bin_participating_media.d.ts.map +1 -0
- package/src/shade/renderer/volumetrics/shader_volumetrics_bin_participating_media.js +110 -0
- package/src/shade/renderer/volumetrics/shader_volumetrics_build_participating_media.d.ts.map +1 -1
- package/src/shade/renderer/volumetrics/shader_volumetrics_build_participating_media.js +38 -14
- package/src/shade/renderer/volumetrics/shader_volumetrics_build_scattering_lut.d.ts.map +1 -1
- package/src/shade/renderer/volumetrics/shader_volumetrics_build_scattering_lut.js +9 -4
- package/src/shade/renderer/volumetrics/shader_volumetrics_split_participating_media.d.ts +31 -0
- package/src/shade/renderer/volumetrics/shader_volumetrics_split_participating_media.d.ts.map +1 -0
- package/src/shade/renderer/volumetrics/shader_volumetrics_split_participating_media.js +139 -0
- 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
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { CodeChunk } from "../../../../compiler/CodeChunk.js";
|
|
2
|
+
import { chunk_aces_ue_matrices } from "./chunk_aces_ue_matrices.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Unreal Engine's default SDR tone mapping, "Filmic", with every setting at its default.
|
|
6
|
+
*
|
|
7
|
+
* A line-for-line port of UE 5.4's `CombineLUTsCommon` (PostProcessCombineLUTs.usf) for the sRGB output device and
|
|
8
|
+
* `FilmToneMap` (TonemapCommon.ush), as UE evaluates them into its colour grading LUT, here evaluated per pixel:
|
|
9
|
+
*
|
|
10
|
+
* 1. into ACEScg (AP1) from UE's default sRGB working space;
|
|
11
|
+
* 2. Expand Gamut at its default 1.0, which pushes bright saturated colours toward wider primaries;
|
|
12
|
+
* 3. the colour corrections at their defaults, which only clamp AP1 at zero;
|
|
13
|
+
* 4. Blue Correction at its default 0.6, a matrix that turns bright blue toward cyan rather than violet, before the
|
|
14
|
+
* curve, and its inverse after;
|
|
15
|
+
* 5. `FilmToneMap` with Slope 0.88, Toe 0.55, Shoulder 0.26, Black Clip 0 and White Clip 0.04 (`FPostProcessSettings`'
|
|
16
|
+
* defaults, Scene.cpp). It is the ACES reference rendering's glow and red modifier and its 0.96 desaturation, then a
|
|
17
|
+
* parametric toe-straight-shoulder curve on log10 of each AP1 channel, solved so that 0.18 comes out at 0.18, then a
|
|
18
|
+
* 0.93 desaturation;
|
|
19
|
+
* 6. back to the working space, clamped at zero, and clipped at 1 as the sRGB target clips it.
|
|
20
|
+
*
|
|
21
|
+
* UE 5.8 keeps Filmic as its default method and its SDR output unchanged. What it does on an HDR display is in
|
|
22
|
+
* shader_tonemap_HDR_aces.
|
|
23
|
+
*
|
|
24
|
+
* Where UE divides 0 by 0 (gamut expansion of black) or takes log10(0), this takes the limit, so black stays black.
|
|
25
|
+
* UE's LUT also limits its input to 43.7, the top of its log encoding; this does not, which moves a few saturated
|
|
26
|
+
* highlights over 43.7 by a few codes.
|
|
27
|
+
*
|
|
28
|
+
* Input: exposed linear Rec.709. Output: display-linear Rec.709 in [0, 1].
|
|
29
|
+
*
|
|
30
|
+
* @see "Color Grading and the Filmic Tonemapper in Unreal Engine", Epic Games
|
|
31
|
+
* @type {CodeChunk}
|
|
32
|
+
*/
|
|
33
|
+
export const chunk_tonemap_ue_filmic = CodeChunk.from(
|
|
34
|
+
//language=WGSL
|
|
35
|
+
`
|
|
36
|
+
const UE_FILM_SLOPE: f32 = 0.88;
|
|
37
|
+
const UE_FILM_TOE: f32 = 0.55;
|
|
38
|
+
const UE_FILM_SHOULDER: f32 = 0.26;
|
|
39
|
+
const UE_FILM_BLACK_CLIP: f32 = 0.0;
|
|
40
|
+
const UE_FILM_WHITE_CLIP: f32 = 0.04;
|
|
41
|
+
const UE_BLUE_CORRECTION: f32 = 0.6;
|
|
42
|
+
const UE_EXPAND_GAMUT_AMOUNT: f32 = 1.0;
|
|
43
|
+
|
|
44
|
+
fn ue_film_saturation(rgb: vec3<f32>) -> f32 {
|
|
45
|
+
let lowest = min(rgb.r, min(rgb.g, rgb.b));
|
|
46
|
+
let highest = max(rgb.r, max(rgb.g, rgb.b));
|
|
47
|
+
return (max(highest, 1e-10) - max(lowest, 1e-10)) / max(highest, 1e-2);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// a luminance proxy for the glow: Y plus 1.75 of the chroma
|
|
51
|
+
fn ue_film_yc(rgb: vec3<f32>) -> f32 {
|
|
52
|
+
let chroma = sqrt(max(rgb.b * (rgb.b - rgb.g) + rgb.g * (rgb.g - rgb.r) + rgb.r * (rgb.r - rgb.b), 0.0));
|
|
53
|
+
return (rgb.b + rgb.g + rgb.r + 1.75 * chroma) / 3.0;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
fn ue_film_glow(yc: f32, gain: f32, mid: f32) -> f32 {
|
|
57
|
+
if (yc <= 2.0 / 3.0 * mid) {
|
|
58
|
+
return gain;
|
|
59
|
+
}
|
|
60
|
+
if (yc >= 2.0 * mid) {
|
|
61
|
+
return 0.0;
|
|
62
|
+
}
|
|
63
|
+
return gain * (mid / yc - 0.5);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
fn ue_film_sigmoid(x: f32) -> f32 {
|
|
67
|
+
let t = max(1.0 - abs(0.5 * x), 0.0);
|
|
68
|
+
return 0.5 * (1.0 + sign(x) * (1.0 - t * t));
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// geometric hue in degrees, [0, 360]; 0 for a neutral
|
|
72
|
+
fn ue_film_hue(rgb: vec3<f32>) -> f32 {
|
|
73
|
+
if (rgb.r == rgb.g && rgb.g == rgb.b) {
|
|
74
|
+
return 0.0;
|
|
75
|
+
}
|
|
76
|
+
var hue = atan2(1.7320508075688772 * (rgb.g - rgb.b), 2.0 * rgb.r - rgb.g - rgb.b) * 57.29577951308232;
|
|
77
|
+
if (hue < 0.0) {
|
|
78
|
+
hue += 360.0;
|
|
79
|
+
}
|
|
80
|
+
return clamp(hue, 0.0, 360.0);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// FilmToneMap: AP1 in, AP1 out
|
|
84
|
+
fn ue_film_tone_map(color_ap1: vec3<f32>) -> vec3<f32> {
|
|
85
|
+
var aces = UE_AP1_TO_AP0 * color_ap1;
|
|
86
|
+
|
|
87
|
+
// the reference rendering's glow
|
|
88
|
+
let saturation = ue_film_saturation(aces);
|
|
89
|
+
let yc = ue_film_yc(aces);
|
|
90
|
+
let s = ue_film_sigmoid((saturation - 0.4) / 0.2);
|
|
91
|
+
aces *= 1.0 + ue_film_glow(yc, 0.05 * s, 0.08);
|
|
92
|
+
|
|
93
|
+
// and its red modifier
|
|
94
|
+
var centered_hue = ue_film_hue(aces);
|
|
95
|
+
if (centered_hue > 180.0) {
|
|
96
|
+
centered_hue -= 360.0;
|
|
97
|
+
}
|
|
98
|
+
let hue_weight = smoothstep(0.0, 1.0, 1.0 - abs(2.0 * centered_hue / 135.0));
|
|
99
|
+
aces.r += hue_weight * hue_weight * saturation * (0.03 - aces.r) * (1.0 - 0.82);
|
|
100
|
+
|
|
101
|
+
var color = max(vec3<f32>(0.0), UE_AP0_TO_AP1 * aces);
|
|
102
|
+
|
|
103
|
+
// pre-desaturate
|
|
104
|
+
color = mix(vec3<f32>(dot(color, UE_AP1_LUMINANCE)), color, 0.96);
|
|
105
|
+
|
|
106
|
+
let toe_scale = 1.0 + UE_FILM_BLACK_CLIP - UE_FILM_TOE;
|
|
107
|
+
let shoulder_scale = 1.0 + UE_FILM_WHITE_CLIP - UE_FILM_SHOULDER;
|
|
108
|
+
|
|
109
|
+
// 0.18 in, 0.18 out, on the toe because the toe is under 0.8
|
|
110
|
+
let bt = (0.18 + UE_FILM_BLACK_CLIP) / toe_scale - 1.0;
|
|
111
|
+
let toe_match = log2(0.18) * 0.30102999566398120 - 0.5 * log((1.0 + bt) / (1.0 - bt)) * (toe_scale / UE_FILM_SLOPE);
|
|
112
|
+
let straight_match = (1.0 - UE_FILM_TOE) / UE_FILM_SLOPE - toe_match;
|
|
113
|
+
let shoulder_match = UE_FILM_SHOULDER / UE_FILM_SLOPE - straight_match;
|
|
114
|
+
|
|
115
|
+
// log10; the floor stands in for log10(0) = -inf, which the toe takes to 0 either way
|
|
116
|
+
let log_color = log2(max(color, vec3<f32>(1e-10))) * 0.30102999566398120;
|
|
117
|
+
|
|
118
|
+
let straight = UE_FILM_SLOPE * (log_color + straight_match);
|
|
119
|
+
|
|
120
|
+
var toe = -UE_FILM_BLACK_CLIP + (2.0 * toe_scale) / (1.0 + exp((-2.0 * UE_FILM_SLOPE / toe_scale) * (log_color - toe_match)));
|
|
121
|
+
var shoulder = (1.0 + UE_FILM_WHITE_CLIP) - (2.0 * shoulder_scale) / (1.0 + exp((2.0 * UE_FILM_SLOPE / shoulder_scale) * (log_color - shoulder_match)));
|
|
122
|
+
|
|
123
|
+
toe = select(straight, toe, log_color < vec3<f32>(toe_match));
|
|
124
|
+
shoulder = select(straight, shoulder, log_color > vec3<f32>(shoulder_match));
|
|
125
|
+
|
|
126
|
+
var t = saturate((log_color - toe_match) / (shoulder_match - toe_match));
|
|
127
|
+
if (shoulder_match < toe_match) {
|
|
128
|
+
t = 1.0 - t;
|
|
129
|
+
}
|
|
130
|
+
t = (3.0 - 2.0 * t) * t * t;
|
|
131
|
+
|
|
132
|
+
var tone = mix(toe, shoulder, t);
|
|
133
|
+
|
|
134
|
+
// post-desaturate
|
|
135
|
+
tone = mix(vec3<f32>(dot(tone, UE_AP1_LUMINANCE)), tone, 0.93);
|
|
136
|
+
|
|
137
|
+
return max(vec3<f32>(0.0), tone);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
fn tonemap_ue_filmic(color_rec709: vec3<f32>) -> vec3<f32> {
|
|
141
|
+
// the scene from zero up, as UE's LUT encodes it
|
|
142
|
+
var color = UE_REC709_TO_AP1 * max(color_rec709, vec3<f32>(0.0));
|
|
143
|
+
|
|
144
|
+
// Expand Gamut. Black has no chroma to expand, and UE's 0 / 0 there comes out as black too
|
|
145
|
+
let luma = dot(color, UE_AP1_LUMINANCE);
|
|
146
|
+
if (luma > 0.0) {
|
|
147
|
+
let chroma = color / luma - 1.0;
|
|
148
|
+
let amount = (1.0 - exp2(-4.0 * dot(chroma, chroma))) * (1.0 - exp2(-4.0 * UE_EXPAND_GAMUT_AMOUNT * luma * luma));
|
|
149
|
+
color = mix(color, UE_EXPAND_GAMUT * color, amount);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// the colour corrections at their defaults
|
|
153
|
+
color = max(color, vec3<f32>(0.0));
|
|
154
|
+
|
|
155
|
+
color = mix(color, UE_BLUE_CORRECT * color, UE_BLUE_CORRECTION);
|
|
156
|
+
color = ue_film_tone_map(color);
|
|
157
|
+
color = mix(color, UE_BLUE_CORRECT_INVERSE * color, UE_BLUE_CORRECTION);
|
|
158
|
+
|
|
159
|
+
return min(max(vec3<f32>(0.0), UE_AP1_TO_REC709 * color), vec3<f32>(1.0));
|
|
160
|
+
}
|
|
161
|
+
`,
|
|
162
|
+
[chunk_aces_ue_matrices]
|
|
163
|
+
);
|
|
@@ -1,11 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The paper white, cd/m², for the CPU side of a pass that needs it: {@link chunk_PAPER_WHITE_NITS} is this number in
|
|
3
|
+
* WGSL.
|
|
4
|
+
*
|
|
5
|
+
* @type {number}
|
|
6
|
+
*/
|
|
7
|
+
export const PAPER_WHITE_NITS: number;
|
|
1
8
|
/**
|
|
2
9
|
* The luminance an exposed scene value of 1.0 is shown at, in cd/m², on every display and in every tone mapping mode.
|
|
3
10
|
* It is where the canvas puts SDR white: 1.0 on an SDR output, and 1.0 of extended Display P3 on an HDR one, so an HDR
|
|
4
11
|
* pass's headroom is the display's peak over this.
|
|
5
12
|
*
|
|
6
|
-
* The value is
|
|
7
|
-
*
|
|
8
|
-
*
|
|
13
|
+
* The value is ITU-R BT.2408's graphics white, 203. GT7's sample code assumes 250 (`GRAN_TURISMO_SDR_PAPER_WHITE`) and
|
|
14
|
+
* accepts no HDR peak below that. The GT7 passes give this to `tonemap_gt7` as the paper white, and the SDR pass also as
|
|
15
|
+
* the peak, which is the sample code's SDR mode. The ACES HDR pass expands its SDR picture by the headroom over it.
|
|
9
16
|
*
|
|
10
17
|
* It is one constant rather than an argument for each pass, so the SDR and HDR outputs cannot drift apart.
|
|
11
18
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk_PAPER_WHITE_NITS.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/shader/chunk/color/tonemap/chunk_PAPER_WHITE_NITS.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;GAaG;AACH,qCAFU,SAAS,CAOjB;
|
|
1
|
+
{"version":3,"file":"chunk_PAPER_WHITE_NITS.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/shader/chunk/color/tonemap/chunk_PAPER_WHITE_NITS.js"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,+BAFU,MAAM,CAEoB;AAEpC;;;;;;;;;;;;;GAaG;AACH,qCAFU,SAAS,CAOjB;0BA7BwB,gCAAgC"}
|
|
@@ -1,13 +1,21 @@
|
|
|
1
1
|
import { CodeChunk } from "../../../compiler/CodeChunk.js";
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* The paper white, cd/m², for the CPU side of a pass that needs it: {@link chunk_PAPER_WHITE_NITS} is this number in
|
|
5
|
+
* WGSL.
|
|
6
|
+
*
|
|
7
|
+
* @type {number}
|
|
8
|
+
*/
|
|
9
|
+
export const PAPER_WHITE_NITS = 203;
|
|
10
|
+
|
|
3
11
|
/**
|
|
4
12
|
* The luminance an exposed scene value of 1.0 is shown at, in cd/m², on every display and in every tone mapping mode.
|
|
5
13
|
* It is where the canvas puts SDR white: 1.0 on an SDR output, and 1.0 of extended Display P3 on an HDR one, so an HDR
|
|
6
14
|
* pass's headroom is the display's peak over this.
|
|
7
15
|
*
|
|
8
|
-
* The value is
|
|
9
|
-
*
|
|
10
|
-
*
|
|
16
|
+
* The value is ITU-R BT.2408's graphics white, 203. GT7's sample code assumes 250 (`GRAN_TURISMO_SDR_PAPER_WHITE`) and
|
|
17
|
+
* accepts no HDR peak below that. The GT7 passes give this to `tonemap_gt7` as the paper white, and the SDR pass also as
|
|
18
|
+
* the peak, which is the sample code's SDR mode. The ACES HDR pass expands its SDR picture by the headroom over it.
|
|
11
19
|
*
|
|
12
20
|
* It is one constant rather than an argument for each pass, so the SDR and HDR outputs cannot drift apart.
|
|
13
21
|
*
|
|
@@ -17,6 +25,6 @@ import { CodeChunk } from "../../../compiler/CodeChunk.js";
|
|
|
17
25
|
export const chunk_PAPER_WHITE_NITS = CodeChunk.from(
|
|
18
26
|
//language=WGSL
|
|
19
27
|
`
|
|
20
|
-
const PAPER_WHITE_NITS: f32 =
|
|
28
|
+
const PAPER_WHITE_NITS: f32 = ${PAPER_WHITE_NITS};
|
|
21
29
|
`
|
|
22
30
|
);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The octahedral uv a texel of a skirted level carries: its own centre for an interior texel, and
|
|
3
|
+
* for a skirt texel the centre of the interior texel the octahedral fold mirrors it onto.
|
|
4
|
+
*
|
|
5
|
+
* A pass that writes a skirted level computes every texel, skirt included, from this uv. A skirt
|
|
6
|
+
* texel then runs the exact computation its interior twin runs, so the two are bit-identical rather
|
|
7
|
+
* than equal to rounding — which is what lets a hardware bilinear sample across the edge match a
|
|
8
|
+
* manual wrap.
|
|
9
|
+
*
|
|
10
|
+
* @see chunk_texture_octahedral_skirt_uv for the layout
|
|
11
|
+
* @type {CodeChunk}
|
|
12
|
+
*/
|
|
13
|
+
export const chunk_texture_octahedral_skirt_texel_uv: CodeChunk;
|
|
14
|
+
import { CodeChunk } from "../../../compiler/CodeChunk.js";
|
|
15
|
+
//# sourceMappingURL=chunk_texture_octahedral_skirt_texel_uv.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chunk_texture_octahedral_skirt_texel_uv.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/shader/chunk/texture/octahedral/chunk_texture_octahedral_skirt_texel_uv.js"],"names":[],"mappings":"AAGA;;;;;;;;;;;GAWG;AACH,sDAFU,SAAS,CAahB;0BA1BuB,gCAAgC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { CodeChunk } from "../../../compiler/CodeChunk.js";
|
|
2
|
+
import { chunk_texture_octahedral_wrap_texel_coordinates } from "./chunk_texture_octahedral_wrap_texel_coordinates.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The octahedral uv a texel of a skirted level carries: its own centre for an interior texel, and
|
|
6
|
+
* for a skirt texel the centre of the interior texel the octahedral fold mirrors it onto.
|
|
7
|
+
*
|
|
8
|
+
* A pass that writes a skirted level computes every texel, skirt included, from this uv. A skirt
|
|
9
|
+
* texel then runs the exact computation its interior twin runs, so the two are bit-identical rather
|
|
10
|
+
* than equal to rounding — which is what lets a hardware bilinear sample across the edge match a
|
|
11
|
+
* manual wrap.
|
|
12
|
+
*
|
|
13
|
+
* @see chunk_texture_octahedral_skirt_uv for the layout
|
|
14
|
+
* @type {CodeChunk}
|
|
15
|
+
*/
|
|
16
|
+
export const chunk_texture_octahedral_skirt_texel_uv = CodeChunk.from(
|
|
17
|
+
//language=WGSL
|
|
18
|
+
`
|
|
19
|
+
fn texture_octahedral_skirt_texel_uv(texel: vec2<u32>, texture_size: u32) -> vec2<f32> {
|
|
20
|
+
let interior = i32(texture_size) - 2;
|
|
21
|
+
let source = texture_octahedral_wrap_texel_coordinates(vec2<i32>(texel) - 1, interior);
|
|
22
|
+
|
|
23
|
+
return (vec2<f32>(source) + 0.5) / f32(interior);
|
|
24
|
+
}
|
|
25
|
+
`, [
|
|
26
|
+
chunk_texture_octahedral_wrap_texel_coordinates,
|
|
27
|
+
]);
|
package/src/shade/renderer/shader/chunk/texture/octahedral/chunk_texture_octahedral_skirt_uv.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where an octahedral uv lands in one level of a skirted octahedral texture.
|
|
3
|
+
*
|
|
4
|
+
* A skirted level of side `texture_size` holds the octahedral square in its interior texels
|
|
5
|
+
* `[1, texture_size - 1)` and a one-texel skirt around it, each skirt texel a copy of the interior
|
|
6
|
+
* texel the octahedral fold puts next to it. With the skirt there, the hardware's bilinear footprint
|
|
7
|
+
* at the edge of the square reads exactly the texels a manual wrap would, so one filtered sample
|
|
8
|
+
* replaces four loads and their wraps.
|
|
9
|
+
*
|
|
10
|
+
* The interior is `texture_size - 2` texels, not half of the level above's, so a level's uv is its
|
|
11
|
+
* own: sample each level through its own size.
|
|
12
|
+
*
|
|
13
|
+
* @see chunk_texture_octahedral_skirt_texel_uv for the inverse, from a skirted texel to the uv it carries
|
|
14
|
+
* @type {CodeChunk}
|
|
15
|
+
*/
|
|
16
|
+
export const chunk_texture_octahedral_skirt_uv: CodeChunk;
|
|
17
|
+
import { CodeChunk } from "../../../compiler/CodeChunk.js";
|
|
18
|
+
//# sourceMappingURL=chunk_texture_octahedral_skirt_uv.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chunk_texture_octahedral_skirt_uv.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/shader/chunk/texture/octahedral/chunk_texture_octahedral_skirt_uv.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;GAcG;AACH,gDAFU,SAAS,CAQhB;0BAvBuB,gCAAgC"}
|
package/src/shade/renderer/shader/chunk/texture/octahedral/chunk_texture_octahedral_skirt_uv.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { CodeChunk } from "../../../compiler/CodeChunk.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Where an octahedral uv lands in one level of a skirted octahedral texture.
|
|
5
|
+
*
|
|
6
|
+
* A skirted level of side `texture_size` holds the octahedral square in its interior texels
|
|
7
|
+
* `[1, texture_size - 1)` and a one-texel skirt around it, each skirt texel a copy of the interior
|
|
8
|
+
* texel the octahedral fold puts next to it. With the skirt there, the hardware's bilinear footprint
|
|
9
|
+
* at the edge of the square reads exactly the texels a manual wrap would, so one filtered sample
|
|
10
|
+
* replaces four loads and their wraps.
|
|
11
|
+
*
|
|
12
|
+
* The interior is `texture_size - 2` texels, not half of the level above's, so a level's uv is its
|
|
13
|
+
* own: sample each level through its own size.
|
|
14
|
+
*
|
|
15
|
+
* @see chunk_texture_octahedral_skirt_texel_uv for the inverse, from a skirted texel to the uv it carries
|
|
16
|
+
* @type {CodeChunk}
|
|
17
|
+
*/
|
|
18
|
+
export const chunk_texture_octahedral_skirt_uv = CodeChunk.from(
|
|
19
|
+
//language=WGSL
|
|
20
|
+
`
|
|
21
|
+
fn texture_octahedral_skirt_uv(octahedral_uv: vec2<f32>, texture_size: f32) -> vec2<f32> {
|
|
22
|
+
return (octahedral_uv * (texture_size - 2.0) + 1.0) / texture_size;
|
|
23
|
+
}
|
|
24
|
+
`);
|
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Works on
|
|
2
|
+
* Works on an octahedral-encoded pre-filtered environment map with a one-texel octahedral skirt on
|
|
3
|
+
* every level it reads (see `texture_octahedral_skirt_uv`).
|
|
4
|
+
*
|
|
5
|
+
* Trilinear as two hardware bilinear taps, one per level, blended here: each level's interior is its
|
|
6
|
+
* own size less the skirt, so one uv cannot address two levels and the sampler's own mip blend would
|
|
7
|
+
* read the coarser one up to a texel off. Most texture units filter trilinear at half the bilinear
|
|
8
|
+
* rate anyway, so the second tap costs about what the hardware blend would.
|
|
9
|
+
*
|
|
10
|
+
* Measured against the manual form this replaces (8 loads, 4 octahedral wraps a level, each wrap
|
|
11
|
+
* two integer divisions and remainders), radiance + irradiance over 1920x1080: 88 → 17 µs on an RTX
|
|
12
|
+
* 4090, 15.4 → 1.3 ms on an RDNA2 iGPU, whose integer division is emulated.
|
|
13
|
+
*
|
|
14
|
+
* Every level the roughness mapping reaches (0 to `SPHERE_PROBE_MIPMAP_LEVELS - 1`) must be at least
|
|
15
|
+
* 3 texels wide to have an interior. A level's size is the texture's halved and kept at 1 or more, as
|
|
16
|
+
* a level's extent is, so a smaller map (the renderer's 1x1 black stand-in, a test's constant) still
|
|
17
|
+
* samples at a finite uv. At the roughest level the second tap reads the level past it at weight 0; a
|
|
18
|
+
* texture without one clamps to the last level, which the weight discards just the same.
|
|
19
|
+
*
|
|
3
20
|
* @see https://github.com/GPUOpen-LibrariesAndSDKs/FidelityFX-SDK/blob/1bbe66e7ea0d358e84af4471a90aa9c35b583de0/samples/hybridreflections/shaders/Common.hlsl#L118
|
|
4
21
|
* @type {CodeChunk}
|
|
5
22
|
*/
|
package/src/shade/renderer/shader/chunk/texture/sample/chunk_sample_environment_map.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk_sample_environment_map.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/shader/chunk/texture/sample/chunk_sample_environment_map.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"chunk_sample_environment_map.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/shader/chunk/texture/sample/chunk_sample_environment_map.js"],"names":[],"mappings":"AAOA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,2CAFU,SAAS,CAyCjB;0BAjEwB,gCAAgC"}
|
|
@@ -2,10 +2,28 @@ import {
|
|
|
2
2
|
chunk_sphere_probe_roughness_to_lod
|
|
3
3
|
} from "../../../../light/environment/chunk_sphere_probe_roughness_to_lod.js";
|
|
4
4
|
import { CodeChunk } from "../../../compiler/CodeChunk.js";
|
|
5
|
-
import {
|
|
5
|
+
import { chunk_uv_octahedral_unit_encode } from "../../geometry/octahedron/chunk_uv_octahedral_unit_encode.js";
|
|
6
|
+
import { chunk_texture_octahedral_skirt_uv } from "../octahedral/chunk_texture_octahedral_skirt_uv.js";
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
|
-
* Works on
|
|
9
|
+
* Works on an octahedral-encoded pre-filtered environment map with a one-texel octahedral skirt on
|
|
10
|
+
* every level it reads (see `texture_octahedral_skirt_uv`).
|
|
11
|
+
*
|
|
12
|
+
* Trilinear as two hardware bilinear taps, one per level, blended here: each level's interior is its
|
|
13
|
+
* own size less the skirt, so one uv cannot address two levels and the sampler's own mip blend would
|
|
14
|
+
* read the coarser one up to a texel off. Most texture units filter trilinear at half the bilinear
|
|
15
|
+
* rate anyway, so the second tap costs about what the hardware blend would.
|
|
16
|
+
*
|
|
17
|
+
* Measured against the manual form this replaces (8 loads, 4 octahedral wraps a level, each wrap
|
|
18
|
+
* two integer divisions and remainders), radiance + irradiance over 1920x1080: 88 → 17 µs on an RTX
|
|
19
|
+
* 4090, 15.4 → 1.3 ms on an RDNA2 iGPU, whose integer division is emulated.
|
|
20
|
+
*
|
|
21
|
+
* Every level the roughness mapping reaches (0 to `SPHERE_PROBE_MIPMAP_LEVELS - 1`) must be at least
|
|
22
|
+
* 3 texels wide to have an interior. A level's size is the texture's halved and kept at 1 or more, as
|
|
23
|
+
* a level's extent is, so a smaller map (the renderer's 1x1 black stand-in, a test's constant) still
|
|
24
|
+
* samples at a finite uv. At the roughest level the second tap reads the level past it at weight 0; a
|
|
25
|
+
* texture without one clamps to the last level, which the weight discards just the same.
|
|
26
|
+
*
|
|
9
27
|
* @see https://github.com/GPUOpen-LibrariesAndSDKs/FidelityFX-SDK/blob/1bbe66e7ea0d358e84af4471a90aa9c35b583de0/samples/hybridreflections/shaders/Common.hlsl#L118
|
|
10
28
|
* @type {CodeChunk}
|
|
11
29
|
*/
|
|
@@ -13,39 +31,39 @@ export const chunk_sample_environment_map = CodeChunk.from(
|
|
|
13
31
|
//language=WGSL
|
|
14
32
|
`
|
|
15
33
|
fn sample_environment_map(
|
|
16
|
-
tEnvironment:texture_2d<f32>,
|
|
17
|
-
|
|
34
|
+
tEnvironment: texture_2d<f32>,
|
|
35
|
+
sEnvironment: sampler,
|
|
36
|
+
direction: vec3<f32>,
|
|
18
37
|
roughness: f32
|
|
19
38
|
) -> vec3<f32> {
|
|
20
|
-
|
|
39
|
+
|
|
21
40
|
let lod = sphere_probe_roughness_to_lod(roughness);
|
|
22
|
-
|
|
23
|
-
let lod_0 =
|
|
24
|
-
let
|
|
25
|
-
|
|
26
|
-
let
|
|
41
|
+
|
|
42
|
+
let lod_0 = floor(lod);
|
|
43
|
+
let level_0 = u32(lod_0);
|
|
44
|
+
|
|
45
|
+
let octahedral_uv = uv_octahedral_unit_encode(direction);
|
|
46
|
+
let size = textureDimensions(tEnvironment).x;
|
|
47
|
+
|
|
48
|
+
let color_0 = textureSampleLevel(
|
|
27
49
|
tEnvironment,
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
direction,
|
|
50
|
+
sEnvironment,
|
|
51
|
+
texture_octahedral_skirt_uv(octahedral_uv, f32(max(size >> level_0, 1u))),
|
|
31
52
|
lod_0
|
|
32
|
-
).rgb;
|
|
33
|
-
|
|
34
|
-
let
|
|
35
|
-
|
|
36
|
-
let color_1 = texture_octahedral_sample_bilinear(
|
|
53
|
+
).rgb;
|
|
54
|
+
|
|
55
|
+
let color_1 = textureSampleLevel(
|
|
37
56
|
tEnvironment,
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
lod_1
|
|
57
|
+
sEnvironment,
|
|
58
|
+
texture_octahedral_skirt_uv(octahedral_uv, f32(max(size >> (level_0 + 1u), 1u))),
|
|
59
|
+
lod_0 + 1.0
|
|
42
60
|
).rgb;
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
return mix(color_0, color_1, f);
|
|
61
|
+
|
|
62
|
+
return mix(color_0, color_1, lod - lod_0);
|
|
46
63
|
}
|
|
47
64
|
`, [
|
|
48
65
|
chunk_sphere_probe_roughness_to_lod,
|
|
49
|
-
|
|
66
|
+
chunk_uv_octahedral_unit_encode,
|
|
67
|
+
chunk_texture_octahedral_skirt_uv,
|
|
50
68
|
]
|
|
51
|
-
);
|
|
69
|
+
);
|