@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.
- package/README.md +33 -64
- package/package.json +1 -1
- package/src/avif/native/DECISIONS.md +544 -536
- package/src/avif/native/heif/parse_avif_file.d.ts.map +1 -1
- package/src/avif/native/heif/parse_avif_file.js +384 -383
- package/src/avif/native/heif/parse_image_grid.d.ts.map +1 -1
- package/src/avif/native/heif/parse_image_grid.js +49 -48
- package/src/basis/BasisBitReader.d.ts +77 -0
- package/src/basis/BasisBitReader.d.ts.map +1 -0
- package/src/basis/BasisBitReader.js +231 -0
- package/src/basis/BasisHuffmanTable.d.ts +53 -0
- package/src/basis/BasisHuffmanTable.d.ts.map +1 -0
- package/src/basis/BasisHuffmanTable.js +263 -0
- package/src/basis/basis_read_huffman_table.d.ts +20 -0
- package/src/basis/basis_read_huffman_table.d.ts.map +1 -0
- package/src/basis/basis_read_huffman_table.js +187 -0
- package/src/basis/etc1s/Etc1sSelectorHistory.d.ts +50 -0
- package/src/basis/etc1s/Etc1sSelectorHistory.d.ts.map +1 -0
- package/src/basis/etc1s/Etc1sSelectorHistory.js +89 -0
- package/src/basis/etc1s/etc1s_block_colors.d.ts +14 -0
- package/src/basis/etc1s/etc1s_block_colors.d.ts.map +1 -0
- package/src/basis/etc1s/etc1s_block_colors.js +75 -0
- package/src/basis/etc1s/etc1s_decode_slice.d.ts +57 -0
- package/src/basis/etc1s/etc1s_decode_slice.d.ts.map +1 -0
- package/src/basis/etc1s/etc1s_decode_slice.js +258 -0
- package/src/basis/etc1s/etc1s_read_endpoint_codebook.d.ts +48 -0
- package/src/basis/etc1s/etc1s_read_endpoint_codebook.d.ts.map +1 -0
- package/src/basis/etc1s/etc1s_read_endpoint_codebook.js +111 -0
- package/src/basis/etc1s/etc1s_read_selector_codebook.d.ts +42 -0
- package/src/basis/etc1s/etc1s_read_selector_codebook.d.ts.map +1 -0
- package/src/basis/etc1s/etc1s_read_selector_codebook.js +127 -0
- package/src/basis/etc1s/etc1s_read_slice_tables.d.ts +54 -0
- package/src/basis/etc1s/etc1s_read_slice_tables.d.ts.map +1 -0
- package/src/basis/etc1s/etc1s_read_slice_tables.js +47 -0
- package/src/basis/transcode/build_range_plan.js +54 -0
- package/src/basis/transcode/etc1s_to_bc1.d.ts +24 -0
- package/src/basis/transcode/etc1s_to_bc1.d.ts.map +1 -0
- package/src/basis/transcode/etc1s_to_bc1.js +205 -0
- package/src/basis/transcode/etc1s_to_bc7.d.ts +30 -0
- package/src/basis/transcode/etc1s_to_bc7.d.ts.map +1 -0
- package/src/basis/transcode/etc1s_to_bc7.js +496 -0
- package/src/basis/transcode/fit_endpoints.d.ts +59 -0
- package/src/basis/transcode/fit_endpoints.d.ts.map +1 -0
- package/src/basis/transcode/fit_endpoints.js +226 -0
- package/src/{avif/native/isobmff → core/binary}/ByteCursor.d.ts +19 -6
- package/src/core/binary/ByteCursor.d.ts.map +1 -0
- package/src/{avif/native/isobmff → core/binary}/ByteCursor.js +41 -14
- package/src/engine/EngineHarness.js +1 -1
- package/src/engine/asset/codec/Codec.d.ts.map +1 -0
- package/src/engine/asset/codec/CodecWithFallback.d.ts.map +1 -0
- package/src/engine/asset/{loaders/image/codec → codec}/CodecWithFallback.js +2 -2
- package/src/engine/asset/loaders/image/IMAGE_CODEC_REVIEW_2026_08_28.md +4 -4
- package/src/engine/asset/loaders/image/ImageRGBADataLoader.d.ts +1 -1
- package/src/engine/asset/loaders/image/ImageRGBADataLoader.d.ts.map +1 -1
- package/src/engine/asset/loaders/image/ImageRGBADataLoader.js +1 -1
- package/src/engine/asset/loaders/image/codec/NativeImageDecoder.d.ts +1 -1
- package/src/engine/asset/loaders/image/codec/NativeImageDecoder.d.ts.map +1 -1
- package/src/engine/asset/loaders/image/codec/NativeImageDecoder.js +1 -1
- package/src/engine/asset/loaders/image/codec/ThreadedImageDecoder.d.ts +1 -1
- package/src/engine/asset/loaders/image/codec/ThreadedImageDecoder.d.ts.map +1 -1
- package/src/engine/asset/loaders/image/codec/ThreadedImageDecoder.js +1 -1
- package/src/engine/graphics/texture/atlas/TextureAtlas.d.ts.map +1 -1
- package/src/engine/graphics/texture/atlas/TextureAtlas.js +13 -0
- package/src/engine/physics/broadphase/generate_pairs.d.ts.map +1 -1
- package/src/engine/physics/broadphase/generate_pairs.js +7 -1
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
- package/src/ktx2/KTX2_IDENTIFIER.d.ts +14 -0
- package/src/ktx2/KTX2_IDENTIFIER.d.ts.map +1 -0
- package/src/ktx2/KTX2_IDENTIFIER.js +15 -0
- package/src/ktx2/KhrDfModel.d.ts +35 -0
- package/src/ktx2/KhrDfModel.d.ts.map +1 -0
- package/src/ktx2/KhrDfModel.js +49 -0
- package/src/ktx2/SupercompressionScheme.d.ts +16 -0
- package/src/ktx2/SupercompressionScheme.d.ts.map +1 -0
- package/src/ktx2/SupercompressionScheme.js +23 -0
- package/src/ktx2/ktx2_read.d.ts +71 -0
- package/src/ktx2/ktx2_read.d.ts.map +1 -0
- package/src/ktx2/ktx2_read.js +581 -0
- package/src/ktx2/ktx2_read_basis_lz_global_data.d.ts +27 -0
- package/src/ktx2/ktx2_read_basis_lz_global_data.d.ts.map +1 -0
- package/src/ktx2/ktx2_read_basis_lz_global_data.js +189 -0
- package/src/ktx2/vk_format_to_texture_format.d.ts +55 -0
- package/src/ktx2/vk_format_to_texture_format.d.ts.map +1 -0
- package/src/ktx2/vk_format_to_texture_format.js +290 -0
- package/src/shade/descriptor/GPUTextureUsage.d.ts +23 -0
- package/src/shade/descriptor/GPUTextureUsage.d.ts.map +1 -0
- package/src/shade/descriptor/GPUTextureUsage.js +24 -0
- package/src/shade/descriptor/WebGPUExtensionType.d.ts +3 -0
- package/src/shade/descriptor/WebGPUExtensionType.js +26 -0
- package/src/shade/descriptor/texture/TextureDescriptor.d.ts +2 -6
- package/src/shade/descriptor/texture/TextureDescriptor.d.ts.map +1 -1
- package/src/shade/descriptor/texture/TextureDescriptor.js +24 -40
- package/src/shade/descriptor/texture/format/TextureFormat.d.ts +125 -0
- package/src/shade/descriptor/texture/format/TextureFormat.d.ts.map +1 -0
- package/src/shade/descriptor/texture/format/TextureFormat.js +146 -0
- package/src/shade/descriptor/texture/format/gpu_texture_format_info.d.ts +60 -0
- package/src/shade/descriptor/texture/format/gpu_texture_format_info.d.ts.map +1 -1
- package/src/shade/descriptor/texture/format/gpu_texture_format_info.js +102 -0
- package/src/shade/device/graph/TextureResourceDescriptor.d.ts.map +1 -1
- package/src/shade/device/graph/TextureResourceDescriptor.js +160 -155
- package/src/shade/device/mock/SoftwareGPUQueue.d.ts +11 -4
- package/src/shade/device/mock/SoftwareGPUQueue.d.ts.map +1 -1
- package/src/shade/device/mock/SoftwareGPUQueue.js +31 -37
- package/src/shade/device/mock/SoftwareGPUTexture.d.ts.map +1 -1
- package/src/shade/device/mock/SoftwareGPUTexture.js +8 -4
- package/src/shade/device/timing/profile/frame_graph_extract_topology.d.ts.map +1 -1
- package/src/shade/device/timing/profile/frame_graph_extract_topology.js +164 -174
- package/src/shade/playground/ground_seam/README.md +235 -0
- package/src/shade/playground/ground_seam/capture_scene_color.d.ts +45 -0
- package/src/shade/playground/ground_seam/capture_scene_color.d.ts.map +1 -0
- package/src/shade/playground/ground_seam/capture_scene_color.js +242 -0
- package/src/shade/playground/ground_seam/depth_step_across_seam.d.ts +11 -0
- package/src/shade/playground/ground_seam/depth_step_across_seam.d.ts.map +1 -0
- package/src/shade/playground/ground_seam/depth_step_across_seam.js +185 -0
- package/src/shade/playground/ground_seam/index.html +195 -0
- package/src/shade/playground/ground_seam/main.d.ts +2 -0
- package/src/shade/playground/ground_seam/main.d.ts.map +1 -0
- package/src/shade/playground/ground_seam/main.js +879 -0
- package/src/shade/playground/ground_seam/make_grid_texture.d.ts +29 -0
- package/src/shade/playground/ground_seam/make_grid_texture.d.ts.map +1 -0
- package/src/shade/playground/ground_seam/make_grid_texture.js +105 -0
- package/src/shade/playground/ground_seam/make_ground.d.ts +70 -0
- package/src/shade/playground/ground_seam/make_ground.d.ts.map +1 -0
- package/src/shade/playground/ground_seam/make_ground.js +161 -0
- package/src/shade/playground/ground_seam/measure_flicker.d.ts +71 -0
- package/src/shade/playground/ground_seam/measure_flicker.d.ts.map +1 -0
- package/src/shade/playground/ground_seam/measure_flicker.js +531 -0
- package/src/shade/renderer/Renderer.d.ts.map +1 -1
- package/src/shade/renderer/Renderer.js +2519 -2511
- package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts.map +1 -1
- package/src/shade/renderer/hiz/HierarchicalZBuffer.js +275 -274
- package/src/shade/renderer/light/GPULightCollection.d.ts.map +1 -1
- package/src/shade/renderer/light/GPULightCollection.js +323 -314
- package/src/shade/renderer/lightmap/GPULightMap.js +336 -336
- package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts.map +1 -1
- package/src/shade/renderer/material/resident/GPUResidentMaterialContext.js +12 -2
- package/src/shade/renderer/material/standard/fragment_gbuffer.d.ts.map +1 -1
- package/src/shade/renderer/material/standard/fragment_gbuffer.js +3 -1
- package/src/shade/renderer/material/standard/fragment_gbuffer_vt.js +169 -169
- package/src/shade/renderer/path_tracer/shader/chunk_sample_material_data.d.ts.map +1 -1
- package/src/shade/renderer/path_tracer/shader/chunk_sample_material_data.js +3 -1
- package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
- package/src/shade/renderer/rasterize/native/oit/chunk_forward_shade_standard_fragment_brick4.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/native/oit/chunk_forward_shade_standard_fragment_brick4.js +3 -1
- package/src/shade/renderer/rasterize/native/oit/chunk_forward_shade_standard_fragment_ibl.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/native/oit/chunk_forward_shade_standard_fragment_ibl.js +3 -1
- package/src/shade/renderer/shader/chunk/geometry/normal/chunk_decode_tangent_normal.d.ts +28 -0
- package/src/shade/renderer/shader/chunk/geometry/normal/chunk_decode_tangent_normal.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/geometry/normal/chunk_decode_tangent_normal.js +39 -0
- package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_barycentric_full.d.ts +45 -0
- package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_barycentric_full.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_barycentric_full.js +94 -61
- package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_barycentric_solve.d.ts +24 -0
- package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_barycentric_solve.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_barycentric_solve.js +43 -0
- package/src/shade/renderer/texture/COMPRESSED_TEXTURE_PLAN_2026_09_01.md +1462 -0
- package/src/shade/renderer/texture/TextureManager.d.ts.map +1 -1
- package/src/shade/renderer/texture/TextureManager.js +20 -8
- package/src/shade/renderer/texture/TextureRole.d.ts +19 -0
- package/src/shade/renderer/texture/TextureRole.d.ts.map +1 -0
- package/src/shade/renderer/texture/TextureRole.js +26 -0
- package/src/shade/renderer/texture/TextureVariantSet.d.ts +71 -0
- package/src/shade/renderer/texture/TextureVariantSet.d.ts.map +1 -0
- package/src/shade/renderer/texture/TextureVariantSet.js +105 -0
- package/src/shade/renderer/texture/download_texture_data.d.ts.map +1 -1
- package/src/shade/renderer/texture/download_texture_data.js +22 -0
- package/src/shade/renderer/texture/format/gpu_texture_compression_support.d.ts +15 -0
- package/src/shade/renderer/texture/format/gpu_texture_compression_support.d.ts.map +1 -0
- package/src/shade/renderer/texture/format/gpu_texture_compression_support.js +50 -0
- package/src/shade/renderer/texture/format/gpu_texture_format_can_generate_mipmaps.d.ts +27 -0
- package/src/shade/renderer/texture/format/gpu_texture_format_can_generate_mipmaps.d.ts.map +1 -0
- package/src/shade/renderer/texture/format/gpu_texture_format_can_generate_mipmaps.js +65 -0
- package/src/shade/renderer/texture/format/infer_format_from_parameters.d.ts +11 -0
- package/src/shade/renderer/texture/format/infer_format_from_parameters.d.ts.map +1 -0
- package/src/shade/renderer/texture/format/infer_format_from_parameters.js +88 -0
- package/src/shade/renderer/texture/format/texture_format_from_shade_image.d.ts +24 -0
- package/src/shade/renderer/texture/format/texture_format_from_shade_image.d.ts.map +1 -0
- package/src/shade/renderer/texture/format/texture_format_from_shade_image.js +71 -0
- package/src/shade/renderer/texture/format/texture_format_preference.d.ts +22 -0
- package/src/shade/renderer/texture/format/texture_format_preference.d.ts.map +1 -0
- package/src/shade/renderer/texture/format/texture_format_preference.js +89 -0
- package/src/shade/renderer/texture/format/texture_variant_select.d.ts +24 -0
- package/src/shade/renderer/texture/format/texture_variant_select.d.ts.map +1 -0
- package/src/shade/renderer/texture/format/texture_variant_select.js +38 -0
- package/src/shade/renderer/texture/shade_texture_might_have_alpha.d.ts +9 -1
- package/src/shade/renderer/texture/shade_texture_might_have_alpha.d.ts.map +1 -1
- package/src/shade/renderer/texture/shade_texture_might_have_alpha.js +73 -8
- package/src/shade/renderer/texture/source/AlphaMode.d.ts +27 -0
- package/src/shade/renderer/texture/source/AlphaMode.d.ts.map +1 -0
- package/src/shade/renderer/texture/source/AlphaMode.js +52 -0
- package/src/shade/renderer/texture/source/ShadeImage.d.ts +33 -0
- package/src/shade/renderer/texture/source/ShadeImage.d.ts.map +1 -1
- package/src/shade/renderer/texture/source/ShadeImage.js +74 -0
- package/src/shade/renderer/texture/source/ShadeTexelData.d.ts +78 -0
- package/src/shade/renderer/texture/source/ShadeTexelData.d.ts.map +1 -0
- package/src/shade/renderer/texture/source/ShadeTexelData.js +158 -0
- package/src/shade/renderer/texture/texture_descriptor_from_texture_shade.d.ts +0 -10
- package/src/shade/renderer/texture/texture_descriptor_from_texture_shade.d.ts.map +1 -1
- package/src/shade/renderer/texture/texture_descriptor_from_texture_shade.js +73 -175
- package/src/shade/renderer/texture/texture_write_level.d.ts +32 -0
- package/src/shade/renderer/texture/texture_write_level.d.ts.map +1 -0
- package/src/shade/renderer/texture/texture_write_level.js +77 -0
- package/src/shade/renderer/texture/texture_write_to_gpu.d.ts +8 -1
- package/src/shade/renderer/texture/texture_write_to_gpu.d.ts.map +1 -1
- package/src/shade/renderer/texture/texture_write_to_gpu.js +62 -37
- package/src/shade/renderer/texture/virtual/source/VTSourceImage.d.ts +8 -0
- package/src/shade/renderer/texture/virtual/source/VTSourceImage.d.ts.map +1 -1
- package/src/shade/renderer/texture/virtual/source/VTSourceImage.js +8 -0
- package/src/shade/util/texture_mip_extent.d.ts +49 -0
- package/src/shade/util/texture_mip_extent.d.ts.map +1 -0
- package/src/shade/util/texture_mip_extent.js +87 -0
- package/src/avif/native/isobmff/ByteCursor.d.ts.map +0 -1
- package/src/engine/asset/loaders/image/codec/Codec.d.ts.map +0 -1
- package/src/engine/asset/loaders/image/codec/CodecWithFallback.d.ts.map +0 -1
- package/src/shade/util/compute_max_mip_count.d.ts +0 -8
- package/src/shade/util/compute_max_mip_count.d.ts.map +0 -1
- package/src/shade/util/compute_max_mip_count.js +0 -27
- /package/src/engine/asset/{loaders/image/codec → codec}/Codec.d.ts +0 -0
- /package/src/engine/asset/{loaders/image/codec → codec}/Codec.js +0 -0
- /package/src/engine/asset/{loaders/image/codec → codec}/CodecWithFallback.d.ts +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TextureManager.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/texture/TextureManager.js"],"names":[],"mappings":"AA2CA;IAiCI;;;OAGG;IACH,+BAIC;IAtBD;;;OAGG;IACH,qCAEC;IAkBD;;;;OAIG;IACH,6BAFa,iBAAiB,CAY7B;IAED;;;;OAIG;IACH,8CAFa,iBAAiB,
|
|
1
|
+
{"version":3,"file":"TextureManager.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/texture/TextureManager.js"],"names":[],"mappings":"AA2CA;IAiCI;;;OAGG;IACH,+BAIC;IAtBD;;;OAGG;IACH,qCAEC;IAkBD;;;;OAIG;IACH,6BAFa,iBAAiB,CAY7B;IAED;;;;OAIG;IACH,8CAFa,iBAAiB,CAwC7B;IAeD;;;;OAIG;IACH,kCAHW,iBAAiB,GACf,iBAAiB,CAa7B;IAED,eAEC;IAED,+BAQC;;CACJ;sCA5LqC,oCAAoC;kCADxC,wBAAwB;kCADxB,+CAA+C"}
|
|
@@ -121,10 +121,22 @@ export class TextureManager {
|
|
|
121
121
|
|
|
122
122
|
const ctx = this.contextFromDescriptor(descriptor);
|
|
123
123
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
124
|
+
/*
|
|
125
|
+
The flag is an instruction, and the descriptor builder has already refused it for any
|
|
126
|
+
format the generator cannot render into — so reaching here with it set means it is
|
|
127
|
+
going to happen. Only the base level is uploaded in that case: the generator produces
|
|
128
|
+
every level above it, and sending levels it is about to overwrite is bytes across the
|
|
129
|
+
bus for nothing.
|
|
130
|
+
*/
|
|
131
|
+
const generate = (shade.flags & ShadeTextureFlags.GenerateMipMaps) !== 0;
|
|
132
|
+
|
|
133
|
+
this.#image_to_texture(
|
|
134
|
+
shade.image,
|
|
135
|
+
ctx.gpu_texture,
|
|
136
|
+
generate ? 1 : shade.image.level_count
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
if (generate) {
|
|
128
140
|
this.#mipmaps.schedule(ctx.gpu_texture, descriptor, shade.mipmapGenerationFilter);
|
|
129
141
|
}
|
|
130
142
|
|
|
@@ -138,13 +150,13 @@ export class TextureManager {
|
|
|
138
150
|
*
|
|
139
151
|
* @param {ShadeImage} image
|
|
140
152
|
* @param {GPUTexture} texture
|
|
153
|
+
* @param {number} level_count how many of the image's levels to upload
|
|
141
154
|
*/
|
|
142
|
-
#image_to_texture(image, texture) {
|
|
143
|
-
|
|
144
|
-
|
|
155
|
+
#image_to_texture(image, texture, level_count) {
|
|
145
156
|
const device = this.#device;
|
|
146
157
|
const queue = device.queue;
|
|
147
|
-
|
|
158
|
+
|
|
159
|
+
texture_write_to_gpu(image, texture, queue, level_count);
|
|
148
160
|
}
|
|
149
161
|
|
|
150
162
|
/**
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a texture is *for*, as far as choosing an encoding for it goes.
|
|
3
|
+
*
|
|
4
|
+
* The renderer knows things about its material slots that no general image pipeline does: that a
|
|
5
|
+
* normal map's channels are a direction and band visibly under a codec tuned for colour, that an ORM
|
|
6
|
+
* map is linear data whose channels are independent, that albedo is the one people look at. Those
|
|
7
|
+
* facts pick a format, so they have to be sayable.
|
|
8
|
+
*
|
|
9
|
+
* The same distinction {@link image_compression_quality_from_usage } already draws for the AVIF
|
|
10
|
+
* encoder, named once instead of twice.
|
|
11
|
+
*/
|
|
12
|
+
export type TextureRole = number;
|
|
13
|
+
export namespace TextureRole {
|
|
14
|
+
let Albedo: number;
|
|
15
|
+
let Normal: number;
|
|
16
|
+
let Orm: number;
|
|
17
|
+
let Emissive: number;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=TextureRole.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TextureRole.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/texture/TextureRole.js"],"names":[],"mappings":";;;;;;;;;;;0BAWU,MAAM"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a texture is *for*, as far as choosing an encoding for it goes.
|
|
3
|
+
*
|
|
4
|
+
* The renderer knows things about its material slots that no general image pipeline does: that a
|
|
5
|
+
* normal map's channels are a direction and band visibly under a codec tuned for colour, that an ORM
|
|
6
|
+
* map is linear data whose channels are independent, that albedo is the one people look at. Those
|
|
7
|
+
* facts pick a format, so they have to be sayable.
|
|
8
|
+
*
|
|
9
|
+
* The same distinction {@link image_compression_quality_from_usage} already draws for the AVIF
|
|
10
|
+
* encoder, named once instead of twice.
|
|
11
|
+
*
|
|
12
|
+
* @enum {number}
|
|
13
|
+
*/
|
|
14
|
+
export const TextureRole = {
|
|
15
|
+
/** Base colour. sRGB, alpha may carry cutout or transparency. */
|
|
16
|
+
Albedo: 0,
|
|
17
|
+
|
|
18
|
+
/** Tangent-space normals. Linear, and the channels are a direction rather than a colour. */
|
|
19
|
+
Normal: 1,
|
|
20
|
+
|
|
21
|
+
/** Occlusion / roughness / metalness, packed per channel. Linear, channels independent. */
|
|
22
|
+
Orm: 2,
|
|
23
|
+
|
|
24
|
+
/** Emitted colour. sRGB, like albedo. */
|
|
25
|
+
Emissive: 3,
|
|
26
|
+
};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What was built for one texture, and where each encoding lives.
|
|
3
|
+
*
|
|
4
|
+
* A texture is not one resource with variants inside it — it is several resources, one per format,
|
|
5
|
+
* and a client fetches the one it wants. This is the manifest that makes that possible: **which
|
|
6
|
+
* encodings exist, known before the first request.** Discovering them by requesting would cost a 404
|
|
7
|
+
* round trip per format a device prefers and nobody built, walking down the preference list, which on
|
|
8
|
+
* a streaming engine is the worst place to put a stall.
|
|
9
|
+
*
|
|
10
|
+
* The {@link fallback} is not a contingency bolted on; it is the entry with no format constraint, and
|
|
11
|
+
* it is what a device with no compression support, a tool, or a test asks for. Every set has one, so
|
|
12
|
+
* selection always has an answer.
|
|
13
|
+
*
|
|
14
|
+
* Deliberately dumb about *content*: it says a format was built and where the bytes are, and nothing
|
|
15
|
+
* about what they decode to. The reader determines that from the payload's own header, which is why
|
|
16
|
+
* a manifest that lies produces a failed read rather than a texture full of garbage.
|
|
17
|
+
*/
|
|
18
|
+
export class TextureVariantSet {
|
|
19
|
+
/**
|
|
20
|
+
* Read one entry of a manifest.
|
|
21
|
+
*
|
|
22
|
+
* ```json
|
|
23
|
+
* {
|
|
24
|
+
* "fallback": "textures/wall_albedo.avif",
|
|
25
|
+
* "formats": {
|
|
26
|
+
* "bc7-rgba-unorm": "textures/wall_albedo.bc7.ktx2",
|
|
27
|
+
* "astc-4x4-unorm": "textures/wall_albedo.astc.ktx2"
|
|
28
|
+
* }
|
|
29
|
+
* }
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* Format names are the WebGPU strings, and the non-srgb ones: `bc7-rgba-unorm` and
|
|
33
|
+
* `bc7-rgba-unorm-srgb` are the same bytes, so srgb-ness is not a property of the encoding to be
|
|
34
|
+
* listed here — it is chosen when the texture is created, from the image's colour space.
|
|
35
|
+
*
|
|
36
|
+
* @param {{fallback: string, formats?: Object<GPUTextureFormat, string>}} json
|
|
37
|
+
* @returns {TextureVariantSet}
|
|
38
|
+
*/
|
|
39
|
+
static fromJSON(json: {
|
|
40
|
+
fallback: string;
|
|
41
|
+
formats?: any;
|
|
42
|
+
}): TextureVariantSet;
|
|
43
|
+
/**
|
|
44
|
+
* @param {string} fallback path of the universally readable encoding
|
|
45
|
+
* @param {Iterable<[GPUTextureFormat, string]>} by_format one entry per format that was built
|
|
46
|
+
*/
|
|
47
|
+
constructor(fallback: string, by_format: Iterable<[GPUTextureFormat, string]>);
|
|
48
|
+
/**
|
|
49
|
+
* Path of the encoding every device can read — AVIF, PNG, whatever ships.
|
|
50
|
+
*
|
|
51
|
+
* @type {string}
|
|
52
|
+
* @readonly
|
|
53
|
+
*/
|
|
54
|
+
readonly fallback: string;
|
|
55
|
+
/**
|
|
56
|
+
* @param {GPUTextureFormat} format
|
|
57
|
+
* @returns {boolean} whether this encoding was built
|
|
58
|
+
*/
|
|
59
|
+
has(format: GPUTextureFormat): boolean;
|
|
60
|
+
/**
|
|
61
|
+
* @param {GPUTextureFormat} format
|
|
62
|
+
* @returns {string|undefined} where it lives, or nothing when it was not built
|
|
63
|
+
*/
|
|
64
|
+
path(format: GPUTextureFormat): string | undefined;
|
|
65
|
+
/**
|
|
66
|
+
* @returns {GPUTextureFormat[]} every format built for this texture, fallback excluded
|
|
67
|
+
*/
|
|
68
|
+
get formats(): GPUTextureFormat[];
|
|
69
|
+
#private;
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=TextureVariantSet.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TextureVariantSet.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/texture/TextureVariantSet.js"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;GAgBG;AACH;IA0DI;;;;;;;;;;;;;;;;;;;OAmBG;IACH,sBAHW;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,MAAkC;KAAC,GAC5D,iBAAiB,CAO7B;IArED;;;OAGG;IACH,sBAHW,MAAM,aACN,SAAS,mBAAmB,MAAM,CAAC,CAAC,EAiB9C;IAhCD;;;;;OAKG;IACH,mBAHU,MAAM,CAGP;IA4BT;;;OAGG;IACH,+BAFa,OAAO,CAInB;IAED;;;OAGG;IACH,gCAFa,MAAM,GAAC,SAAS,CAI5B;IAED;;OAEG;IACH,kCAEC;;CA4BJ"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { assert } from "../../../core/assert.js";
|
|
2
|
+
import { gpu_texture_format_info } from "../../descriptor/texture/format/gpu_texture_format_info.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* What was built for one texture, and where each encoding lives.
|
|
6
|
+
*
|
|
7
|
+
* A texture is not one resource with variants inside it — it is several resources, one per format,
|
|
8
|
+
* and a client fetches the one it wants. This is the manifest that makes that possible: **which
|
|
9
|
+
* encodings exist, known before the first request.** Discovering them by requesting would cost a 404
|
|
10
|
+
* round trip per format a device prefers and nobody built, walking down the preference list, which on
|
|
11
|
+
* a streaming engine is the worst place to put a stall.
|
|
12
|
+
*
|
|
13
|
+
* The {@link fallback} is not a contingency bolted on; it is the entry with no format constraint, and
|
|
14
|
+
* it is what a device with no compression support, a tool, or a test asks for. Every set has one, so
|
|
15
|
+
* selection always has an answer.
|
|
16
|
+
*
|
|
17
|
+
* Deliberately dumb about *content*: it says a format was built and where the bytes are, and nothing
|
|
18
|
+
* about what they decode to. The reader determines that from the payload's own header, which is why
|
|
19
|
+
* a manifest that lies produces a failed read rather than a texture full of garbage.
|
|
20
|
+
*/
|
|
21
|
+
export class TextureVariantSet {
|
|
22
|
+
/**
|
|
23
|
+
* Path of the encoding every device can read — AVIF, PNG, whatever ships.
|
|
24
|
+
*
|
|
25
|
+
* @type {string}
|
|
26
|
+
* @readonly
|
|
27
|
+
*/
|
|
28
|
+
fallback;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @type {Map<GPUTextureFormat, string>}
|
|
32
|
+
*/
|
|
33
|
+
#by_format = new Map();
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* @param {string} fallback path of the universally readable encoding
|
|
37
|
+
* @param {Iterable<[GPUTextureFormat, string]>} by_format one entry per format that was built
|
|
38
|
+
*/
|
|
39
|
+
constructor(fallback, by_format) {
|
|
40
|
+
assert.isString(fallback, 'fallback');
|
|
41
|
+
assert.defined(by_format, 'by_format');
|
|
42
|
+
|
|
43
|
+
for (const [format, path] of by_format) {
|
|
44
|
+
// throws for a name that is not a GPUTextureFormat — a manifest naming one is a build
|
|
45
|
+
// artefact nobody can ask for, and finding that out here beats finding it out at a fetch
|
|
46
|
+
gpu_texture_format_info(format);
|
|
47
|
+
|
|
48
|
+
assert.isString(path, `path for '${format}'`);
|
|
49
|
+
|
|
50
|
+
this.#by_format.set(format, path);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
this.fallback = fallback;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* @param {GPUTextureFormat} format
|
|
58
|
+
* @returns {boolean} whether this encoding was built
|
|
59
|
+
*/
|
|
60
|
+
has(format) {
|
|
61
|
+
return this.#by_format.has(format);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* @param {GPUTextureFormat} format
|
|
66
|
+
* @returns {string|undefined} where it lives, or nothing when it was not built
|
|
67
|
+
*/
|
|
68
|
+
path(format) {
|
|
69
|
+
return this.#by_format.get(format);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* @returns {GPUTextureFormat[]} every format built for this texture, fallback excluded
|
|
74
|
+
*/
|
|
75
|
+
get formats() {
|
|
76
|
+
return Array.from(this.#by_format.keys());
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Read one entry of a manifest.
|
|
81
|
+
*
|
|
82
|
+
* ```json
|
|
83
|
+
* {
|
|
84
|
+
* "fallback": "textures/wall_albedo.avif",
|
|
85
|
+
* "formats": {
|
|
86
|
+
* "bc7-rgba-unorm": "textures/wall_albedo.bc7.ktx2",
|
|
87
|
+
* "astc-4x4-unorm": "textures/wall_albedo.astc.ktx2"
|
|
88
|
+
* }
|
|
89
|
+
* }
|
|
90
|
+
* ```
|
|
91
|
+
*
|
|
92
|
+
* Format names are the WebGPU strings, and the non-srgb ones: `bc7-rgba-unorm` and
|
|
93
|
+
* `bc7-rgba-unorm-srgb` are the same bytes, so srgb-ness is not a property of the encoding to be
|
|
94
|
+
* listed here — it is chosen when the texture is created, from the image's colour space.
|
|
95
|
+
*
|
|
96
|
+
* @param {{fallback: string, formats?: Object<GPUTextureFormat, string>}} json
|
|
97
|
+
* @returns {TextureVariantSet}
|
|
98
|
+
*/
|
|
99
|
+
static fromJSON(json) {
|
|
100
|
+
assert.defined(json, 'json');
|
|
101
|
+
assert.isString(json.fallback, 'json.fallback');
|
|
102
|
+
|
|
103
|
+
return new TextureVariantSet(json.fallback, Object.entries(json.formats ?? {}));
|
|
104
|
+
}
|
|
105
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"download_texture_data.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/texture/download_texture_data.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"download_texture_data.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/texture/download_texture_data.js"],"names":[],"mappings":"AASA;;;;;;;;;GASG;AACH,kGAFa,mBAAmB,CAwI/B"}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { assert } from "../../../core/assert.js";
|
|
2
2
|
import { round_up } from "../../../core/math/round_up.js";
|
|
3
3
|
import { decode_typed_gpu_data } from "./format/decode_typed_gpu_data.js";
|
|
4
|
+
import {
|
|
5
|
+
gpu_texture_format_info,
|
|
6
|
+
gpu_texture_format_is_block_compressed
|
|
7
|
+
} from "../../descriptor/texture/format/gpu_texture_format_info.js";
|
|
4
8
|
import { parse_gpu_texture_format } from "../../descriptor/texture/format/parse_gpu_texture_format.js";
|
|
5
9
|
|
|
6
10
|
/**
|
|
@@ -61,6 +65,24 @@ export async function download_texture_data({
|
|
|
61
65
|
label: "Download Texture Data"
|
|
62
66
|
});
|
|
63
67
|
|
|
68
|
+
/*
|
|
69
|
+
Readback decodes texels into typed array elements, which a block-compressed format has none of —
|
|
70
|
+
`parse_gpu_texture_format`'s expression cannot parse one of their names and would fail with a
|
|
71
|
+
regex error naming nothing. Say what is actually wrong instead.
|
|
72
|
+
|
|
73
|
+
Not an oversight to fix later: there is no useful decoded form of a BC7 block on the CPU short of
|
|
74
|
+
a decoder, and a caller that wants the bytes wants `copyTextureToBuffer` rather than this.
|
|
75
|
+
*/
|
|
76
|
+
const format_info = gpu_texture_format_info(source.format);
|
|
77
|
+
|
|
78
|
+
if (gpu_texture_format_is_block_compressed(source.format)) {
|
|
79
|
+
throw new Error(
|
|
80
|
+
`download_texture_data: '${source.format}' is block-compressed`
|
|
81
|
+
+ ` (${format_info.block_width}x${format_info.block_height}), which has no per-texel`
|
|
82
|
+
+ ` value to read back. Copy the raw blocks with copyTextureToBuffer instead.`
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
|
|
64
86
|
// figure out data type
|
|
65
87
|
const spec = parse_gpu_texture_format(source.format);
|
|
66
88
|
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Every compressed {@link GPUTextureFormat} this device can sample.
|
|
3
|
+
*
|
|
4
|
+
* WebGPU gates compression behind three optional features, all of them all-or-nothing within their
|
|
5
|
+
* family. This turns "which features did we get" into "which formats may we ask the network for",
|
|
6
|
+
* which is the question the asset layer actually has (§5).
|
|
7
|
+
*
|
|
8
|
+
* Empty is an ordinary answer, not a failure: a device with no compression support loads every scene
|
|
9
|
+
* through the uncompressed encoding, exactly as one did before any of this existed.
|
|
10
|
+
*
|
|
11
|
+
* @param {GPUDevice} device
|
|
12
|
+
* @returns {Set<GPUTextureFormat>}
|
|
13
|
+
*/
|
|
14
|
+
export function gpu_texture_compression_support(device: GPUDevice): Set<GPUTextureFormat>;
|
|
15
|
+
//# sourceMappingURL=gpu_texture_compression_support.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gpu_texture_compression_support.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/texture/format/gpu_texture_compression_support.js"],"names":[],"mappings":"AAkBA;;;;;;;;;;;;GAYG;AACH,oEAFa,qBAAqB,CAoBjC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { WebGPUExtensionType } from "../../../descriptor/WebGPUExtensionType.js";
|
|
2
|
+
import { gpu_texture_format_names } from "../../../descriptor/texture/format/gpu_texture_format_info.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Which compressed formats a feature name brings with it.
|
|
6
|
+
*
|
|
7
|
+
* Derived from the format table's own names rather than listed, because the three families partition
|
|
8
|
+
* it cleanly by prefix and a hand-written list is one more thing to forget a format from.
|
|
9
|
+
*
|
|
10
|
+
* @type {[GPUFeatureName, RegExp][]}
|
|
11
|
+
*/
|
|
12
|
+
const FAMILIES = [
|
|
13
|
+
[WebGPUExtensionType.TextureCompressionBC, /^bc[0-9]/],
|
|
14
|
+
// ETC2 and EAC arrive together, under one feature
|
|
15
|
+
[WebGPUExtensionType.TextureCompressionETC2, /^(etc2|eac)-/],
|
|
16
|
+
[WebGPUExtensionType.TextureCompressionASTC, /^astc-/],
|
|
17
|
+
];
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Every compressed {@link GPUTextureFormat} this device can sample.
|
|
21
|
+
*
|
|
22
|
+
* WebGPU gates compression behind three optional features, all of them all-or-nothing within their
|
|
23
|
+
* family. This turns "which features did we get" into "which formats may we ask the network for",
|
|
24
|
+
* which is the question the asset layer actually has (§5).
|
|
25
|
+
*
|
|
26
|
+
* Empty is an ordinary answer, not a failure: a device with no compression support loads every scene
|
|
27
|
+
* through the uncompressed encoding, exactly as one did before any of this existed.
|
|
28
|
+
*
|
|
29
|
+
* @param {GPUDevice} device
|
|
30
|
+
* @returns {Set<GPUTextureFormat>}
|
|
31
|
+
*/
|
|
32
|
+
export function gpu_texture_compression_support(device) {
|
|
33
|
+
const features = device.features;
|
|
34
|
+
|
|
35
|
+
const supported = new Set();
|
|
36
|
+
|
|
37
|
+
for (const [feature, pattern] of FAMILIES) {
|
|
38
|
+
if (!features.has(feature)) {
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
for (const format of gpu_texture_format_names()) {
|
|
43
|
+
if (pattern.test(format)) {
|
|
44
|
+
supported.add(format);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return supported;
|
|
50
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether {@link WebGPUMipmapGenerator} can produce this format's mip levels.
|
|
3
|
+
*
|
|
4
|
+
* It generates by *rendering* between mip levels, so the question is whether the format can be a
|
|
5
|
+
* colour attachment. Three classes cannot:
|
|
6
|
+
*
|
|
7
|
+
* 1. **Block-compressed.** BC, ETC2 and ASTC are neither render attachments nor storage bindings,
|
|
8
|
+
* and nothing on the device turns a BC7 base level into BC7 mips. Their mips come from whatever
|
|
9
|
+
* encoded them, and that is the case this predicate exists for.
|
|
10
|
+
* 2. **Depth and stencil.** Renderable, but not as *colour*, which is what the generator's pipeline
|
|
11
|
+
* writes.
|
|
12
|
+
* 3. **`snorm`, and `rgb9e5ufloat`.** Sampleable colour formats that WebGPU does not allow as
|
|
13
|
+
* attachments — a gap that predates compressed textures and would otherwise surface as a
|
|
14
|
+
* pipeline-creation failure deep inside the generator.
|
|
15
|
+
*
|
|
16
|
+
* **Not a general renderability table.** Anything outside those three classes answers `true`, which
|
|
17
|
+
* is right for every format the engine currently produces and is not a promise about exotic ones —
|
|
18
|
+
* `rg11b10ufloat` is renderable only with a feature enabled, and this does not check for it. The
|
|
19
|
+
* value of answering here rather than in `createRenderPipeline` is a message that names the texture
|
|
20
|
+
* and says what to do instead.
|
|
21
|
+
*
|
|
22
|
+
* @param {GPUTextureFormat} format
|
|
23
|
+
* @returns {boolean}
|
|
24
|
+
* @throws {Error} for a name that is not a GPUTextureFormat
|
|
25
|
+
*/
|
|
26
|
+
export function gpu_texture_format_can_generate_mipmaps(format: GPUTextureFormat): boolean;
|
|
27
|
+
//# sourceMappingURL=gpu_texture_format_can_generate_mipmaps.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gpu_texture_format_can_generate_mipmaps.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/texture/format/gpu_texture_format_can_generate_mipmaps.js"],"names":[],"mappings":"AAyBA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,mFAHa,OAAO,CAiBnB"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import {
|
|
2
|
+
gpu_texture_format_info,
|
|
3
|
+
gpu_texture_format_is_block_compressed
|
|
4
|
+
} from "../../../descriptor/texture/format/gpu_texture_format_info.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Formats that are colour formats and still cannot be a render attachment.
|
|
8
|
+
*
|
|
9
|
+
* Every `snorm` format, plus the shared-exponent packed one. Listed rather than matched on the name
|
|
10
|
+
* for the reason {@link gpu_texture_format_info} gives about its own table — though here the name
|
|
11
|
+
* would in fact carry it, a name-shaped rule invites the next entry to be added by pattern instead of
|
|
12
|
+
* by specification.
|
|
13
|
+
*
|
|
14
|
+
* @type {Set<GPUTextureFormat>}
|
|
15
|
+
*/
|
|
16
|
+
const NOT_RENDERABLE = new Set([
|
|
17
|
+
"r8snorm",
|
|
18
|
+
"rg8snorm",
|
|
19
|
+
"rgba8snorm",
|
|
20
|
+
"r16snorm",
|
|
21
|
+
"rg16snorm",
|
|
22
|
+
"rgba16snorm",
|
|
23
|
+
"rgb9e5ufloat",
|
|
24
|
+
]);
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Whether {@link WebGPUMipmapGenerator} can produce this format's mip levels.
|
|
28
|
+
*
|
|
29
|
+
* It generates by *rendering* between mip levels, so the question is whether the format can be a
|
|
30
|
+
* colour attachment. Three classes cannot:
|
|
31
|
+
*
|
|
32
|
+
* 1. **Block-compressed.** BC, ETC2 and ASTC are neither render attachments nor storage bindings,
|
|
33
|
+
* and nothing on the device turns a BC7 base level into BC7 mips. Their mips come from whatever
|
|
34
|
+
* encoded them, and that is the case this predicate exists for.
|
|
35
|
+
* 2. **Depth and stencil.** Renderable, but not as *colour*, which is what the generator's pipeline
|
|
36
|
+
* writes.
|
|
37
|
+
* 3. **`snorm`, and `rgb9e5ufloat`.** Sampleable colour formats that WebGPU does not allow as
|
|
38
|
+
* attachments — a gap that predates compressed textures and would otherwise surface as a
|
|
39
|
+
* pipeline-creation failure deep inside the generator.
|
|
40
|
+
*
|
|
41
|
+
* **Not a general renderability table.** Anything outside those three classes answers `true`, which
|
|
42
|
+
* is right for every format the engine currently produces and is not a promise about exotic ones —
|
|
43
|
+
* `rg11b10ufloat` is renderable only with a feature enabled, and this does not check for it. The
|
|
44
|
+
* value of answering here rather than in `createRenderPipeline` is a message that names the texture
|
|
45
|
+
* and says what to do instead.
|
|
46
|
+
*
|
|
47
|
+
* @param {GPUTextureFormat} format
|
|
48
|
+
* @returns {boolean}
|
|
49
|
+
* @throws {Error} for a name that is not a GPUTextureFormat
|
|
50
|
+
*/
|
|
51
|
+
export function gpu_texture_format_can_generate_mipmaps(format) {
|
|
52
|
+
const info = gpu_texture_format_info(format);
|
|
53
|
+
|
|
54
|
+
if (gpu_texture_format_is_block_compressed(format)) {
|
|
55
|
+
// block-compressed: no attachment, no storage, no way to write a mip on the device
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (info.aspects.length !== 1 || info.aspects[0] !== "all") {
|
|
60
|
+
// depth and/or stencil — not a colour attachment
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return !NOT_RENDERABLE.has(format);
|
|
65
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param {number} channel_count
|
|
3
|
+
* @param {BinaryDataType} data_type
|
|
4
|
+
* @param {boolean} normalized
|
|
5
|
+
* @param {ColorSpace} color_space
|
|
6
|
+
* @returns {GPUTextureFormat}
|
|
7
|
+
*/
|
|
8
|
+
export function infer_format_from_parameters(channel_count: number, data_type: BinaryDataType, normalized: boolean, color_space: ColorSpace): GPUTextureFormat;
|
|
9
|
+
import { BinaryDataType } from "../../../../core/binary/type/BinaryDataType.js";
|
|
10
|
+
import { ColorSpace } from "../ColorSpace.js";
|
|
11
|
+
//# sourceMappingURL=infer_format_from_parameters.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"infer_format_from_parameters.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/texture/format/infer_format_from_parameters.js"],"names":[],"mappings":"AAIA;;;;;;GAMG;AACH,4DANW,MAAM,aACN,cAAc,cACd,OAAO,eACP,UAAU,oBA6EpB;+BArF8B,gDAAgD;2BAEpD,kBAAkB"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { BinaryDataType } from "../../../../core/binary/type/BinaryDataType.js";
|
|
2
|
+
import { dataTypeByteSize } from "../../../../core/binary/type/DataTypeByteSizes.js";
|
|
3
|
+
import { ColorSpace } from "../ColorSpace.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @param {number} channel_count
|
|
7
|
+
* @param {BinaryDataType} data_type
|
|
8
|
+
* @param {boolean} normalized
|
|
9
|
+
* @param {ColorSpace} color_space
|
|
10
|
+
* @returns {GPUTextureFormat}
|
|
11
|
+
*/
|
|
12
|
+
export function infer_format_from_parameters(
|
|
13
|
+
channel_count,
|
|
14
|
+
data_type,
|
|
15
|
+
normalized,
|
|
16
|
+
color_space
|
|
17
|
+
) {
|
|
18
|
+
|
|
19
|
+
// Some channel counts are unsupported, specifically RGB, so we have to go up 1 to RGBA
|
|
20
|
+
const valid_channel_counts = [1, 2, 4];
|
|
21
|
+
|
|
22
|
+
let valid_channel_count = channel_count;
|
|
23
|
+
|
|
24
|
+
if (valid_channel_counts.includes(channel_count) === false) {
|
|
25
|
+
for (let i = 0; i < valid_channel_counts.length; i++) {
|
|
26
|
+
let vs = valid_channel_counts[i];
|
|
27
|
+
|
|
28
|
+
if (channel_count < vs) {
|
|
29
|
+
valid_channel_count = vs;
|
|
30
|
+
break;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const prefix = 'rgba'.slice(0, valid_channel_count);
|
|
36
|
+
|
|
37
|
+
const byte_size = dataTypeByteSize(data_type);
|
|
38
|
+
|
|
39
|
+
const bit_size = byte_size * 8;
|
|
40
|
+
|
|
41
|
+
let ending;
|
|
42
|
+
if (color_space === ColorSpace.LinearSRGB) {
|
|
43
|
+
if (data_type === BinaryDataType.Uint8) {
|
|
44
|
+
ending = "unorm";
|
|
45
|
+
} else if (data_type === BinaryDataType.Float32) {
|
|
46
|
+
ending = "float";
|
|
47
|
+
} else if (data_type === BinaryDataType.Float16 || data_type === BinaryDataType.Uint16) {
|
|
48
|
+
// Half-float HDR data (e.g. octahedral environment maps). parse_rgbe stores f16 bit
|
|
49
|
+
// patterns in a Uint16Array, so the same half-float payload can be classified as either
|
|
50
|
+
// Float16 or Uint16 depending on the runtime — both map to the 16-bit float format.
|
|
51
|
+
ending = "float";
|
|
52
|
+
} else {
|
|
53
|
+
throw new Error(`Unsupported data type '${data_type}'`);
|
|
54
|
+
}
|
|
55
|
+
} else if (color_space === ColorSpace.None) {
|
|
56
|
+
if (
|
|
57
|
+
data_type === BinaryDataType.Uint8
|
|
58
|
+
|| data_type === BinaryDataType.Uint16
|
|
59
|
+
|| data_type === BinaryDataType.Uint32
|
|
60
|
+
) {
|
|
61
|
+
if (normalized) {
|
|
62
|
+
ending = "unorm";
|
|
63
|
+
} else {
|
|
64
|
+
ending = "uint";
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
} else if (
|
|
68
|
+
data_type === BinaryDataType.Float32
|
|
69
|
+
|| data_type === BinaryDataType.Float16
|
|
70
|
+
) {
|
|
71
|
+
ending = "float";
|
|
72
|
+
} else {
|
|
73
|
+
throw new Error(`Unsupported data type '${data_type}'`);
|
|
74
|
+
}
|
|
75
|
+
} else if (color_space === ColorSpace.SRGB) {
|
|
76
|
+
if (data_type === BinaryDataType.Uint8) {
|
|
77
|
+
ending = "unorm-srgb";
|
|
78
|
+
} else {
|
|
79
|
+
throw new Error(`Unsupported data type '${data_type}'`);
|
|
80
|
+
}
|
|
81
|
+
} else {
|
|
82
|
+
throw new Error(`Unsupported color space '${color_space}'`);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return `${prefix}${bit_size}${ending}`;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The {@link GPUTextureFormat} a {@link ShadeImage}'s texels are in.
|
|
3
|
+
*
|
|
4
|
+
* A free function rather than a getter on the image, because {@link ShadeImage} describes *data* —
|
|
5
|
+
* a channel count, a data type, a colour space, some bytes — and what WebGPU calls that arrangement
|
|
6
|
+
* is not the data's business. The image stays a model the encoder, the container readers and the
|
|
7
|
+
* asset pipeline can hold without any of them importing a graphics API.
|
|
8
|
+
*
|
|
9
|
+
* What this replaces is the same inference run at *upload* time, inside the descriptor builder. The
|
|
10
|
+
* move matters more than the mechanism: a format worked out by inspecting pixels is a question
|
|
11
|
+
* block-compressed texels cannot answer, so a {@link ShadeTexelData} states its format instead and
|
|
12
|
+
* this function simply reports it. That is what lets both kinds share one path.
|
|
13
|
+
*
|
|
14
|
+
* **Not cached anywhere.** `color_space` is assigned *after* construction in nine places
|
|
15
|
+
* (`gltf_create_material` among them), so a format captured once would leave every glTF albedo map
|
|
16
|
+
* on `rgba8unorm` and silently drop its sRGB decode.
|
|
17
|
+
*
|
|
18
|
+
* @param {ShadeImage} image
|
|
19
|
+
* @returns {GPUTextureFormat}
|
|
20
|
+
* @throws {Error} if the image has no source, or one this does not recognise — a format guessed for
|
|
21
|
+
* texels nobody can describe would put the wrong number of bytes on both sides of the upload
|
|
22
|
+
*/
|
|
23
|
+
export function texture_format_from_shade_image(image: ShadeImage): GPUTextureFormat;
|
|
24
|
+
//# sourceMappingURL=texture_format_from_shade_image.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"texture_format_from_shade_image.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/texture/format/texture_format_from_shade_image.js"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qFA2CC"}
|