@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.
Files changed (180) hide show
  1. package/package.json +1 -1
  2. package/src/engine/graphics3/make_default_environment.d.ts.map +1 -1
  3. package/src/engine/graphics3/make_default_environment.js +11 -5
  4. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  5. package/src/shade/playground/particle_ecs/moonlit_environment.d.ts.map +1 -1
  6. package/src/shade/playground/particle_ecs/moonlit_environment.js +11 -5
  7. package/src/shade/playground/sh_exponential/sh_exp_playground_shaders.d.ts.map +1 -1
  8. package/src/shade/playground/sh_exponential/sh_exp_playground_shaders.js +3 -1
  9. package/src/shade/playground/tonemap_sdr/README.md +5 -3
  10. package/src/shade/renderer/Renderer.d.ts +1 -1
  11. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  12. package/src/shade/renderer/Renderer.js +43 -15
  13. package/src/shade/renderer/ShadeToneMappingMode.d.ts +3 -2
  14. package/src/shade/renderer/ShadeToneMappingMode.js +15 -4
  15. package/src/shade/renderer/atmosphere/chunk_sample_environment_color.d.ts +3 -0
  16. package/src/shade/renderer/atmosphere/chunk_sample_environment_color.d.ts.map +1 -1
  17. package/src/shade/renderer/atmosphere/chunk_sample_environment_color.js +11 -8
  18. package/src/shade/renderer/atmosphere/shader_sky_irradiance_lut.d.ts +6 -0
  19. package/src/shade/renderer/atmosphere/shader_sky_irradiance_lut.d.ts.map +1 -1
  20. package/src/shade/renderer/atmosphere/shader_sky_irradiance_lut.js +227 -215
  21. package/src/shade/renderer/deferred/SHADING_LIGHT_RESOURCE_GROUP.d.ts.map +1 -1
  22. package/src/shade/renderer/deferred/SHADING_LIGHT_RESOURCE_GROUP.js +2 -0
  23. package/src/shade/renderer/deferred/indirect/chunk_get_ibl_irradiance.d.ts.map +1 -1
  24. package/src/shade/renderer/deferred/indirect/chunk_get_ibl_irradiance.js +4 -2
  25. package/src/shade/renderer/deferred/indirect/chunk_get_ibl_radiance.d.ts.map +1 -1
  26. package/src/shade/renderer/deferred/indirect/chunk_get_ibl_radiance.js +4 -2
  27. package/src/shade/renderer/deferred/shader_background.d.ts.map +1 -1
  28. package/src/shade/renderer/deferred/shader_background.js +4 -2
  29. package/src/shade/renderer/deferred/tonemap/TonemapAces2Tables.d.ts +38 -0
  30. package/src/shade/renderer/deferred/tonemap/TonemapAces2Tables.d.ts.map +1 -0
  31. package/src/shade/renderer/deferred/tonemap/TonemapAces2Tables.js +97 -0
  32. package/src/shade/renderer/deferred/{TonemapDisplaySettings.d.ts → tonemap/TonemapDisplaySettings.d.ts} +1 -1
  33. package/src/shade/renderer/deferred/tonemap/TonemapDisplaySettings.d.ts.map +1 -0
  34. package/src/shade/renderer/deferred/{TonemapDisplaySettings.js → tonemap/TonemapDisplaySettings.js} +5 -5
  35. package/src/shade/renderer/deferred/{shader_tonemap_HDR.d.ts → tonemap/shader_tonemap_HDR.d.ts} +1 -1
  36. package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR.d.ts.map +1 -0
  37. package/src/shade/renderer/deferred/{shader_tonemap_HDR.js → tonemap/shader_tonemap_HDR.js} +9 -9
  38. package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_aces.d.ts +17 -0
  39. package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_aces.d.ts.map +1 -0
  40. package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_aces.js +101 -0
  41. package/src/shade/renderer/deferred/{shader_tonemap_HDR_none.d.ts → tonemap/shader_tonemap_HDR_none.d.ts} +1 -1
  42. package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_none.d.ts.map +1 -0
  43. package/src/shade/renderer/deferred/{shader_tonemap_HDR_none.js → tonemap/shader_tonemap_HDR_none.js} +6 -6
  44. package/src/shade/renderer/deferred/{shader_tonemap_HDR_pbr_neutral.d.ts → tonemap/shader_tonemap_HDR_pbr_neutral.d.ts} +1 -1
  45. package/src/shade/renderer/deferred/tonemap/shader_tonemap_HDR_pbr_neutral.d.ts.map +1 -0
  46. package/src/shade/renderer/deferred/{shader_tonemap_HDR_pbr_neutral.js → tonemap/shader_tonemap_HDR_pbr_neutral.js} +8 -8
  47. package/src/shade/renderer/deferred/{shader_tonemap_LDR.d.ts → tonemap/shader_tonemap_LDR.d.ts} +1 -1
  48. package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR.d.ts.map +1 -0
  49. package/src/shade/renderer/deferred/{shader_tonemap_LDR.js → tonemap/shader_tonemap_LDR.js} +10 -10
  50. package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_aces.d.ts +10 -0
  51. package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_aces.d.ts.map +1 -0
  52. package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_aces.js +77 -0
  53. package/src/shade/renderer/deferred/{shader_tonemap_LDR_none.d.ts → tonemap/shader_tonemap_LDR_none.d.ts} +1 -1
  54. package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_none.d.ts.map +1 -0
  55. package/src/shade/renderer/deferred/{shader_tonemap_LDR_none.js → tonemap/shader_tonemap_LDR_none.js} +7 -7
  56. package/src/shade/renderer/deferred/{shader_tonemap_LDR_pbr_neutral.d.ts → tonemap/shader_tonemap_LDR_pbr_neutral.d.ts} +1 -1
  57. package/src/shade/renderer/deferred/tonemap/shader_tonemap_LDR_pbr_neutral.d.ts.map +1 -0
  58. package/src/shade/renderer/deferred/{shader_tonemap_LDR_pbr_neutral.js → tonemap/shader_tonemap_LDR_pbr_neutral.js} +8 -8
  59. package/src/shade/renderer/fluid/GPUFluidCascade.d.ts +3 -3
  60. package/src/shade/renderer/fluid/GPUFluidCascadeStack.d.ts +1 -1
  61. package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts +6 -6
  62. package/src/shade/renderer/fluid/pressure/GPUFluidPressureSolve.d.ts +1 -1
  63. package/src/shade/renderer/fluid/query/GPUFluidQueries.d.ts +1 -1
  64. package/src/shade/renderer/global_illumination/brick4/gpu/bake/shader_brick4_bake_probes.d.ts.map +1 -1
  65. package/src/shade/renderer/global_illumination/brick4/gpu/bake/shader_brick4_bake_probes.js +3 -1
  66. package/src/shade/renderer/global_illumination/ibl/shader_diffuse_IBL.d.ts.map +1 -1
  67. package/src/shade/renderer/global_illumination/ibl/shader_diffuse_IBL.js +3 -1
  68. package/src/shade/renderer/global_illumination/ibl/shader_specular_IBL.d.ts.map +1 -1
  69. package/src/shade/renderer/global_illumination/ibl/shader_specular_IBL.js +3 -1
  70. package/src/shade/renderer/global_illumination/lpv/deprecated/probe_trace_compute_shader_code.d.ts.map +1 -1
  71. package/src/shade/renderer/global_illumination/lpv/deprecated/probe_trace_compute_shader_code.js +3 -1
  72. package/src/shade/renderer/global_illumination/probe/octahedral/shader_lpv_build_gbuffer.d.ts.map +1 -1
  73. package/src/shade/renderer/global_illumination/probe/octahedral/shader_lpv_build_gbuffer.js +4 -2
  74. package/src/shade/renderer/light/GPULightCollection.d.ts.map +1 -1
  75. package/src/shade/renderer/light/GPULightCollection.js +44 -0
  76. package/src/shade/renderer/light/environment/ENVIRONMENT_MAP_RESOURCE.d.ts +2 -1
  77. package/src/shade/renderer/light/environment/ENVIRONMENT_MAP_RESOURCE.d.ts.map +1 -1
  78. package/src/shade/renderer/light/environment/ENVIRONMENT_MAP_RESOURCE.js +3 -2
  79. package/src/shade/renderer/light/environment/ENVIRONMENT_MAP_SAMPLER_RESOURCE.d.ts +14 -0
  80. package/src/shade/renderer/light/environment/ENVIRONMENT_MAP_SAMPLER_RESOURCE.d.ts.map +1 -0
  81. package/src/shade/renderer/light/environment/ENVIRONMENT_MAP_SAMPLER_RESOURCE.js +25 -0
  82. package/src/shade/renderer/light/environment/execute_filter_environment_map.d.ts.map +1 -1
  83. package/src/shade/renderer/light/environment/execute_filter_environment_map.js +3 -4
  84. package/src/shade/renderer/light/environment/octahedral_skirt_matches.d.ts +19 -0
  85. package/src/shade/renderer/light/environment/octahedral_skirt_matches.d.ts.map +1 -0
  86. package/src/shade/renderer/light/environment/octahedral_skirt_matches.js +67 -0
  87. package/src/shade/renderer/light/environment/octahedral_skirt_source_texel.d.ts +16 -0
  88. package/src/shade/renderer/light/environment/octahedral_skirt_source_texel.d.ts.map +1 -0
  89. package/src/shade/renderer/light/environment/octahedral_skirt_source_texel.js +35 -0
  90. package/src/shade/renderer/light/environment/resample_cube_to_octahedral.d.ts +7 -2
  91. package/src/shade/renderer/light/environment/resample_cube_to_octahedral.d.ts.map +1 -1
  92. package/src/shade/renderer/light/environment/resample_cube_to_octahedral.js +23 -7
  93. package/src/shade/renderer/light/environment/resample_equirectangular_to_octahedral.d.ts +8 -2
  94. package/src/shade/renderer/light/environment/resample_equirectangular_to_octahedral.d.ts.map +1 -1
  95. package/src/shade/renderer/light/environment/resample_equirectangular_to_octahedral.js +24 -7
  96. package/src/shade/renderer/light/environment/sampler2d_octahedral_skirt_fill.d.ts +12 -0
  97. package/src/shade/renderer/light/environment/sampler2d_octahedral_skirt_fill.d.ts.map +1 -0
  98. package/src/shade/renderer/light/environment/sampler2d_octahedral_skirt_fill.js +54 -0
  99. package/src/shade/renderer/light/environment/sh_exponential/shader_sh_exp_environment_cells.d.ts +2 -2
  100. package/src/shade/renderer/light/environment/sh_exponential/shader_sh_exp_environment_cells.d.ts.map +1 -1
  101. package/src/shade/renderer/light/environment/sh_exponential/shader_sh_exp_environment_cells.js +5 -4
  102. package/src/shade/renderer/light/environment/shader_convolve_reflection_map.d.ts.map +1 -1
  103. package/src/shade/renderer/light/environment/shader_convolve_reflection_map.js +13 -9
  104. package/src/shade/renderer/light/environment/shader_project_environment_sh.d.ts.map +1 -1
  105. package/src/shade/renderer/light/environment/shader_project_environment_sh.js +3 -1
  106. package/src/shade/renderer/lightmap/bake/shader_lightmap_viz_to_irradiance_flat.d.ts.map +1 -1
  107. package/src/shade/renderer/lightmap/bake/shader_lightmap_viz_to_irradiance_flat.js +3 -1
  108. package/src/shade/renderer/lightmap/bake/shader_lightmap_viz_to_sh.d.ts.map +1 -1
  109. package/src/shade/renderer/lightmap/bake/shader_lightmap_viz_to_sh.js +3 -1
  110. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
  111. package/src/shade/renderer/path_tracer/accumulating/shader_accumulating_path_tracer.d.ts.map +1 -1
  112. package/src/shade/renderer/path_tracer/accumulating/shader_accumulating_path_tracer.js +3 -1
  113. package/src/shade/renderer/path_tracer/graph_path_trace_scene.d.ts.map +1 -1
  114. package/src/shade/renderer/path_tracer/graph_path_trace_scene.js +3 -1
  115. package/src/shade/renderer/path_tracer/shader/chunk_render_trace_path.js +1 -1
  116. package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
  117. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader.d.ts.map +1 -1
  118. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader.js +3 -1
  119. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_CONSTANTS.d.ts +0 -5
  120. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_CONSTANTS.d.ts.map +1 -1
  121. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_CONSTANTS.js +0 -6
  122. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_counts_to_extinction.d.ts.map +1 -1
  123. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_counts_to_extinction.js +4 -1
  124. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts.map +1 -1
  125. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.js +3 -0
  126. package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.d.ts.map +1 -1
  127. package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.js +3 -0
  128. package/src/shade/renderer/shader/chunk/color/tonemap/ACES_TONE_MAPPING_BRIEF_2026_10_17.md +160 -0
  129. package/src/shade/renderer/shader/chunk/color/tonemap/HDR_TONE_MAPPING_FORMS_BRIEF_2026_10_16.md +5 -1
  130. package/src/shade/renderer/shader/chunk/color/tonemap/SDR_TONE_MAPPING_BRIEF_2026_10_16.md +15 -5
  131. package/src/shade/renderer/shader/chunk/color/tonemap/aces/aces2_transform_block.d.ts +41 -0
  132. package/src/shade/renderer/shader/chunk/color/tonemap/aces/aces2_transform_block.d.ts.map +1 -0
  133. package/src/shade/renderer/shader/chunk/color/tonemap/aces/aces2_transform_block.js +692 -0
  134. package/src/shade/renderer/shader/chunk/color/tonemap/aces/chunk_aces2_output_transform.d.ts +25 -0
  135. package/src/shade/renderer/shader/chunk/color/tonemap/aces/chunk_aces2_output_transform.d.ts.map +1 -0
  136. package/src/shade/renderer/shader/chunk/color/tonemap/aces/chunk_aces2_output_transform.js +446 -0
  137. package/src/shade/renderer/shader/chunk/color/tonemap/aces/chunk_aces_ue_matrices.d.ts +22 -0
  138. package/src/shade/renderer/shader/chunk/color/tonemap/aces/chunk_aces_ue_matrices.d.ts.map +1 -0
  139. package/src/shade/renderer/shader/chunk/color/tonemap/aces/chunk_aces_ue_matrices.js +68 -0
  140. package/src/shade/renderer/shader/chunk/color/tonemap/aces/chunk_tonemap_ue_filmic.d.ts +32 -0
  141. package/src/shade/renderer/shader/chunk/color/tonemap/aces/chunk_tonemap_ue_filmic.d.ts.map +1 -0
  142. package/src/shade/renderer/shader/chunk/color/tonemap/aces/chunk_tonemap_ue_filmic.js +163 -0
  143. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_PAPER_WHITE_NITS.d.ts +10 -3
  144. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_PAPER_WHITE_NITS.d.ts.map +1 -1
  145. package/src/shade/renderer/shader/chunk/color/tonemap/chunk_PAPER_WHITE_NITS.js +12 -4
  146. package/src/shade/renderer/shader/chunk/texture/octahedral/chunk_texture_octahedral_skirt_texel_uv.d.ts +15 -0
  147. package/src/shade/renderer/shader/chunk/texture/octahedral/chunk_texture_octahedral_skirt_texel_uv.d.ts.map +1 -0
  148. package/src/shade/renderer/shader/chunk/texture/octahedral/chunk_texture_octahedral_skirt_texel_uv.js +27 -0
  149. package/src/shade/renderer/shader/chunk/texture/octahedral/chunk_texture_octahedral_skirt_uv.d.ts +18 -0
  150. package/src/shade/renderer/shader/chunk/texture/octahedral/chunk_texture_octahedral_skirt_uv.d.ts.map +1 -0
  151. package/src/shade/renderer/shader/chunk/texture/octahedral/chunk_texture_octahedral_skirt_uv.js +24 -0
  152. package/src/shade/renderer/shader/chunk/texture/sample/chunk_sample_environment_map.d.ts +18 -1
  153. package/src/shade/renderer/shader/chunk/texture/sample/chunk_sample_environment_map.d.ts.map +1 -1
  154. package/src/shade/renderer/shader/chunk/texture/sample/chunk_sample_environment_map.js +45 -27
  155. package/src/shade/renderer/view/GPUViewSkyContext.js +169 -169
  156. package/src/shade/renderer/volumetrics/NOTES.md +209 -0
  157. package/src/shade/renderer/volumetrics/VOLUMETRICS_METADATA_STRUCT.d.ts.map +1 -1
  158. package/src/shade/renderer/volumetrics/VOLUMETRICS_METADATA_STRUCT.js +1 -1
  159. package/src/shade/renderer/volumetrics/chunk_volumetrics_media_group_list.d.ts +36 -0
  160. package/src/shade/renderer/volumetrics/chunk_volumetrics_media_group_list.d.ts.map +1 -0
  161. package/src/shade/renderer/volumetrics/chunk_volumetrics_media_group_list.js +129 -0
  162. package/src/shade/renderer/volumetrics/graph_build_volumetrics.d.ts.map +1 -1
  163. package/src/shade/renderer/volumetrics/graph_build_volumetrics.js +75 -0
  164. package/src/shade/renderer/volumetrics/shader_volumetrics_bin_participating_media.d.ts +26 -0
  165. package/src/shade/renderer/volumetrics/shader_volumetrics_bin_participating_media.d.ts.map +1 -0
  166. package/src/shade/renderer/volumetrics/shader_volumetrics_bin_participating_media.js +110 -0
  167. package/src/shade/renderer/volumetrics/shader_volumetrics_build_participating_media.d.ts.map +1 -1
  168. package/src/shade/renderer/volumetrics/shader_volumetrics_build_participating_media.js +38 -14
  169. package/src/shade/renderer/volumetrics/shader_volumetrics_build_scattering_lut.d.ts.map +1 -1
  170. package/src/shade/renderer/volumetrics/shader_volumetrics_build_scattering_lut.js +9 -4
  171. package/src/shade/renderer/volumetrics/shader_volumetrics_split_participating_media.d.ts +31 -0
  172. package/src/shade/renderer/volumetrics/shader_volumetrics_split_participating_media.d.ts.map +1 -0
  173. package/src/shade/renderer/volumetrics/shader_volumetrics_split_participating_media.js +139 -0
  174. package/src/shade/renderer/deferred/TonemapDisplaySettings.d.ts.map +0 -1
  175. package/src/shade/renderer/deferred/shader_tonemap_HDR.d.ts.map +0 -1
  176. package/src/shade/renderer/deferred/shader_tonemap_HDR_none.d.ts.map +0 -1
  177. package/src/shade/renderer/deferred/shader_tonemap_HDR_pbr_neutral.d.ts.map +0 -1
  178. package/src/shade/renderer/deferred/shader_tonemap_LDR.d.ts.map +0 -1
  179. package/src/shade/renderer/deferred/shader_tonemap_LDR_none.d.ts.map +0 -1
  180. package/src/shade/renderer/deferred/shader_tonemap_LDR_pbr_neutral.d.ts.map +0 -1
@@ -34,7 +34,7 @@ export class GPUFluidPressureSolve {
34
34
  * @param {*} _resources
35
35
  * @param {{encoder: ShadeGPUCommandContext}} context
36
36
  */
37
- static "__#262@#execute"(data: {
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 "__#267@#execute"(pass: object, resources: import("../../../../engine/graphics/render/frame_graph/FramePassResources.js").FramePassResources, context: {
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
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"shader_brick4_bake_probes.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/global_illumination/brick4/gpu/bake/shader_brick4_bake_probes.js"],"names":[],"mappings":"AAqHA,sDAIG;8BA1G2B,qCAAqC"}
1
+ {"version":3,"file":"shader_brick4_bake_probes.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/global_illumination/brick4/gpu/bake/shader_brick4_bake_probes.js"],"names":[],"mappings":"AAuHA,sDAIG;8BA5G2B,qCAAqC"}
@@ -19,6 +19,7 @@ import { RESOURCE_GROUP_RTX } from "../../../../geometry/sr_create_group_RTX.js"
19
19
  import { PARTICIPATING_MEDIA_NOISE_SAMPLER_DESCRIPTOR } from "../../../../volumetrics/noise/PARTICIPATING_MEDIA_NOISE.js";
20
20
  import { wind_field_add_resources } from "../../../../wind/wind_field_add_resources.js";
21
21
  import { chunk_direction_by_index_rand1 } from "./sampling/chunk_direction_by_index_rand1.js";
22
+ import { ENVIRONMENT_MAP_SAMPLER_RESOURCE } from "../../../../light/environment/ENVIRONMENT_MAP_SAMPLER_RESOURCE.js";
22
23
 
23
24
  const resources = new ShaderResourceSetDescriptor();
24
25
 
@@ -32,7 +33,8 @@ resources.createGroup()
32
33
  // the scene's wind, which carries the fog volumes' noise: one uniform, one texture, one sampler
33
34
  wind_field_add_resources(resources.createGroup()
34
35
  .addStorageBuffer("light_data", WebGPUArray.u32)
35
- .addTexture("tEnvironment", "unfilterable-float", "2d")
36
+ .addTexture("tEnvironment", "float", "2d")
37
+ .add(ENVIRONMENT_MAP_SAMPLER_RESOURCE)
36
38
  // the fog volumes' noise, read through participating_media_volume_density_at
37
39
  .addTexture("tParticipatingMediaNoise", "float", "3d")
38
40
  .addSampler("sParticipatingMediaNoise", "filtering", PARTICIPATING_MEDIA_NOISE_SAMPLER_DESCRIPTOR));
@@ -1 +1 @@
1
- {"version":3,"file":"shader_diffuse_IBL.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/global_illumination/ibl/shader_diffuse_IBL.js"],"names":[],"mappings":"AAyCA,6CAaE;4BAlD0B,6BAA6B"}
1
+ {"version":3,"file":"shader_diffuse_IBL.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/global_illumination/ibl/shader_diffuse_IBL.js"],"names":[],"mappings":"AA2CA,6CAaE;4BApD0B,6BAA6B"}
@@ -5,12 +5,14 @@ import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
5
5
  import { ImageShader } from "../../shader/ImageShader.js";
6
6
  import { ShaderResourceSetDescriptor } from "../../shader/resource/ShaderResourceSetDescriptor.js";
7
7
  import { ShaderDescriptor } from "../../shader/ShaderDescriptor.js";
8
+ import { ENVIRONMENT_MAP_SAMPLER_RESOURCE } from "../../light/environment/ENVIRONMENT_MAP_SAMPLER_RESOURCE.js";
8
9
 
9
10
  const resources = new ShaderResourceSetDescriptor();
10
11
  resources.createGroup()
11
12
  .addTexture("tBentNormals", "uint")
12
13
  .addTexture("tGBufferAlbedo")
13
- .addTexture("tEnvironment")
14
+ .addTexture("tEnvironment", "float")
15
+ .add(ENVIRONMENT_MAP_SAMPLER_RESOURCE)
14
16
 
15
17
  const body = CodeChunk.from(
16
18
  //language=WGSL
@@ -1 +1 @@
1
- {"version":3,"file":"shader_specular_IBL.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/global_illumination/ibl/shader_specular_IBL.js"],"names":[],"mappings":"AAuEA,8CAaE;4BA5E0B,6BAA6B"}
1
+ {"version":3,"file":"shader_specular_IBL.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/global_illumination/ibl/shader_specular_IBL.js"],"names":[],"mappings":"AAyEA,8CAaE;4BA9E0B,6BAA6B"}
@@ -9,12 +9,14 @@ import { CodeChunk } from "../../shader/compiler/CodeChunk.js";
9
9
  import { ImageShader } from "../../shader/ImageShader.js";
10
10
  import { ShaderResourceSetDescriptor } from "../../shader/resource/ShaderResourceSetDescriptor.js";
11
11
  import { ShaderDescriptor } from "../../shader/ShaderDescriptor.js";
12
+ import { ENVIRONMENT_MAP_SAMPLER_RESOURCE } from "../../light/environment/ENVIRONMENT_MAP_SAMPLER_RESOURCE.js";
12
13
 
13
14
  const resources = new ShaderResourceSetDescriptor();
14
15
  resources.createGroup()
15
16
  .addTexture("tBentNormals", "uint")
16
17
  .addTexture("tNormals", "uint")
17
- .addTexture("tEnvironment")
18
+ .addTexture("tEnvironment", "float")
19
+ .add(ENVIRONMENT_MAP_SAMPLER_RESOURCE)
18
20
  .addTexture("tPBR")
19
21
  .addTexture("tDepth")
20
22
  .addUniform("camera", CAMERA_UNIFORM_STRUCT)
@@ -1 +1 @@
1
- {"version":3,"file":"probe_trace_compute_shader_code.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/global_illumination/lpv/deprecated/probe_trace_compute_shader_code.js"],"names":[],"mappings":"AA2BA,sDAIG;AAwKH,4DAIG;6BAzM0B,sCAAsC;8BAiBrC,kCAAkC"}
1
+ {"version":3,"file":"probe_trace_compute_shader_code.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/global_illumination/lpv/deprecated/probe_trace_compute_shader_code.js"],"names":[],"mappings":"AA4BA,sDAIG;AAyKH,4DAIG;6BA3M0B,sCAAsC;8BAiBrC,kCAAkC"}
@@ -24,6 +24,7 @@ import { LIGHT_PROBE_STRUCT } from "../LIGHT_PROBE_STRUCT.js";
24
24
  import { LIGHT_PROBE_VOLUME_METADATA_STRUCT } from "../LIGHT_PROBE_VOLUME_METADATA_STRUCT.js";
25
25
  import { PARTICIPATING_MEDIA_NOISE_SAMPLER_DESCRIPTOR } from "../../../volumetrics/noise/PARTICIPATING_MEDIA_NOISE.js";
26
26
  import { wind_field_add_resources } from "../../../wind/wind_field_add_resources.js";
27
+ import { ENVIRONMENT_MAP_SAMPLER_RESOURCE } from "../../../light/environment/ENVIRONMENT_MAP_SAMPLER_RESOURCE.js";
27
28
 
28
29
  export const PROBE_BAKE_UNIFORMS_STRUCT = WebGPUStruct.from({
29
30
  direction: vec3f,
@@ -45,7 +46,8 @@ wind_field_add_resources(resources.createGroup({ label: 'LPV & scene' })
45
46
  .addUniform('media', MEDIA_TABLE_STRUCT)
46
47
  .addTexture('textures', 'unfilterable-float', '2d-array', false)
47
48
  .addUniform('bake_settings', PROBE_BAKE_UNIFORMS_STRUCT)
48
- .addTexture('tEnvironment', 'unfilterable-float')
49
+ .addTexture("tEnvironment", "float", "2d")
50
+ .add(ENVIRONMENT_MAP_SAMPLER_RESOURCE)
49
51
  // the fog volumes' noise, read through participating_media_volume_density_at
50
52
  .addTexture("tParticipatingMediaNoise", "float", "3d")
51
53
  .addSampler("sParticipatingMediaNoise", "filtering", PARTICIPATING_MEDIA_NOISE_SAMPLER_DESCRIPTOR));
@@ -1 +1 @@
1
- {"version":3,"file":"shader_lpv_build_gbuffer.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/global_illumination/probe/octahedral/shader_lpv_build_gbuffer.js"],"names":[],"mappings":"AAmMA,mDA4BG;4BAvLyB,gCAAgC"}
1
+ {"version":3,"file":"shader_lpv_build_gbuffer.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/global_illumination/probe/octahedral/shader_lpv_build_gbuffer.js"],"names":[],"mappings":"AAqMA,mDA4BG;4BAzLyB,gCAAgC"}
@@ -44,6 +44,7 @@ import { ShaderDescriptor } from "../../../shader/ShaderDescriptor.js";
44
44
  import { sr_create_group_RTX } from "../../../geometry/sr_create_group_RTX.js";
45
45
  import { LIGHT_PROBE_STRUCT } from "../../lpv/LIGHT_PROBE_STRUCT.js";
46
46
  import { ProbeGBufferTypes } from "./ProbeGBufferTypes.js";
47
+ import { ENVIRONMENT_MAP_SAMPLER_RESOURCE } from "../../../light/environment/ENVIRONMENT_MAP_SAMPLER_RESOURCE.js";
47
48
 
48
49
  const PUSH_CONSTANTS = WebGPUStruct.from({
49
50
  probe_resolution: u32,
@@ -65,7 +66,8 @@ resources.createGroup()
65
66
  resources.createGroup({ label: "materials" })
66
67
  .addUniform("materials", INDIRECT_MATERIAL_ARRAY_TYPE)
67
68
  .addTexture("textures", "unfilterable-float", "2d-array", false)
68
- .addTexture("tEnvironment")
69
+ .addTexture("tEnvironment", "float")
70
+ .add(ENVIRONMENT_MAP_SAMPLER_RESOURCE)
69
71
  ;
70
72
 
71
73
  sr_create_group_RTX(resources);
@@ -131,7 +133,7 @@ fn main(
131
133
  if(hit.t <= 0.0){
132
134
 
133
135
  // didn't hit anything
134
- output.emissive = rgbe9995_encode( sample_environment_color(tEnvironment, ray.direction) );
136
+ output.emissive = rgbe9995_encode( sample_environment_color(tEnvironment, sEnvironment, ray.direction) );
135
137
  output.pbr.a = 1; // mark a miss
136
138
  output.position = vec4(ray.direction, 0.0); // needed to reconstruct direction later on
137
139
 
@@ -1 +1 @@
1
- {"version":3,"file":"GPULightCollection.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/light/GPULightCollection.js"],"names":[],"mappings":"AA+CA;IAEI;;;;;OAKG;IACH,iCAFW,eAAe,QAMzB;IAoJD;;;;;;OAMG;IACH,sBALW,eAAe,aACf,eAAe,EAqCzB;IApLD;;;OAGG;IACH,6DAEC;IAeD;;OAEG;IACH,4BAEC;IAED;;;;;;OAMG;IACH,6BAEC;IAED;;;;;;;OAOG;IACH,qFAEC;IAWD;;OAEG;IACH,+CAEC;IAgDD;;;OAGG;IACH,qCAEC;IAED;;;;;;OAMG;IACH,gCAEC;IAGD,4BAKC;IAgID;;;OAGG;IACH,YAFW,eAAe,QA8BzB;IAED;;;;;;;;;OASG;IACH,gBAFW,OAAO,+BAA+B,EAAE,YAAY,QAkC9D;IAED;;;;;;OAMG;IACH,uBAHW,sBAAsB,mCAyBhC;IAwED,gBASC;;CACJ;8BAjfY,OAAO,0CAA0C,EAAE,eAAe;8BAClE,OAAO,uBAAuB,EAAE,eAAe;8BAC/C,OAAO,6BAA6B,EAAE,eAAe;8BACrD,OAAO,sBAAsB,EAAE,eAAe;4BAzB/B,gCAAgC;yCACnB,2CAA2C;kCAClD,iCAAiC;uCAH5B,wCAAwC"}
1
+ {"version":3,"file":"GPULightCollection.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/light/GPULightCollection.js"],"names":[],"mappings":"AAkDA;IAEI;;;;;OAKG;IACH,iCAFW,eAAe,QAMzB;IAoJD;;;;;;OAMG;IACH,sBALW,eAAe,aACf,eAAe,EAqCzB;IApLD;;;OAGG;IACH,6DAEC;IAeD;;OAEG;IACH,4BAEC;IAED;;;;;;OAMG;IACH,6BAEC;IAED;;;;;;;OAOG;IACH,qFAEC;IAWD;;OAEG;IACH,+CAEC;IAgDD;;;OAGG;IACH,qCAEC;IAED;;;;;;OAMG;IACH,gCAEC;IAGD,4BAKC;IAyKD;;;OAGG;IACH,YAFW,eAAe,QA8BzB;IAED;;;;;;;;;OASG;IACH,gBAFW,OAAO,+BAA+B,EAAE,YAAY,QAkC9D;IAED;;;;;;OAMG;IACH,uBAHW,sBAAsB,mCAyBhC;IAwED,gBASC;;CACJ;8BA1hBY,OAAO,0CAA0C,EAAE,eAAe;8BAClE,OAAO,uBAAuB,EAAE,eAAe;8BAC/C,OAAO,6BAA6B,EAAE,eAAe;8BACrD,OAAO,sBAAsB,EAAE,eAAe;4BA3B/B,gCAAgC;yCACnB,2CAA2C;kCAClD,iCAAiC;uCAH5B,wCAAwC"}
@@ -1,4 +1,5 @@
1
1
  import { assert } from "../../../core/assert.js";
2
+ import { gpu_texture_format_info } from "../../descriptor/texture/format/gpu_texture_format_info.js";
2
3
  import { isImageBitmap } from "../../../core/dom/isImageBitmap.js";
3
4
  import { ShadeGPUCommandContext } from "../../device/ShadeGPUCommandContext.js";
4
5
  import { GPUDatabase } from "../buffer/table/GPUDatabase.js";
@@ -10,6 +11,8 @@ import {
10
11
  enquire_filter_environment_map_pipelines,
11
12
  execute_filter_environment_map
12
13
  } from "./environment/execute_filter_environment_map.js";
14
+ import { SPHERE_PROBE_MIPMAP_LEVELS } from "./environment/DEFINES.js";
15
+ import { octahedral_skirt_matches } from "./environment/octahedral_skirt_matches.js";
13
16
  import { ENVIRONMENT_SH_TYPE, shader_project_environment_sh } from "./environment/shader_project_environment_sh.js";
14
17
  import { LIGHT_DATABASE_SPEC } from "./LIGHT_DATABASE_SPEC.js";
15
18
  import { light_record_directional } from "./model/io/light_record_directional.js";
@@ -287,6 +290,47 @@ export class GPULightCollection {
287
290
  }
288
291
 
289
292
  const source_image = source_env.image;
293
+
294
+ /*
295
+ An environment map comes with a one-texel octahedral skirt: the octahedral square in the
296
+ interior, each texel of the outer ring a copy of the one the fold puts beside it. The renderer
297
+ filters it in hardware through that skirt and skirts the levels it filters itself; an
298
+ unskirted map is the caller's error, and it would read as seams along the octahedron's
299
+ edges. Every level the roughness mapping reaches needs an interior, so 3 texels at the last.
300
+ `resample_equirectangular_to_octahedral` and the offline converter write the skirt by default.
301
+
302
+ Checked where the pixels are on hand; an ImageBitmap's are not.
303
+ */
304
+ assert.greaterThanOrEqual(
305
+ source_image.width >> (SPHERE_PROBE_MIPMAP_LEVELS - 1),
306
+ 3,
307
+ 'environment map too small for its last filtered level'
308
+ );
309
+
310
+ assert.equal(source_image.width, source_image.height, 'an octahedral environment map is square');
311
+
312
+ const source_texels = source_image.source;
313
+
314
+ if (source_texels?.isSampler2D === true) {
315
+ assert.ok(
316
+ octahedral_skirt_matches(source_texels.data, source_texels.itemSize, source_texels.width),
317
+ 'environment map has no octahedral skirt (see sampler2d_octahedral_skirt_fill)'
318
+ );
319
+ } else if (
320
+ source_texels?.isShadeTexelData === true
321
+ && source_texels.levels[0] !== undefined
322
+ && gpu_texture_format_info(source_texels.format).block_width === 1
323
+ ) {
324
+ assert.ok(
325
+ octahedral_skirt_matches(
326
+ source_texels.levels[0],
327
+ gpu_texture_format_info(source_texels.format).bytes_per_block,
328
+ source_texels.width
329
+ ),
330
+ 'environment map has no octahedral skirt (see sampler2d_octahedral_skirt_fill)'
331
+ );
332
+ }
333
+
290
334
  gpu_ctx.resize(source_image.width, source_image.height);
291
335
  /*
292
336
  The environment map is equirectangular and this context is built 2D a few lines up — the
@@ -1,5 +1,6 @@
1
1
  /**
2
- * The environment map, sampled by direction and roughness.
2
+ * The environment map, sampled by direction and roughness. Filterable: the hardware filters it through
3
+ * its octahedral skirt (`texture_octahedral_skirt_uv`) and `ENVIRONMENT_MAP_SAMPLER_RESOURCE`.
3
4
  * @type {ShaderResourceDescriptor}
4
5
  */
5
6
  export const ENVIRONMENT_MAP_RESOURCE: ShaderResourceDescriptor;
@@ -1 +1 @@
1
- {"version":3,"file":"ENVIRONMENT_MAP_RESOURCE.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/light/environment/ENVIRONMENT_MAP_RESOURCE.js"],"names":[],"mappings":"AAEA;;;GAGG;AACH,uCAFU,wBAAwB,CAEuD;yCANhD,mDAAmD"}
1
+ {"version":3,"file":"ENVIRONMENT_MAP_RESOURCE.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/light/environment/ENVIRONMENT_MAP_RESOURCE.js"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,uCAFU,wBAAwB,CAEgE;yCAPzD,mDAAmD"}
@@ -1,7 +1,8 @@
1
1
  import { ShaderResourceDescriptor } from "../../shader/resource/ShaderResourceDescriptor.js";
2
2
 
3
3
  /**
4
- * The environment map, sampled by direction and roughness.
4
+ * The environment map, sampled by direction and roughness. Filterable: the hardware filters it through
5
+ * its octahedral skirt (`texture_octahedral_skirt_uv`) and `ENVIRONMENT_MAP_SAMPLER_RESOURCE`.
5
6
  * @type {ShaderResourceDescriptor}
6
7
  */
7
- export const ENVIRONMENT_MAP_RESOURCE = ShaderResourceDescriptor.texture("tEnvironment");
8
+ export const ENVIRONMENT_MAP_RESOURCE = ShaderResourceDescriptor.texture("tEnvironment", "float");
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Bilinear within a level, clamped. Levels are chosen by the caller, one whole level per sample,
3
+ * because each level of a skirted map has a uv of its own (see `texture_octahedral_skirt_uv`).
4
+ * @type {SamplerDescriptor}
5
+ */
6
+ export const ENVIRONMENT_MAP_SAMPLER_DESCRIPTOR: SamplerDescriptor;
7
+ /**
8
+ * The sampler the environment map is read through.
9
+ * @type {ShaderResourceDescriptor}
10
+ */
11
+ export const ENVIRONMENT_MAP_SAMPLER_RESOURCE: ShaderResourceDescriptor;
12
+ import { SamplerDescriptor } from "../../../descriptor/texture/SamplerDescriptor.js";
13
+ import { ShaderResourceDescriptor } from "../../shader/resource/ShaderResourceDescriptor.js";
14
+ //# sourceMappingURL=ENVIRONMENT_MAP_SAMPLER_RESOURCE.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ENVIRONMENT_MAP_SAMPLER_RESOURCE.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/light/environment/ENVIRONMENT_MAP_SAMPLER_RESOURCE.js"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,iDAFU,iBAAiB,CAQvB;AAEJ;;;GAGG;AACH,+CAFU,wBAAwB,CAMhC;kCAxBgC,kDAAkD;yCAC3C,mDAAmD"}
@@ -0,0 +1,25 @@
1
+ import { SamplerDescriptor } from "../../../descriptor/texture/SamplerDescriptor.js";
2
+ import { ShaderResourceDescriptor } from "../../shader/resource/ShaderResourceDescriptor.js";
3
+
4
+ /**
5
+ * Bilinear within a level, clamped. Levels are chosen by the caller, one whole level per sample,
6
+ * because each level of a skirted map has a uv of its own (see `texture_octahedral_skirt_uv`).
7
+ * @type {SamplerDescriptor}
8
+ */
9
+ export const ENVIRONMENT_MAP_SAMPLER_DESCRIPTOR = Object.freeze(SamplerDescriptor.from({
10
+ magFilter: "linear",
11
+ minFilter: "linear",
12
+ mipmapFilter: "nearest",
13
+ addressModeU: "clamp-to-edge",
14
+ addressModeV: "clamp-to-edge",
15
+ }));
16
+
17
+ /**
18
+ * The sampler the environment map is read through.
19
+ * @type {ShaderResourceDescriptor}
20
+ */
21
+ export const ENVIRONMENT_MAP_SAMPLER_RESOURCE = ShaderResourceDescriptor.sampler(
22
+ "sEnvironment",
23
+ "filtering",
24
+ ENVIRONMENT_MAP_SAMPLER_DESCRIPTOR
25
+ );
@@ -1 +1 @@
1
- {"version":3,"file":"execute_filter_environment_map.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/light/environment/execute_filter_environment_map.js"],"names":[],"mappings":"AAKA;;GAEG;AAEH;;;;GAIG;AACH,kEAFW,eAAe,QAIzB;AAED;;;;GAIG;AACH,8GAmDC;8BApEY,OAAO,6CAA6C,EAAE,eAAe"}
1
+ {"version":3,"file":"execute_filter_environment_map.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/light/environment/execute_filter_environment_map.js"],"names":[],"mappings":"AAKA;;GAEG;AAEH;;;;GAIG;AACH,kEAFW,eAAe,QAIzB;AAED;;;;GAIG;AACH,8GAkDC;8BAnEY,OAAO,6CAA6C,EAAE,eAAe"}
@@ -39,10 +39,9 @@ export function execute_filter_environment_map(
39
39
  the allocation were two sources of truth for one number, and this is the one that decides what
40
40
  gets filtered.
41
41
 
42
- Still open, and not this line's to fix: an environment map smaller than 16x16 has fewer than
43
- five levels, so `roughness_to_lod` can ask for a level the texture does not have and the
44
- sampler clamps to a blurrier one than the roughness wanted. That needs the mapping to know the
45
- texture's real level count, which is a change to every shader that samples one.
42
+ Every level written here is skirted: the convolve computes the skirt texels as their interior
43
+ twins, so a level needs at least 3 texels, and `GPULightCollection` refuses a map whose last
44
+ filtered level would have fewer.
46
45
  */
47
46
  const mips = Math.min(map.descriptor.mipLevelCount, SPHERE_PROBE_MIPMAP_LEVELS);
48
47
 
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Whether a square octahedral level carries a one-texel octahedral skirt: at least 3x3, and every
3
+ * texel of the outer ring equal, element for element, to the interior texel the octahedral fold puts
4
+ * next to it.
5
+ *
6
+ * Exact equality, on purpose. A skirt is a copy, and a copy survives any encoding that maps equal
7
+ * values to equal values — RGBE and half floats both do — so a level that only nearly matches was not
8
+ * written with one. A constant level passes, which is right: its skirt is already what a fill would
9
+ * write. Elements are compared with `Object.is`, so this works on channel values and on raw bytes alike.
10
+ *
11
+ * Walks the perimeter only.
12
+ *
13
+ * @param {ArrayLike<number>} data texels, row-major, tightly packed
14
+ * @param {number} texel_stride elements per texel: channels of a sampler, or bytes of a raw payload
15
+ * @param {number} size side of the level
16
+ * @returns {boolean}
17
+ */
18
+ export function octahedral_skirt_matches(data: ArrayLike<number>, texel_stride: number, size: number): boolean;
19
+ //# sourceMappingURL=octahedral_skirt_matches.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"octahedral_skirt_matches.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/light/environment/octahedral_skirt_matches.js"],"names":[],"mappings":"AAOA;;;;;;;;;;;;;;;;GAgBG;AACH,+CALW,UAAU,MAAM,CAAC,gBACjB,MAAM,QACN,MAAM,GACJ,OAAO,CAqBnB"}
@@ -0,0 +1,67 @@
1
+ import { octahedral_skirt_source_texel } from "./octahedral_skirt_source_texel.js";
2
+
3
+ /**
4
+ * @type {Uint32Array}
5
+ */
6
+ const SCRATCH_SOURCE = new Uint32Array(2);
7
+
8
+ /**
9
+ * Whether a square octahedral level carries a one-texel octahedral skirt: at least 3x3, and every
10
+ * texel of the outer ring equal, element for element, to the interior texel the octahedral fold puts
11
+ * next to it.
12
+ *
13
+ * Exact equality, on purpose. A skirt is a copy, and a copy survives any encoding that maps equal
14
+ * values to equal values — RGBE and half floats both do — so a level that only nearly matches was not
15
+ * written with one. A constant level passes, which is right: its skirt is already what a fill would
16
+ * write. Elements are compared with `Object.is`, so this works on channel values and on raw bytes alike.
17
+ *
18
+ * Walks the perimeter only.
19
+ *
20
+ * @param {ArrayLike<number>} data texels, row-major, tightly packed
21
+ * @param {number} texel_stride elements per texel: channels of a sampler, or bytes of a raw payload
22
+ * @param {number} size side of the level
23
+ * @returns {boolean}
24
+ */
25
+ export function octahedral_skirt_matches(data, texel_stride, size) {
26
+ if (size < 3) {
27
+ return false;
28
+ }
29
+
30
+ const last = size - 1;
31
+
32
+ for (let i = 0; i < size; i++) {
33
+ if (
34
+ !matches_source(data, texel_stride, size, i, 0)
35
+ || !matches_source(data, texel_stride, size, i, last)
36
+ || !matches_source(data, texel_stride, size, 0, i)
37
+ || !matches_source(data, texel_stride, size, last, i)
38
+ ) {
39
+ return false;
40
+ }
41
+ }
42
+
43
+ return true;
44
+ }
45
+
46
+ /**
47
+ * @param {ArrayLike<number>} data
48
+ * @param {number} texel_stride
49
+ * @param {number} size
50
+ * @param {number} x
51
+ * @param {number} y
52
+ * @returns {boolean}
53
+ */
54
+ function matches_source(data, texel_stride, size, x, y) {
55
+ octahedral_skirt_source_texel(SCRATCH_SOURCE, x, y, size);
56
+
57
+ const target = (y * size + x) * texel_stride;
58
+ const source = (SCRATCH_SOURCE[1] * size + SCRATCH_SOURCE[0]) * texel_stride;
59
+
60
+ for (let c = 0; c < texel_stride; c++) {
61
+ if (!Object.is(data[target + c], data[source + c])) {
62
+ return false;
63
+ }
64
+ }
65
+
66
+ return true;
67
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * The interior texel a texel of a skirted octahedral level carries — itself for an interior texel, and
3
+ * for a skirt texel the interior texel the octahedral fold mirrors it onto. Coordinates are in the
4
+ * skirted texture, so an interior texel comes back unchanged.
5
+ *
6
+ * CPU twin of the WGSL `texture_octahedral_skirt_texel_uv` (through
7
+ * `texture_octahedral_wrap_texel_coordinates`), which the GPU producers of skirted levels use; the two
8
+ * must agree texel for texel or a skirt written on one side reads as missing on the other.
9
+ *
10
+ * @param {number[]|Uint32Array} out receives `[x, y]`
11
+ * @param {number} x texel column in the skirted texture, `0` to `size - 1`
12
+ * @param {number} y texel row in the skirted texture, `0` to `size - 1`
13
+ * @param {number} size side of the skirted texture, interior plus two
14
+ */
15
+ export function octahedral_skirt_source_texel(out: number[] | Uint32Array, x: number, y: number, size: number): void;
16
+ //# sourceMappingURL=octahedral_skirt_source_texel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"octahedral_skirt_source_texel.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/light/environment/octahedral_skirt_source_texel.js"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,mDALW,MAAM,EAAE,GAAC,WAAW,KACpB,MAAM,KACN,MAAM,QACN,MAAM,QAsBhB"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * The interior texel a texel of a skirted octahedral level carries — itself for an interior texel, and
3
+ * for a skirt texel the interior texel the octahedral fold mirrors it onto. Coordinates are in the
4
+ * skirted texture, so an interior texel comes back unchanged.
5
+ *
6
+ * CPU twin of the WGSL `texture_octahedral_skirt_texel_uv` (through
7
+ * `texture_octahedral_wrap_texel_coordinates`), which the GPU producers of skirted levels use; the two
8
+ * must agree texel for texel or a skirt written on one side reads as missing on the other.
9
+ *
10
+ * @param {number[]|Uint32Array} out receives `[x, y]`
11
+ * @param {number} x texel column in the skirted texture, `0` to `size - 1`
12
+ * @param {number} y texel row in the skirted texture, `0` to `size - 1`
13
+ * @param {number} size side of the skirted texture, interior plus two
14
+ */
15
+ export function octahedral_skirt_source_texel(out, x, y, size) {
16
+ const interior = size - 2;
17
+
18
+ const tx = x - 1;
19
+ const ty = y - 1;
20
+
21
+ const wrapped_x = ((tx % interior) + interior) % interior;
22
+ const wrapped_y = ((ty % interior) + interior) % interior;
23
+
24
+ // which fold the texel is past, as the WGSL counts it: i32 division truncates toward zero
25
+ const fold_x = Math.abs(Math.trunc(tx / interior)) + (tx < 0 ? 1 : 0);
26
+ const fold_y = Math.abs(Math.trunc(ty / interior)) + (ty < 0 ? 1 : 0);
27
+
28
+ if (((fold_x ^ fold_y) & 1) !== 0) {
29
+ out[0] = interior - wrapped_x;
30
+ out[1] = interior - wrapped_y;
31
+ } else {
32
+ out[0] = wrapped_x + 1;
33
+ out[1] = wrapped_y + 1;
34
+ }
35
+ }
@@ -13,9 +13,14 @@
13
13
  *
14
14
  * @param {Sampler2D[]} faces six faces in +X, -X, +Y, -Y, +Z, -Z order — what `buildCubeURLs`
15
15
  * emits and what `CubeTextureLoader` consumes
16
- * @param {number} output_resolution
16
+ * With `skirt`, the octahedral square is resampled into the interior `output_resolution - 2` texels and
17
+ * a one-texel octahedral skirt is written around it — the layout the renderer requires of an
18
+ * environment map (see `sampler2d_octahedral_skirt_fill`).
19
+ *
20
+ * @param {number} output_resolution side of the output, skirt included
21
+ * @param {boolean} [skirt]
17
22
  * @returns {Sampler2D} float32 RGBA, opaque
18
23
  */
19
- export function resample_cube_to_octahedral(faces: Sampler2D[], output_resolution: number): Sampler2D;
24
+ export function resample_cube_to_octahedral(faces: Sampler2D[], output_resolution: number, skirt?: boolean): Sampler2D;
20
25
  import { Sampler2D } from "../../../../engine/graphics/texture/sampler/Sampler2D.js";
21
26
  //# sourceMappingURL=resample_cube_to_octahedral.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"resample_cube_to_octahedral.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/light/environment/resample_cube_to_octahedral.js"],"names":[],"mappings":"AAuFA;;;;;;;;;;;;;;;;;GAiBG;AACH,mDALW,SAAS,EAAE,qBAEX,MAAM,GACJ,SAAS,CAqDrB;0BA3JyB,0DAA0D"}
1
+ {"version":3,"file":"resample_cube_to_octahedral.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/light/environment/resample_cube_to_octahedral.js"],"names":[],"mappings":"AAwFA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,mDAVW,SAAS,EAAE,qBAMX,MAAM,UACN,OAAO,GACL,SAAS,CA+DrB;0BA3KyB,0DAA0D"}
@@ -2,6 +2,7 @@ import { assert } from "../../../../core/assert.js";
2
2
  import { Sampler2D } from "../../../../engine/graphics/texture/sampler/Sampler2D.js";
3
3
  import { SAMPLE_OFFSETS, SAMPLE_WEIGHTS, SUPER_SAMPLE_COUNT } from "./octahedral_resample_kernel.js";
4
4
  import { octahedral_z_pole_uv_to_direction } from "./octahedral_z_pole_uv_to_direction.js";
5
+ import { sampler2d_octahedral_skirt_fill } from "./sampler2d_octahedral_skirt_fill.js";
5
6
 
6
7
  /**
7
8
  * Standard cube-map face selection — the GL/D3D/WebGPU table — for a direction already in cube
@@ -100,28 +101,39 @@ const SCRATCH_SAMPLE = new Float64Array(3);
100
101
  *
101
102
  * @param {Sampler2D[]} faces six faces in +X, -X, +Y, -Y, +Z, -Z order — what `buildCubeURLs`
102
103
  * emits and what `CubeTextureLoader` consumes
103
- * @param {number} output_resolution
104
+ * With `skirt`, the octahedral square is resampled into the interior `output_resolution - 2` texels and
105
+ * a one-texel octahedral skirt is written around it — the layout the renderer requires of an
106
+ * environment map (see `sampler2d_octahedral_skirt_fill`).
107
+ *
108
+ * @param {number} output_resolution side of the output, skirt included
109
+ * @param {boolean} [skirt]
104
110
  * @returns {Sampler2D} float32 RGBA, opaque
105
111
  */
106
- export function resample_cube_to_octahedral(faces, output_resolution) {
112
+ export function resample_cube_to_octahedral(faces, output_resolution, skirt = true) {
107
113
  assert.equal(faces.length, 6, 'faces.length');
108
114
  assert.isNonNegativeInteger(output_resolution, 'output_resolution');
115
+ assert.isBoolean(skirt, 'skirt');
116
+
117
+ const border = skirt ? 1 : 0;
118
+ const interior = output_resolution - 2 * border;
119
+
120
+ assert.greaterThan(interior, 0, 'interior resolution');
109
121
 
110
122
  const output = Sampler2D.float32(4, output_resolution, output_resolution);
111
123
 
112
124
  // the alpha channel is written once, here
113
125
  output.data.fill(1);
114
126
 
115
- for (let y = 0; y < output_resolution; y++) {
116
- for (let x = 0; x < output_resolution; x++) {
127
+ for (let y = 0; y < interior; y++) {
128
+ for (let x = 0; x < interior; x++) {
117
129
 
118
130
  SCRATCH_SAMPLE.fill(0);
119
131
 
120
132
  let weight_sum = 0;
121
133
 
122
134
  for (let s = 0; s < SUPER_SAMPLE_COUNT; s++) {
123
- const u = (x + SAMPLE_OFFSETS[s * 2] + 0.5) / output_resolution;
124
- const v = (y + SAMPLE_OFFSETS[s * 2 + 1] + 0.5) / output_resolution;
135
+ const u = (x + SAMPLE_OFFSETS[s * 2] + 0.5) / interior;
136
+ const v = (y + SAMPLE_OFFSETS[s * 2 + 1] + 0.5) / interior;
125
137
 
126
138
  // the direction the GPU will sample this texel for
127
139
  octahedral_z_pole_uv_to_direction(SCRATCH_DIRECTION, u, v);
@@ -148,10 +160,14 @@ export function resample_cube_to_octahedral(faces, output_resolution) {
148
160
  }
149
161
 
150
162
  for (let i = 0; i < 3; i++) {
151
- output.writeChannel(x, y, i, SCRATCH_SAMPLE[i] / weight_sum);
163
+ output.writeChannel(x + border, y + border, i, SCRATCH_SAMPLE[i] / weight_sum);
152
164
  }
153
165
  }
154
166
  }
155
167
 
168
+ if (skirt) {
169
+ sampler2d_octahedral_skirt_fill(output);
170
+ }
171
+
156
172
  return output;
157
173
  }
@@ -1,8 +1,14 @@
1
1
  /**
2
+ * With `skirt`, the octahedral square is resampled into the interior `output_resolution - 2` texels and
3
+ * a one-texel octahedral skirt is written around it — the layout the renderer requires of an
4
+ * environment map (see `sampler2d_octahedral_skirt_fill`). Without, the square fills the whole output,
5
+ * which is a map the renderer will refuse.
2
6
  *
3
7
  * @param {Sampler2D} input must be a float format
4
- * @param {number} output_resolution
8
+ * @param {number} output_resolution side of the output, skirt included
9
+ * @param {boolean} [skirt]
10
+ * @returns {Sampler2D} float32 RGBA
5
11
  */
6
- export function resample_equirectangular_to_octahedral(input: Sampler2D, output_resolution: number): Sampler2D;
12
+ export function resample_equirectangular_to_octahedral(input: Sampler2D, output_resolution: number, skirt?: boolean): Sampler2D;
7
13
  import { Sampler2D } from "../../../../engine/graphics/texture/sampler/Sampler2D.js";
8
14
  //# sourceMappingURL=resample_equirectangular_to_octahedral.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"resample_equirectangular_to_octahedral.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/light/environment/resample_equirectangular_to_octahedral.js"],"names":[],"mappings":"AAMA;;;;GAIG;AACH,8DAHW,SAAS,qBACT,MAAM,aAoEhB;0BA5EyB,0DAA0D"}
1
+ {"version":3,"file":"resample_equirectangular_to_octahedral.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/light/environment/resample_equirectangular_to_octahedral.js"],"names":[],"mappings":"AAOA;;;;;;;;;;GAUG;AACH,8DALW,SAAS,qBACT,MAAM,UACN,OAAO,GACL,SAAS,CA8ErB;0BA7FyB,0DAA0D"}