@woosh/meep-engine 3.61.0 → 3.61.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/package.json +1 -1
- package/src/engine/ecs/storage/populateEngineSerializationRegistry.d.ts.map +1 -1
- package/src/engine/ecs/storage/populateEngineSerializationRegistry.js +4 -0
- package/src/engine/graphics/ecs/decal/v2/Decal.d.ts +46 -2
- package/src/engine/graphics/ecs/decal/v2/Decal.d.ts.map +1 -1
- package/src/engine/graphics/ecs/decal/v2/Decal.js +74 -5
- package/src/engine/graphics/ecs/decal/v2/DecalSerializationAdapter.d.ts.map +1 -1
- package/src/engine/graphics/ecs/decal/v2/DecalSerializationAdapter.js +13 -1
- package/src/engine/graphics/ecs/decal/v2/DecalSerializationUpgrader_1_2.d.ts +9 -0
- package/src/engine/graphics/ecs/decal/v2/DecalSerializationUpgrader_1_2.d.ts.map +1 -0
- package/src/engine/graphics/ecs/decal/v2/DecalSerializationUpgrader_1_2.js +37 -0
- package/src/engine/graphics3/DecalSystem.d.ts.map +1 -1
- package/src/engine/graphics3/DecalSystem.js +462 -447
- package/src/engine/graphics3/decal/DECAL_GPU_RECORD.d.ts +14 -0
- package/src/engine/graphics3/decal/DECAL_GPU_RECORD.d.ts.map +1 -1
- package/src/engine/graphics3/decal/DECAL_GPU_RECORD.js +53 -13
- package/src/engine/graphics3/decal/chunk_decal_record.d.ts +6 -1
- package/src/engine/graphics3/decal/chunk_decal_record.d.ts.map +1 -1
- package/src/engine/graphics3/decal/chunk_decal_record.js +28 -9
- package/src/engine/graphics3/decal/decal_gpu_records.d.ts +2 -1
- package/src/engine/graphics3/decal/decal_gpu_records.d.ts.map +1 -1
- package/src/engine/graphics3/decal/decal_gpu_records.js +26 -5
- package/src/engine/graphics3/decal/decal_material_samplers.d.ts +6 -0
- package/src/engine/graphics3/decal/decal_material_samplers.d.ts.map +1 -1
- package/src/engine/graphics3/decal/decal_material_samplers.js +13 -0
- package/src/engine/graphics3/decal/shader_cluster_assign_decals.js +1 -1
- package/src/engine/graphics3/decal/shader_cull_decals_frustum.js +1 -1
- package/src/engine/graphics3/decal/shader_decal_composite.d.ts +5 -0
- package/src/engine/graphics3/decal/shader_decal_composite.d.ts.map +1 -1
- package/src/engine/graphics3/decal/shader_decal_composite.js +69 -28
- package/src/engine/network/sim/SimActionExecutor.d.ts +4 -0
- package/src/engine/network/sim/SimActionExecutor.d.ts.map +1 -1
- package/src/engine/network/sim/SimActionExecutor.js +4 -0
- package/src/generation/foliage/material/foliage_atlas_cutout.d.ts.map +1 -1
- package/src/generation/foliage/material/foliage_atlas_cutout.js +21 -5
- package/src/generation/foliage/mesh/tree_cluster_representatives.d.ts +8 -0
- package/src/generation/foliage/mesh/tree_cluster_representatives.d.ts.map +1 -1
- package/src/generation/foliage/mesh/tree_cluster_representatives.js +178 -78
- package/src/generation/foliage/mesh/tree_mesh_build_bark.d.ts.map +1 -1
- package/src/generation/foliage/mesh/tree_mesh_build_bark.js +178 -97
- package/src/generation/foliage/skeleton/ShootLightField.d.ts +1 -0
- package/src/generation/foliage/skeleton/ShootLightField.d.ts.map +1 -1
- package/src/generation/foliage/skeleton/ShootLightField.js +88 -17
- package/src/generation/foliage/skeleton/ShootWoodHash.d.ts +8 -4
- package/src/generation/foliage/skeleton/ShootWoodHash.d.ts.map +1 -1
- package/src/generation/foliage/skeleton/ShootWoodHash.js +216 -27
- package/src/shade/playground/probe_clipmap/main.d.ts.map +1 -1
- package/src/shade/playground/probe_clipmap/main.js +4 -0
- package/src/shade/playground/probe_clipmap_box/README.md +55 -0
- package/src/shade/playground/probe_clipmap_box/index.html +185 -0
- package/src/shade/playground/probe_clipmap_box/main.d.ts +8 -0
- package/src/shade/playground/probe_clipmap_box/main.d.ts.map +1 -0
- package/src/shade/playground/probe_clipmap_box/main.js +323 -0
- package/src/shade/playground/probe_clipmap_box/scene.d.ts +93 -0
- package/src/shade/playground/probe_clipmap_box/scene.d.ts.map +1 -0
- package/src/shade/playground/probe_clipmap_box/scene.js +256 -0
- package/src/shade/renderer/Renderer.d.ts.map +1 -1
- package/src/shade/renderer/Renderer.js +6 -1
- package/src/shade/renderer/buffer/graph_read_buffer.d.ts +3 -1
- package/src/shade/renderer/buffer/graph_read_buffer.d.ts.map +1 -1
- package/src/shade/renderer/buffer/graph_read_buffer.js +9 -6
- package/src/shade/renderer/global_illumination/brick4/gpu/encoding/v2/chunk_brick4_sh3_color_decode.d.ts +12 -0
- package/src/shade/renderer/global_illumination/brick4/gpu/encoding/v2/chunk_brick4_sh3_color_decode.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/brick4/gpu/encoding/v2/chunk_brick4_sh3_color_decode.js +49 -24
- package/src/shade/renderer/global_illumination/brick4/gpu/encoding/v2/chunk_brick4_sh3_color_encode.d.ts +12 -0
- package/src/shade/renderer/global_illumination/brick4/gpu/encoding/v2/chunk_brick4_sh3_color_encode.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/brick4/gpu/encoding/v2/chunk_brick4_sh3_color_encode.js +50 -19
- package/src/shade/renderer/global_illumination/brick4/gpu/encoding/v2/chunk_sh3_compress.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/brick4/gpu/encoding/v2/chunk_sh3_compress.js +6 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts +5 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.js +7 -3
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts +6 -4
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.js +10 -9
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.d.ts +12 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.js +14 -0
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.d.ts +17 -22
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.js +53 -65
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_pick.d.ts +2 -3
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_pick.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_pick.js +9 -20
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.d.ts +2 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.js +14 -19
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_accumulate.d.ts +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_accumulate.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_accumulate.js +8 -4
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_admit.js +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_bounce.d.ts +2 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_bounce.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_bounce.js +13 -18
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_candidate.d.ts +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_candidate.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_candidate.js +4 -2
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_diffuse.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_diffuse.js +4 -6
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_indirect_lighting.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_indirect_lighting.js +4 -7
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_project.d.ts +4 -3
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_project.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_project.js +14 -13
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace.d.ts +3 -4
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace.js +7 -15
- package/src/shade/renderer/light/environment/shader_downsample_environment_map.d.ts.map +1 -1
- package/src/shade/renderer/light/environment/shader_downsample_environment_map.js +5 -1
- package/src/shade/renderer/particles/GPUParticleSystem.d.ts.map +1 -1
- package/src/shade/renderer/particles/GPUParticleSystem.js +1 -7
- package/src/shade/renderer/postprocess/eye/GPUCameraExposureManager.d.ts +26 -8
- package/src/shade/renderer/postprocess/eye/GPUCameraExposureManager.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/eye/GPUCameraExposureManager.js +170 -142
- package/src/shade/renderer/rasterize/forward/chunk_forward_sample_indirect_probe_clipmap.d.ts +1 -1
- package/src/shade/renderer/rasterize/forward/chunk_forward_sample_indirect_probe_clipmap.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/forward/chunk_forward_sample_indirect_probe_clipmap.js +5 -8
- package/src/shade/renderer/restir/di/chunk_restir_resolve.d.ts.map +1 -1
- package/src/shade/renderer/restir/di/chunk_restir_resolve.js +91 -94
- package/src/shade/renderer/restir/reservoir/chunk_rtxdi_stream_sample.js +1 -1
- package/src/shade/renderer/shader/chunk/color/rgbe9995/chunk_rgbe9995_decode.d.ts +14 -0
- package/src/shade/renderer/shader/chunk/color/rgbe9995/chunk_rgbe9995_decode.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/color/rgbe9995/chunk_rgbe9995_decode.js +36 -21
- package/src/shade/renderer/shader/chunk/color/rgbe9995/chunk_rgbe9995_sample_gather.d.ts +22 -0
- package/src/shade/renderer/shader/chunk/color/rgbe9995/chunk_rgbe9995_sample_gather.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/color/rgbe9995/chunk_rgbe9995_sample_gather.js +64 -0
- package/src/shade/renderer/shader/chunk/filter/chunk_multiscale_mean.d.ts +15 -4
- package/src/shade/renderer/shader/chunk/filter/chunk_multiscale_mean.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/filter/chunk_multiscale_mean.js +33 -7
- package/src/shade/renderer/shader/chunk/geometry/normal/chunk_decode_vertex_normal.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/geometry/normal/chunk_decode_vertex_normal.js +13 -18
- package/src/shade/renderer/shader/chunk/geometry/normal/chunk_encode_vertex_normal.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/geometry/normal/chunk_encode_vertex_normal.js +28 -30
- package/src/shade/renderer/shader/chunk/geometry/vec2/chunk_unit_u32_to_vec2.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/geometry/vec2/chunk_unit_u32_to_vec2.js +15 -16
- package/src/shade/renderer/shader/chunk/geometry/vec2/chunk_unit_vec2_to_u32.d.ts +0 -1
- package/src/shade/renderer/shader/chunk/geometry/vec2/chunk_unit_vec2_to_u32.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/geometry/vec2/chunk_unit_vec2_to_u32.js +15 -18
- package/src/shade/renderer/shader/chunk/noise/chunk_sobol_sample_vec2.d.ts +40 -0
- package/src/shade/renderer/shader/chunk/noise/chunk_sobol_sample_vec2.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/noise/chunk_sobol_sample_vec2.js +75 -0
- package/src/shade/renderer/shader/chunk/noise/chunk_vdc_radical_inverse.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/noise/chunk_vdc_radical_inverse.js +3 -1
- package/src/shade/renderer/shader/chunk/random/chunk_hash_lk.d.ts +28 -0
- package/src/shade/renderer/shader/chunk/random/chunk_hash_lk.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/random/chunk_hash_lk.js +41 -0
- package/src/shade/renderer/shader/chunk/spherical_harmonics/chunk_sh3_color_add_scaled.d.ts +12 -0
- package/src/shade/renderer/shader/chunk/spherical_harmonics/chunk_sh3_color_add_scaled.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/spherical_harmonics/chunk_sh3_color_add_scaled.js +24 -0
- package/src/shade/renderer/volumetrics/irradiance_clipmap/GPUIrradianceClipmap.d.ts +3 -2
- package/src/shade/renderer/volumetrics/irradiance_clipmap/GPUIrradianceClipmap.d.ts.map +1 -1
- package/src/shade/renderer/volumetrics/irradiance_clipmap/GPUIrradianceClipmap.js +4 -0
- package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_gi_sample.d.ts +2 -5
- package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_gi_sample.d.ts.map +1 -1
- package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_gi_sample.js +3 -20
- package/src/shade/renderer/water/chunk_water_gi.d.ts +1 -1
- package/src/shade/renderer/water/chunk_water_gi.d.ts.map +1 -1
- package/src/shade/renderer/water/chunk_water_gi.js +6 -8
- package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +8 -1
- package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts.map +1 -1
- package/src/shade/wgsl/emulator/WGSLLanguageCore.js +79 -35
- package/src/core/math/hash/squirrel3.d.ts +0 -17
- package/src/core/math/hash/squirrel3.d.ts.map +0 -1
- package/src/core/math/hash/squirrel3.js +0 -30
- package/src/shade/renderer/global_illumination/brick4/cpu/brick4_sh3_color_encode.d.ts +0 -2
- package/src/shade/renderer/global_illumination/brick4/cpu/brick4_sh3_color_encode.d.ts.map +0 -1
- package/src/shade/renderer/global_illumination/brick4/cpu/brick4_sh3_color_encode.js +0 -6
- package/src/shade/renderer/shader/chunk/random/chunk_hash_squirrel3.d.ts +0 -12
- package/src/shade/renderer/shader/chunk/random/chunk_hash_squirrel3.d.ts.map +0 -1
- package/src/shade/renderer/shader/chunk/random/chunk_hash_squirrel3.js +0 -30
|
@@ -6,6 +6,12 @@
|
|
|
6
6
|
* ask, per pixel, whether a world position is inside the cube and where in the decal's texture it
|
|
7
7
|
* lands. Deriving either from the other is a matrix inverse — cheap once on the CPU, and absurd per
|
|
8
8
|
* pixel per decal inside the composite's loop.
|
|
9
|
+
*
|
|
10
|
+
* **Shaders read the record as `array<u32>`** and bitcast the float fields. The packed weights are
|
|
11
|
+
* bit patterns, not floats — a weight of one in a high half reads as a NaN — and neither WGSL nor a
|
|
12
|
+
* JavaScript `Float32Array` promises to keep a NaN's bits through a float load, so the words are only
|
|
13
|
+
* ever moved as integers and never read through a float view. The CPU writes them through a
|
|
14
|
+
* `Uint32Array` over the same memory.
|
|
9
15
|
*/
|
|
10
16
|
export const DECAL_GPU_RECORD: WebGPUStruct;
|
|
11
17
|
/**
|
|
@@ -44,6 +50,14 @@ export const DECAL_RECORD_OFFSET_EMISSIVE: number;
|
|
|
44
50
|
* @type {number}
|
|
45
51
|
*/
|
|
46
52
|
export const DECAL_RECORD_OFFSET_PARAMS: number;
|
|
53
|
+
/**
|
|
54
|
+
* @type {number}
|
|
55
|
+
*/
|
|
56
|
+
export const DECAL_RECORD_OFFSET_WEIGHTS: number;
|
|
57
|
+
/**
|
|
58
|
+
* @type {number}
|
|
59
|
+
*/
|
|
60
|
+
export const DECAL_RECORD_OFFSET_WEIGHT_EMISSIVE: number;
|
|
47
61
|
/**
|
|
48
62
|
* @type {number}
|
|
49
63
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DECAL_GPU_RECORD.d.ts","sourceRoot":"","sources":["../../../../../src/engine/graphics3/decal/DECAL_GPU_RECORD.js"],"names":[],"mappings":"AAGA
|
|
1
|
+
{"version":3,"file":"DECAL_GPU_RECORD.d.ts","sourceRoot":"","sources":["../../../../../src/engine/graphics3/decal/DECAL_GPU_RECORD.js"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;GAcG;AACH,4CAkEyB;AAczB;;GAEG;AACH,sCAFU,MAAM,CAEiD;AAEjE;;GAEG;AACH,4CAFU,MAAM,CAEsD;AAEtE;;GAEG;AACH,oDAFU,MAAM,CAEsE;AAEtF;;GAEG;AACH,4CAFU,MAAM,CAEsD;AAEtE;;GAEG;AACH,4CAFU,MAAM,CAEsD;AAEtE;;GAEG;AACH,yCAFU,MAAM,CAEgD;AAEhE;;GAEG;AACH,wCAFU,MAAM,CAE8C;AAE9D;;GAEG;AACH,2CAFU,MAAM,CAEoD;AAEpE;;GAEG;AACH,yCAFU,MAAM,CAEgD;AAEhE;;GAEG;AACH,0CAFU,MAAM,CAEkD;AAElE;;GAEG;AACH,kDAFU,MAAM,CAEkE;AAElF;;GAEG;AACH,sCAFU,MAAM,CAE0C;6BA3J7B,qDAAqD"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { mat4x4f, vec4f } from "../../../shade/renderer/shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
|
|
1
|
+
import { mat4x4f, u32, vec2f, vec2u, vec3f, vec4f } from "../../../shade/renderer/shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
|
|
2
2
|
import { WebGPUStruct } from "../../../shade/renderer/shader/type/WebGPUStruct.js";
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -9,6 +9,12 @@ import { WebGPUStruct } from "../../../shade/renderer/shader/type/WebGPUStruct.j
|
|
|
9
9
|
* ask, per pixel, whether a world position is inside the cube and where in the decal's texture it
|
|
10
10
|
* lands. Deriving either from the other is a matrix inverse — cheap once on the CPU, and absurd per
|
|
11
11
|
* pixel per decal inside the composite's loop.
|
|
12
|
+
*
|
|
13
|
+
* **Shaders read the record as `array<u32>`** and bitcast the float fields. The packed weights are
|
|
14
|
+
* bit patterns, not floats — a weight of one in a high half reads as a NaN — and neither WGSL nor a
|
|
15
|
+
* JavaScript `Float32Array` promises to keep a NaN's bits through a float load, so the words are only
|
|
16
|
+
* ever moved as integers and never read through a float view. The CPU writes them through a
|
|
17
|
+
* `Uint32Array` over the same memory.
|
|
12
18
|
*/
|
|
13
19
|
export const DECAL_GPU_RECORD = WebGPUStruct.from({
|
|
14
20
|
/**
|
|
@@ -47,12 +53,24 @@ export const DECAL_GPU_RECORD = WebGPUStruct.from({
|
|
|
47
53
|
* `emissive_color.rgb * emissive_intensity`. Zero for every decal that does not emit, which is
|
|
48
54
|
* every decal the game authors today.
|
|
49
55
|
*/
|
|
50
|
-
emissive:
|
|
56
|
+
emissive: vec3f,
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* `pack2x16unorm(emissive_weight, 0)`.
|
|
60
|
+
*/
|
|
61
|
+
weight_emissive: u32,
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* roughness, metalness.
|
|
65
|
+
*/
|
|
66
|
+
params: vec2f,
|
|
51
67
|
|
|
52
68
|
/**
|
|
53
|
-
*
|
|
69
|
+
* `pack2x16unorm(albedo_weight, normal_weight)`, `pack2x16unorm(roughness_weight, metalness_weight)`:
|
|
70
|
+
* how much of each channel the decal writes, each scaling the mask's coverage for that channel
|
|
71
|
+
* alone.
|
|
54
72
|
*/
|
|
55
|
-
|
|
73
|
+
weights: vec2u,
|
|
56
74
|
|
|
57
75
|
/**
|
|
58
76
|
* The deepest mip level each of the three atlases may be sampled at for this decal — albedo,
|
|
@@ -66,6 +84,18 @@ export const DECAL_GPU_RECORD = WebGPUStruct.from({
|
|
|
66
84
|
lod: vec4f,
|
|
67
85
|
}, "DecalRecord").pack();
|
|
68
86
|
|
|
87
|
+
/**
|
|
88
|
+
* Where a field sits, in words. Derived from the struct, because {@link WebGPUStruct#pack} chooses the
|
|
89
|
+
* order, and an offset written by hand would go on agreeing with the shaders while disagreeing with the
|
|
90
|
+
* layout the record declares.
|
|
91
|
+
*
|
|
92
|
+
* @param {string} name
|
|
93
|
+
* @returns {number}
|
|
94
|
+
*/
|
|
95
|
+
function word_offset(name) {
|
|
96
|
+
return DECAL_GPU_RECORD.get(name).offset / 4;
|
|
97
|
+
}
|
|
98
|
+
|
|
69
99
|
/**
|
|
70
100
|
* @type {number}
|
|
71
101
|
*/
|
|
@@ -74,44 +104,54 @@ export const DECAL_RECORD_WORD_COUNT = DECAL_GPU_RECORD.size / 4;
|
|
|
74
104
|
/**
|
|
75
105
|
* @type {number}
|
|
76
106
|
*/
|
|
77
|
-
export const DECAL_RECORD_OFFSET_TRANSFORM =
|
|
107
|
+
export const DECAL_RECORD_OFFSET_TRANSFORM = word_offset("transform");
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* @type {number}
|
|
111
|
+
*/
|
|
112
|
+
export const DECAL_RECORD_OFFSET_TRANSFORM_INVERSE = word_offset("transform_inverse");
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* @type {number}
|
|
116
|
+
*/
|
|
117
|
+
export const DECAL_RECORD_OFFSET_UV_ALBEDO = word_offset("uv_albedo");
|
|
78
118
|
|
|
79
119
|
/**
|
|
80
120
|
* @type {number}
|
|
81
121
|
*/
|
|
82
|
-
export const
|
|
122
|
+
export const DECAL_RECORD_OFFSET_UV_NORMAL = word_offset("uv_normal");
|
|
83
123
|
|
|
84
124
|
/**
|
|
85
125
|
* @type {number}
|
|
86
126
|
*/
|
|
87
|
-
export const
|
|
127
|
+
export const DECAL_RECORD_OFFSET_UV_ORM = word_offset("uv_orm");
|
|
88
128
|
|
|
89
129
|
/**
|
|
90
130
|
* @type {number}
|
|
91
131
|
*/
|
|
92
|
-
export const
|
|
132
|
+
export const DECAL_RECORD_OFFSET_COLOR = word_offset("color");
|
|
93
133
|
|
|
94
134
|
/**
|
|
95
135
|
* @type {number}
|
|
96
136
|
*/
|
|
97
|
-
export const
|
|
137
|
+
export const DECAL_RECORD_OFFSET_EMISSIVE = word_offset("emissive");
|
|
98
138
|
|
|
99
139
|
/**
|
|
100
140
|
* @type {number}
|
|
101
141
|
*/
|
|
102
|
-
export const
|
|
142
|
+
export const DECAL_RECORD_OFFSET_PARAMS = word_offset("params");
|
|
103
143
|
|
|
104
144
|
/**
|
|
105
145
|
* @type {number}
|
|
106
146
|
*/
|
|
107
|
-
export const
|
|
147
|
+
export const DECAL_RECORD_OFFSET_WEIGHTS = word_offset("weights");
|
|
108
148
|
|
|
109
149
|
/**
|
|
110
150
|
* @type {number}
|
|
111
151
|
*/
|
|
112
|
-
export const
|
|
152
|
+
export const DECAL_RECORD_OFFSET_WEIGHT_EMISSIVE = word_offset("weight_emissive");
|
|
113
153
|
|
|
114
154
|
/**
|
|
115
155
|
* @type {number}
|
|
116
156
|
*/
|
|
117
|
-
export const DECAL_RECORD_OFFSET_LOD =
|
|
157
|
+
export const DECAL_RECORD_OFFSET_LOD = word_offset("lod");
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Shared WGSL accessors for reading packed decal records
|
|
2
|
+
* Shared WGSL accessors for reading packed decal records from a `decal_data` storage buffer bound as
|
|
3
|
+
* `array<u32>`. Float fields are bitcast out of their words; packed fields are read as the words
|
|
4
|
+
* they are (see {@link DECAL_GPU_RECORD}).
|
|
3
5
|
*
|
|
4
6
|
* ```wgsl
|
|
7
|
+
* fn decal_word(index: u32, field: u32) -> u32
|
|
8
|
+
* fn decal_vec2(index: u32, field: u32) -> vec2<f32>
|
|
9
|
+
* fn decal_vec3(index: u32, field: u32) -> vec3<f32>
|
|
5
10
|
* fn decal_vec4(index: u32, field: u32) -> vec4<f32>
|
|
6
11
|
* fn decal_matrix(index: u32, field: u32) -> mat4x4<f32>
|
|
7
12
|
* fn decal_transform(index: u32) -> mat4x4<f32>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk_decal_record.d.ts","sourceRoot":"","sources":["../../../../../src/engine/graphics3/decal/chunk_decal_record.js"],"names":[],"mappings":"AAGA
|
|
1
|
+
{"version":3,"file":"chunk_decal_record.d.ts","sourceRoot":"","sources":["../../../../../src/engine/graphics3/decal/chunk_decal_record.js"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;GAeG;AACH,iCAFU,SAAS,CA6CjB;0BA9DwB,sDAAsD"}
|
|
@@ -2,9 +2,14 @@ import { CodeChunk } from "../../../shade/renderer/shader/compiler/CodeChunk.js"
|
|
|
2
2
|
import { DECAL_RECORD_OFFSET_TRANSFORM, DECAL_RECORD_WORD_COUNT } from "./DECAL_GPU_RECORD.js";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* Shared WGSL accessors for reading packed decal records
|
|
5
|
+
* Shared WGSL accessors for reading packed decal records from a `decal_data` storage buffer bound as
|
|
6
|
+
* `array<u32>`. Float fields are bitcast out of their words; packed fields are read as the words
|
|
7
|
+
* they are (see {@link DECAL_GPU_RECORD}).
|
|
6
8
|
*
|
|
7
9
|
* ```wgsl
|
|
10
|
+
* fn decal_word(index: u32, field: u32) -> u32
|
|
11
|
+
* fn decal_vec2(index: u32, field: u32) -> vec2<f32>
|
|
12
|
+
* fn decal_vec3(index: u32, field: u32) -> vec3<f32>
|
|
8
13
|
* fn decal_vec4(index: u32, field: u32) -> vec4<f32>
|
|
9
14
|
* fn decal_matrix(index: u32, field: u32) -> mat4x4<f32>
|
|
10
15
|
* fn decal_transform(index: u32) -> mat4x4<f32>
|
|
@@ -18,22 +23,36 @@ export const chunk_decal_record = CodeChunk.from(
|
|
|
18
23
|
const DECAL_RECORD_WORD_COUNT : u32 = ${DECAL_RECORD_WORD_COUNT}u;
|
|
19
24
|
const DECAL_RECORD_OFFSET_TRANSFORM : u32 = ${DECAL_RECORD_OFFSET_TRANSFORM}u;
|
|
20
25
|
|
|
26
|
+
fn decal_word(index: u32, field: u32) -> u32 {
|
|
27
|
+
return decal_data[index * DECAL_RECORD_WORD_COUNT + field];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
fn decal_vec2(index: u32, field: u32) -> vec2<f32> {
|
|
31
|
+
let base = index * DECAL_RECORD_WORD_COUNT + field;
|
|
32
|
+
|
|
33
|
+
return bitcast<vec2<f32>>(vec2<u32>(decal_data[base], decal_data[base + 1u]));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
fn decal_vec3(index: u32, field: u32) -> vec3<f32> {
|
|
37
|
+
let base = index * DECAL_RECORD_WORD_COUNT + field;
|
|
38
|
+
|
|
39
|
+
return bitcast<vec3<f32>>(vec3<u32>(decal_data[base], decal_data[base + 1u], decal_data[base + 2u]));
|
|
40
|
+
}
|
|
41
|
+
|
|
21
42
|
fn decal_vec4(index: u32, field: u32) -> vec4<f32> {
|
|
22
43
|
let base = index * DECAL_RECORD_WORD_COUNT + field;
|
|
23
44
|
|
|
24
|
-
return vec4<f32>(
|
|
45
|
+
return bitcast<vec4<f32>>(vec4<u32>(
|
|
25
46
|
decal_data[base], decal_data[base + 1u], decal_data[base + 2u], decal_data[base + 3u]
|
|
26
|
-
);
|
|
47
|
+
));
|
|
27
48
|
}
|
|
28
49
|
|
|
29
50
|
fn decal_matrix(index: u32, field: u32) -> mat4x4<f32> {
|
|
30
|
-
let base = index * DECAL_RECORD_WORD_COUNT + field;
|
|
31
|
-
|
|
32
51
|
return mat4x4<f32>(
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
52
|
+
decal_vec4(index, field),
|
|
53
|
+
decal_vec4(index, field + 4u),
|
|
54
|
+
decal_vec4(index, field + 8u),
|
|
55
|
+
decal_vec4(index, field + 12u)
|
|
37
56
|
);
|
|
38
57
|
}
|
|
39
58
|
|
|
@@ -2,13 +2,14 @@
|
|
|
2
2
|
* Write one decal into the buffer every decal shader reads.
|
|
3
3
|
*
|
|
4
4
|
* @param {Float32Array} target
|
|
5
|
+
* @param {Uint32Array} target_words the same memory as `target`, for the fields that are bit patterns
|
|
5
6
|
* @param {number} offset in words, a multiple of the record size
|
|
6
7
|
* @param {Decal} decal
|
|
7
8
|
* @param {Float32Array|number[]} matrix the entity's world transform, column-major
|
|
8
9
|
* @param {{albedo: Rectangle, normal: Rectangle, orm: Rectangle}} uv atlas rectangles
|
|
9
10
|
* @param {{albedo: number, normal: number, orm: number}} max_lod per atlas, from each patch's border
|
|
10
11
|
*/
|
|
11
|
-
export function write_decal_record(target: Float32Array, offset: number, decal: Decal, matrix: Float32Array | number[], uv: {
|
|
12
|
+
export function write_decal_record(target: Float32Array, target_words: Uint32Array, offset: number, decal: Decal, matrix: Float32Array | number[], uv: {
|
|
12
13
|
albedo: Rectangle;
|
|
13
14
|
normal: Rectangle;
|
|
14
15
|
orm: Rectangle;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decal_gpu_records.d.ts","sourceRoot":"","sources":["../../../../../src/engine/graphics3/decal/decal_gpu_records.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"decal_gpu_records.d.ts","sourceRoot":"","sources":["../../../../../src/engine/graphics3/decal/decal_gpu_records.js"],"names":[],"mappings":"AA4CA;;;;;;;;;;GAUG;AACH,2CARW,YAAY,gBACZ,WAAW,UACX,MAAM,wBAEN,YAAY,GAAC,MAAM,EAAE,MACrB;IAAC,MAAM,YAAY;IAAC,MAAM,YAAY;IAAC,GAAG,YAAW;CAAC,WACtD;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAC,QAsDvD;AAED;;;;;;;;;;;;GAYG;AACH,iDAHW,MAAM;IAAC,KAAK,QAAO;CAAC,CAAC,GACnB,MAAM;IAAC,KAAK,QAAO;CAAC,CAAC,CAoBjC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { assert } from "../../../core/assert.js";
|
|
2
2
|
import { m4_invert } from "../../../core/geom/3d/mat4/m4_invert.js";
|
|
3
3
|
import { array_copy } from "../../../core/collection/array/array_copy.js";
|
|
4
|
+
import { clamp01 } from "../../../core/math/clamp01.js";
|
|
4
5
|
import {
|
|
5
6
|
DECAL_RECORD_OFFSET_COLOR,
|
|
6
7
|
DECAL_RECORD_OFFSET_EMISSIVE,
|
|
@@ -10,9 +11,25 @@ import {
|
|
|
10
11
|
DECAL_RECORD_OFFSET_TRANSFORM_INVERSE,
|
|
11
12
|
DECAL_RECORD_OFFSET_UV_ALBEDO,
|
|
12
13
|
DECAL_RECORD_OFFSET_UV_NORMAL,
|
|
13
|
-
DECAL_RECORD_OFFSET_UV_ORM
|
|
14
|
+
DECAL_RECORD_OFFSET_UV_ORM,
|
|
15
|
+
DECAL_RECORD_OFFSET_WEIGHT_EMISSIVE,
|
|
16
|
+
DECAL_RECORD_OFFSET_WEIGHTS
|
|
14
17
|
} from "./DECAL_GPU_RECORD.js";
|
|
15
18
|
|
|
19
|
+
/**
|
|
20
|
+
* WGSL's `pack2x16unorm`: `low` in bits 0..15, `high` in bits 16..31, each clamped to [0, 1].
|
|
21
|
+
*
|
|
22
|
+
* @param {number} low
|
|
23
|
+
* @param {number} high
|
|
24
|
+
* @returns {number} u32
|
|
25
|
+
*/
|
|
26
|
+
function pack2x16unorm(low, high) {
|
|
27
|
+
const x = Math.round(clamp01(low) * 65535);
|
|
28
|
+
const y = Math.round(clamp01(high) * 65535);
|
|
29
|
+
|
|
30
|
+
return ((y << 16) | x) >>> 0;
|
|
31
|
+
}
|
|
32
|
+
|
|
16
33
|
/**
|
|
17
34
|
* @param {Float32Array} target
|
|
18
35
|
* @param {number} offset in words
|
|
@@ -29,14 +46,17 @@ function write_uv(target, offset, uv) {
|
|
|
29
46
|
* Write one decal into the buffer every decal shader reads.
|
|
30
47
|
*
|
|
31
48
|
* @param {Float32Array} target
|
|
49
|
+
* @param {Uint32Array} target_words the same memory as `target`, for the fields that are bit patterns
|
|
32
50
|
* @param {number} offset in words, a multiple of the record size
|
|
33
51
|
* @param {Decal} decal
|
|
34
52
|
* @param {Float32Array|number[]} matrix the entity's world transform, column-major
|
|
35
53
|
* @param {{albedo: Rectangle, normal: Rectangle, orm: Rectangle}} uv atlas rectangles
|
|
36
54
|
* @param {{albedo: number, normal: number, orm: number}} max_lod per atlas, from each patch's border
|
|
37
55
|
*/
|
|
38
|
-
export function write_decal_record(target, offset, decal, matrix, uv, max_lod) {
|
|
56
|
+
export function write_decal_record(target, target_words, offset, decal, matrix, uv, max_lod) {
|
|
39
57
|
assert.defined(target, 'target');
|
|
58
|
+
assert.equal(target_words.buffer, target.buffer, 'target_words aliases target');
|
|
59
|
+
assert.equal(target_words.byteOffset, target.byteOffset, 'target_words.byteOffset === target.byteOffset');
|
|
40
60
|
assert.defined(decal, 'decal');
|
|
41
61
|
assert.defined(matrix, 'matrix');
|
|
42
62
|
|
|
@@ -73,12 +93,13 @@ export function write_decal_record(target, offset, decal, matrix, uv, max_lod) {
|
|
|
73
93
|
target[offset + DECAL_RECORD_OFFSET_EMISSIVE] = emissive.r * intensity;
|
|
74
94
|
target[offset + DECAL_RECORD_OFFSET_EMISSIVE + 1] = emissive.g * intensity;
|
|
75
95
|
target[offset + DECAL_RECORD_OFFSET_EMISSIVE + 2] = emissive.b * intensity;
|
|
76
|
-
target[offset + DECAL_RECORD_OFFSET_EMISSIVE + 3] = 0;
|
|
77
96
|
|
|
78
97
|
target[offset + DECAL_RECORD_OFFSET_PARAMS] = decal.roughness;
|
|
79
98
|
target[offset + DECAL_RECORD_OFFSET_PARAMS + 1] = decal.metalness;
|
|
80
|
-
|
|
81
|
-
|
|
99
|
+
|
|
100
|
+
target_words[offset + DECAL_RECORD_OFFSET_WEIGHTS] = pack2x16unorm(decal.albedo_weight, decal.normal_weight);
|
|
101
|
+
target_words[offset + DECAL_RECORD_OFFSET_WEIGHTS + 1] = pack2x16unorm(decal.roughness_weight, decal.metalness_weight);
|
|
102
|
+
target_words[offset + DECAL_RECORD_OFFSET_WEIGHT_EMISSIVE] = pack2x16unorm(decal.emissive_weight, 0);
|
|
82
103
|
|
|
83
104
|
target[offset + DECAL_RECORD_OFFSET_LOD] = max_lod.albedo;
|
|
84
105
|
target[offset + DECAL_RECORD_OFFSET_LOD + 1] = max_lod.normal;
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Opaque white: a mask of one everywhere, and a colour that the tint alone decides.
|
|
3
|
+
*
|
|
4
|
+
* @returns {Sampler2D}
|
|
5
|
+
*/
|
|
6
|
+
export function decal_identity_albedo(): Sampler2D;
|
|
1
7
|
/**
|
|
2
8
|
* A flat tangent-space normal: (0, 0, 1) encoded the way a normal map stores it.
|
|
3
9
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decal_material_samplers.d.ts","sourceRoot":"","sources":["../../../../../src/engine/graphics3/decal/decal_material_samplers.js"],"names":[],"mappings":"AAcA;;;;GAIG;AACH,yCAFa,SAAS,CAUrB;AAED;;;;;;;;;;;;;;GAcG;AACH,sCAFa,SAAS,CAWrB;AAED;;;;;;;;;;;;;GAaG;AACH,oCAJW,SAAS,GAAC,IAAI,YACd,SAAS,GAAC,IAAI,GACZ,SAAS,GAAC,IAAI,CAyC1B;
|
|
1
|
+
{"version":3,"file":"decal_material_samplers.d.ts","sourceRoot":"","sources":["../../../../../src/engine/graphics3/decal/decal_material_samplers.js"],"names":[],"mappings":"AAcA;;;;GAIG;AACH,yCAFa,SAAS,CAQrB;AAED;;;;GAIG;AACH,yCAFa,SAAS,CAUrB;AAED;;;;;;;;;;;;;;GAcG;AACH,sCAFa,SAAS,CAWrB;AAED;;;;;;;;;;;;;GAaG;AACH,oCAJW,SAAS,GAAC,IAAI,YACd,SAAS,GAAC,IAAI,GACZ,SAAS,GAAC,IAAI,CAyC1B;0BAxHyB,6CAA6C"}
|
|
@@ -12,6 +12,19 @@ import { Sampler2D } from "../../graphics/texture/sampler/Sampler2D.js";
|
|
|
12
12
|
*/
|
|
13
13
|
const IDENTITY_SIZE = 8;
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Opaque white: a mask of one everywhere, and a colour that the tint alone decides.
|
|
17
|
+
*
|
|
18
|
+
* @returns {Sampler2D}
|
|
19
|
+
*/
|
|
20
|
+
export function decal_identity_albedo() {
|
|
21
|
+
const sampler = Sampler2D.uint8(4, IDENTITY_SIZE, IDENTITY_SIZE);
|
|
22
|
+
|
|
23
|
+
sampler.data.fill(255);
|
|
24
|
+
|
|
25
|
+
return sampler;
|
|
26
|
+
}
|
|
27
|
+
|
|
15
28
|
/**
|
|
16
29
|
* A flat tangent-space normal: (0, 0, 1) encoded the way a normal map stores it.
|
|
17
30
|
*
|
|
@@ -53,7 +53,7 @@ resources.createGroup()
|
|
|
53
53
|
.addUniform("settings", DECAL_CLUSTER_ASSIGNMENT_SETTINGS);
|
|
54
54
|
|
|
55
55
|
resources.createGroup()
|
|
56
|
-
.addStorageBuffer("decal_data", WebGPUArray.
|
|
56
|
+
.addStorageBuffer("decal_data", WebGPUArray.u32);
|
|
57
57
|
|
|
58
58
|
const CLUSTER_DATA_STRUCT = WebGPUStruct.from({
|
|
59
59
|
offset: atomic_u32,
|
|
@@ -34,7 +34,7 @@ resources.createGroup()
|
|
|
34
34
|
.addUniform("settings", SETTINGS_STRUCT);
|
|
35
35
|
|
|
36
36
|
resources.createGroup()
|
|
37
|
-
.addStorageBuffer("decal_data", WebGPUArray.
|
|
37
|
+
.addStorageBuffer("decal_data", WebGPUArray.u32);
|
|
38
38
|
|
|
39
39
|
resources.createGroup()
|
|
40
40
|
.addStorageBuffer("output", OUTPUT_STRUCT, true);
|
|
@@ -9,6 +9,11 @@ export const DECAL_COMPOSITE_SETTINGS: WebGPUStruct;
|
|
|
9
9
|
* `shader_decal_tile_copy`'s copy of the same tiles, so only the covered part of the screen
|
|
10
10
|
* is read and written twice, rather than all of it once.
|
|
11
11
|
*
|
|
12
|
+
* **Each channel blends by the decal's mask times that channel's own weight**, so a decal may write
|
|
13
|
+
* any subset of albedo, normal, roughness, metalness and emission. A channel no decal over a pixel
|
|
14
|
+
* weights comes back with exactly the bits it had, and a decal skips the atlas samples only its
|
|
15
|
+
* unweighted channels would read.
|
|
16
|
+
*
|
|
12
17
|
* The face normal is carried through untouched. A decal changes what a surface looks like, not which
|
|
13
18
|
* way it is turned, and the face normal is what the fade and everything downstream reason about.
|
|
14
19
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shader_decal_composite.d.ts","sourceRoot":"","sources":["../../../../../src/engine/graphics3/decal/shader_decal_composite.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"shader_decal_composite.d.ts","sourceRoot":"","sources":["../../../../../src/engine/graphics3/decal/shader_decal_composite.js"],"names":[],"mappings":"AAkEA,oDAKG;AAyTH;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qCAFU,eAAe,CActB;6BAlX0B,qDAAqD;gCARlD,sBAAsB"}
|
|
@@ -59,7 +59,9 @@ import {
|
|
|
59
59
|
DECAL_RECORD_OFFSET_TRANSFORM_INVERSE,
|
|
60
60
|
DECAL_RECORD_OFFSET_UV_ALBEDO,
|
|
61
61
|
DECAL_RECORD_OFFSET_UV_NORMAL,
|
|
62
|
-
DECAL_RECORD_OFFSET_UV_ORM
|
|
62
|
+
DECAL_RECORD_OFFSET_UV_ORM,
|
|
63
|
+
DECAL_RECORD_OFFSET_WEIGHT_EMISSIVE,
|
|
64
|
+
DECAL_RECORD_OFFSET_WEIGHTS
|
|
63
65
|
} from "./DECAL_GPU_RECORD.js";
|
|
64
66
|
|
|
65
67
|
export const DECAL_COMPOSITE_SETTINGS = WebGPUStruct.from({
|
|
@@ -91,7 +93,7 @@ resources.createGroup()
|
|
|
91
93
|
.addTexture("scene_depth");
|
|
92
94
|
|
|
93
95
|
resources.createGroup()
|
|
94
|
-
.addStorageBuffer("decal_data", WebGPUArray.
|
|
96
|
+
.addStorageBuffer("decal_data", WebGPUArray.u32)
|
|
95
97
|
.addStorageBuffer("cluster_lookup", WebGPUArray.from(DECAL_CLUSTER_METADATA))
|
|
96
98
|
.addStorageBuffer("cluster_data", WebGPUArray.u32)
|
|
97
99
|
.addStorageBuffer("decal_tiles", WebGPUArray.u32);
|
|
@@ -227,6 +229,9 @@ fn main(
|
|
|
227
229
|
var normal = shading_normal;
|
|
228
230
|
var emissive = rgbe9995_decode(old_emissive);
|
|
229
231
|
|
|
232
|
+
var wrote_normal = false;
|
|
233
|
+
var wrote_emissive = false;
|
|
234
|
+
|
|
230
235
|
let uv_bias = view_uv_derivative_bias(view.upscale_ratio);
|
|
231
236
|
|
|
232
237
|
for (var i = 0u; i < metadata.count; i++) {
|
|
@@ -277,50 +282,81 @@ fn main(
|
|
|
277
282
|
// coverage together and the fade scales both at once
|
|
278
283
|
let source = albedo_sample * tint * fade;
|
|
279
284
|
|
|
285
|
+
// the mask: every channel blends by this, scaled by its own weight
|
|
280
286
|
let coverage = source.a;
|
|
281
287
|
|
|
282
288
|
if (coverage <= 0.0) {
|
|
283
289
|
continue;
|
|
284
290
|
}
|
|
285
291
|
|
|
286
|
-
|
|
292
|
+
let weights_albedo_normal = unpack2x16unorm(decal_word(decal_index, ${DECAL_RECORD_OFFSET_WEIGHTS}u));
|
|
293
|
+
let weights_roughness_metalness = unpack2x16unorm(decal_word(decal_index, ${DECAL_RECORD_OFFSET_WEIGHTS + 1}u));
|
|
294
|
+
let weight_emissive = unpack2x16unorm(decal_word(decal_index, ${DECAL_RECORD_OFFSET_WEIGHT_EMISSIVE}u)).x;
|
|
287
295
|
|
|
288
|
-
let
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
);
|
|
296
|
+
let weight_albedo = weights_albedo_normal.x;
|
|
297
|
+
let weight_normal = weights_albedo_normal.y;
|
|
298
|
+
let weight_roughness = weights_roughness_metalness.x;
|
|
299
|
+
let weight_metalness = weights_roughness_metalness.y;
|
|
293
300
|
|
|
294
|
-
|
|
301
|
+
// premultiplied, so the weight scales the colour and the coverage it replaces alike
|
|
302
|
+
albedo = source.rgb * weight_albedo + albedo * (1.0 - coverage * weight_albedo);
|
|
295
303
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
304
|
+
if (weight_roughness > 0.0 || weight_metalness > 0.0 || weight_emissive > 0.0) {
|
|
305
|
+
let orm = textureSampleBarycentric(
|
|
306
|
+
atlas_orm,
|
|
307
|
+
atlas_orm_sampler,
|
|
308
|
+
decal_sampling_info(local_uv, duv_dx, duv_dy, decal_vec4(decal_index, ${DECAL_RECORD_OFFSET_UV_ORM}u), lod.z, atlas_orm_size)
|
|
309
|
+
);
|
|
299
310
|
|
|
300
|
-
|
|
301
|
-
atlas_normal,
|
|
302
|
-
atlas_normal_sampler,
|
|
303
|
-
decal_sampling_info(local_uv, duv_dx, duv_dy, decal_vec4(decal_index, ${DECAL_RECORD_OFFSET_UV_NORMAL}u), lod.y, atlas_normal_size)
|
|
304
|
-
).rgb * 2.0 - 1.0;
|
|
311
|
+
let params = decal_vec2(decal_index, ${DECAL_RECORD_OFFSET_PARAMS}u);
|
|
305
312
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
313
|
+
// glTF packing, whose R channel is ambient occlusion and is deliberately unused
|
|
314
|
+
roughness = mix(roughness, orm.g * params.x, coverage * weight_roughness);
|
|
315
|
+
metalness = mix(metalness, orm.b * params.y, coverage * weight_metalness);
|
|
316
|
+
|
|
317
|
+
if (weight_emissive > 0.0) {
|
|
318
|
+
let emission = decal_vec3(decal_index, ${DECAL_RECORD_OFFSET_EMISSIVE}u) * orm.a;
|
|
319
|
+
|
|
320
|
+
// lerp, not add: a decal is a surface override and occludes whatever was emitting beneath it
|
|
321
|
+
emissive = mix(emissive, emission, coverage * weight_emissive);
|
|
322
|
+
|
|
323
|
+
wrote_emissive = true;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
if (weight_normal > 0.0) {
|
|
328
|
+
let tangent_normal = textureSampleBarycentric(
|
|
329
|
+
atlas_normal,
|
|
330
|
+
atlas_normal_sampler,
|
|
331
|
+
decal_sampling_info(local_uv, duv_dx, duv_dy, decal_vec4(decal_index, ${DECAL_RECORD_OFFSET_UV_NORMAL}u), lod.y, atlas_normal_size)
|
|
332
|
+
).rgb * 2.0 - 1.0;
|
|
311
333
|
|
|
312
|
-
|
|
334
|
+
let decal_normal = normalize(
|
|
335
|
+
tangent_normal.x * frame.tangent
|
|
336
|
+
+ tangent_normal.y * frame.bitangent
|
|
337
|
+
+ tangent_normal.z * frame.normal
|
|
338
|
+
);
|
|
313
339
|
|
|
314
|
-
|
|
340
|
+
normal = normalize(mix(normal, decal_normal, coverage * weight_normal));
|
|
315
341
|
|
|
316
|
-
|
|
317
|
-
|
|
342
|
+
wrote_normal = true;
|
|
343
|
+
}
|
|
318
344
|
}
|
|
319
345
|
|
|
320
346
|
out.albedo = vec4<f32>(albedo, old_albedo.a);
|
|
321
347
|
out.pbr = vec2<f32>(metalness, roughness);
|
|
322
|
-
|
|
323
|
-
|
|
348
|
+
|
|
349
|
+
/*
|
|
350
|
+
The two encoded channels are re-encoded only when a decal wrote them: decoding and encoding
|
|
351
|
+
again is not exact, and a channel no decal weights must come back with the bits it had.
|
|
352
|
+
*/
|
|
353
|
+
if (wrote_normal) {
|
|
354
|
+
out.normal = vec4<u32>(encode_g_buffer_normal(normal), old_normal.zw);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
if (wrote_emissive) {
|
|
358
|
+
out.emissive = rgbe9995_encode(emissive);
|
|
359
|
+
}
|
|
324
360
|
|
|
325
361
|
return out;
|
|
326
362
|
}
|
|
@@ -356,6 +392,11 @@ fn main(
|
|
|
356
392
|
* `shader_decal_tile_copy`'s copy of the same tiles, so only the covered part of the screen
|
|
357
393
|
* is read and written twice, rather than all of it once.
|
|
358
394
|
*
|
|
395
|
+
* **Each channel blends by the decal's mask times that channel's own weight**, so a decal may write
|
|
396
|
+
* any subset of albedo, normal, roughness, metalness and emission. A channel no decal over a pixel
|
|
397
|
+
* weights comes back with exactly the bits it had, and a decal skips the atlas samples only its
|
|
398
|
+
* unweighted channels would read.
|
|
399
|
+
*
|
|
359
400
|
* The face normal is carried through untouched. A decal changes what a surface looks like, not which
|
|
360
401
|
* way it is turned, and the face normal is what the fade and everything downstream reason about.
|
|
361
402
|
*
|
|
@@ -224,6 +224,10 @@ export class SimActionExecutor {
|
|
|
224
224
|
/**
|
|
225
225
|
* Execute an action: capture prior state of affected components, apply, log.
|
|
226
226
|
*
|
|
227
|
+
* Not re-entrant: calling `execute` or {@link record} from inside `affected_components`,
|
|
228
|
+
* {@link authorize}, `apply`, `announce` or {@link on_component_written} is illegal (the
|
|
229
|
+
* executor is passed to actions for `slot_table` / `current_sender_id` reads only).
|
|
230
|
+
*
|
|
227
231
|
* @param {SimAction} action
|
|
228
232
|
* @param {number} [sender_id] peer that originated this action.
|
|
229
233
|
* Defaults to {@link SENDER_LOCAL} for locally-originated actions.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SimActionExecutor.d.ts","sourceRoot":"","sources":["../../../../../src/engine/network/sim/SimActionExecutor.js"],"names":[],"mappings":"AAGA;;;;;;;GAOG;AACH,2BAFU,MAAM,CAEiB;AAEjC;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,6BAFU,MAAM,CAEmB;AAEnC;;;;;;;;;;GAUG;AACH,8BAFU,MAAM,CAEoB;AAEpC;;;;;;;;;;;;GAYG;AACH,+BAFU,MAAM,CAEqB;AAErC;;;;;;GAMG;AACH,0BAFU,MAAM,CAEgB;AAEhC;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH;IA2EI;;;;;;;;;OASG;IACH,sGATW;QACV,KAAS,yBAAyB;QAClC,UAAc,YAAY;QAC1B,eAAmB,oBAAoB;QACvC,kBAAsB,8BAA8B;QACpD,UAAc,uBAAuB;QACrC,gBAAoB,CAAC,mBAAmB;KACrC,EAyFH;IAjKD;;;;;;;;;OASG;IACH,gBAFU,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAEP;IAEtB;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,WAFU,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,WAAW,KAAK,OAAO,CAAC,GAAG,IAAI,CAEtE;IAEjB;;;;;;;;;;;;;;;OAeG;IACH,UAFU,OAAO,CAEA;IAEjB;;;;;;;OAOG;IACH,sBAFU,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,eAAe,UAAU,KAAK,IAAI,CAAC,GAAG,IAAI,CAE7C;IAaxB;;OAEG;IACH,8BAAkB;IAElB;;OAEG;IACH,sBAA4B;IAE5B;;OAEG;IACH,mCAAsC;IAEtC;;OAEG;IACH,gDAA4C;IAE5C;;;;OAIG;IACH,iCAA4B;IAE5B;;;;;;;;;;;OAWG;IACH,kBAFU,mBAAiB,IAAI,CAES;IA4BxC;;;;;;;OAOG;IACH,mBAFU,MAAM,CAEqB;IAErC;;;;;;;OAOG;IACH,kBAFU,MAAM,CAEoB;IAGxC
|
|
1
|
+
{"version":3,"file":"SimActionExecutor.d.ts","sourceRoot":"","sources":["../../../../../src/engine/network/sim/SimActionExecutor.js"],"names":[],"mappings":"AAGA;;;;;;;GAOG;AACH,2BAFU,MAAM,CAEiB;AAEjC;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,6BAFU,MAAM,CAEmB;AAEnC;;;;;;;;;;GAUG;AACH,8BAFU,MAAM,CAEoB;AAEpC;;;;;;;;;;;;GAYG;AACH,+BAFU,MAAM,CAEqB;AAErC;;;;;;GAMG;AACH,0BAFU,MAAM,CAEgB;AAEhC;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH;IA2EI;;;;;;;;;OASG;IACH,sGATW;QACV,KAAS,yBAAyB;QAClC,UAAc,YAAY;QAC1B,eAAmB,oBAAoB;QACvC,kBAAsB,8BAA8B;QACpD,UAAc,uBAAuB;QACrC,gBAAoB,CAAC,mBAAmB;KACrC,EAyFH;IAjKD;;;;;;;;;OASG;IACH,gBAFU,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAEP;IAEtB;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,WAFU,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,WAAW,KAAK,OAAO,CAAC,GAAG,IAAI,CAEtE;IAEjB;;;;;;;;;;;;;;;OAeG;IACH,UAFU,OAAO,CAEA;IAEjB;;;;;;;OAOG;IACH,sBAFU,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,eAAe,UAAU,KAAK,IAAI,CAAC,GAAG,IAAI,CAE7C;IAaxB;;OAEG;IACH,8BAAkB;IAElB;;OAEG;IACH,sBAA4B;IAE5B;;OAEG;IACH,mCAAsC;IAEtC;;OAEG;IACH,gDAA4C;IAE5C;;;;OAIG;IACH,iCAA4B;IAE5B;;;;;;;;;;;OAWG;IACH,kBAFU,mBAAiB,IAAI,CAES;IA4BxC;;;;;;;OAOG;IACH,mBAFU,MAAM,CAEqB;IAErC;;;;;;;OAOG;IACH,kBAFU,MAAM,CAEoB;IAGxC;;;;;;;;;;;;;;OAcG;IACH,uCAPW,MAAM,GAGJ,OAAO,CA0KnB;IAkCD;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,gCAwCC;IAED;;;;;;;;;;;;;OAaG;IACH,4BAFW,MAAM,QAqChB;IAED;;;;;;;;OAQG;IACH,sBAJW,UAAU,UACV,MAAM,UACN,MAAM,QAchB;;CACJ;mBAjnBkB,uCAAuC"}
|
|
@@ -274,6 +274,10 @@ export class SimActionExecutor {
|
|
|
274
274
|
/**
|
|
275
275
|
* Execute an action: capture prior state of affected components, apply, log.
|
|
276
276
|
*
|
|
277
|
+
* Not re-entrant: calling `execute` or {@link record} from inside `affected_components`,
|
|
278
|
+
* {@link authorize}, `apply`, `announce` or {@link on_component_written} is illegal (the
|
|
279
|
+
* executor is passed to actions for `slot_table` / `current_sender_id` reads only).
|
|
280
|
+
*
|
|
277
281
|
* @param {SimAction} action
|
|
278
282
|
* @param {number} [sender_id] peer that originated this action.
|
|
279
283
|
* Defaults to {@link SENDER_LOCAL} for locally-originated actions.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"foliage_atlas_cutout.d.ts","sourceRoot":"","sources":["../../../../../src/generation/foliage/material/foliage_atlas_cutout.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"foliage_atlas_cutout.d.ts","sourceRoot":"","sources":["../../../../../src/generation/foliage/material/foliage_atlas_cutout.js"],"names":[],"mappings":"AAaA;;;;;;;;;;;;GAYG;AACH,mDARW,kBAAkB,WAClB,MAAM,WACN,UAAU,WACV,UAAU,gBACV,MAAM,SACN,MAAM,WACN,MAAM,QAiHhB;AAED;;;;;;;;GAQG;AACH,oDANW,kBAAkB,WAClB,MAAM,SACN,YAAY,SACZ,MAAM,WACN,MAAM,QAkBhB;AAED;;;;;;;;GAQG;AACH,8CAJW,OAAO,gCAAgC,EAAE,iBAAiB,QAC1D,kBAAkB,GAChB,kBAAkB,CAqB9B;mCA3L4D,yBAAyB"}
|