@woosh/meep-engine 3.14.1 → 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 +31 -24
- 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
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
import { FramePhase } from "../../renderer/extension/FramePhase.js";
|
|
2
|
+
import { RenderExtension } from "../../renderer/extension/RenderExtension.js";
|
|
3
|
+
import { SceneColor } from "../../renderer/extension/SceneColor.js";
|
|
4
|
+
import { ImageShader } from "../../renderer/shader/ImageShader.js";
|
|
5
|
+
import { CodeChunk } from "../../renderer/shader/compiler/CodeChunk.js";
|
|
6
|
+
import { graph_image_pass } from "../../renderer/shader/graph/graph_image_pass.js";
|
|
7
|
+
import { graph_import_texture } from "../../renderer/shader/graph/graph_import_texture.js";
|
|
8
|
+
import { ShaderResourceSetDescriptor } from "../../renderer/shader/resource/ShaderResourceSetDescriptor.js";
|
|
9
|
+
import { ShaderDescriptor } from "../../renderer/shader/ShaderDescriptor.js";
|
|
10
|
+
import { GPUTextureContext } from "../../renderer/texture/GPUTextureContext.js";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Copy the scene colour, exactly, into a texture the caller owns.
|
|
14
|
+
*
|
|
15
|
+
* A `textureLoad` at the fragment's own integer coordinate — no sampler, no filtering, no
|
|
16
|
+
* conversion. The point of this capture is to compare frames against each other at the texel, so
|
|
17
|
+
* anything that mixed neighbours would put the answer into the measurement.
|
|
18
|
+
*/
|
|
19
|
+
const resources = new ShaderResourceSetDescriptor();
|
|
20
|
+
|
|
21
|
+
resources.createGroup().addTexture("tSource");
|
|
22
|
+
|
|
23
|
+
const shader_copy_scene_color = new ImageShader({
|
|
24
|
+
descriptor: ShaderDescriptor.from({
|
|
25
|
+
label: "ground_seam/copy scene colour",
|
|
26
|
+
resources,
|
|
27
|
+
body: CodeChunk.from(
|
|
28
|
+
//language=WGSL
|
|
29
|
+
`
|
|
30
|
+
@fragment
|
|
31
|
+
fn main(
|
|
32
|
+
@builtin(position) coord: vec4<f32>,
|
|
33
|
+
) -> @location(0) vec4<f32> {
|
|
34
|
+
return textureLoad(tSource, vec2<u32>(coord.xy), 0);
|
|
35
|
+
}
|
|
36
|
+
`
|
|
37
|
+
),
|
|
38
|
+
}),
|
|
39
|
+
targets: [
|
|
40
|
+
{
|
|
41
|
+
label: "ground_seam capture",
|
|
42
|
+
format: "rgba16float",
|
|
43
|
+
}
|
|
44
|
+
],
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* The scene colour *before* the temporal filter, made readable.
|
|
49
|
+
*
|
|
50
|
+
* This exists to split one question in two. The burst measurement sees the picture the temporal
|
|
51
|
+
* filter produced, and a seam in it can come from either side of that filter: the shading may be
|
|
52
|
+
* responding differently to the sub-pixel jitter on the two triangles, or the shading may be
|
|
53
|
+
* identical and the filter may be resolving it differently. Those want opposite fixes, and no
|
|
54
|
+
* amount of staring at the output distinguishes them.
|
|
55
|
+
*
|
|
56
|
+
* {@link FramePhase.AfterTransparency} is the last phase before the upscale, so what is captured
|
|
57
|
+
* here is the full pre-TAA frame at internal resolution — the temporal filter's *input*.
|
|
58
|
+
*
|
|
59
|
+
* The pass writes an imported texture, which the graph treats as a side effect, so it is not elided
|
|
60
|
+
* for having no consumer inside the frame.
|
|
61
|
+
*/
|
|
62
|
+
export class CaptureSceneColor extends RenderExtension {
|
|
63
|
+
name = 'ground_seam/capture scene colour';
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Which phase to capture at. {@link FramePhase.AfterTransparency} is the temporal filter's
|
|
67
|
+
* *input* — the last phase before the upscale. {@link FramePhase.BeforePresent} is its output,
|
|
68
|
+
* still HDR but past DOF, motion blur and bloom. Capturing at both is how the chain gets split
|
|
69
|
+
* into 'what TAA was given' and 'what TAA produced'.
|
|
70
|
+
*
|
|
71
|
+
* Assigning it after the extension is registered has no effect: the registry resolves the
|
|
72
|
+
* ordering when an extension is added, so a phase change means removing and re-adding.
|
|
73
|
+
*
|
|
74
|
+
* @type {FramePhase}
|
|
75
|
+
*/
|
|
76
|
+
phase = FramePhase.AfterTransparency;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* @type {GPUTextureContext|undefined}
|
|
80
|
+
*/
|
|
81
|
+
#texture;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* @type {GPUDevice}
|
|
85
|
+
*/
|
|
86
|
+
#device;
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* @type {GPUBuffer|undefined}
|
|
90
|
+
*/
|
|
91
|
+
#buffer;
|
|
92
|
+
|
|
93
|
+
#width = 0;
|
|
94
|
+
#height = 0;
|
|
95
|
+
#bytes_per_row = 0;
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Whether to record at all. Off by default: a capture costs a full-resolution copy every frame,
|
|
99
|
+
* and the burst measurement this page mostly runs does not want one.
|
|
100
|
+
*
|
|
101
|
+
* @type {boolean}
|
|
102
|
+
*/
|
|
103
|
+
enabled = false;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* @param {GPUDevice} device
|
|
107
|
+
*/
|
|
108
|
+
constructor(device) {
|
|
109
|
+
super();
|
|
110
|
+
|
|
111
|
+
this.#device = device;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* @param {number} width
|
|
116
|
+
* @param {number} height
|
|
117
|
+
*/
|
|
118
|
+
#ensure(width, height) {
|
|
119
|
+
if (this.#width === width && this.#height === height) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
this.#texture?.destroy();
|
|
124
|
+
this.#buffer?.destroy();
|
|
125
|
+
|
|
126
|
+
const device = this.#device;
|
|
127
|
+
|
|
128
|
+
this.#texture = GPUTextureContext.fromTexture(
|
|
129
|
+
device.createTexture({
|
|
130
|
+
label: 'ground_seam/scene colour capture',
|
|
131
|
+
size: [width, height, 1],
|
|
132
|
+
format: 'rgba16float',
|
|
133
|
+
usage: GPUTextureUsage.RENDER_ATTACHMENT
|
|
134
|
+
| GPUTextureUsage.TEXTURE_BINDING
|
|
135
|
+
| GPUTextureUsage.COPY_SRC,
|
|
136
|
+
}),
|
|
137
|
+
device
|
|
138
|
+
);
|
|
139
|
+
|
|
140
|
+
this.#bytes_per_row = Math.ceil(width * 8 / 256) * 256;
|
|
141
|
+
|
|
142
|
+
this.#buffer = device.createBuffer({
|
|
143
|
+
label: 'ground_seam/scene colour readback',
|
|
144
|
+
size: this.#bytes_per_row * height,
|
|
145
|
+
usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ,
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
this.#width = width;
|
|
149
|
+
this.#height = height;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* @param {FrameContext} frame
|
|
154
|
+
*/
|
|
155
|
+
record(frame) {
|
|
156
|
+
if (!this.enabled) {
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const colour = frame.get(SceneColor).color;
|
|
161
|
+
|
|
162
|
+
const resolution = frame.resolution;
|
|
163
|
+
|
|
164
|
+
this.#ensure(resolution[0], resolution[1]);
|
|
165
|
+
|
|
166
|
+
graph_image_pass({
|
|
167
|
+
graph: frame.graph,
|
|
168
|
+
shader: shader_copy_scene_color,
|
|
169
|
+
inputs: { tSource: colour },
|
|
170
|
+
output: [graph_import_texture(frame.graph, this.#texture, 'ground_seam capture')],
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Luminance of the captured frame, one entry per pixel.
|
|
176
|
+
*
|
|
177
|
+
* Rec. 709 weights on the linear HDR values — this is upstream of the tonemap, so the numbers
|
|
178
|
+
* are radiance rather than display code values and there is no 8-bit quantization floor under
|
|
179
|
+
* the measurement.
|
|
180
|
+
*
|
|
181
|
+
* @returns {Promise<{luma: Float32Array, width: number, height: number}>}
|
|
182
|
+
*/
|
|
183
|
+
async read_luminance() {
|
|
184
|
+
if (this.#texture === undefined) {
|
|
185
|
+
throw new Error('nothing has been captured yet — enable the extension and render a frame');
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const device = this.#device;
|
|
189
|
+
|
|
190
|
+
const encoder = device.createCommandEncoder({ label: 'ground_seam/scene colour readback' });
|
|
191
|
+
|
|
192
|
+
encoder.copyTextureToBuffer(
|
|
193
|
+
{ texture: this.#texture.gpu_texture, mipLevel: 0 },
|
|
194
|
+
{ buffer: this.#buffer, bytesPerRow: this.#bytes_per_row },
|
|
195
|
+
[this.#width, this.#height, 1]
|
|
196
|
+
);
|
|
197
|
+
|
|
198
|
+
device.queue.submit([encoder.finish()]);
|
|
199
|
+
|
|
200
|
+
await this.#buffer.mapAsync(GPUMapMode.READ);
|
|
201
|
+
|
|
202
|
+
const source = new Uint16Array(this.#buffer.getMappedRange());
|
|
203
|
+
|
|
204
|
+
const stride = this.#bytes_per_row / 2;
|
|
205
|
+
|
|
206
|
+
const luma = new Float32Array(this.#width * this.#height);
|
|
207
|
+
|
|
208
|
+
for (let y = 0; y < this.#height; y++) {
|
|
209
|
+
for (let x = 0; x < this.#width; x++) {
|
|
210
|
+
const i = y * stride + x * 4;
|
|
211
|
+
|
|
212
|
+
luma[y * this.#width + x] = 0.2126 * half_to_float(source[i])
|
|
213
|
+
+ 0.7152 * half_to_float(source[i + 1])
|
|
214
|
+
+ 0.0722 * half_to_float(source[i + 2]);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
this.#buffer.unmap();
|
|
219
|
+
|
|
220
|
+
return { luma, width: this.#width, height: this.#height };
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* @param {number} h a float16 bit pattern
|
|
226
|
+
* @returns {number}
|
|
227
|
+
*/
|
|
228
|
+
function half_to_float(h) {
|
|
229
|
+
const sign = (h & 0x8000) !== 0 ? -1 : 1;
|
|
230
|
+
const exponent = (h & 0x7C00) >> 10;
|
|
231
|
+
const fraction = h & 0x03FF;
|
|
232
|
+
|
|
233
|
+
if (exponent === 0) {
|
|
234
|
+
return sign * Math.pow(2, -14) * (fraction / 1024);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
if (exponent === 31) {
|
|
238
|
+
return fraction !== 0 ? NaN : sign * Infinity;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
return sign * Math.pow(2, exponent - 15) * (1 + fraction / 1024);
|
|
242
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param {Float32Array} depth
|
|
3
|
+
* @param {Int8Array} side −1 / +1 / 0, as {@link classify_ground} produces
|
|
4
|
+
* @param {function(number, number): number} distance signed screen distance to the seam, in pixels
|
|
5
|
+
* @param {number} width
|
|
6
|
+
* @param {number} height
|
|
7
|
+
* @param {number} [exclude] pixels either side of the seam to leave out of the fits
|
|
8
|
+
* @returns {object}
|
|
9
|
+
*/
|
|
10
|
+
export function depth_step_across_seam(depth: Float32Array, side: Int8Array, distance: (arg0: number, arg1: number) => number, width: number, height: number, exclude?: number): object;
|
|
11
|
+
//# sourceMappingURL=depth_step_across_seam.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"depth_step_across_seam.d.ts","sourceRoot":"","sources":["../../../../../src/shade/playground/ground_seam/depth_step_across_seam.js"],"names":[],"mappings":"AAgHA;;;;;;;;GAQG;AACH,8CARW,YAAY,QACZ,SAAS,mBACA,MAAM,QAAE,MAAM,KAAG,MAAM,SAChC,MAAM,UACN,MAAM,YACN,MAAM,GACJ,MAAM,CAiElB"}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Does the rasterized depth step across the shared edge, and by how much?
|
|
3
|
+
*
|
|
4
|
+
* This is the first of the checks the ground-seam brief calls for and the only one that reaches the
|
|
5
|
+
* rasterizer's own output rather than an inference about it. The reasoning it rests on:
|
|
6
|
+
*
|
|
7
|
+
* Under a reverse-Z, infinite-far projection the depth written is `near / (−z_view)`, and
|
|
8
|
+
* `1/(−z_view)` is an affine function of the screen coordinate over a planar surface. So the depth
|
|
9
|
+
* across each of the ground quad's triangles is **exactly** a plane in `(x, y)` — not approximately.
|
|
10
|
+
* The two triangles share two vertices, so the seam is one segment and both interpolations must
|
|
11
|
+
* agree along it. Whether they *do* is a number.
|
|
12
|
+
*
|
|
13
|
+
* Each side is fitted separately by least squares over pixels at least `exclude` from the seam, so
|
|
14
|
+
* neither fit sees the other's pixels or the boundary's partially covered ones. The two fits are
|
|
15
|
+
* then evaluated *on* the seam and differenced. The residuals come back with them: the fit is exact
|
|
16
|
+
* for a plane, so a residual much above the depth format's own quantization means the premise is
|
|
17
|
+
* broken and the difference is not the quantity it claims to be.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Least-squares fit of `depth ≈ a·x + b·y + c` over the pixels a predicate accepts.
|
|
22
|
+
*
|
|
23
|
+
* Normal equations in f64 over a 3×3 symmetric system. The coordinates are centred on the frame
|
|
24
|
+
* before the system is built — `x` running to 1258 against a constant term of 1 spans six orders of
|
|
25
|
+
* magnitude, and the inverse of that would be all rounding.
|
|
26
|
+
*
|
|
27
|
+
* @param {Float32Array} depth
|
|
28
|
+
* @param {number} width
|
|
29
|
+
* @param {number} height
|
|
30
|
+
* @param {function(number): boolean} accept given the pixel index
|
|
31
|
+
* @returns {{a: number, b: number, c: number, residual_rms: number, count: number}}
|
|
32
|
+
*/
|
|
33
|
+
function fit_plane(depth, width, height, accept) {
|
|
34
|
+
let sxx = 0, sxy = 0, sx1 = 0, syy = 0, sy1 = 0, s11 = 0;
|
|
35
|
+
let sxd = 0, syd = 0, s1d = 0;
|
|
36
|
+
let count = 0;
|
|
37
|
+
|
|
38
|
+
const cx = width * 0.5;
|
|
39
|
+
const cy = height * 0.5;
|
|
40
|
+
|
|
41
|
+
for (let py = 0; py < height; py++) {
|
|
42
|
+
for (let px = 0; px < width; px++) {
|
|
43
|
+
const p = py * width + px;
|
|
44
|
+
|
|
45
|
+
if (!accept(p)) {
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const x = px - cx;
|
|
50
|
+
const y = py - cy;
|
|
51
|
+
const d = depth[p];
|
|
52
|
+
|
|
53
|
+
sxx += x * x;
|
|
54
|
+
sxy += x * y;
|
|
55
|
+
sx1 += x;
|
|
56
|
+
syy += y * y;
|
|
57
|
+
sy1 += y;
|
|
58
|
+
s11 += 1;
|
|
59
|
+
sxd += x * d;
|
|
60
|
+
syd += y * d;
|
|
61
|
+
s1d += d;
|
|
62
|
+
|
|
63
|
+
count++;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (count < 16) {
|
|
68
|
+
throw new Error(`only ${count} pixels accepted — not enough to fit a plane`);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const m = [sxx, sxy, sx1, sxy, syy, sy1, sx1, sy1, s11];
|
|
72
|
+
|
|
73
|
+
const c00 = m[4] * m[8] - m[5] * m[7];
|
|
74
|
+
const c01 = m[5] * m[6] - m[3] * m[8];
|
|
75
|
+
const c02 = m[3] * m[7] - m[4] * m[6];
|
|
76
|
+
|
|
77
|
+
const det = m[0] * c00 + m[1] * c01 + m[2] * c02;
|
|
78
|
+
|
|
79
|
+
if (det === 0) {
|
|
80
|
+
throw new Error('degenerate depth fit');
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const c10 = m[2] * m[7] - m[1] * m[8];
|
|
84
|
+
const c11 = m[0] * m[8] - m[2] * m[6];
|
|
85
|
+
const c12 = m[1] * m[6] - m[0] * m[7];
|
|
86
|
+
const c20 = m[1] * m[5] - m[2] * m[4];
|
|
87
|
+
const c21 = m[2] * m[3] - m[0] * m[5];
|
|
88
|
+
const c22 = m[0] * m[4] - m[1] * m[3];
|
|
89
|
+
|
|
90
|
+
const a = (c00 * sxd + c10 * syd + c20 * s1d) / det;
|
|
91
|
+
const b = (c01 * sxd + c11 * syd + c21 * s1d) / det;
|
|
92
|
+
const c = (c02 * sxd + c12 * syd + c22 * s1d) / det;
|
|
93
|
+
|
|
94
|
+
let residual = 0;
|
|
95
|
+
|
|
96
|
+
for (let py = 0; py < height; py++) {
|
|
97
|
+
for (let px = 0; px < width; px++) {
|
|
98
|
+
const p = py * width + px;
|
|
99
|
+
|
|
100
|
+
if (!accept(p)) {
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const e = depth[p] - (a * (px - cx) + b * (py - cy) + c);
|
|
105
|
+
|
|
106
|
+
residual += e * e;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return { a, b, c, residual_rms: Math.sqrt(residual / count), count };
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* @param {Float32Array} depth
|
|
115
|
+
* @param {Int8Array} side −1 / +1 / 0, as {@link classify_ground} produces
|
|
116
|
+
* @param {function(number, number): number} distance signed screen distance to the seam, in pixels
|
|
117
|
+
* @param {number} width
|
|
118
|
+
* @param {number} height
|
|
119
|
+
* @param {number} [exclude] pixels either side of the seam to leave out of the fits
|
|
120
|
+
* @returns {object}
|
|
121
|
+
*/
|
|
122
|
+
export function depth_step_across_seam(depth, side, distance, width, height, exclude = 8) {
|
|
123
|
+
|
|
124
|
+
const far_enough = new Uint8Array(width * height);
|
|
125
|
+
|
|
126
|
+
for (let py = 0; py < height; py++) {
|
|
127
|
+
for (let px = 0; px < width; px++) {
|
|
128
|
+
far_enough[py * width + px] = Math.abs(distance(px, py)) >= exclude ? 1 : 0;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const negative = fit_plane(depth, width, height, p => side[p] === -1 && far_enough[p] === 1);
|
|
133
|
+
const positive = fit_plane(depth, width, height, p => side[p] === 1 && far_enough[p] === 1);
|
|
134
|
+
|
|
135
|
+
/*
|
|
136
|
+
Walk the seam and evaluate both fits along it. One point would do for two exact planes; the
|
|
137
|
+
walk reports the worst disagreement anywhere on the edge, which is what a slight *rotation*
|
|
138
|
+
between the two planes looks like and what a single sample would miss.
|
|
139
|
+
*/
|
|
140
|
+
const cx = width * 0.5;
|
|
141
|
+
const cy = height * 0.5;
|
|
142
|
+
|
|
143
|
+
let worst = 0;
|
|
144
|
+
let worst_at = null;
|
|
145
|
+
let worst_ulps = 0;
|
|
146
|
+
let samples = 0;
|
|
147
|
+
|
|
148
|
+
for (let py = 0; py < height; py++) {
|
|
149
|
+
for (let px = 0; px < width; px++) {
|
|
150
|
+
if (Math.abs(distance(px, py)) > 0.5) {
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const x = px - cx;
|
|
155
|
+
const y = py - cy;
|
|
156
|
+
|
|
157
|
+
const dn = negative.a * x + negative.b * y + negative.c;
|
|
158
|
+
const dp = positive.a * x + positive.b * y + positive.c;
|
|
159
|
+
|
|
160
|
+
const difference = Math.abs(dn - dp);
|
|
161
|
+
|
|
162
|
+
samples++;
|
|
163
|
+
|
|
164
|
+
if (difference > worst) {
|
|
165
|
+
worst = difference;
|
|
166
|
+
worst_at = [px, py];
|
|
167
|
+
|
|
168
|
+
// one ULP of an f32 at this magnitude, which is the unit the question is asked in
|
|
169
|
+
const magnitude = Math.max(Math.abs(dn), 1e-30);
|
|
170
|
+
const ulp = Math.pow(2, Math.floor(Math.log2(magnitude)) - 23);
|
|
171
|
+
|
|
172
|
+
worst_ulps = difference / ulp;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
return {
|
|
178
|
+
negative,
|
|
179
|
+
positive,
|
|
180
|
+
seam_samples: samples,
|
|
181
|
+
worst_difference: worst,
|
|
182
|
+
worst_difference_ulps: worst_ulps,
|
|
183
|
+
worst_at,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<title>meep — ground seam repro</title>
|
|
6
|
+
<style>
|
|
7
|
+
:root {
|
|
8
|
+
color-scheme: dark;
|
|
9
|
+
--bg: #14161a;
|
|
10
|
+
--panel: #1c1f25;
|
|
11
|
+
--line: #2b3038;
|
|
12
|
+
--text: #d6dae0;
|
|
13
|
+
--muted: #8b939f;
|
|
14
|
+
--pass: #55c46a;
|
|
15
|
+
--fail: #ff6b6b;
|
|
16
|
+
--warn: #e5b54a;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
* { box-sizing: border-box; }
|
|
20
|
+
|
|
21
|
+
body {
|
|
22
|
+
margin: 0;
|
|
23
|
+
padding: 16px;
|
|
24
|
+
background: var(--bg);
|
|
25
|
+
color: var(--text);
|
|
26
|
+
font: 13px/1.5 system-ui, -apple-system, Segoe UI, sans-serif;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
h1 { font-size: 16px; font-weight: 600; margin: 0 0 4px; }
|
|
30
|
+
|
|
31
|
+
p.lede { margin: 0 0 14px; color: var(--muted); max-width: 90ch; }
|
|
32
|
+
|
|
33
|
+
.stage { display: flex; gap: 16px; align-items: flex-start; flex-wrap: wrap; }
|
|
34
|
+
|
|
35
|
+
canvas {
|
|
36
|
+
display: block;
|
|
37
|
+
border: 1px solid var(--line);
|
|
38
|
+
border-radius: 4px;
|
|
39
|
+
background: #000;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
aside {
|
|
43
|
+
width: 300px;
|
|
44
|
+
background: var(--panel);
|
|
45
|
+
border: 1px solid var(--line);
|
|
46
|
+
border-radius: 8px;
|
|
47
|
+
padding: 12px 14px;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
aside h2 {
|
|
51
|
+
font-size: 11px;
|
|
52
|
+
text-transform: uppercase;
|
|
53
|
+
letter-spacing: 0.06em;
|
|
54
|
+
color: var(--muted);
|
|
55
|
+
margin: 0 0 8px;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
aside h2 + * { margin-top: 0; }
|
|
59
|
+
|
|
60
|
+
label { display: flex; gap: 8px; align-items: center; padding: 3px 0; }
|
|
61
|
+
|
|
62
|
+
label span { flex: 1; }
|
|
63
|
+
|
|
64
|
+
select, input[type="number"] {
|
|
65
|
+
font: inherit;
|
|
66
|
+
background: #14161a;
|
|
67
|
+
color: var(--text);
|
|
68
|
+
border: 1px solid var(--line);
|
|
69
|
+
border-radius: 4px;
|
|
70
|
+
padding: 3px 6px;
|
|
71
|
+
width: 110px;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
button {
|
|
75
|
+
font: inherit;
|
|
76
|
+
padding: 6px 12px;
|
|
77
|
+
border-radius: 6px;
|
|
78
|
+
border: 1px solid var(--line);
|
|
79
|
+
background: #22303f;
|
|
80
|
+
color: var(--text);
|
|
81
|
+
cursor: pointer;
|
|
82
|
+
margin-top: 10px;
|
|
83
|
+
width: 100%;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
button:disabled { opacity: 0.45; cursor: default; }
|
|
87
|
+
|
|
88
|
+
#status { color: var(--muted); }
|
|
89
|
+
#status.pass { color: var(--pass); }
|
|
90
|
+
#status.fail { color: var(--fail); }
|
|
91
|
+
#status.warn { color: var(--warn); }
|
|
92
|
+
|
|
93
|
+
pre {
|
|
94
|
+
background: #14161a;
|
|
95
|
+
border: 1px solid var(--line);
|
|
96
|
+
border-radius: 6px;
|
|
97
|
+
padding: 8px 10px;
|
|
98
|
+
font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
|
|
99
|
+
font-size: 11.5px;
|
|
100
|
+
white-space: pre-wrap;
|
|
101
|
+
margin: 10px 0 0;
|
|
102
|
+
max-height: 40vh;
|
|
103
|
+
overflow: auto;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
hr { border: 0; border-top: 1px solid var(--line); margin: 12px 0; }
|
|
107
|
+
</style>
|
|
108
|
+
</head>
|
|
109
|
+
<body>
|
|
110
|
+
|
|
111
|
+
<h1>ground seam — temporal repro</h1>
|
|
112
|
+
<p class="lede">
|
|
113
|
+
One 425×425 ground quad, two triangles, a tiling grid albedo, a still camera. “Measure” settles
|
|
114
|
+
the temporal filter, records a burst of frames into a texture this page owns, and maps the
|
|
115
|
+
per-pixel luminance spread across the burst. Pixels are labelled by which triangle covers them
|
|
116
|
+
by unprojecting through the camera’s own matrix — nothing is fitted to the picture.
|
|
117
|
+
</p>
|
|
118
|
+
|
|
119
|
+
<div class="stage">
|
|
120
|
+
<div>
|
|
121
|
+
<canvas id="view"></canvas>
|
|
122
|
+
<canvas id="diff" style="margin-top: 12px"></canvas>
|
|
123
|
+
</div>
|
|
124
|
+
|
|
125
|
+
<aside>
|
|
126
|
+
<h2>scene</h2>
|
|
127
|
+
|
|
128
|
+
<label><span>subdivision</span>
|
|
129
|
+
<select id="segments">
|
|
130
|
+
<option value="1" selected>1 × 1 (2 tris)</option>
|
|
131
|
+
<option value="2">2 × 2</option>
|
|
132
|
+
<option value="8">8 × 8</option>
|
|
133
|
+
<option value="32">32 × 32</option>
|
|
134
|
+
</select>
|
|
135
|
+
</label>
|
|
136
|
+
|
|
137
|
+
<label><span>triangulation</span>
|
|
138
|
+
<select id="triangulation">
|
|
139
|
+
<option value="default" selected>default (x = −z)</option>
|
|
140
|
+
<option value="flipped">flipped (x = z)</option>
|
|
141
|
+
<option value="rotated">same tris, anchor rotated</option>
|
|
142
|
+
</select>
|
|
143
|
+
</label>
|
|
144
|
+
|
|
145
|
+
<label><span>extent</span>
|
|
146
|
+
<select id="extent">
|
|
147
|
+
<option value="425" selected>425</option>
|
|
148
|
+
<option value="4000">4000</option>
|
|
149
|
+
<option value="40000">40000</option>
|
|
150
|
+
</select>
|
|
151
|
+
</label>
|
|
152
|
+
|
|
153
|
+
<label><span>anisotropy</span><input type="checkbox" id="anisotropy" checked></label>
|
|
154
|
+
|
|
155
|
+
<label><span>ground yaw°</span><input type="number" id="yaw" value="0" step="90"></label>
|
|
156
|
+
|
|
157
|
+
<hr>
|
|
158
|
+
|
|
159
|
+
<h2>renderer</h2>
|
|
160
|
+
|
|
161
|
+
<label><span>TAA</span><input type="checkbox" id="taa" checked></label>
|
|
162
|
+
<label><span>GTAO</span><input type="checkbox" id="ssao" checked></label>
|
|
163
|
+
<label><span>shadows</span><input type="checkbox" id="shadows" checked></label>
|
|
164
|
+
<label><span>sharpening</span><input type="checkbox" id="sharpening" checked></label>
|
|
165
|
+
<label><span>auto exposure</span><input type="checkbox" id="exposure"></label>
|
|
166
|
+
<label><span>environment</span><input type="checkbox" id="environment"></label>
|
|
167
|
+
|
|
168
|
+
<label><span>exposure (stops)</span><input type="number" id="exposure_compensation" value="2.5" step="0.5"></label>
|
|
169
|
+
|
|
170
|
+
<label><span>width</span><input type="number" id="width" value="1258" step="2"></label>
|
|
171
|
+
<label><span>height</span><input type="number" id="height" value="566" step="2"></label>
|
|
172
|
+
|
|
173
|
+
<hr>
|
|
174
|
+
|
|
175
|
+
<h2>burst</h2>
|
|
176
|
+
|
|
177
|
+
<label><span>settle frames</span><input type="number" id="settle" value="240"></label>
|
|
178
|
+
<label><span>burst frames</span><input type="number" id="frames" value="16"></label>
|
|
179
|
+
<label><span>diff gain</span><input type="number" id="gain" value="8"></label>
|
|
180
|
+
|
|
181
|
+
<button id="measure">Measure</button>
|
|
182
|
+
<button id="apply">Apply scene / renderer</button>
|
|
183
|
+
|
|
184
|
+
<pre id="report">ready</pre>
|
|
185
|
+
</aside>
|
|
186
|
+
</div>
|
|
187
|
+
|
|
188
|
+
<script type="module">
|
|
189
|
+
import { start } from './main.js';
|
|
190
|
+
|
|
191
|
+
start();
|
|
192
|
+
</script>
|
|
193
|
+
|
|
194
|
+
</body>
|
|
195
|
+
</html>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../../../../src/shade/playground/ground_seam/main.js"],"names":[],"mappings":"AAiEA,uCA6yBC"}
|