@woosh/meep-engine 3.14.0 → 3.14.2

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 (220) hide show
  1. package/README.md +33 -64
  2. package/package.json +1 -1
  3. package/src/avif/native/DECISIONS.md +544 -536
  4. package/src/avif/native/heif/parse_avif_file.d.ts.map +1 -1
  5. package/src/avif/native/heif/parse_avif_file.js +384 -383
  6. package/src/avif/native/heif/parse_image_grid.d.ts.map +1 -1
  7. package/src/avif/native/heif/parse_image_grid.js +49 -48
  8. package/src/basis/BasisBitReader.d.ts +77 -0
  9. package/src/basis/BasisBitReader.d.ts.map +1 -0
  10. package/src/basis/BasisBitReader.js +231 -0
  11. package/src/basis/BasisHuffmanTable.d.ts +53 -0
  12. package/src/basis/BasisHuffmanTable.d.ts.map +1 -0
  13. package/src/basis/BasisHuffmanTable.js +263 -0
  14. package/src/basis/basis_read_huffman_table.d.ts +20 -0
  15. package/src/basis/basis_read_huffman_table.d.ts.map +1 -0
  16. package/src/basis/basis_read_huffman_table.js +187 -0
  17. package/src/basis/etc1s/Etc1sSelectorHistory.d.ts +50 -0
  18. package/src/basis/etc1s/Etc1sSelectorHistory.d.ts.map +1 -0
  19. package/src/basis/etc1s/Etc1sSelectorHistory.js +89 -0
  20. package/src/basis/etc1s/etc1s_block_colors.d.ts +14 -0
  21. package/src/basis/etc1s/etc1s_block_colors.d.ts.map +1 -0
  22. package/src/basis/etc1s/etc1s_block_colors.js +75 -0
  23. package/src/basis/etc1s/etc1s_decode_slice.d.ts +57 -0
  24. package/src/basis/etc1s/etc1s_decode_slice.d.ts.map +1 -0
  25. package/src/basis/etc1s/etc1s_decode_slice.js +258 -0
  26. package/src/basis/etc1s/etc1s_read_endpoint_codebook.d.ts +48 -0
  27. package/src/basis/etc1s/etc1s_read_endpoint_codebook.d.ts.map +1 -0
  28. package/src/basis/etc1s/etc1s_read_endpoint_codebook.js +111 -0
  29. package/src/basis/etc1s/etc1s_read_selector_codebook.d.ts +42 -0
  30. package/src/basis/etc1s/etc1s_read_selector_codebook.d.ts.map +1 -0
  31. package/src/basis/etc1s/etc1s_read_selector_codebook.js +127 -0
  32. package/src/basis/etc1s/etc1s_read_slice_tables.d.ts +54 -0
  33. package/src/basis/etc1s/etc1s_read_slice_tables.d.ts.map +1 -0
  34. package/src/basis/etc1s/etc1s_read_slice_tables.js +47 -0
  35. package/src/basis/transcode/build_range_plan.js +54 -0
  36. package/src/basis/transcode/etc1s_to_bc1.d.ts +24 -0
  37. package/src/basis/transcode/etc1s_to_bc1.d.ts.map +1 -0
  38. package/src/basis/transcode/etc1s_to_bc1.js +205 -0
  39. package/src/basis/transcode/etc1s_to_bc7.d.ts +30 -0
  40. package/src/basis/transcode/etc1s_to_bc7.d.ts.map +1 -0
  41. package/src/basis/transcode/etc1s_to_bc7.js +496 -0
  42. package/src/basis/transcode/fit_endpoints.d.ts +59 -0
  43. package/src/basis/transcode/fit_endpoints.d.ts.map +1 -0
  44. package/src/basis/transcode/fit_endpoints.js +226 -0
  45. package/src/{avif/native/isobmff → core/binary}/ByteCursor.d.ts +19 -6
  46. package/src/core/binary/ByteCursor.d.ts.map +1 -0
  47. package/src/{avif/native/isobmff → core/binary}/ByteCursor.js +41 -14
  48. package/src/engine/EngineHarness.js +1 -1
  49. package/src/engine/asset/codec/Codec.d.ts.map +1 -0
  50. package/src/engine/asset/codec/CodecWithFallback.d.ts.map +1 -0
  51. package/src/engine/asset/{loaders/image/codec → codec}/CodecWithFallback.js +2 -2
  52. package/src/engine/asset/loaders/image/IMAGE_CODEC_REVIEW_2026_08_28.md +4 -4
  53. package/src/engine/asset/loaders/image/ImageRGBADataLoader.d.ts +1 -1
  54. package/src/engine/asset/loaders/image/ImageRGBADataLoader.d.ts.map +1 -1
  55. package/src/engine/asset/loaders/image/ImageRGBADataLoader.js +1 -1
  56. package/src/engine/asset/loaders/image/codec/NativeImageDecoder.d.ts +1 -1
  57. package/src/engine/asset/loaders/image/codec/NativeImageDecoder.d.ts.map +1 -1
  58. package/src/engine/asset/loaders/image/codec/NativeImageDecoder.js +1 -1
  59. package/src/engine/asset/loaders/image/codec/ThreadedImageDecoder.d.ts +1 -1
  60. package/src/engine/asset/loaders/image/codec/ThreadedImageDecoder.d.ts.map +1 -1
  61. package/src/engine/asset/loaders/image/codec/ThreadedImageDecoder.js +1 -1
  62. package/src/engine/graphics/texture/atlas/TextureAtlas.d.ts.map +1 -1
  63. package/src/engine/graphics/texture/atlas/TextureAtlas.js +13 -0
  64. package/src/engine/physics/broadphase/generate_pairs.d.ts.map +1 -1
  65. package/src/engine/physics/broadphase/generate_pairs.js +7 -1
  66. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  67. package/src/ktx2/KTX2_IDENTIFIER.d.ts +14 -0
  68. package/src/ktx2/KTX2_IDENTIFIER.d.ts.map +1 -0
  69. package/src/ktx2/KTX2_IDENTIFIER.js +15 -0
  70. package/src/ktx2/KhrDfModel.d.ts +35 -0
  71. package/src/ktx2/KhrDfModel.d.ts.map +1 -0
  72. package/src/ktx2/KhrDfModel.js +49 -0
  73. package/src/ktx2/SupercompressionScheme.d.ts +16 -0
  74. package/src/ktx2/SupercompressionScheme.d.ts.map +1 -0
  75. package/src/ktx2/SupercompressionScheme.js +23 -0
  76. package/src/ktx2/ktx2_read.d.ts +71 -0
  77. package/src/ktx2/ktx2_read.d.ts.map +1 -0
  78. package/src/ktx2/ktx2_read.js +581 -0
  79. package/src/ktx2/ktx2_read_basis_lz_global_data.d.ts +27 -0
  80. package/src/ktx2/ktx2_read_basis_lz_global_data.d.ts.map +1 -0
  81. package/src/ktx2/ktx2_read_basis_lz_global_data.js +189 -0
  82. package/src/ktx2/vk_format_to_texture_format.d.ts +55 -0
  83. package/src/ktx2/vk_format_to_texture_format.d.ts.map +1 -0
  84. package/src/ktx2/vk_format_to_texture_format.js +290 -0
  85. package/src/shade/descriptor/GPUTextureUsage.d.ts +23 -0
  86. package/src/shade/descriptor/GPUTextureUsage.d.ts.map +1 -0
  87. package/src/shade/descriptor/GPUTextureUsage.js +24 -0
  88. package/src/shade/descriptor/WebGPUExtensionType.d.ts +3 -0
  89. package/src/shade/descriptor/WebGPUExtensionType.js +26 -0
  90. package/src/shade/descriptor/texture/TextureDescriptor.d.ts +2 -6
  91. package/src/shade/descriptor/texture/TextureDescriptor.d.ts.map +1 -1
  92. package/src/shade/descriptor/texture/TextureDescriptor.js +24 -40
  93. package/src/shade/descriptor/texture/format/TextureFormat.d.ts +125 -0
  94. package/src/shade/descriptor/texture/format/TextureFormat.d.ts.map +1 -0
  95. package/src/shade/descriptor/texture/format/TextureFormat.js +146 -0
  96. package/src/shade/descriptor/texture/format/gpu_texture_format_info.d.ts +60 -0
  97. package/src/shade/descriptor/texture/format/gpu_texture_format_info.d.ts.map +1 -1
  98. package/src/shade/descriptor/texture/format/gpu_texture_format_info.js +102 -0
  99. package/src/shade/device/graph/TextureResourceDescriptor.d.ts.map +1 -1
  100. package/src/shade/device/graph/TextureResourceDescriptor.js +160 -155
  101. package/src/shade/device/mock/SoftwareGPUQueue.d.ts +11 -4
  102. package/src/shade/device/mock/SoftwareGPUQueue.d.ts.map +1 -1
  103. package/src/shade/device/mock/SoftwareGPUQueue.js +31 -37
  104. package/src/shade/device/mock/SoftwareGPUTexture.d.ts.map +1 -1
  105. package/src/shade/device/mock/SoftwareGPUTexture.js +8 -4
  106. package/src/shade/device/timing/profile/frame_graph_extract_topology.d.ts.map +1 -1
  107. package/src/shade/device/timing/profile/frame_graph_extract_topology.js +164 -174
  108. package/src/shade/playground/ground_seam/README.md +235 -0
  109. package/src/shade/playground/ground_seam/capture_scene_color.d.ts +45 -0
  110. package/src/shade/playground/ground_seam/capture_scene_color.d.ts.map +1 -0
  111. package/src/shade/playground/ground_seam/capture_scene_color.js +242 -0
  112. package/src/shade/playground/ground_seam/depth_step_across_seam.d.ts +11 -0
  113. package/src/shade/playground/ground_seam/depth_step_across_seam.d.ts.map +1 -0
  114. package/src/shade/playground/ground_seam/depth_step_across_seam.js +185 -0
  115. package/src/shade/playground/ground_seam/index.html +195 -0
  116. package/src/shade/playground/ground_seam/main.d.ts +2 -0
  117. package/src/shade/playground/ground_seam/main.d.ts.map +1 -0
  118. package/src/shade/playground/ground_seam/main.js +879 -0
  119. package/src/shade/playground/ground_seam/make_grid_texture.d.ts +29 -0
  120. package/src/shade/playground/ground_seam/make_grid_texture.d.ts.map +1 -0
  121. package/src/shade/playground/ground_seam/make_grid_texture.js +105 -0
  122. package/src/shade/playground/ground_seam/make_ground.d.ts +70 -0
  123. package/src/shade/playground/ground_seam/make_ground.d.ts.map +1 -0
  124. package/src/shade/playground/ground_seam/make_ground.js +161 -0
  125. package/src/shade/playground/ground_seam/measure_flicker.d.ts +71 -0
  126. package/src/shade/playground/ground_seam/measure_flicker.d.ts.map +1 -0
  127. package/src/shade/playground/ground_seam/measure_flicker.js +531 -0
  128. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  129. package/src/shade/renderer/Renderer.js +2519 -2511
  130. package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts.map +1 -1
  131. package/src/shade/renderer/hiz/HierarchicalZBuffer.js +275 -274
  132. package/src/shade/renderer/light/GPULightCollection.d.ts.map +1 -1
  133. package/src/shade/renderer/light/GPULightCollection.js +323 -314
  134. package/src/shade/renderer/lightmap/GPULightMap.js +336 -336
  135. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts.map +1 -1
  136. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.js +12 -2
  137. package/src/shade/renderer/material/standard/fragment_gbuffer.d.ts.map +1 -1
  138. package/src/shade/renderer/material/standard/fragment_gbuffer.js +3 -1
  139. package/src/shade/renderer/material/standard/fragment_gbuffer_vt.js +169 -169
  140. package/src/shade/renderer/path_tracer/shader/chunk_sample_material_data.d.ts.map +1 -1
  141. package/src/shade/renderer/path_tracer/shader/chunk_sample_material_data.js +3 -1
  142. package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
  143. package/src/shade/renderer/rasterize/native/oit/chunk_forward_shade_standard_fragment_brick4.d.ts.map +1 -1
  144. package/src/shade/renderer/rasterize/native/oit/chunk_forward_shade_standard_fragment_brick4.js +3 -1
  145. package/src/shade/renderer/rasterize/native/oit/chunk_forward_shade_standard_fragment_ibl.d.ts.map +1 -1
  146. package/src/shade/renderer/rasterize/native/oit/chunk_forward_shade_standard_fragment_ibl.js +3 -1
  147. package/src/shade/renderer/shader/chunk/geometry/normal/chunk_decode_tangent_normal.d.ts +28 -0
  148. package/src/shade/renderer/shader/chunk/geometry/normal/chunk_decode_tangent_normal.d.ts.map +1 -0
  149. package/src/shade/renderer/shader/chunk/geometry/normal/chunk_decode_tangent_normal.js +39 -0
  150. package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_barycentric_full.d.ts +45 -0
  151. package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_barycentric_full.d.ts.map +1 -1
  152. package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_barycentric_full.js +94 -61
  153. package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_barycentric_solve.d.ts +24 -0
  154. package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_barycentric_solve.d.ts.map +1 -0
  155. package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_barycentric_solve.js +43 -0
  156. package/src/shade/renderer/texture/COMPRESSED_TEXTURE_PLAN_2026_09_01.md +1462 -0
  157. package/src/shade/renderer/texture/TextureManager.d.ts.map +1 -1
  158. package/src/shade/renderer/texture/TextureManager.js +20 -8
  159. package/src/shade/renderer/texture/TextureRole.d.ts +19 -0
  160. package/src/shade/renderer/texture/TextureRole.d.ts.map +1 -0
  161. package/src/shade/renderer/texture/TextureRole.js +26 -0
  162. package/src/shade/renderer/texture/TextureVariantSet.d.ts +71 -0
  163. package/src/shade/renderer/texture/TextureVariantSet.d.ts.map +1 -0
  164. package/src/shade/renderer/texture/TextureVariantSet.js +105 -0
  165. package/src/shade/renderer/texture/download_texture_data.d.ts.map +1 -1
  166. package/src/shade/renderer/texture/download_texture_data.js +22 -0
  167. package/src/shade/renderer/texture/format/gpu_texture_compression_support.d.ts +15 -0
  168. package/src/shade/renderer/texture/format/gpu_texture_compression_support.d.ts.map +1 -0
  169. package/src/shade/renderer/texture/format/gpu_texture_compression_support.js +50 -0
  170. package/src/shade/renderer/texture/format/gpu_texture_format_can_generate_mipmaps.d.ts +27 -0
  171. package/src/shade/renderer/texture/format/gpu_texture_format_can_generate_mipmaps.d.ts.map +1 -0
  172. package/src/shade/renderer/texture/format/gpu_texture_format_can_generate_mipmaps.js +65 -0
  173. package/src/shade/renderer/texture/format/infer_format_from_parameters.d.ts +11 -0
  174. package/src/shade/renderer/texture/format/infer_format_from_parameters.d.ts.map +1 -0
  175. package/src/shade/renderer/texture/format/infer_format_from_parameters.js +88 -0
  176. package/src/shade/renderer/texture/format/texture_format_from_shade_image.d.ts +24 -0
  177. package/src/shade/renderer/texture/format/texture_format_from_shade_image.d.ts.map +1 -0
  178. package/src/shade/renderer/texture/format/texture_format_from_shade_image.js +71 -0
  179. package/src/shade/renderer/texture/format/texture_format_preference.d.ts +22 -0
  180. package/src/shade/renderer/texture/format/texture_format_preference.d.ts.map +1 -0
  181. package/src/shade/renderer/texture/format/texture_format_preference.js +89 -0
  182. package/src/shade/renderer/texture/format/texture_variant_select.d.ts +24 -0
  183. package/src/shade/renderer/texture/format/texture_variant_select.d.ts.map +1 -0
  184. package/src/shade/renderer/texture/format/texture_variant_select.js +38 -0
  185. package/src/shade/renderer/texture/shade_texture_might_have_alpha.d.ts +9 -1
  186. package/src/shade/renderer/texture/shade_texture_might_have_alpha.d.ts.map +1 -1
  187. package/src/shade/renderer/texture/shade_texture_might_have_alpha.js +73 -8
  188. package/src/shade/renderer/texture/source/AlphaMode.d.ts +27 -0
  189. package/src/shade/renderer/texture/source/AlphaMode.d.ts.map +1 -0
  190. package/src/shade/renderer/texture/source/AlphaMode.js +52 -0
  191. package/src/shade/renderer/texture/source/ShadeImage.d.ts +33 -0
  192. package/src/shade/renderer/texture/source/ShadeImage.d.ts.map +1 -1
  193. package/src/shade/renderer/texture/source/ShadeImage.js +74 -0
  194. package/src/shade/renderer/texture/source/ShadeTexelData.d.ts +78 -0
  195. package/src/shade/renderer/texture/source/ShadeTexelData.d.ts.map +1 -0
  196. package/src/shade/renderer/texture/source/ShadeTexelData.js +158 -0
  197. package/src/shade/renderer/texture/texture_descriptor_from_texture_shade.d.ts +0 -10
  198. package/src/shade/renderer/texture/texture_descriptor_from_texture_shade.d.ts.map +1 -1
  199. package/src/shade/renderer/texture/texture_descriptor_from_texture_shade.js +73 -175
  200. package/src/shade/renderer/texture/texture_write_level.d.ts +32 -0
  201. package/src/shade/renderer/texture/texture_write_level.d.ts.map +1 -0
  202. package/src/shade/renderer/texture/texture_write_level.js +77 -0
  203. package/src/shade/renderer/texture/texture_write_to_gpu.d.ts +8 -1
  204. package/src/shade/renderer/texture/texture_write_to_gpu.d.ts.map +1 -1
  205. package/src/shade/renderer/texture/texture_write_to_gpu.js +62 -37
  206. package/src/shade/renderer/texture/virtual/source/VTSourceImage.d.ts +8 -0
  207. package/src/shade/renderer/texture/virtual/source/VTSourceImage.d.ts.map +1 -1
  208. package/src/shade/renderer/texture/virtual/source/VTSourceImage.js +8 -0
  209. package/src/shade/util/texture_mip_extent.d.ts +49 -0
  210. package/src/shade/util/texture_mip_extent.d.ts.map +1 -0
  211. package/src/shade/util/texture_mip_extent.js +87 -0
  212. package/src/avif/native/isobmff/ByteCursor.d.ts.map +0 -1
  213. package/src/engine/asset/loaders/image/codec/Codec.d.ts.map +0 -1
  214. package/src/engine/asset/loaders/image/codec/CodecWithFallback.d.ts.map +0 -1
  215. package/src/shade/util/compute_max_mip_count.d.ts +0 -8
  216. package/src/shade/util/compute_max_mip_count.d.ts.map +0 -1
  217. package/src/shade/util/compute_max_mip_count.js +0 -27
  218. /package/src/engine/asset/{loaders/image/codec → codec}/Codec.d.ts +0 -0
  219. /package/src/engine/asset/{loaders/image/codec → codec}/Codec.js +0 -0
  220. /package/src/engine/asset/{loaders/image/codec → codec}/CodecWithFallback.d.ts +0 -0
@@ -4,7 +4,8 @@ import { to_half_float_uint16 } from "../../../core/binary/to_half_float_uint16.
4
4
  import { BinaryDataType } from "../../../core/binary/type/BinaryDataType.js";
5
5
  import { dataTypeByteSize } from "../../../core/binary/type/DataTypeByteSizes.js";
6
6
  import { array_copy } from "../../../core/collection/array/array_copy.js";
7
- import { ColorSpace } from "./ColorSpace.js";
7
+ import { AlphaMode } from "./source/AlphaMode.js";
8
+ import { texture_write_level } from "./texture_write_level.js";
8
9
  import { gpu_texture_format_channel_count } from "./format/gpu_texture_format_channel_count.js";
9
10
 
10
11
  /**
@@ -82,13 +83,22 @@ function premultiply_rgba_in_place(data, data_type) {
82
83
  }
83
84
 
84
85
  /**
86
+ * Bring loose pixels into the shape the texture's format expects, then hand them to
87
+ * {@link texture_write_level}.
88
+ *
89
+ * Padding and premultiplication happen *before* the write rather than inside it, which is what keeps
90
+ * the primitive a primitive: it takes texels that are already correct, and a payload that arrived
91
+ * correct (a {@link ShadeTexelData}) skips this function entirely rather than threading a "nothing
92
+ * to do" flag through it.
93
+ *
94
+ * A single-level path by construction — a `Sampler2D` or an `ArrayBuffer` is one level of pixels, and
95
+ * any others are generated.
85
96
  *
86
97
  * @param {ShadeImage} image
87
98
  * @param {ArrayBuffer} source_data
88
99
  * @param {GPUQueue} queue
89
100
  * @param {GPUTexture} texture
90
101
  * @param {boolean} premultiplyAlpha
91
- * @param copySize
92
102
  */
93
103
  function texture_write_raw(
94
104
  image,
@@ -101,10 +111,6 @@ function texture_write_raw(
101
111
  const source_channel_count = image.channel_count;
102
112
  const source_bytes_per_element = dataTypeByteSize(image.data_type);
103
113
 
104
- const bytes_per_pixel = source_channel_count * source_bytes_per_element;
105
-
106
- let bytesPerRow = bytes_per_pixel * image.width;
107
-
108
114
  let upload_data = source_data;
109
115
 
110
116
  if (source_channel_count === 3) {
@@ -143,9 +149,6 @@ function texture_write_raw(
143
149
  );
144
150
  }
145
151
 
146
- //
147
- bytesPerRow = source_bytes_per_element * image.width * 4;
148
-
149
152
  // alpha is 1 everywhere, premultiplication is the identity
150
153
 
151
154
  } else if (premultiplyAlpha && source_channel_count === 4) {
@@ -156,46 +159,41 @@ function texture_write_raw(
156
159
  premultiply_rgba_in_place(upload_data, image.data_type);
157
160
  }
158
161
 
159
- const dataLayout = {
160
- offset: 0,
161
- bytesPerRow: bytesPerRow
162
- };
163
-
164
- if(image.depth > 1){
165
- dataLayout.rowsPerImage = image.height;
166
- }
167
-
168
- queue.writeTexture(
169
- {
170
- texture: texture,
171
- mipLevel: 0,
172
- origin: {
173
- x: 0, y: 0, z: 0
174
- },
175
- },
176
- upload_data,
177
- dataLayout,
178
- [image.width, image.height, image.depth]
179
- )
180
-
162
+ /*
163
+ Row stride is no longer computed here. It comes from the texture's format, which is the only
164
+ thing that knows how wide a row of blocks is — and which, for the padded case above, correctly
165
+ reports the four channels the texture has rather than the three the image had.
166
+ */
167
+ texture_write_level(queue, texture, 0, upload_data);
181
168
  }
182
169
 
183
170
  /**
171
+ * Upload an image's texels into a texture.
172
+ *
173
+ * `level_count` says how many of the image's levels to write, from the base up, and is required
174
+ * rather than defaulted: the one caller that wants fewer than all of them — {@link TextureManager},
175
+ * about to run the mip generator — is the caller least able to have that decision made for it.
176
+ * Uploading levels the generator is about to overwrite is bytes across the bus for nothing.
184
177
  *
185
178
  * @param {ShadeImage} image
186
179
  * @param {GPUTexture} texture
187
180
  * @param {GPUQueue} queue
181
+ * @param {number} level_count how many levels to write; `image.level_count` for all of them
188
182
  */
189
183
  export function texture_write_to_gpu(
190
184
  image,
191
185
  texture,
192
- queue
186
+ queue,
187
+ level_count
193
188
  ) {
194
189
 
195
190
  assert.defined(image, 'image');
196
191
  assert.defined(texture, 'texture');
197
192
  assert.defined(queue, 'queue');
198
193
 
194
+ assert.isNonNegativeInteger(level_count, 'level_count');
195
+ assert.greaterThan(level_count, 0, 'level_count');
196
+
199
197
  assert.equal(image.isShadeImage, true, "image.isShadeImage !== true");
200
198
 
201
199
  const source = image.source;
@@ -210,11 +208,38 @@ export function texture_write_to_gpu(
210
208
  depthOrArrayLayers: texture.depthOrArrayLayers,
211
209
  };
212
210
 
213
- /**
214
- * see https://www.realtimerendering.com/blog/gpus-prefer-premultiplication/
215
- * @type {boolean}
216
- */
217
- const premultiplyAlpha = image.color_space !== ColorSpace.None;
211
+ /*
212
+ Asked of the image rather than re-derived here. `AlphaMode.Straight` is what `color_space !==
213
+ None` used to mean inline, so this is the same decision — but it is now one the image can be
214
+ told, which is how a payload that arrived already premultiplied (an encoder's output) says so.
215
+ */
216
+ const premultiplyAlpha = image.alpha_mode === AlphaMode.Straight;
217
+
218
+ if (source.isShadeTexelData === true) {
219
+ /*
220
+ Already in the texture's format, already laid out in rows of blocks. Nothing to pad, nothing
221
+ to premultiply — an encoder did both, or there was nothing to do — so the levels go straight
222
+ down.
223
+
224
+ A level may be absent: a streaming payload declares its whole chain up front and fills it in
225
+ coarsest-first, so "not here yet" is an ordinary state rather than a gap to complain about.
226
+ */
227
+ const levels = source.levels;
228
+
229
+ const upload_count = Math.min(level_count, levels.length);
230
+
231
+ for (let level = 0; level < upload_count; level++) {
232
+ const bytes = levels[level];
233
+
234
+ if (bytes === undefined) {
235
+ continue;
236
+ }
237
+
238
+ texture_write_level(queue, texture, level, bytes);
239
+ }
240
+
241
+ return;
242
+ }
218
243
 
219
244
  if (source.isSampler2D) {
220
245
 
@@ -13,6 +13,14 @@
13
13
  *
14
14
  * Layers are the standard group order: [albedo, normal, orm]. Pass
15
15
  * `undefined` for layers the material doesn't have — they're masked out.
16
+ *
17
+ * **Uncompressed sources only, structurally.** Page borders are resolved here at
18
+ * runtime by blitting from neighbouring content, and for block-compressed data
19
+ * that is impossible: the border and the page interior share blocks at the seam,
20
+ * and re-encoding a block at runtime is machinery the engine does not have. A
21
+ * compressed stack has to come from a source whose tiles were produced with their
22
+ * borders already inside them — {@link VTSourceTiled} — which is also what
23
+ * {@link VTPhysicalCache#upload} means by "border already baked in".
16
24
  */
17
25
  export class VTSourceImage {
18
26
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"VTSourceImage.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/texture/virtual/source/VTSourceImage.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;GAeG;AACH;IAyBI;;;;;;OAMG;IACH;QAJ+E,MAAM,EAA1E,CAAC,WAAW,GAAC,gBAAgB,GAAC,eAAe,GAAC,SAAS,CAAC,EAAE;QAExC,IAAI,GAAtB,OAAO;OAajB;IAzCD;;OAEG;IACH,YAFU,MAAM,CAED;IAwCf,6BA2CC;IAED;;;;;;;OAOG;IACH,eANW,MAAM,KACN,MAAM,KACN,MAAM,UACN,WAAW,GACT,QAAQ,CAAC,WAAW,GAAC,SAAS,CAAC,EAAE,CAAC,CAuF9C;IAED,gBAEC;;CACJ"}
1
+ {"version":3,"file":"VTSourceImage.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/texture/virtual/source/VTSourceImage.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH;IAyBI;;;;;;OAMG;IACH;QAJ+E,MAAM,EAA1E,CAAC,WAAW,GAAC,gBAAgB,GAAC,eAAe,GAAC,SAAS,CAAC,EAAE;QAExC,IAAI,GAAtB,OAAO;OAajB;IAzCD;;OAEG;IACH,YAFU,MAAM,CAED;IAwCf,6BA2CC;IAED;;;;;;;OAOG;IACH,eANW,MAAM,KACN,MAAM,KACN,MAAM,UACN,WAAW,GACT,QAAQ,CAAC,WAAW,GAAC,SAAS,CAAC,EAAE,CAAC,CAuF9C;IAED,gBAEC;;CACJ"}
@@ -15,6 +15,14 @@ import { assert } from "../../../../../core/assert.js";
15
15
  *
16
16
  * Layers are the standard group order: [albedo, normal, orm]. Pass
17
17
  * `undefined` for layers the material doesn't have — they're masked out.
18
+ *
19
+ * **Uncompressed sources only, structurally.** Page borders are resolved here at
20
+ * runtime by blitting from neighbouring content, and for block-compressed data
21
+ * that is impossible: the border and the page interior share blocks at the seam,
22
+ * and re-encoding a block at runtime is machinery the engine does not have. A
23
+ * compressed stack has to come from a source whose tiles were produced with their
24
+ * borders already inside them — {@link VTSourceTiled} — which is also what
25
+ * {@link VTPhysicalCache#upload} means by "border already baked in".
18
26
  */
19
27
  export class VTSourceImage {
20
28
 
@@ -0,0 +1,49 @@
1
+ /**
2
+ * One dimension of a texture at `level`.
3
+ *
4
+ * Halving, floored at 1 — a 1024-wide texture is still 1 texel wide at level 10 and at level 20.
5
+ * Trivial, and re-derived in enough places that getting it wrong is a real event rather than a
6
+ * hypothetical one.
7
+ *
8
+ * @param {number} size texels, at the base level
9
+ * @param {number} level
10
+ * @returns {number} texels, at `level`
11
+ */
12
+ export function texture_mip_size(size: number, level: number): number;
13
+ /**
14
+ * The extent of a texture at `level`.
15
+ *
16
+ * **Only a 3D texture's depth halves.** The third component of an array texture is a layer count,
17
+ * and every layer carries every mip — so it does not shrink with the others. That single distinction
18
+ * is the reason this exists as a named thing: written out by hand it reads as an obvious `>> level`
19
+ * on all three components, and that mistake under-reported a six-layer cube map's memory by close to
20
+ * half and would have uploaded its levels at the wrong extent.
21
+ *
22
+ * @param {number} width texels, at the base level
23
+ * @param {number} height texels, at the base level
24
+ * @param {number} depth_or_layers depth for a 3D texture, layer count otherwise
25
+ * @param {GPUTextureDimension|string} dimension
26
+ * @param {number} level
27
+ * @returns {number[]} `[width, height, depthOrArrayLayers]` at `level`, in the shape
28
+ * `GPUExtent3D` takes
29
+ */
30
+ export function texture_mip_extent(width: number, height: number, depth_or_layers: number, dimension: GPUTextureDimension | string, level: number): number[];
31
+ /**
32
+ * The number of levels in a texture's full mip chain.
33
+ *
34
+ * The count that {@link texture_mip_extent} implies: the chain runs until every halving axis has
35
+ * reached 1, so it is as long as the longest axis that halves. **Only a 3D texture's depth halves**
36
+ * — the same distinction, one derivative up. Written as `max(width, height)` it silently truncates
37
+ * every volume deeper than it is wide: a 4x4x16 has five levels and that reading gives three, while
38
+ * `texture_mip_extent` will happily report the extent of all five.
39
+ *
40
+ * A zero-sized texture has no levels. Any other size has at least one, which is what the `+ 1` is.
41
+ *
42
+ * @param {number} width texels, at the base level
43
+ * @param {number} height texels, at the base level
44
+ * @param {number} depth_or_layers depth for a 3D texture, layer count otherwise
45
+ * @param {GPUTextureDimension|string} dimension
46
+ * @returns {number}
47
+ */
48
+ export function texture_mip_level_count(width: number, height: number, depth_or_layers: number, dimension: GPUTextureDimension | string): number;
49
+ //# sourceMappingURL=texture_mip_extent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"texture_mip_extent.d.ts","sourceRoot":"","sources":["../../../../src/shade/util/texture_mip_extent.js"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AACH,uCAJW,MAAM,SACN,MAAM,GACJ,MAAM,CAIlB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,0CARW,MAAM,UACN,MAAM,mBACN,MAAM,aACN,sBAAoB,MAAM,SAC1B,MAAM,GACJ,MAAM,EAAE,CAYpB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,+CANW,MAAM,UACN,MAAM,mBACN,MAAM,aACN,sBAAoB,MAAM,GACxB,MAAM,CA0BlB"}
@@ -0,0 +1,87 @@
1
+ import { assert } from "../../core/assert.js";
2
+
3
+ /**
4
+ * One dimension of a texture at `level`.
5
+ *
6
+ * Halving, floored at 1 — a 1024-wide texture is still 1 texel wide at level 10 and at level 20.
7
+ * Trivial, and re-derived in enough places that getting it wrong is a real event rather than a
8
+ * hypothetical one.
9
+ *
10
+ * @param {number} size texels, at the base level
11
+ * @param {number} level
12
+ * @returns {number} texels, at `level`
13
+ */
14
+ export function texture_mip_size(size, level) {
15
+ return Math.max(size >> level, 1);
16
+ }
17
+
18
+ /**
19
+ * The extent of a texture at `level`.
20
+ *
21
+ * **Only a 3D texture's depth halves.** The third component of an array texture is a layer count,
22
+ * and every layer carries every mip — so it does not shrink with the others. That single distinction
23
+ * is the reason this exists as a named thing: written out by hand it reads as an obvious `>> level`
24
+ * on all three components, and that mistake under-reported a six-layer cube map's memory by close to
25
+ * half and would have uploaded its levels at the wrong extent.
26
+ *
27
+ * @param {number} width texels, at the base level
28
+ * @param {number} height texels, at the base level
29
+ * @param {number} depth_or_layers depth for a 3D texture, layer count otherwise
30
+ * @param {GPUTextureDimension|string} dimension
31
+ * @param {number} level
32
+ * @returns {number[]} `[width, height, depthOrArrayLayers]` at `level`, in the shape
33
+ * `GPUExtent3D` takes
34
+ */
35
+ export function texture_mip_extent(width, height, depth_or_layers, dimension, level) {
36
+ assert.isString(dimension, 'dimension');
37
+ assert.isNonNegativeInteger(level, 'level');
38
+
39
+ return [
40
+ texture_mip_size(width, level),
41
+ texture_mip_size(height, level),
42
+ dimension === "3d" ? texture_mip_size(depth_or_layers, level) : depth_or_layers,
43
+ ];
44
+ }
45
+
46
+ /**
47
+ * The number of levels in a texture's full mip chain.
48
+ *
49
+ * The count that {@link texture_mip_extent} implies: the chain runs until every halving axis has
50
+ * reached 1, so it is as long as the longest axis that halves. **Only a 3D texture's depth halves**
51
+ * — the same distinction, one derivative up. Written as `max(width, height)` it silently truncates
52
+ * every volume deeper than it is wide: a 4x4x16 has five levels and that reading gives three, while
53
+ * `texture_mip_extent` will happily report the extent of all five.
54
+ *
55
+ * A zero-sized texture has no levels. Any other size has at least one, which is what the `+ 1` is.
56
+ *
57
+ * @param {number} width texels, at the base level
58
+ * @param {number} height texels, at the base level
59
+ * @param {number} depth_or_layers depth for a 3D texture, layer count otherwise
60
+ * @param {GPUTextureDimension|string} dimension
61
+ * @returns {number}
62
+ */
63
+ export function texture_mip_level_count(width, height, depth_or_layers, dimension) {
64
+ assert.isString(dimension, 'dimension');
65
+
66
+ assert.isNumber(width, 'width');
67
+ assert.isNumber(height, 'height');
68
+ assert.isNumber(depth_or_layers, 'depth_or_layers');
69
+
70
+ assert.notNaN(width, 'width');
71
+ assert.notNaN(height, 'height');
72
+ assert.notNaN(depth_or_layers, 'depth_or_layers');
73
+
74
+ assert.greaterThanOrEqual(width, 0, 'width');
75
+ assert.greaterThanOrEqual(height, 0, 'height');
76
+ assert.greaterThanOrEqual(depth_or_layers, 0, 'depth_or_layers');
77
+
78
+ const longest = dimension === "3d"
79
+ ? Math.max(width, height, depth_or_layers)
80
+ : Math.max(width, height);
81
+
82
+ if (longest === 0) {
83
+ return 0;
84
+ }
85
+
86
+ return Math.floor(Math.log2(longest)) + 1;
87
+ }
@@ -1 +0,0 @@
1
- {"version":3,"file":"ByteCursor.d.ts","sourceRoot":"","sources":["../../../../../src/avif/native/isobmff/ByteCursor.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;GAcG;AACH;IACI;;OAEG;IACH,MAFU,QAAQ,CAEN;IAEZ;;OAEG;IACH,OAFU,UAAU,CAEP;IAEb;;;OAGG;IACH,UAFU,MAAM,CAEH;IAEb;;;OAGG;IACH,KAFU,MAAM,CAER;IAER;;;;;OAKG;IACH,aALW,WAAW,GAAC,UAAU,gBACtB,MAAM,gBACN,MAAM,GACJ,UAAU,CAmBtB;IAED;;;;;OAKG;IACH,wBAJW,MAAM,eACN,MAAM,GACJ,UAAU,CAetB;IAED;;OAEG;IACH,wBAEC;IAED;;;OAGG;IACH,eAHW,MAAM,QACN,MAAM,QAMhB;IAED;;OAEG;IACH,MAFa,MAAM,CAMlB;IAED;;OAEG;IACH,OAFa,MAAM,CAUlB;IAED;;OAEG;IACH,OAFa,MAAM,CAWlB;IAED;;OAEG;IACH,OAFa,MAAM,CAUlB;IAED;;OAEG;IACH,OAFa,MAAM,CAUlB;IAED;;OAEG;IACH,OAFa,MAAM,CAUlB;IAED;;;;;;;OAOG;IACH,OAFa,MAAM,CAelB;IAED;;;;;;OAMG;IACH,mBAHW,MAAM,GACJ,MAAM,CAoBlB;IAED;;;OAGG;IACH,UAFa,MAAM,CAUlB;IAED;;;;OAIG;IACH,eAFa,MAAM,CAgBlB;IAED;;;;OAIG;IACH,mBAHW,MAAM,GACJ,UAAU,CAUtB;IAED;;OAEG;IACH,YAFW,MAAM,QAMhB;IAED;;OAEG;IACH,eAFW,MAAM,QAQhB;CACJ"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"Codec.d.ts","sourceRoot":"","sources":["../../../../../../../src/engine/asset/loaders/image/codec/Codec.js"],"names":[],"mappings":"AAAA;;;;GAIG;AACH;IACI;;;;OAIG;IACH,aAHW,UAAU,GACR,QAAQ,CAAC,CAAC,CAKtB;IAED;;;;OAIG;IACH,WAHW,UAAU,GACT,QAAQ,OAAO,CAAC,CAI3B;CACJ"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"CodecWithFallback.d.ts","sourceRoot":"","sources":["../../../../../../../src/engine/asset/loaders/image/codec/CodecWithFallback.js"],"names":[],"mappings":"AAIA;;;;;GAKG;AACH;IAOI;;;OAGG;IACH,uBAFW,MAAM,CAAC,CAAC,EAclB;IAtBD;;;OAGG;IACH,UAFU,MAAM,CAAC,CAAC,EAAE,CAEP;IAgCb,kCAeC;IAED,8BAuCC;;CACJ;sBAtGqB,YAAY"}
@@ -1,8 +0,0 @@
1
- /**
2
- * Maximum mip count for given texture dimensions
3
- * @param {number} width
4
- * @param {number} height
5
- * @returns {number}
6
- */
7
- export function compute_max_mip_count(width: number, height: number): number;
8
- //# sourceMappingURL=compute_max_mip_count.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"compute_max_mip_count.d.ts","sourceRoot":"","sources":["../../../../src/shade/util/compute_max_mip_count.js"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,6CAJW,MAAM,UACN,MAAM,GACJ,MAAM,CAoBlB"}
@@ -1,27 +0,0 @@
1
- import { assert } from "../../core/assert.js";
2
-
3
- /**
4
- * Maximum mip count for given texture dimensions
5
- * @param {number} width
6
- * @param {number} height
7
- * @returns {number}
8
- */
9
- export function compute_max_mip_count(width, height) {
10
- assert.isNumber(width, 'width');
11
- assert.isNumber(height, 'height');
12
-
13
- assert.notNaN(width, "width");
14
- assert.notNaN(height, "height");
15
-
16
- assert.greaterThanOrEqual(width, 0);
17
- assert.greaterThanOrEqual(height, 0);
18
-
19
- // the +1 is to indicate that there's always at least 1 level
20
- const max_size = Math.max(width, height);
21
-
22
- if (max_size === 0) {
23
- return 0;
24
- }
25
-
26
- return Math.floor(Math.log2(max_size)) + 1;
27
- }