@zephyr3d/scene 0.9.25 → 0.9.27
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/dist/animation/animationset.js +92 -30
- package/dist/animation/animationset.js.map +1 -1
- package/dist/animation/hair/gpu_hair_simulation.js +1090 -0
- package/dist/animation/hair/gpu_hair_simulation.js.map +1 -0
- package/dist/animation/joint_dynamics/controller.js +7 -5
- package/dist/animation/joint_dynamics/controller.js.map +1 -1
- package/dist/animation/joint_dynamics/convex_collider.js +320 -0
- package/dist/animation/joint_dynamics/convex_collider.js.map +1 -0
- package/dist/animation/joint_dynamics/joint_dynamics_system.js +81 -5
- package/dist/animation/joint_dynamics/joint_dynamics_system.js.map +1 -1
- package/dist/animation/morphtrack.js +3 -4
- package/dist/animation/morphtrack.js.map +1 -1
- package/dist/animation/skeleton.js +79 -25
- package/dist/animation/skeleton.js.map +1 -1
- package/dist/animation/spring/multi_chain_spring_system.js +577 -179
- package/dist/animation/spring/multi_chain_spring_system.js.map +1 -1
- package/dist/animation/spring/spring_collider.js +4 -3
- package/dist/animation/spring/spring_collider.js.map +1 -1
- package/dist/animation/spring/spring_node_pose_tracker.js +40 -0
- package/dist/animation/spring/spring_node_pose_tracker.js.map +1 -0
- package/dist/animation/spring/spring_particle.js +2 -0
- package/dist/animation/spring/spring_particle.js.map +1 -1
- package/dist/animation/spring/spring_system.js +11 -3
- package/dist/animation/spring/spring_system.js.map +1 -1
- package/dist/animation/spring_modifier.js +10 -0
- package/dist/animation/spring_modifier.js.map +1 -1
- package/dist/app/engine.js +53 -43
- package/dist/app/engine.js.map +1 -1
- package/dist/app/scriptingsystem.js +119 -6
- package/dist/app/scriptingsystem.js.map +1 -1
- package/dist/app/scriptregistry.js +3 -2
- package/dist/app/scriptregistry.js.map +1 -1
- package/dist/asset/assetmanager.js +284 -67
- package/dist/asset/assetmanager.js.map +1 -1
- package/dist/asset/loaders/zhair/zhair_format.js +288 -0
- package/dist/asset/loaders/zhair/zhair_format.js.map +1 -0
- package/dist/asset/loaders/zhair/zhair_loader.js +221 -0
- package/dist/asset/loaders/zhair/zhair_loader.js.map +1 -0
- package/dist/asset/model.js +184 -69
- package/dist/asset/model.js.map +1 -1
- package/dist/camera/camera.js +268 -44
- package/dist/camera/camera.js.map +1 -1
- package/dist/camera/perspectivecamera.js +3 -1
- package/dist/camera/perspectivecamera.js.map +1 -1
- package/dist/index.d.ts +9044 -5139
- package/dist/index.js +17 -6
- package/dist/index.js.map +1 -1
- package/dist/material/eye.js +932 -0
- package/dist/material/eye.js.map +1 -0
- package/dist/material/hair.js +917 -0
- package/dist/material/hair.js.map +1 -0
- package/dist/material/hairstrand.js +842 -0
- package/dist/material/hairstrand.js.map +1 -0
- package/dist/material/hairstrand_data.js +162 -0
- package/dist/material/hairstrand_data.js.map +1 -0
- package/dist/material/lambert.js +5 -2
- package/dist/material/lambert.js.map +1 -1
- package/dist/material/material.js +48 -10
- package/dist/material/material.js.map +1 -1
- package/dist/material/meshmaterial.js +120 -19
- package/dist/material/meshmaterial.js.map +1 -1
- package/dist/material/mixins/albedocolor.js +1 -1
- package/dist/material/mixins/albedocolor.js.map +1 -1
- package/dist/material/mixins/lightmodel/blinnphong.js +5 -3
- package/dist/material/mixins/lightmodel/blinnphong.js.map +1 -1
- package/dist/material/mixins/lightmodel/lambert.js +5 -4
- package/dist/material/mixins/lightmodel/lambert.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrblueprintmixin.js +3 -3
- package/dist/material/mixins/lightmodel/pbrblueprintmixin.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrmetallicroughness.js +5 -5
- package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrspecularglossness.js +3 -3
- package/dist/material/mixins/lightmodel/pbrspecularglossness.js.map +1 -1
- package/dist/material/mixins/lit.js +106 -19
- package/dist/material/mixins/lit.js.map +1 -1
- package/dist/material/mixins/pbr/common.js +4 -4
- package/dist/material/mixins/pbr/common.js.map +1 -1
- package/dist/material/mixins/texture.js +48 -11
- package/dist/material/mixins/texture.js.map +1 -1
- package/dist/material/mtoon.js +6 -5
- package/dist/material/mtoon.js.map +1 -1
- package/dist/material/pbrblueprint.js +146 -28
- package/dist/material/pbrblueprint.js.map +1 -1
- package/dist/material/pbrblueprint_instance.js +501 -0
- package/dist/material/pbrblueprint_instance.js.map +1 -0
- package/dist/material/pbrmr.js +15 -16
- package/dist/material/pbrmr.js.map +1 -1
- package/dist/material/shader/helper.js +734 -23
- package/dist/material/shader/helper.js.map +1 -1
- package/dist/material/shader/terrain_blend.js +55 -0
- package/dist/material/shader/terrain_blend.js.map +1 -0
- package/dist/material/skin.js +192 -32
- package/dist/material/skin.js.map +1 -1
- package/dist/material/spriteblueprint.js +16 -1
- package/dist/material/spriteblueprint.js.map +1 -1
- package/dist/material/subsurfaceprofile.js +86 -23
- package/dist/material/subsurfaceprofile.js.map +1 -1
- package/dist/material/water.js +2059 -72
- package/dist/material/water.js.map +1 -1
- package/dist/posteffect/bloom.js +167 -7
- package/dist/posteffect/bloom.js.map +1 -1
- package/dist/posteffect/coloradjust.js +2 -1
- package/dist/posteffect/coloradjust.js.map +1 -1
- package/dist/posteffect/compositor.js.map +1 -1
- package/dist/posteffect/fxaa.js +2 -1
- package/dist/posteffect/fxaa.js.map +1 -1
- package/dist/posteffect/grayscale.js +3 -1
- package/dist/posteffect/grayscale.js.map +1 -1
- package/dist/posteffect/motionblur.js +664 -56
- package/dist/posteffect/motionblur.js.map +1 -1
- package/dist/posteffect/posteffect.js +12 -1
- package/dist/posteffect/posteffect.js.map +1 -1
- package/dist/posteffect/sao.js +46 -44
- package/dist/posteffect/sao.js.map +1 -1
- package/dist/posteffect/skinsss.js +368 -69
- package/dist/posteffect/skinsss.js.map +1 -1
- package/dist/posteffect/ssgi.js +16 -9
- package/dist/posteffect/ssgi.js.map +1 -1
- package/dist/posteffect/ssr.js +3 -0
- package/dist/posteffect/ssr.js.map +1 -1
- package/dist/posteffect/sss.js +121 -36
- package/dist/posteffect/sss.js.map +1 -1
- package/dist/posteffect/taa.js.map +1 -1
- package/dist/posteffect/tonemap.js +44 -1
- package/dist/posteffect/tonemap.js.map +1 -1
- package/dist/render/abuffer_oit.js +8 -2
- package/dist/render/abuffer_oit.js.map +1 -1
- package/dist/render/clipmap.js +156 -5
- package/dist/render/clipmap.js.map +1 -1
- package/dist/render/cull_visitor.js +20 -0
- package/dist/render/cull_visitor.js.map +1 -1
- package/dist/render/depthpass.js +36 -2
- package/dist/render/depthpass.js.map +1 -1
- package/dist/render/drawable_mixin.js +26 -1
- package/dist/render/drawable_mixin.js.map +1 -1
- package/dist/render/dualdepthpeeling_oit.js +3 -2
- package/dist/render/dualdepthpeeling_oit.js.map +1 -1
- package/dist/render/envlight.js +1 -1
- package/dist/render/envlight.js.map +1 -1
- package/dist/render/fbm_wavegenerator.js +6 -3
- package/dist/render/fbm_wavegenerator.js.map +1 -1
- package/dist/render/fft_wavegenerator.js +57 -15
- package/dist/render/fft_wavegenerator.js.map +1 -1
- package/dist/render/gerstner_wavegenerator.js +130 -20
- package/dist/render/gerstner_wavegenerator.js.map +1 -1
- package/dist/render/globalbindgroup_allocator.js +3 -0
- package/dist/render/globalbindgroup_allocator.js.map +1 -1
- package/dist/render/hzb.js +80 -22
- package/dist/render/hzb.js.map +1 -1
- package/dist/render/lightpass.js +6 -3
- package/dist/render/lightpass.js.map +1 -1
- package/dist/render/oit.js +29 -0
- package/dist/render/oit.js.map +1 -0
- package/dist/render/render_queue.js +39 -0
- package/dist/render/render_queue.js.map +1 -1
- package/dist/render/renderer.js +4 -0
- package/dist/render/renderer.js.map +1 -1
- package/dist/render/rendergraph/blackboard.js +1 -0
- package/dist/render/rendergraph/blackboard.js.map +1 -1
- package/dist/render/rendergraph/device_pool_allocator.js.map +1 -1
- package/dist/render/rendergraph/executor.js +2 -0
- package/dist/render/rendergraph/executor.js.map +1 -1
- package/dist/render/rendergraph/forward_plus_builder.js +379 -10
- package/dist/render/rendergraph/forward_plus_builder.js.map +1 -1
- package/dist/render/rendergraph/frame_resource_requirements.js +1 -0
- package/dist/render/rendergraph/frame_resource_requirements.js.map +1 -1
- package/dist/render/rendergraph/history_resources.js +8 -1
- package/dist/render/rendergraph/history_resources.js.map +1 -1
- package/dist/render/rendergraph/rendergraph.js.map +1 -1
- package/dist/render/rendergraph/texture_affinity_cache.js +1 -1
- package/dist/render/rendergraph/texture_affinity_cache.js.map +1 -1
- package/dist/render/rendergraph/types.js.map +1 -1
- package/dist/render/shadow_mask_pass.js +73 -8
- package/dist/render/shadow_mask_pass.js.map +1 -1
- package/dist/render/sky.js +166 -126
- package/dist/render/sky.js.map +1 -1
- package/dist/render/underwater.js +624 -0
- package/dist/render/underwater.js.map +1 -0
- package/dist/render/water_caustics.js +1380 -0
- package/dist/render/water_caustics.js.map +1 -0
- package/dist/render/weightedblended_oit.js +3 -2
- package/dist/render/weightedblended_oit.js.map +1 -1
- package/dist/scene/basesprite.js +8 -0
- package/dist/scene/basesprite.js.map +1 -1
- package/dist/scene/batchgroup.js +3 -0
- package/dist/scene/batchgroup.js.map +1 -1
- package/dist/scene/environment.js +4 -1
- package/dist/scene/environment.js.map +1 -1
- package/dist/scene/hair.js +963 -0
- package/dist/scene/hair.js.map +1 -0
- package/dist/scene/light.js +5 -1
- package/dist/scene/light.js.map +1 -1
- package/dist/scene/mesh.js +481 -47
- package/dist/scene/mesh.js.map +1 -1
- package/dist/scene/meshdrawable.js +6 -0
- package/dist/scene/meshdrawable.js.map +1 -1
- package/dist/scene/msdftext.js +3 -0
- package/dist/scene/msdftext.js.map +1 -1
- package/dist/scene/msdftextsprite.js +3 -0
- package/dist/scene/msdftextsprite.js.map +1 -1
- package/dist/scene/particlesys.js +6 -0
- package/dist/scene/particlesys.js.map +1 -1
- package/dist/scene/scene.js +3 -0
- package/dist/scene/scene.js.map +1 -1
- package/dist/scene/scene_node.js +6 -1
- package/dist/scene/scene_node.js.map +1 -1
- package/dist/scene/terrain-cm/grass.js +3 -0
- package/dist/scene/terrain-cm/grass.js.map +1 -1
- package/dist/scene/terrain-cm/grassmaterial.js +3 -0
- package/dist/scene/terrain-cm/grassmaterial.js.map +1 -1
- package/dist/scene/terrain-cm/terrain-cm.js +6 -0
- package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
- package/dist/scene/terrain-cm/texture_cache.js +309 -0
- package/dist/scene/terrain-cm/texture_cache.js.map +1 -0
- package/dist/scene/water.js +546 -4
- package/dist/scene/water.js.map +1 -1
- package/dist/shaders/atmosphere.js.map +1 -1
- package/dist/shaders/diffusion.js +54 -0
- package/dist/shaders/diffusion.js.map +1 -0
- package/dist/shaders/shadow.js +33 -21
- package/dist/shaders/shadow.js.map +1 -1
- package/dist/shaders/temporal.js +71 -33
- package/dist/shaders/temporal.js.map +1 -1
- package/dist/shaders/water.js +22 -19
- package/dist/shaders/water.js.map +1 -1
- package/dist/shaders/water_medium.js +56 -0
- package/dist/shaders/water_medium.js.map +1 -0
- package/dist/shadow/dom.js +546 -0
- package/dist/shadow/dom.js.map +1 -0
- package/dist/shadow/pcf_opt.js +3 -5
- package/dist/shadow/pcf_opt.js.map +1 -1
- package/dist/shadow/pcf_pd.js +1 -1
- package/dist/shadow/pcf_pd.js.map +1 -1
- package/dist/shadow/receiver_bias.js +41 -0
- package/dist/shadow/receiver_bias.js.map +1 -0
- package/dist/shadow/shader.js +20 -60
- package/dist/shadow/shader.js.map +1 -1
- package/dist/shadow/shadow_impl.js +89 -0
- package/dist/shadow/shadow_impl.js.map +1 -1
- package/dist/shadow/shadow_region.js +1 -1
- package/dist/shadow/shadow_region.js.map +1 -1
- package/dist/shadow/shadowmapper.js +150 -37
- package/dist/shadow/shadowmapper.js.map +1 -1
- package/dist/shapes/shape.js +11 -2
- package/dist/shapes/shape.js.map +1 -1
- package/dist/shapes/sphere.js +50 -9
- package/dist/shapes/sphere.js.map +1 -1
- package/dist/utility/blueprint/common/constants.js +112 -2
- package/dist/utility/blueprint/common/constants.js.map +1 -1
- package/dist/utility/blueprint/material/func.js +142 -49
- package/dist/utility/blueprint/material/func.js.map +1 -1
- package/dist/utility/blueprint/material/ir.js +490 -25
- package/dist/utility/blueprint/material/ir.js.map +1 -1
- package/dist/utility/blueprint/material/texture.js +898 -4
- package/dist/utility/blueprint/material/texture.js.map +1 -1
- package/dist/utility/serialization/manager.js +434 -101
- package/dist/utility/serialization/manager.js.map +1 -1
- package/dist/utility/serialization/scene/animation.js +401 -5
- package/dist/utility/serialization/scene/animation.js.map +1 -1
- package/dist/utility/serialization/scene/batch.js +4 -0
- package/dist/utility/serialization/scene/batch.js.map +1 -1
- package/dist/utility/serialization/scene/camera.js +186 -26
- package/dist/utility/serialization/scene/camera.js.map +1 -1
- package/dist/utility/serialization/scene/common.js +26 -5
- package/dist/utility/serialization/scene/common.js.map +1 -1
- package/dist/utility/serialization/scene/hair.js +1141 -0
- package/dist/utility/serialization/scene/hair.js.map +1 -0
- package/dist/utility/serialization/scene/light.js +84 -4
- package/dist/utility/serialization/scene/light.js.map +1 -1
- package/dist/utility/serialization/scene/material.js +1867 -166
- package/dist/utility/serialization/scene/material.js.map +1 -1
- package/dist/utility/serialization/scene/mesh.js +231 -14
- package/dist/utility/serialization/scene/mesh.js.map +1 -1
- package/dist/utility/serialization/scene/node.js +141 -7
- package/dist/utility/serialization/scene/node.js.map +1 -1
- package/dist/utility/serialization/scene/particle.js +4 -0
- package/dist/utility/serialization/scene/particle.js.map +1 -1
- package/dist/utility/serialization/scene/primitive.js +18 -0
- package/dist/utility/serialization/scene/primitive.js.map +1 -1
- package/dist/utility/serialization/scene/sprite.js +4 -0
- package/dist/utility/serialization/scene/sprite.js.map +1 -1
- package/dist/utility/serialization/scene/terrain.js +4 -0
- package/dist/utility/serialization/scene/terrain.js.map +1 -1
- package/dist/utility/serialization/scene/text.js +4 -0
- package/dist/utility/serialization/scene/text.js.map +1 -1
- package/dist/utility/serialization/scene/water.js +1105 -21
- package/dist/utility/serialization/scene/water.js.map +1 -1
- package/dist/utility/serialization/types.js.map +1 -1
- package/dist/utility/shprojector.js +9 -8
- package/dist/utility/shprojector.js.map +1 -1
- package/dist/values.js +49 -2
- package/dist/values.js.map +1 -1
- package/package.json +3 -3
- package/dist/render/rendergraph/frame_graph_context.js +0 -41
- package/dist/render/rendergraph/frame_graph_context.js.map +0 -1
- package/dist/shaders/ssgi.js +0 -63
- package/dist/shaders/ssgi.js.map +0 -1
- package/dist/shaders/ssgi_reprojection.js +0 -118
- package/dist/shaders/ssgi_reprojection.js.map +0 -1
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
import { DRef } from '@zephyr3d/base';
|
|
2
|
+
import { Primitive } from '../../render/primitive.js';
|
|
3
|
+
import { fetchSampler } from '../../utility/misc.js';
|
|
4
|
+
import { getDevice } from '../../app/api.js';
|
|
5
|
+
import { sampleTerrainSplatMasks, accumulateTerrainLayers } from '../../material/shader/terrain_blend.js';
|
|
6
|
+
|
|
7
|
+
// Window minimum used to mark a fine level that has not been baked yet. Any
|
|
8
|
+
// terrain uv minus this becomes hugely negative, so the shader coverage test
|
|
9
|
+
// always rejects the level.
|
|
10
|
+
const INVALID_WINDOW = 9999;
|
|
11
|
+
// A level window is snapped to multiples of its extent divided by this value,
|
|
12
|
+
// so the level is re-baked after the camera moves 1/8 of the window size.
|
|
13
|
+
const WINDOW_SNAP_STEPS = 8;
|
|
14
|
+
/**
|
|
15
|
+
* Bakes the terrain detail blending result (albedo, tangent-space normal and
|
|
16
|
+
* roughness) into cache textures so the per-pixel shading cost no longer
|
|
17
|
+
* depends on the number of detail layers.
|
|
18
|
+
*
|
|
19
|
+
* Layout:
|
|
20
|
+
* - A static cache covering the whole terrain region (mipmapped) acts as the
|
|
21
|
+
* coarsest level and the far-field fallback.
|
|
22
|
+
* - Optional camera-centered fine levels stored as array layers (no mips).
|
|
23
|
+
* Fine level i covers `0.5^(fineLevels-i)` of the region per axis, so each
|
|
24
|
+
* finer level doubles the texel density. Windows snap to a fraction of
|
|
25
|
+
* their extent and are re-baked when the camera crosses the snap grid.
|
|
26
|
+
*
|
|
27
|
+
* At most one bake (static or a single fine level) is issued per update call
|
|
28
|
+
* to keep the per-frame cost bounded and to avoid same-frame uniform aliasing
|
|
29
|
+
* on the shared bind group.
|
|
30
|
+
*
|
|
31
|
+
* Requires MRT and array textures, so WebGL1 is not supported and the terrain
|
|
32
|
+
* silently keeps its live shading path there.
|
|
33
|
+
*
|
|
34
|
+
* @public
|
|
35
|
+
*/ class TerrainTextureCache {
|
|
36
|
+
static _programs = new Map();
|
|
37
|
+
static _quad = null;
|
|
38
|
+
static _renderStates = null;
|
|
39
|
+
_staticSize;
|
|
40
|
+
_levelSize;
|
|
41
|
+
_fineLevels;
|
|
42
|
+
_albedoTexture;
|
|
43
|
+
_normalTexture;
|
|
44
|
+
_levelAlbedoTexture;
|
|
45
|
+
_levelNormalTexture;
|
|
46
|
+
_levelWindows;
|
|
47
|
+
_staticFramebuffer;
|
|
48
|
+
_levelFramebuffer;
|
|
49
|
+
_bindGroup;
|
|
50
|
+
_bindGroupLayerCount;
|
|
51
|
+
_staticBaked;
|
|
52
|
+
constructor(staticSize = 2048, levelSize = 1024, fineLevels = 3){
|
|
53
|
+
this._staticSize = staticSize;
|
|
54
|
+
this._levelSize = levelSize;
|
|
55
|
+
this._fineLevels = Math.max(0, fineLevels);
|
|
56
|
+
this._albedoTexture = new DRef();
|
|
57
|
+
this._normalTexture = new DRef();
|
|
58
|
+
this._levelAlbedoTexture = new DRef();
|
|
59
|
+
this._levelNormalTexture = new DRef();
|
|
60
|
+
this._levelWindows = new Float32Array(Math.max(1, this._fineLevels) * 4);
|
|
61
|
+
this._staticFramebuffer = null;
|
|
62
|
+
this._levelFramebuffer = null;
|
|
63
|
+
this._bindGroup = null;
|
|
64
|
+
this._bindGroupLayerCount = 0;
|
|
65
|
+
this._staticBaked = false;
|
|
66
|
+
this.resetWindows();
|
|
67
|
+
}
|
|
68
|
+
/** Static cache texture resolution */ get staticSize() {
|
|
69
|
+
return this._staticSize;
|
|
70
|
+
}
|
|
71
|
+
/** Fine level texture resolution */ get levelSize() {
|
|
72
|
+
return this._levelSize;
|
|
73
|
+
}
|
|
74
|
+
/** Number of camera-centered fine levels */ get fineLevels() {
|
|
75
|
+
return this._fineLevels;
|
|
76
|
+
}
|
|
77
|
+
/** Baked whole-region albedo texture (rgb: blended albedo) */ get albedoTexture() {
|
|
78
|
+
return this._albedoTexture.get();
|
|
79
|
+
}
|
|
80
|
+
/** Baked whole-region normal texture (rg: tangent-space normal xy packed, b: blended roughness) */ get normalTexture() {
|
|
81
|
+
return this._normalTexture.get();
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Texture bindings for {@link ClipmapTerrainMaterial.setTextureCache}, or
|
|
85
|
+
* null while the static cache has not been baked yet.
|
|
86
|
+
* @internal
|
|
87
|
+
*/ get binding() {
|
|
88
|
+
const albedo = this._albedoTexture.get();
|
|
89
|
+
const normal = this._normalTexture.get();
|
|
90
|
+
if (!this._staticBaked || !albedo || !normal) {
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
return {
|
|
94
|
+
albedoTexture: albedo,
|
|
95
|
+
normalTexture: normal,
|
|
96
|
+
levelAlbedoTexture: this._levelAlbedoTexture.get(),
|
|
97
|
+
levelNormalTexture: this._levelNormalTexture.get(),
|
|
98
|
+
levelWindows: this._levelWindows,
|
|
99
|
+
fineLevels: this._fineLevels
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Invalidates all baked content (static and fine levels) so it gets re-baked
|
|
104
|
+
* over the next frames.
|
|
105
|
+
*/ invalidate() {
|
|
106
|
+
this._staticBaked = false;
|
|
107
|
+
this.resetWindows();
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Bakes at most one outstanding target: the static cache first, then the
|
|
111
|
+
* coarsest outdated fine level. Fine level windows follow `cameraUV`, the
|
|
112
|
+
* camera position in normalized terrain region space.
|
|
113
|
+
*
|
|
114
|
+
* @returns true if the cache is usable (static level baked)
|
|
115
|
+
*/ update(material, cameraUV) {
|
|
116
|
+
const device = getDevice();
|
|
117
|
+
if (device.type === 'webgl') {
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
if (material.numDetailMaps === 0 || !material.getSplatMap() || !material.detailAlbedoArray) {
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
if (!this._staticBaked) {
|
|
124
|
+
if (this.bake(device, material, -1, 0, 0, 1, 1)) {
|
|
125
|
+
this._staticBaked = true;
|
|
126
|
+
}
|
|
127
|
+
return this._staticBaked;
|
|
128
|
+
}
|
|
129
|
+
for(let i = this._fineLevels - 1; i >= 0; i--){
|
|
130
|
+
const sizeUV = Math.pow(0.5, this._fineLevels - i);
|
|
131
|
+
const snap = sizeUV / WINDOW_SNAP_STEPS;
|
|
132
|
+
const minU = clampWindow(Math.round((cameraUV.x - sizeUV * 0.5) / snap) * snap, sizeUV);
|
|
133
|
+
const minV = clampWindow(Math.round((cameraUV.y - sizeUV * 0.5) / snap) * snap, sizeUV);
|
|
134
|
+
if (this._levelWindows[i * 4] !== minU || this._levelWindows[i * 4 + 1] !== minV) {
|
|
135
|
+
if (this.bake(device, material, i, minU, minV, sizeUV, sizeUV)) {
|
|
136
|
+
this._levelWindows[i * 4] = minU;
|
|
137
|
+
this._levelWindows[i * 4 + 1] = minV;
|
|
138
|
+
this._levelWindows[i * 4 + 2] = 1 / sizeUV;
|
|
139
|
+
this._levelWindows[i * 4 + 3] = 1 / sizeUV;
|
|
140
|
+
}
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return true;
|
|
145
|
+
}
|
|
146
|
+
dispose() {
|
|
147
|
+
this._staticFramebuffer?.dispose();
|
|
148
|
+
this._staticFramebuffer = null;
|
|
149
|
+
this._levelFramebuffer?.dispose();
|
|
150
|
+
this._levelFramebuffer = null;
|
|
151
|
+
this._albedoTexture.dispose();
|
|
152
|
+
this._normalTexture.dispose();
|
|
153
|
+
this._levelAlbedoTexture.dispose();
|
|
154
|
+
this._levelNormalTexture.dispose();
|
|
155
|
+
this._bindGroup = null;
|
|
156
|
+
this._staticBaked = false;
|
|
157
|
+
this.resetWindows();
|
|
158
|
+
}
|
|
159
|
+
resetWindows() {
|
|
160
|
+
for(let i = 0; i < this._levelWindows.length; i += 4){
|
|
161
|
+
this._levelWindows[i] = INVALID_WINDOW;
|
|
162
|
+
this._levelWindows[i + 1] = INVALID_WINDOW;
|
|
163
|
+
this._levelWindows[i + 2] = 1;
|
|
164
|
+
this._levelWindows[i + 3] = 1;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Renders the blend of all detail layers over the given sub-window of the
|
|
169
|
+
* terrain region into the requested target.
|
|
170
|
+
*
|
|
171
|
+
* @param level - Fine level index, or -1 for the static whole-region cache
|
|
172
|
+
*/ bake(device, material, level, minU, minV, sizeU, sizeV) {
|
|
173
|
+
const numDetailMaps = material.numDetailMaps;
|
|
174
|
+
const splatMap = material.getSplatMap();
|
|
175
|
+
const albedoArray = material.detailAlbedoArray;
|
|
176
|
+
const normalArray = material.detailNormalArray;
|
|
177
|
+
if (numDetailMaps === 0 || !splatMap || !albedoArray || !normalArray) {
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
180
|
+
this.ensureResources(device);
|
|
181
|
+
const program = TerrainTextureCache.getProgram(device, numDetailMaps);
|
|
182
|
+
if (!this._bindGroup || this._bindGroupLayerCount !== numDetailMaps) {
|
|
183
|
+
this._bindGroup = device.createBindGroup(program.bindGroupLayouts[0]);
|
|
184
|
+
this._bindGroupLayerCount = numDetailMaps;
|
|
185
|
+
}
|
|
186
|
+
const bindGroup = this._bindGroup;
|
|
187
|
+
bindGroup.setTexture('splatMap', splatMap);
|
|
188
|
+
bindGroup.setTexture('detailAlbedoMap', albedoArray, fetchSampler('repeat_linear'));
|
|
189
|
+
bindGroup.setTexture('detailNormalMap', normalArray, fetchSampler('repeat_linear'));
|
|
190
|
+
bindGroup.setValue('detailParams', material.detailMapParams);
|
|
191
|
+
bindGroup.setValue('bakeWindow', new Float32Array([
|
|
192
|
+
minU,
|
|
193
|
+
minV,
|
|
194
|
+
sizeU,
|
|
195
|
+
sizeV
|
|
196
|
+
]));
|
|
197
|
+
let framebuffer;
|
|
198
|
+
if (level < 0) {
|
|
199
|
+
framebuffer = this._staticFramebuffer;
|
|
200
|
+
} else {
|
|
201
|
+
framebuffer = this._levelFramebuffer;
|
|
202
|
+
framebuffer.setColorAttachmentLayer(0, level);
|
|
203
|
+
framebuffer.setColorAttachmentLayer(1, level);
|
|
204
|
+
}
|
|
205
|
+
device.pushDeviceStates();
|
|
206
|
+
device.setFramebuffer(framebuffer);
|
|
207
|
+
device.setProgram(program);
|
|
208
|
+
device.setBindGroup(0, bindGroup);
|
|
209
|
+
device.setRenderStates(TerrainTextureCache._renderStates);
|
|
210
|
+
TerrainTextureCache._quad.draw();
|
|
211
|
+
device.popDeviceStates();
|
|
212
|
+
if (level < 0) {
|
|
213
|
+
// fine levels are sampled with explicit lod 0 and need no mip chain;
|
|
214
|
+
// the static level is the far-field fallback and does need one
|
|
215
|
+
this._albedoTexture.get().generateMipmaps();
|
|
216
|
+
this._normalTexture.get().generateMipmaps();
|
|
217
|
+
}
|
|
218
|
+
return true;
|
|
219
|
+
}
|
|
220
|
+
ensureResources(device) {
|
|
221
|
+
if (!this._albedoTexture.get()) {
|
|
222
|
+
this._albedoTexture.set(device.createTexture2D('rgba8unorm', this._staticSize, this._staticSize));
|
|
223
|
+
this._normalTexture.set(device.createTexture2D('rgba8unorm', this._staticSize, this._staticSize));
|
|
224
|
+
this._staticFramebuffer = device.createFrameBuffer([
|
|
225
|
+
this._albedoTexture.get(),
|
|
226
|
+
this._normalTexture.get()
|
|
227
|
+
], null);
|
|
228
|
+
}
|
|
229
|
+
if (this._fineLevels > 0 && !this._levelAlbedoTexture.get()) {
|
|
230
|
+
this._levelAlbedoTexture.set(device.createTexture2DArray('rgba8unorm', this._levelSize, this._levelSize, this._fineLevels, {
|
|
231
|
+
mipmapping: false
|
|
232
|
+
}));
|
|
233
|
+
this._levelNormalTexture.set(device.createTexture2DArray('rgba8unorm', this._levelSize, this._levelSize, this._fineLevels, {
|
|
234
|
+
mipmapping: false
|
|
235
|
+
}));
|
|
236
|
+
this._levelFramebuffer = device.createFrameBuffer([
|
|
237
|
+
this._levelAlbedoTexture.get(),
|
|
238
|
+
this._levelNormalTexture.get()
|
|
239
|
+
], null);
|
|
240
|
+
}
|
|
241
|
+
if (!TerrainTextureCache._quad) {
|
|
242
|
+
const quad = new Primitive();
|
|
243
|
+
quad.createAndSetVertexBuffer('position_f32', new Float32Array([
|
|
244
|
+
0,
|
|
245
|
+
1,
|
|
246
|
+
2,
|
|
247
|
+
3
|
|
248
|
+
]));
|
|
249
|
+
quad.indexCount = 4;
|
|
250
|
+
quad.indexStart = 0;
|
|
251
|
+
quad.primitiveType = 'triangle-strip';
|
|
252
|
+
TerrainTextureCache._quad = quad;
|
|
253
|
+
}
|
|
254
|
+
if (!TerrainTextureCache._renderStates) {
|
|
255
|
+
const renderStates = device.createRenderStateSet();
|
|
256
|
+
renderStates.useDepthState().enableTest(false).enableWrite(false);
|
|
257
|
+
renderStates.useRasterizerState().setCullMode('none');
|
|
258
|
+
TerrainTextureCache._renderStates = renderStates;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
static getProgram(device, numDetailMaps) {
|
|
262
|
+
let program = TerrainTextureCache._programs.get(numDetailMaps);
|
|
263
|
+
if (!program) {
|
|
264
|
+
program = device.buildRenderProgram({
|
|
265
|
+
vertex (pb) {
|
|
266
|
+
this.bakeWindow = pb.vec4().uniform(0);
|
|
267
|
+
this.$inputs.position = pb.float().attrib('position');
|
|
268
|
+
this.axis = [
|
|
269
|
+
pb.vec2(-1, -1),
|
|
270
|
+
pb.vec2(1, -1),
|
|
271
|
+
pb.vec2(-1, 1),
|
|
272
|
+
pb.vec2(1, 1)
|
|
273
|
+
];
|
|
274
|
+
pb.main(function() {
|
|
275
|
+
this.$l.vertexAxis = this.axis.at(this.$builtins.vertexIndex);
|
|
276
|
+
this.$l.quadUV = pb.add(pb.mul(this.vertexAxis, 0.5), pb.vec2(0.5));
|
|
277
|
+
this.$outputs.uv = pb.add(this.bakeWindow.xy, pb.mul(this.quadUV, this.bakeWindow.zw));
|
|
278
|
+
this.$builtins.position = pb.getDevice().type === 'webgpu' ? pb.vec4(this.vertexAxis.x, pb.neg(this.vertexAxis.y), 0, 1) : pb.vec4(this.vertexAxis.x, this.vertexAxis.y, 0, 1);
|
|
279
|
+
});
|
|
280
|
+
},
|
|
281
|
+
fragment (pb) {
|
|
282
|
+
this.splatMap = pb.tex2DArray().uniform(0);
|
|
283
|
+
this.detailAlbedoMap = pb.tex2DArray().uniform(0);
|
|
284
|
+
this.detailNormalMap = pb.tex2DArray().uniform(0);
|
|
285
|
+
this.detailParams = pb.vec4[numDetailMaps]().uniform(0);
|
|
286
|
+
this.$outputs.outAlbedo = pb.vec4();
|
|
287
|
+
this.$outputs.outNormal = pb.vec4();
|
|
288
|
+
pb.main(function() {
|
|
289
|
+
const masks = sampleTerrainSplatMasks(this, this.splatMap, this.$inputs.uv, numDetailMaps, false);
|
|
290
|
+
this.$l.albedo = accumulateTerrainLayers(this, 'albedoAccum', pb.vec3(0), numDetailMaps, this.$inputs.uv, masks, (i)=>this.detailParams[i].x, (scope, i, uv)=>pb.textureArraySample(scope.detailAlbedoMap, uv, i).rgb);
|
|
291
|
+
this.$l.detailNormal = accumulateTerrainLayers(this, 'normalAccum', pb.vec3(0), numDetailMaps, this.$inputs.uv, masks, (i)=>this.detailParams[i].x, (scope, i, uv)=>pb.normalize(pb.sub(pb.mul(pb.textureArraySample(scope.detailNormalMap, uv, i).rgb, 2), pb.vec3(1))));
|
|
292
|
+
this.$l.roughness = accumulateTerrainLayers(this, 'roughnessAccum', pb.float(0), numDetailMaps, this.$inputs.uv, masks, null, (scope, i)=>scope.detailParams[i].y);
|
|
293
|
+
this.$l.packedNormal = pb.normalize(this.detailNormal);
|
|
294
|
+
this.$outputs.outAlbedo = pb.vec4(this.albedo, 1);
|
|
295
|
+
this.$outputs.outNormal = pb.vec4(pb.add(pb.mul(this.packedNormal.xy, 0.5), pb.vec2(0.5)), this.roughness, 1);
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
});
|
|
299
|
+
TerrainTextureCache._programs.set(numDetailMaps, program);
|
|
300
|
+
}
|
|
301
|
+
return program;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
function clampWindow(minUV, sizeUV) {
|
|
305
|
+
return Math.min(Math.max(minUV, 0), 1 - sizeUV);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
export { TerrainTextureCache };
|
|
309
|
+
//# sourceMappingURL=texture_cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"texture_cache.js","sources":["../../../src/scene/terrain-cm/texture_cache.ts"],"sourcesContent":["import type { Nullable } from '@zephyr3d/base';\r\nimport { DRef } from '@zephyr3d/base';\r\nimport type {\r\n AbstractDevice,\r\n BindGroup,\r\n FrameBuffer,\r\n GPUProgram,\r\n RenderStateSet,\r\n Texture2D,\r\n Texture2DArray\r\n} from '@zephyr3d/device';\r\nimport { Primitive } from '../../render/primitive';\r\nimport { fetchSampler } from '../../utility/misc';\r\nimport { getDevice } from '../../app/api';\r\nimport type { ClipmapTerrainMaterial, TerrainTextureCacheBinding } from '../../material/terrain-cm';\r\nimport { accumulateTerrainLayers, sampleTerrainSplatMasks } from '../../material/shader/terrain_blend';\r\n\r\n// Window minimum used to mark a fine level that has not been baked yet. Any\r\n// terrain uv minus this becomes hugely negative, so the shader coverage test\r\n// always rejects the level.\r\nconst INVALID_WINDOW = 9999;\r\n// A level window is snapped to multiples of its extent divided by this value,\r\n// so the level is re-baked after the camera moves 1/8 of the window size.\r\nconst WINDOW_SNAP_STEPS = 8;\r\n\r\n/**\r\n * Bakes the terrain detail blending result (albedo, tangent-space normal and\r\n * roughness) into cache textures so the per-pixel shading cost no longer\r\n * depends on the number of detail layers.\r\n *\r\n * Layout:\r\n * - A static cache covering the whole terrain region (mipmapped) acts as the\r\n * coarsest level and the far-field fallback.\r\n * - Optional camera-centered fine levels stored as array layers (no mips).\r\n * Fine level i covers `0.5^(fineLevels-i)` of the region per axis, so each\r\n * finer level doubles the texel density. Windows snap to a fraction of\r\n * their extent and are re-baked when the camera crosses the snap grid.\r\n *\r\n * At most one bake (static or a single fine level) is issued per update call\r\n * to keep the per-frame cost bounded and to avoid same-frame uniform aliasing\r\n * on the shared bind group.\r\n *\r\n * Requires MRT and array textures, so WebGL1 is not supported and the terrain\r\n * silently keeps its live shading path there.\r\n *\r\n * @public\r\n */\r\nexport class TerrainTextureCache {\r\n private static readonly _programs: Map<number, GPUProgram> = new Map();\r\n private static _quad: Nullable<Primitive> = null;\r\n private static _renderStates: Nullable<RenderStateSet> = null;\r\n private readonly _staticSize: number;\r\n private readonly _levelSize: number;\r\n private readonly _fineLevels: number;\r\n private readonly _albedoTexture: DRef<Texture2D>;\r\n private readonly _normalTexture: DRef<Texture2D>;\r\n private readonly _levelAlbedoTexture: DRef<Texture2DArray>;\r\n private readonly _levelNormalTexture: DRef<Texture2DArray>;\r\n private readonly _levelWindows: Float32Array<ArrayBuffer>;\r\n private _staticFramebuffer: Nullable<FrameBuffer>;\r\n private _levelFramebuffer: Nullable<FrameBuffer>;\r\n private _bindGroup: Nullable<BindGroup>;\r\n private _bindGroupLayerCount: number;\r\n private _staticBaked: boolean;\r\n constructor(staticSize = 2048, levelSize = 1024, fineLevels = 3) {\r\n this._staticSize = staticSize;\r\n this._levelSize = levelSize;\r\n this._fineLevels = Math.max(0, fineLevels);\r\n this._albedoTexture = new DRef();\r\n this._normalTexture = new DRef();\r\n this._levelAlbedoTexture = new DRef();\r\n this._levelNormalTexture = new DRef();\r\n this._levelWindows = new Float32Array(Math.max(1, this._fineLevels) * 4);\r\n this._staticFramebuffer = null;\r\n this._levelFramebuffer = null;\r\n this._bindGroup = null;\r\n this._bindGroupLayerCount = 0;\r\n this._staticBaked = false;\r\n this.resetWindows();\r\n }\r\n /** Static cache texture resolution */\r\n get staticSize() {\r\n return this._staticSize;\r\n }\r\n /** Fine level texture resolution */\r\n get levelSize() {\r\n return this._levelSize;\r\n }\r\n /** Number of camera-centered fine levels */\r\n get fineLevels() {\r\n return this._fineLevels;\r\n }\r\n /** Baked whole-region albedo texture (rgb: blended albedo) */\r\n get albedoTexture() {\r\n return this._albedoTexture.get();\r\n }\r\n /** Baked whole-region normal texture (rg: tangent-space normal xy packed, b: blended roughness) */\r\n get normalTexture() {\r\n return this._normalTexture.get();\r\n }\r\n /**\r\n * Texture bindings for {@link ClipmapTerrainMaterial.setTextureCache}, or\r\n * null while the static cache has not been baked yet.\r\n * @internal\r\n */\r\n get binding(): Nullable<TerrainTextureCacheBinding> {\r\n const albedo = this._albedoTexture.get();\r\n const normal = this._normalTexture.get();\r\n if (!this._staticBaked || !albedo || !normal) {\r\n return null;\r\n }\r\n return {\r\n albedoTexture: albedo,\r\n normalTexture: normal,\r\n levelAlbedoTexture: this._levelAlbedoTexture.get(),\r\n levelNormalTexture: this._levelNormalTexture.get(),\r\n levelWindows: this._levelWindows,\r\n fineLevels: this._fineLevels\r\n };\r\n }\r\n /**\r\n * Invalidates all baked content (static and fine levels) so it gets re-baked\r\n * over the next frames.\r\n */\r\n invalidate() {\r\n this._staticBaked = false;\r\n this.resetWindows();\r\n }\r\n /**\r\n * Bakes at most one outstanding target: the static cache first, then the\r\n * coarsest outdated fine level. Fine level windows follow `cameraUV`, the\r\n * camera position in normalized terrain region space.\r\n *\r\n * @returns true if the cache is usable (static level baked)\r\n */\r\n update(material: ClipmapTerrainMaterial, cameraUV: { x: number; y: number }) {\r\n const device = getDevice();\r\n if (device.type === 'webgl') {\r\n return false;\r\n }\r\n if (material.numDetailMaps === 0 || !material.getSplatMap() || !material.detailAlbedoArray) {\r\n return false;\r\n }\r\n if (!this._staticBaked) {\r\n if (this.bake(device, material, -1, 0, 0, 1, 1)) {\r\n this._staticBaked = true;\r\n }\r\n return this._staticBaked;\r\n }\r\n for (let i = this._fineLevels - 1; i >= 0; i--) {\r\n const sizeUV = Math.pow(0.5, this._fineLevels - i);\r\n const snap = sizeUV / WINDOW_SNAP_STEPS;\r\n const minU = clampWindow(Math.round((cameraUV.x - sizeUV * 0.5) / snap) * snap, sizeUV);\r\n const minV = clampWindow(Math.round((cameraUV.y - sizeUV * 0.5) / snap) * snap, sizeUV);\r\n if (this._levelWindows[i * 4] !== minU || this._levelWindows[i * 4 + 1] !== minV) {\r\n if (this.bake(device, material, i, minU, minV, sizeUV, sizeUV)) {\r\n this._levelWindows[i * 4] = minU;\r\n this._levelWindows[i * 4 + 1] = minV;\r\n this._levelWindows[i * 4 + 2] = 1 / sizeUV;\r\n this._levelWindows[i * 4 + 3] = 1 / sizeUV;\r\n }\r\n break;\r\n }\r\n }\r\n return true;\r\n }\r\n dispose() {\r\n this._staticFramebuffer?.dispose();\r\n this._staticFramebuffer = null;\r\n this._levelFramebuffer?.dispose();\r\n this._levelFramebuffer = null;\r\n this._albedoTexture.dispose();\r\n this._normalTexture.dispose();\r\n this._levelAlbedoTexture.dispose();\r\n this._levelNormalTexture.dispose();\r\n this._bindGroup = null;\r\n this._staticBaked = false;\r\n this.resetWindows();\r\n }\r\n private resetWindows() {\r\n for (let i = 0; i < this._levelWindows.length; i += 4) {\r\n this._levelWindows[i] = INVALID_WINDOW;\r\n this._levelWindows[i + 1] = INVALID_WINDOW;\r\n this._levelWindows[i + 2] = 1;\r\n this._levelWindows[i + 3] = 1;\r\n }\r\n }\r\n /**\r\n * Renders the blend of all detail layers over the given sub-window of the\r\n * terrain region into the requested target.\r\n *\r\n * @param level - Fine level index, or -1 for the static whole-region cache\r\n */\r\n private bake(\r\n device: AbstractDevice,\r\n material: ClipmapTerrainMaterial,\r\n level: number,\r\n minU: number,\r\n minV: number,\r\n sizeU: number,\r\n sizeV: number\r\n ) {\r\n const numDetailMaps = material.numDetailMaps;\r\n const splatMap = material.getSplatMap();\r\n const albedoArray = material.detailAlbedoArray;\r\n const normalArray = material.detailNormalArray;\r\n if (numDetailMaps === 0 || !splatMap || !albedoArray || !normalArray) {\r\n return false;\r\n }\r\n this.ensureResources(device);\r\n const program = TerrainTextureCache.getProgram(device, numDetailMaps);\r\n if (!this._bindGroup || this._bindGroupLayerCount !== numDetailMaps) {\r\n this._bindGroup = device.createBindGroup(program.bindGroupLayouts[0]);\r\n this._bindGroupLayerCount = numDetailMaps;\r\n }\r\n const bindGroup = this._bindGroup!;\r\n bindGroup.setTexture('splatMap', splatMap);\r\n bindGroup.setTexture('detailAlbedoMap', albedoArray, fetchSampler('repeat_linear'));\r\n bindGroup.setTexture('detailNormalMap', normalArray, fetchSampler('repeat_linear'));\r\n bindGroup.setValue('detailParams', material.detailMapParams);\r\n bindGroup.setValue('bakeWindow', new Float32Array([minU, minV, sizeU, sizeV]));\r\n let framebuffer: FrameBuffer;\r\n if (level < 0) {\r\n framebuffer = this._staticFramebuffer!;\r\n } else {\r\n framebuffer = this._levelFramebuffer!;\r\n framebuffer.setColorAttachmentLayer(0, level);\r\n framebuffer.setColorAttachmentLayer(1, level);\r\n }\r\n device.pushDeviceStates();\r\n device.setFramebuffer(framebuffer);\r\n device.setProgram(program);\r\n device.setBindGroup(0, bindGroup);\r\n device.setRenderStates(TerrainTextureCache._renderStates!);\r\n TerrainTextureCache._quad!.draw();\r\n device.popDeviceStates();\r\n if (level < 0) {\r\n // fine levels are sampled with explicit lod 0 and need no mip chain;\r\n // the static level is the far-field fallback and does need one\r\n this._albedoTexture.get()!.generateMipmaps();\r\n this._normalTexture.get()!.generateMipmaps();\r\n }\r\n return true;\r\n }\r\n private ensureResources(device: AbstractDevice) {\r\n if (!this._albedoTexture.get()) {\r\n this._albedoTexture.set(device.createTexture2D('rgba8unorm', this._staticSize, this._staticSize));\r\n this._normalTexture.set(device.createTexture2D('rgba8unorm', this._staticSize, this._staticSize));\r\n this._staticFramebuffer = device.createFrameBuffer(\r\n [this._albedoTexture.get()!, this._normalTexture.get()!],\r\n null\r\n );\r\n }\r\n if (this._fineLevels > 0 && !this._levelAlbedoTexture.get()) {\r\n this._levelAlbedoTexture.set(\r\n device.createTexture2DArray('rgba8unorm', this._levelSize, this._levelSize, this._fineLevels, {\r\n mipmapping: false\r\n })\r\n );\r\n this._levelNormalTexture.set(\r\n device.createTexture2DArray('rgba8unorm', this._levelSize, this._levelSize, this._fineLevels, {\r\n mipmapping: false\r\n })\r\n );\r\n this._levelFramebuffer = device.createFrameBuffer(\r\n [this._levelAlbedoTexture.get()!, this._levelNormalTexture.get()!],\r\n null\r\n );\r\n }\r\n if (!TerrainTextureCache._quad) {\r\n const quad = new Primitive();\r\n quad.createAndSetVertexBuffer('position_f32', new Float32Array([0, 1, 2, 3]));\r\n quad.indexCount = 4;\r\n quad.indexStart = 0;\r\n quad.primitiveType = 'triangle-strip';\r\n TerrainTextureCache._quad = quad;\r\n }\r\n if (!TerrainTextureCache._renderStates) {\r\n const renderStates = device.createRenderStateSet();\r\n renderStates.useDepthState().enableTest(false).enableWrite(false);\r\n renderStates.useRasterizerState().setCullMode('none');\r\n TerrainTextureCache._renderStates = renderStates;\r\n }\r\n }\r\n private static getProgram(device: AbstractDevice, numDetailMaps: number) {\r\n let program = TerrainTextureCache._programs.get(numDetailMaps);\r\n if (!program) {\r\n program = device.buildRenderProgram({\r\n vertex(pb) {\r\n this.bakeWindow = pb.vec4().uniform(0);\r\n this.$inputs.position = pb.float().attrib('position');\r\n this.axis = [pb.vec2(-1, -1), pb.vec2(1, -1), pb.vec2(-1, 1), pb.vec2(1, 1)];\r\n pb.main(function () {\r\n this.$l.vertexAxis = this.axis.at(this.$builtins.vertexIndex);\r\n this.$l.quadUV = pb.add(pb.mul(this.vertexAxis, 0.5), pb.vec2(0.5));\r\n this.$outputs.uv = pb.add(this.bakeWindow.xy, pb.mul(this.quadUV, this.bakeWindow.zw));\r\n this.$builtins.position =\r\n pb.getDevice().type === 'webgpu'\r\n ? pb.vec4(this.vertexAxis.x, pb.neg(this.vertexAxis.y), 0, 1)\r\n : pb.vec4(this.vertexAxis.x, this.vertexAxis.y, 0, 1);\r\n });\r\n },\r\n fragment(pb) {\r\n this.splatMap = pb.tex2DArray().uniform(0);\r\n this.detailAlbedoMap = pb.tex2DArray().uniform(0);\r\n this.detailNormalMap = pb.tex2DArray().uniform(0);\r\n this.detailParams = pb.vec4[numDetailMaps]().uniform(0);\r\n this.$outputs.outAlbedo = pb.vec4();\r\n this.$outputs.outNormal = pb.vec4();\r\n pb.main(function () {\r\n const masks = sampleTerrainSplatMasks(this, this.splatMap, this.$inputs.uv, numDetailMaps, false);\r\n this.$l.albedo = accumulateTerrainLayers(\r\n this,\r\n 'albedoAccum',\r\n pb.vec3(0),\r\n numDetailMaps,\r\n this.$inputs.uv,\r\n masks,\r\n (i) => this.detailParams[i].x,\r\n (scope, i, uv) => pb.textureArraySample(scope.detailAlbedoMap, uv, i).rgb\r\n );\r\n this.$l.detailNormal = accumulateTerrainLayers(\r\n this,\r\n 'normalAccum',\r\n pb.vec3(0),\r\n numDetailMaps,\r\n this.$inputs.uv,\r\n masks,\r\n (i) => this.detailParams[i].x,\r\n (scope, i, uv) =>\r\n pb.normalize(\r\n pb.sub(pb.mul(pb.textureArraySample(scope.detailNormalMap, uv, i).rgb, 2), pb.vec3(1))\r\n )\r\n );\r\n this.$l.roughness = accumulateTerrainLayers(\r\n this,\r\n 'roughnessAccum',\r\n pb.float(0),\r\n numDetailMaps,\r\n this.$inputs.uv,\r\n masks,\r\n null,\r\n (scope, i) => scope.detailParams[i].y\r\n );\r\n this.$l.packedNormal = pb.normalize(this.detailNormal);\r\n this.$outputs.outAlbedo = pb.vec4(this.albedo, 1);\r\n this.$outputs.outNormal = pb.vec4(\r\n pb.add(pb.mul(this.packedNormal.xy, 0.5), pb.vec2(0.5)),\r\n this.roughness,\r\n 1\r\n );\r\n });\r\n }\r\n })!;\r\n TerrainTextureCache._programs.set(numDetailMaps, program);\r\n }\r\n return program;\r\n }\r\n}\r\n\r\nfunction clampWindow(minUV: number, sizeUV: number) {\r\n return Math.min(Math.max(minUV, 0), 1 - sizeUV);\r\n}\r\n"],"names":["INVALID_WINDOW","WINDOW_SNAP_STEPS","TerrainTextureCache","_programs","Map","_quad","_renderStates","_staticSize","_levelSize","_fineLevels","_albedoTexture","_normalTexture","_levelAlbedoTexture","_levelNormalTexture","_levelWindows","_staticFramebuffer","_levelFramebuffer","_bindGroup","_bindGroupLayerCount","_staticBaked","staticSize","levelSize","fineLevels","Math","max","DRef","Float32Array","resetWindows","albedoTexture","get","normalTexture","binding","albedo","normal","levelAlbedoTexture","levelNormalTexture","levelWindows","invalidate","update","material","cameraUV","device","getDevice","type","numDetailMaps","getSplatMap","detailAlbedoArray","bake","i","sizeUV","pow","snap","minU","clampWindow","round","x","minV","y","dispose","length","level","sizeU","sizeV","splatMap","albedoArray","normalArray","detailNormalArray","ensureResources","program","getProgram","createBindGroup","bindGroupLayouts","bindGroup","setTexture","fetchSampler","setValue","detailMapParams","framebuffer","setColorAttachmentLayer","pushDeviceStates","setFramebuffer","setProgram","setBindGroup","setRenderStates","draw","popDeviceStates","generateMipmaps","set","createTexture2D","createFrameBuffer","createTexture2DArray","mipmapping","quad","Primitive","createAndSetVertexBuffer","indexCount","indexStart","primitiveType","renderStates","createRenderStateSet","useDepthState","enableTest","enableWrite","useRasterizerState","setCullMode","buildRenderProgram","vertex","pb","bakeWindow","vec4","uniform","$inputs","position","float","attrib","axis","vec2","main","$l","vertexAxis","at","$builtins","vertexIndex","quadUV","add","mul","$outputs","uv","xy","zw","neg","fragment","tex2DArray","detailAlbedoMap","detailNormalMap","detailParams","outAlbedo","outNormal","masks","sampleTerrainSplatMasks","accumulateTerrainLayers","vec3","scope","textureArraySample","rgb","detailNormal","normalize","sub","roughness","packedNormal","minUV","min"],"mappings":";;;;;;AAiBA;AACA;AACA;AACA,MAAMA,cAAiB,GAAA,IAAA;AACvB;AACA;AACA,MAAMC,iBAAoB,GAAA,CAAA;AAE1B;;;;;;;;;;;;;;;;;;;;;AAqBC,IACM,MAAMC,mBAAAA,CAAAA;IACX,OAAwBC,SAAAA,GAAqC,IAAIC,GAAM,EAAA;AACvE,IAAA,OAAeC,QAA6B,IAAK;AACjD,IAAA,OAAeC,gBAA0C,IAAK;IAC7CC,WAAoB;IACpBC,UAAmB;IACnBC,WAAoB;IACpBC,cAAgC;IAChCC,cAAgC;IAChCC,mBAA0C;IAC1CC,mBAA0C;IAC1CC,aAAyC;IAClDC,kBAA0C;IAC1CC,iBAAyC;IACzCC,UAAgC;IAChCC,oBAA6B;IAC7BC,YAAsB;IAC9B,WAAYC,CAAAA,UAAAA,GAAa,IAAI,EAAEC,SAAAA,GAAY,IAAI,EAAEC,UAAAA,GAAa,CAAC,CAAE;QAC/D,IAAI,CAACf,WAAW,GAAGa,UAAAA;QACnB,IAAI,CAACZ,UAAU,GAAGa,SAAAA;AAClB,QAAA,IAAI,CAACZ,WAAW,GAAGc,IAAKC,CAAAA,GAAG,CAAC,CAAGF,EAAAA,UAAAA,CAAAA;QAC/B,IAAI,CAACZ,cAAc,GAAG,IAAIe,IAAAA,EAAAA;QAC1B,IAAI,CAACd,cAAc,GAAG,IAAIc,IAAAA,EAAAA;QAC1B,IAAI,CAACb,mBAAmB,GAAG,IAAIa,IAAAA,EAAAA;QAC/B,IAAI,CAACZ,mBAAmB,GAAG,IAAIY,IAAAA,EAAAA;AAC/B,QAAA,IAAI,CAACX,aAAa,GAAG,IAAIY,YAAaH,CAAAA,IAAAA,CAAKC,GAAG,CAAC,CAAG,EAAA,IAAI,CAACf,WAAW,CAAI,GAAA,CAAA,CAAA;QACtE,IAAI,CAACM,kBAAkB,GAAG,IAAA;QAC1B,IAAI,CAACC,iBAAiB,GAAG,IAAA;QACzB,IAAI,CAACC,UAAU,GAAG,IAAA;QAClB,IAAI,CAACC,oBAAoB,GAAG,CAAA;QAC5B,IAAI,CAACC,YAAY,GAAG,KAAA;AACpB,QAAA,IAAI,CAACQ,YAAY,EAAA;AACnB;2CAEA,IAAIP,UAAa,GAAA;QACf,OAAO,IAAI,CAACb,WAAW;AACzB;yCAEA,IAAIc,SAAY,GAAA;QACd,OAAO,IAAI,CAACb,UAAU;AACxB;iDAEA,IAAIc,UAAa,GAAA;QACf,OAAO,IAAI,CAACb,WAAW;AACzB;mEAEA,IAAImB,aAAgB,GAAA;AAClB,QAAA,OAAO,IAAI,CAAClB,cAAc,CAACmB,GAAG,EAAA;AAChC;wGAEA,IAAIC,aAAgB,GAAA;AAClB,QAAA,OAAO,IAAI,CAACnB,cAAc,CAACkB,GAAG,EAAA;AAChC;AACA;;;;AAIC,MACD,IAAIE,OAAgD,GAAA;AAClD,QAAA,MAAMC,MAAS,GAAA,IAAI,CAACtB,cAAc,CAACmB,GAAG,EAAA;AACtC,QAAA,MAAMI,MAAS,GAAA,IAAI,CAACtB,cAAc,CAACkB,GAAG,EAAA;QACtC,IAAI,CAAC,IAAI,CAACV,YAAY,IAAI,CAACa,MAAAA,IAAU,CAACC,MAAQ,EAAA;YAC5C,OAAO,IAAA;AACT;QACA,OAAO;YACLL,aAAeI,EAAAA,MAAAA;YACfF,aAAeG,EAAAA,MAAAA;AACfC,YAAAA,kBAAAA,EAAoB,IAAI,CAACtB,mBAAmB,CAACiB,GAAG,EAAA;AAChDM,YAAAA,kBAAAA,EAAoB,IAAI,CAACtB,mBAAmB,CAACgB,GAAG,EAAA;YAChDO,YAAc,EAAA,IAAI,CAACtB,aAAa;YAChCQ,UAAY,EAAA,IAAI,CAACb;AACnB,SAAA;AACF;AACA;;;AAGC,MACD4B,UAAa,GAAA;QACX,IAAI,CAAClB,YAAY,GAAG,KAAA;AACpB,QAAA,IAAI,CAACQ,YAAY,EAAA;AACnB;AACA;;;;;;AAMC,MACDW,MAAOC,CAAAA,QAAgC,EAAEC,QAAkC,EAAE;AAC3E,QAAA,MAAMC,MAASC,GAAAA,SAAAA,EAAAA;QACf,IAAID,MAAAA,CAAOE,IAAI,KAAK,OAAS,EAAA;YAC3B,OAAO,KAAA;AACT;QACA,IAAIJ,QAAAA,CAASK,aAAa,KAAK,CAAK,IAAA,CAACL,QAASM,CAAAA,WAAW,EAAM,IAAA,CAACN,QAASO,CAAAA,iBAAiB,EAAE;YAC1F,OAAO,KAAA;AACT;AACA,QAAA,IAAI,CAAC,IAAI,CAAC3B,YAAY,EAAE;YACtB,IAAI,IAAI,CAAC4B,IAAI,CAACN,MAAAA,EAAQF,QAAU,EAAA,EAAI,EAAA,CAAA,EAAG,CAAG,EAAA,CAAA,EAAG,CAAI,CAAA,EAAA;gBAC/C,IAAI,CAACpB,YAAY,GAAG,IAAA;AACtB;YACA,OAAO,IAAI,CAACA,YAAY;AAC1B;QACA,IAAK,IAAI6B,IAAI,IAAI,CAACvC,WAAW,GAAG,CAAA,EAAGuC,CAAK,IAAA,CAAA,EAAGA,CAAK,EAAA,CAAA;YAC9C,MAAMC,MAAAA,GAAS1B,KAAK2B,GAAG,CAAC,KAAK,IAAI,CAACzC,WAAW,GAAGuC,CAAAA,CAAAA;AAChD,YAAA,MAAMG,OAAOF,MAAShD,GAAAA,iBAAAA;AACtB,YAAA,MAAMmD,IAAOC,GAAAA,WAAAA,CAAY9B,IAAK+B,CAAAA,KAAK,CAAC,CAACd,QAASe,CAAAA,CAAC,GAAGN,MAAAA,GAAS,GAAE,IAAKE,QAAQA,IAAMF,EAAAA,MAAAA,CAAAA;AAChF,YAAA,MAAMO,IAAOH,GAAAA,WAAAA,CAAY9B,IAAK+B,CAAAA,KAAK,CAAC,CAACd,QAASiB,CAAAA,CAAC,GAAGR,MAAAA,GAAS,GAAE,IAAKE,QAAQA,IAAMF,EAAAA,MAAAA,CAAAA;AAChF,YAAA,IAAI,IAAI,CAACnC,aAAa,CAACkC,CAAAA,GAAI,EAAE,KAAKI,IAAAA,IAAQ,IAAI,CAACtC,aAAa,CAACkC,CAAAA,GAAI,CAAI,GAAA,CAAA,CAAE,KAAKQ,IAAM,EAAA;gBAChF,IAAI,IAAI,CAACT,IAAI,CAACN,MAAAA,EAAQF,UAAUS,CAAGI,EAAAA,IAAAA,EAAMI,IAAMP,EAAAA,MAAAA,EAAQA,MAAS,CAAA,EAAA;AAC9D,oBAAA,IAAI,CAACnC,aAAa,CAACkC,CAAAA,GAAI,EAAE,GAAGI,IAAAA;AAC5B,oBAAA,IAAI,CAACtC,aAAa,CAACkC,CAAI,GAAA,CAAA,GAAI,EAAE,GAAGQ,IAAAA;AAChC,oBAAA,IAAI,CAAC1C,aAAa,CAACkC,IAAI,CAAI,GAAA,CAAA,CAAE,GAAG,CAAIC,GAAAA,MAAAA;AACpC,oBAAA,IAAI,CAACnC,aAAa,CAACkC,IAAI,CAAI,GAAA,CAAA,CAAE,GAAG,CAAIC,GAAAA,MAAAA;AACtC;AACA,gBAAA;AACF;AACF;QACA,OAAO,IAAA;AACT;IACAS,OAAU,GAAA;QACR,IAAI,CAAC3C,kBAAkB,EAAE2C,OAAAA,EAAAA;QACzB,IAAI,CAAC3C,kBAAkB,GAAG,IAAA;QAC1B,IAAI,CAACC,iBAAiB,EAAE0C,OAAAA,EAAAA;QACxB,IAAI,CAAC1C,iBAAiB,GAAG,IAAA;QACzB,IAAI,CAACN,cAAc,CAACgD,OAAO,EAAA;QAC3B,IAAI,CAAC/C,cAAc,CAAC+C,OAAO,EAAA;QAC3B,IAAI,CAAC9C,mBAAmB,CAAC8C,OAAO,EAAA;QAChC,IAAI,CAAC7C,mBAAmB,CAAC6C,OAAO,EAAA;QAChC,IAAI,CAACzC,UAAU,GAAG,IAAA;QAClB,IAAI,CAACE,YAAY,GAAG,KAAA;AACpB,QAAA,IAAI,CAACQ,YAAY,EAAA;AACnB;IACQA,YAAe,GAAA;QACrB,IAAK,IAAIqB,CAAI,GAAA,CAAA,EAAGA,CAAI,GAAA,IAAI,CAAClC,aAAa,CAAC6C,MAAM,EAAEX,CAAAA,IAAK,CAAG,CAAA;AACrD,YAAA,IAAI,CAAClC,aAAa,CAACkC,CAAAA,CAAE,GAAGhD,cAAAA;AACxB,YAAA,IAAI,CAACc,aAAa,CAACkC,CAAAA,GAAI,EAAE,GAAGhD,cAAAA;AAC5B,YAAA,IAAI,CAACc,aAAa,CAACkC,CAAAA,GAAI,EAAE,GAAG,CAAA;AAC5B,YAAA,IAAI,CAAClC,aAAa,CAACkC,CAAAA,GAAI,EAAE,GAAG,CAAA;AAC9B;AACF;AACA;;;;;AAKC,MACD,IAAQD,CACNN,MAAsB,EACtBF,QAAgC,EAChCqB,KAAa,EACbR,IAAY,EACZI,IAAY,EACZK,KAAa,EACbC,KAAa,EACb;QACA,MAAMlB,aAAAA,GAAgBL,SAASK,aAAa;QAC5C,MAAMmB,QAAAA,GAAWxB,SAASM,WAAW,EAAA;QACrC,MAAMmB,WAAAA,GAAczB,SAASO,iBAAiB;QAC9C,MAAMmB,WAAAA,GAAc1B,SAAS2B,iBAAiB;AAC9C,QAAA,IAAItB,kBAAkB,CAAK,IAAA,CAACmB,YAAY,CAACC,WAAAA,IAAe,CAACC,WAAa,EAAA;YACpE,OAAO,KAAA;AACT;QACA,IAAI,CAACE,eAAe,CAAC1B,MAAAA,CAAAA;AACrB,QAAA,MAAM2B,OAAUlE,GAAAA,mBAAAA,CAAoBmE,UAAU,CAAC5B,MAAQG,EAAAA,aAAAA,CAAAA;QACvD,IAAI,CAAC,IAAI,CAAC3B,UAAU,IAAI,IAAI,CAACC,oBAAoB,KAAK0B,aAAe,EAAA;YACnE,IAAI,CAAC3B,UAAU,GAAGwB,MAAAA,CAAO6B,eAAe,CAACF,OAAAA,CAAQG,gBAAgB,CAAC,CAAE,CAAA,CAAA;YACpE,IAAI,CAACrD,oBAAoB,GAAG0B,aAAAA;AAC9B;QACA,MAAM4B,SAAAA,GAAY,IAAI,CAACvD,UAAU;QACjCuD,SAAUC,CAAAA,UAAU,CAAC,UAAYV,EAAAA,QAAAA,CAAAA;AACjCS,QAAAA,SAAAA,CAAUC,UAAU,CAAC,iBAAmBT,EAAAA,WAAAA,EAAaU,YAAa,CAAA,eAAA,CAAA,CAAA;AAClEF,QAAAA,SAAAA,CAAUC,UAAU,CAAC,iBAAmBR,EAAAA,WAAAA,EAAaS,YAAa,CAAA,eAAA,CAAA,CAAA;AAClEF,QAAAA,SAAAA,CAAUG,QAAQ,CAAC,cAAgBpC,EAAAA,QAAAA,CAASqC,eAAe,CAAA;AAC3DJ,QAAAA,SAAAA,CAAUG,QAAQ,CAAC,YAAc,EAAA,IAAIjD,YAAa,CAAA;AAAC0B,YAAAA,IAAAA;AAAMI,YAAAA,IAAAA;AAAMK,YAAAA,KAAAA;AAAOC,YAAAA;AAAM,SAAA,CAAA,CAAA;QAC5E,IAAIe,WAAAA;AACJ,QAAA,IAAIjB,QAAQ,CAAG,EAAA;YACbiB,WAAc,GAAA,IAAI,CAAC9D,kBAAkB;SAChC,MAAA;YACL8D,WAAc,GAAA,IAAI,CAAC7D,iBAAiB;YACpC6D,WAAYC,CAAAA,uBAAuB,CAAC,CAAGlB,EAAAA,KAAAA,CAAAA;YACvCiB,WAAYC,CAAAA,uBAAuB,CAAC,CAAGlB,EAAAA,KAAAA,CAAAA;AACzC;AACAnB,QAAAA,MAAAA,CAAOsC,gBAAgB,EAAA;AACvBtC,QAAAA,MAAAA,CAAOuC,cAAc,CAACH,WAAAA,CAAAA;AACtBpC,QAAAA,MAAAA,CAAOwC,UAAU,CAACb,OAAAA,CAAAA;QAClB3B,MAAOyC,CAAAA,YAAY,CAAC,CAAGV,EAAAA,SAAAA,CAAAA;QACvB/B,MAAO0C,CAAAA,eAAe,CAACjF,mBAAAA,CAAoBI,aAAa,CAAA;QACxDJ,mBAAoBG,CAAAA,KAAK,CAAE+E,IAAI,EAAA;AAC/B3C,QAAAA,MAAAA,CAAO4C,eAAe,EAAA;AACtB,QAAA,IAAIzB,QAAQ,CAAG,EAAA;;;AAGb,YAAA,IAAI,CAAClD,cAAc,CAACmB,GAAG,GAAIyD,eAAe,EAAA;AAC1C,YAAA,IAAI,CAAC3E,cAAc,CAACkB,GAAG,GAAIyD,eAAe,EAAA;AAC5C;QACA,OAAO,IAAA;AACT;AACQnB,IAAAA,eAAAA,CAAgB1B,MAAsB,EAAE;AAC9C,QAAA,IAAI,CAAC,IAAI,CAAC/B,cAAc,CAACmB,GAAG,EAAI,EAAA;AAC9B,YAAA,IAAI,CAACnB,cAAc,CAAC6E,GAAG,CAAC9C,MAAO+C,CAAAA,eAAe,CAAC,YAAA,EAAc,IAAI,CAACjF,WAAW,EAAE,IAAI,CAACA,WAAW,CAAA,CAAA;AAC/F,YAAA,IAAI,CAACI,cAAc,CAAC4E,GAAG,CAAC9C,MAAO+C,CAAAA,eAAe,CAAC,YAAA,EAAc,IAAI,CAACjF,WAAW,EAAE,IAAI,CAACA,WAAW,CAAA,CAAA;AAC/F,YAAA,IAAI,CAACQ,kBAAkB,GAAG0B,MAAAA,CAAOgD,iBAAiB,CAChD;gBAAC,IAAI,CAAC/E,cAAc,CAACmB,GAAG,EAAA;gBAAK,IAAI,CAAClB,cAAc,CAACkB,GAAG;aAAI,EACxD,IAAA,CAAA;AAEJ;QACA,IAAI,IAAI,CAACpB,WAAW,GAAG,CAAA,IAAK,CAAC,IAAI,CAACG,mBAAmB,CAACiB,GAAG,EAAI,EAAA;YAC3D,IAAI,CAACjB,mBAAmB,CAAC2E,GAAG,CAC1B9C,MAAOiD,CAAAA,oBAAoB,CAAC,YAAc,EAAA,IAAI,CAAClF,UAAU,EAAE,IAAI,CAACA,UAAU,EAAE,IAAI,CAACC,WAAW,EAAE;gBAC5FkF,UAAY,EAAA;AACd,aAAA,CAAA,CAAA;YAEF,IAAI,CAAC9E,mBAAmB,CAAC0E,GAAG,CAC1B9C,MAAOiD,CAAAA,oBAAoB,CAAC,YAAc,EAAA,IAAI,CAAClF,UAAU,EAAE,IAAI,CAACA,UAAU,EAAE,IAAI,CAACC,WAAW,EAAE;gBAC5FkF,UAAY,EAAA;AACd,aAAA,CAAA,CAAA;AAEF,YAAA,IAAI,CAAC3E,iBAAiB,GAAGyB,MAAAA,CAAOgD,iBAAiB,CAC/C;gBAAC,IAAI,CAAC7E,mBAAmB,CAACiB,GAAG,EAAA;gBAAK,IAAI,CAAChB,mBAAmB,CAACgB,GAAG;aAAI,EAClE,IAAA,CAAA;AAEJ;QACA,IAAI,CAAC3B,mBAAoBG,CAAAA,KAAK,EAAE;AAC9B,YAAA,MAAMuF,OAAO,IAAIC,SAAAA,EAAAA;AACjBD,YAAAA,IAAAA,CAAKE,wBAAwB,CAAC,cAAgB,EAAA,IAAIpE,YAAa,CAAA;AAAC,gBAAA,CAAA;AAAG,gBAAA,CAAA;AAAG,gBAAA,CAAA;AAAG,gBAAA;AAAE,aAAA,CAAA,CAAA;AAC3EkE,YAAAA,IAAAA,CAAKG,UAAU,GAAG,CAAA;AAClBH,YAAAA,IAAAA,CAAKI,UAAU,GAAG,CAAA;AAClBJ,YAAAA,IAAAA,CAAKK,aAAa,GAAG,gBAAA;AACrB/F,YAAAA,mBAAAA,CAAoBG,KAAK,GAAGuF,IAAAA;AAC9B;QACA,IAAI,CAAC1F,mBAAoBI,CAAAA,aAAa,EAAE;YACtC,MAAM4F,YAAAA,GAAezD,OAAO0D,oBAAoB,EAAA;AAChDD,YAAAA,YAAAA,CAAaE,aAAa,EAAGC,CAAAA,UAAU,CAAC,KAAA,CAAA,CAAOC,WAAW,CAAC,KAAA,CAAA;YAC3DJ,YAAaK,CAAAA,kBAAkB,EAAGC,CAAAA,WAAW,CAAC,MAAA,CAAA;AAC9CtG,YAAAA,mBAAAA,CAAoBI,aAAa,GAAG4F,YAAAA;AACtC;AACF;AACA,IAAA,OAAe7B,UAAW5B,CAAAA,MAAsB,EAAEG,aAAqB,EAAE;AACvE,QAAA,IAAIwB,OAAUlE,GAAAA,mBAAAA,CAAoBC,SAAS,CAAC0B,GAAG,CAACe,aAAAA,CAAAA;AAChD,QAAA,IAAI,CAACwB,OAAS,EAAA;YACZA,OAAU3B,GAAAA,MAAAA,CAAOgE,kBAAkB,CAAC;AAClCC,gBAAAA,MAAAA,CAAAA,CAAOC,EAAE,EAAA;AACP,oBAAA,IAAI,CAACC,UAAU,GAAGD,GAAGE,IAAI,EAAA,CAAGC,OAAO,CAAC,CAAA,CAAA;oBACpC,IAAI,CAACC,OAAO,CAACC,QAAQ,GAAGL,EAAGM,CAAAA,KAAK,EAAGC,CAAAA,MAAM,CAAC,UAAA,CAAA;oBAC1C,IAAI,CAACC,IAAI,GAAG;AAACR,wBAAAA,EAAAA,CAAGS,IAAI,CAAC,EAAC,EAAG,EAAC,CAAA;wBAAIT,EAAGS,CAAAA,IAAI,CAAC,CAAA,EAAG,EAAC,CAAA;wBAAIT,EAAGS,CAAAA,IAAI,CAAC,EAAI,EAAA,CAAA,CAAA;wBAAIT,EAAGS,CAAAA,IAAI,CAAC,CAAG,EAAA,CAAA;AAAG,qBAAA;AAC5ET,oBAAAA,EAAAA,CAAGU,IAAI,CAAC,WAAA;AACN,wBAAA,IAAI,CAACC,EAAE,CAACC,UAAU,GAAG,IAAI,CAACJ,IAAI,CAACK,EAAE,CAAC,IAAI,CAACC,SAAS,CAACC,WAAW,CAAA;AAC5D,wBAAA,IAAI,CAACJ,EAAE,CAACK,MAAM,GAAGhB,EAAAA,CAAGiB,GAAG,CAACjB,EAAAA,CAAGkB,GAAG,CAAC,IAAI,CAACN,UAAU,EAAE,GAAMZ,CAAAA,EAAAA,EAAAA,CAAGS,IAAI,CAAC,GAAA,CAAA,CAAA;wBAC9D,IAAI,CAACU,QAAQ,CAACC,EAAE,GAAGpB,GAAGiB,GAAG,CAAC,IAAI,CAAChB,UAAU,CAACoB,EAAE,EAAErB,EAAAA,CAAGkB,GAAG,CAAC,IAAI,CAACF,MAAM,EAAE,IAAI,CAACf,UAAU,CAACqB,EAAE,CAAA,CAAA;wBACpF,IAAI,CAACR,SAAS,CAACT,QAAQ,GACrBL,EAAGjE,CAAAA,SAAS,GAAGC,IAAI,KAAK,WACpBgE,EAAGE,CAAAA,IAAI,CAAC,IAAI,CAACU,UAAU,CAAChE,CAAC,EAAEoD,EAAAA,CAAGuB,GAAG,CAAC,IAAI,CAACX,UAAU,CAAC9D,CAAC,CAAA,EAAG,GAAG,CACzDkD,CAAAA,GAAAA,EAAAA,CAAGE,IAAI,CAAC,IAAI,CAACU,UAAU,CAAChE,CAAC,EAAE,IAAI,CAACgE,UAAU,CAAC9D,CAAC,EAAE,CAAG,EAAA,CAAA,CAAA;AACzD,qBAAA,CAAA;AACF,iBAAA;AACA0E,gBAAAA,QAAAA,CAAAA,CAASxB,EAAE,EAAA;AACT,oBAAA,IAAI,CAAC5C,QAAQ,GAAG4C,GAAGyB,UAAU,EAAA,CAAGtB,OAAO,CAAC,CAAA,CAAA;AACxC,oBAAA,IAAI,CAACuB,eAAe,GAAG1B,GAAGyB,UAAU,EAAA,CAAGtB,OAAO,CAAC,CAAA,CAAA;AAC/C,oBAAA,IAAI,CAACwB,eAAe,GAAG3B,GAAGyB,UAAU,EAAA,CAAGtB,OAAO,CAAC,CAAA,CAAA;oBAC/C,IAAI,CAACyB,YAAY,GAAG5B,EAAAA,CAAGE,IAAI,CAACjE,aAAAA,CAAc,EAAGkE,CAAAA,OAAO,CAAC,CAAA,CAAA;AACrD,oBAAA,IAAI,CAACgB,QAAQ,CAACU,SAAS,GAAG7B,GAAGE,IAAI,EAAA;AACjC,oBAAA,IAAI,CAACiB,QAAQ,CAACW,SAAS,GAAG9B,GAAGE,IAAI,EAAA;AACjCF,oBAAAA,EAAAA,CAAGU,IAAI,CAAC,WAAA;AACN,wBAAA,MAAMqB,KAAQC,GAAAA,uBAAAA,CAAwB,IAAI,EAAE,IAAI,CAAC5E,QAAQ,EAAE,IAAI,CAACgD,OAAO,CAACgB,EAAE,EAAEnF,aAAe,EAAA,KAAA,CAAA;AAC3F,wBAAA,IAAI,CAAC0E,EAAE,CAACtF,MAAM,GAAG4G,uBAAAA,CACf,IAAI,EACJ,aAAA,EACAjC,GAAGkC,IAAI,CAAC,IACRjG,aACA,EAAA,IAAI,CAACmE,OAAO,CAACgB,EAAE,EACfW,KAAAA,EACA,CAAC1F,CAAM,GAAA,IAAI,CAACuF,YAAY,CAACvF,EAAE,CAACO,CAAC,EAC7B,CAACuF,KAAAA,EAAO9F,GAAG+E,EAAOpB,GAAAA,EAAAA,CAAGoC,kBAAkB,CAACD,KAAAA,CAAMT,eAAe,EAAEN,EAAAA,EAAI/E,GAAGgG,GAAG,CAAA;wBAE3E,IAAI,CAAC1B,EAAE,CAAC2B,YAAY,GAAGL,uBACrB,CAAA,IAAI,EACJ,aAAA,EACAjC,EAAGkC,CAAAA,IAAI,CAAC,CAAA,CAAA,EACRjG,eACA,IAAI,CAACmE,OAAO,CAACgB,EAAE,EACfW,KACA,EAAA,CAAC1F,CAAM,GAAA,IAAI,CAACuF,YAAY,CAACvF,CAAAA,CAAE,CAACO,CAAC,EAC7B,CAACuF,KAAAA,EAAO9F,CAAG+E,EAAAA,EAAAA,GACTpB,EAAGuC,CAAAA,SAAS,CACVvC,EAAAA,CAAGwC,GAAG,CAACxC,EAAGkB,CAAAA,GAAG,CAAClB,EAAAA,CAAGoC,kBAAkB,CAACD,KAAMR,CAAAA,eAAe,EAAEP,EAAAA,EAAI/E,CAAGgG,CAAAA,CAAAA,GAAG,EAAE,CAAA,CAAA,EAAIrC,EAAGkC,CAAAA,IAAI,CAAC,CAAA,CAAA,CAAA,CAAA,CAAA;AAGzF,wBAAA,IAAI,CAACvB,EAAE,CAAC8B,SAAS,GAAGR,uBAAAA,CAClB,IAAI,EACJ,gBACAjC,EAAAA,EAAAA,CAAGM,KAAK,CAAC,IACTrE,aACA,EAAA,IAAI,CAACmE,OAAO,CAACgB,EAAE,EACfW,KAAAA,EACA,IACA,EAAA,CAACI,KAAO9F,EAAAA,CAAAA,GAAM8F,KAAMP,CAAAA,YAAY,CAACvF,CAAAA,CAAE,CAACS,CAAC,CAAA;wBAEvC,IAAI,CAAC6D,EAAE,CAAC+B,YAAY,GAAG1C,GAAGuC,SAAS,CAAC,IAAI,CAACD,YAAY,CAAA;wBACrD,IAAI,CAACnB,QAAQ,CAACU,SAAS,GAAG7B,EAAGE,CAAAA,IAAI,CAAC,IAAI,CAAC7E,MAAM,EAAE,CAAA,CAAA;AAC/C,wBAAA,IAAI,CAAC8F,QAAQ,CAACW,SAAS,GAAG9B,EAAAA,CAAGE,IAAI,CAC/BF,EAAGiB,CAAAA,GAAG,CAACjB,EAAAA,CAAGkB,GAAG,CAAC,IAAI,CAACwB,YAAY,CAACrB,EAAE,EAAE,GAAMrB,CAAAA,EAAAA,EAAAA,CAAGS,IAAI,CAAC,GAClD,CAAA,CAAA,EAAA,IAAI,CAACgC,SAAS,EACd,CAAA,CAAA;AAEJ,qBAAA,CAAA;AACF;AACF,aAAA,CAAA;AACAlJ,YAAAA,mBAAAA,CAAoBC,SAAS,CAACoF,GAAG,CAAC3C,aAAewB,EAAAA,OAAAA,CAAAA;AACnD;QACA,OAAOA,OAAAA;AACT;AACF;AAEA,SAASf,WAAAA,CAAYiG,KAAa,EAAErG,MAAc,EAAA;IAChD,OAAO1B,IAAAA,CAAKgI,GAAG,CAAChI,IAAAA,CAAKC,GAAG,CAAC8H,KAAAA,EAAO,IAAI,CAAIrG,GAAAA,MAAAA,CAAAA;AAC1C;;;;"}
|