@playcanvas/web-components 0.16.0 → 0.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/README.md +5 -3
  2. package/dist/app.d.cts +18 -13
  3. package/dist/app.d.ts +18 -13
  4. package/dist/asset.d.cts +13 -3
  5. package/dist/asset.d.ts +13 -3
  6. package/dist/async-element.d.cts +13 -13
  7. package/dist/async-element.d.ts +13 -13
  8. package/dist/components/anim-clip.d.cts +4 -0
  9. package/dist/components/anim-clip.d.ts +4 -0
  10. package/dist/components/anim-component.d.cts +38 -5
  11. package/dist/components/anim-component.d.ts +38 -5
  12. package/dist/components/audio-listener-component.d.cts +26 -0
  13. package/dist/components/audio-listener-component.d.ts +26 -0
  14. package/dist/components/button-component.d.cts +10 -1
  15. package/dist/components/button-component.d.ts +10 -1
  16. package/dist/components/camera-component.d.cts +37 -1
  17. package/dist/components/camera-component.d.ts +37 -1
  18. package/dist/components/collision-component.d.cts +9 -1
  19. package/dist/components/collision-component.d.ts +9 -1
  20. package/dist/components/component.d.cts +3 -2
  21. package/dist/components/component.d.ts +3 -2
  22. package/dist/components/element-component.d.cts +11 -0
  23. package/dist/components/element-component.d.ts +11 -0
  24. package/dist/components/gsplat-component.d.cts +6 -0
  25. package/dist/components/gsplat-component.d.ts +6 -0
  26. package/dist/components/joint-component.d.cts +14 -2
  27. package/dist/components/joint-component.d.ts +14 -2
  28. package/dist/components/{layoutchild-component.d.cts → layout-child-component.d.cts} +7 -1
  29. package/dist/components/{layoutchild-component.d.ts → layout-child-component.d.ts} +7 -1
  30. package/dist/components/{layoutgroup-component.d.cts → layout-group-component.d.cts} +7 -1
  31. package/dist/components/{layoutgroup-component.d.ts → layout-group-component.d.ts} +7 -1
  32. package/dist/components/light-component.d.cts +52 -1
  33. package/dist/components/light-component.d.ts +52 -1
  34. package/dist/components/{particlesystem-component.d.cts → particle-system-component.d.cts} +7 -1
  35. package/dist/components/{particlesystem-component.d.ts → particle-system-component.d.ts} +7 -1
  36. package/dist/components/render-component.d.cts +7 -0
  37. package/dist/components/render-component.d.ts +7 -0
  38. package/dist/components/{rigidbody-component.d.cts → rigid-body-component.d.cts} +8 -1
  39. package/dist/components/{rigidbody-component.d.ts → rigid-body-component.d.ts} +8 -1
  40. package/dist/components/screen-component.d.cts +6 -0
  41. package/dist/components/screen-component.d.ts +6 -0
  42. package/dist/components/script-component.d.cts +26 -12
  43. package/dist/components/script-component.d.ts +26 -12
  44. package/dist/components/{script.d.cts → script-instance.d.cts} +11 -7
  45. package/dist/components/{script.d.ts → script-instance.d.ts} +11 -7
  46. package/dist/components/{scrollview-component.d.cts → scroll-view-component.d.cts} +7 -1
  47. package/dist/components/{scrollview-component.d.ts → scroll-view-component.d.ts} +7 -1
  48. package/dist/components/scrollbar-component.d.cts +6 -0
  49. package/dist/components/scrollbar-component.d.ts +6 -0
  50. package/dist/components/sound-component.d.cts +7 -1
  51. package/dist/components/sound-component.d.ts +7 -1
  52. package/dist/components/sound-slot.d.cts +5 -2
  53. package/dist/components/sound-slot.d.ts +5 -2
  54. package/dist/custom-elements.json +1852 -974
  55. package/dist/entity-base.d.cts +7 -6
  56. package/dist/entity-base.d.ts +7 -6
  57. package/dist/entity-owner.d.cts +118 -0
  58. package/dist/entity-owner.d.ts +118 -0
  59. package/dist/entity.d.cts +14 -102
  60. package/dist/entity.d.ts +14 -102
  61. package/dist/index.d.cts +26 -22
  62. package/dist/index.d.ts +26 -22
  63. package/dist/material.d.cts +18 -7
  64. package/dist/material.d.ts +18 -7
  65. package/dist/model.d.cts +72 -24
  66. package/dist/model.d.ts +72 -24
  67. package/dist/node.d.cts +6 -1
  68. package/dist/node.d.ts +6 -1
  69. package/dist/pwc.cjs +807 -293
  70. package/dist/pwc.cjs.map +1 -1
  71. package/dist/pwc.js +807 -293
  72. package/dist/pwc.js.map +1 -1
  73. package/dist/pwc.min.js +1 -1
  74. package/dist/pwc.min.js.map +1 -1
  75. package/dist/pwc.min.mjs +1 -1
  76. package/dist/pwc.min.mjs.map +1 -1
  77. package/dist/pwc.mjs +805 -292
  78. package/dist/pwc.mjs.map +1 -1
  79. package/dist/scene.d.cts +3 -0
  80. package/dist/scene.d.ts +3 -0
  81. package/dist/sky.d.cts +4 -0
  82. package/dist/sky.d.ts +4 -0
  83. package/dist/vscode.html-custom-data.json +351 -121
  84. package/dist/{module.d.cts → wasm.d.cts} +10 -6
  85. package/dist/{module.d.ts → wasm.d.ts} +10 -6
  86. package/dist/web-types.json +465 -291
  87. package/package.json +7 -7
  88. package/src/app.ts +49 -35
  89. package/src/asset.ts +13 -4
  90. package/src/async-element.ts +14 -14
  91. package/src/components/anim-clip.ts +4 -0
  92. package/src/components/anim-component.ts +89 -14
  93. package/src/components/audio-listener-component.ts +36 -0
  94. package/src/components/button-component.ts +10 -1
  95. package/src/components/camera-component.ts +65 -6
  96. package/src/components/collision-component.ts +9 -1
  97. package/src/components/component.ts +4 -3
  98. package/src/components/element-component.ts +11 -0
  99. package/src/components/gsplat-component.ts +6 -0
  100. package/src/components/joint-component.ts +14 -2
  101. package/src/components/{layoutchild-component.ts → layout-child-component.ts} +8 -2
  102. package/src/components/{layoutgroup-component.ts → layout-group-component.ts} +8 -2
  103. package/src/components/light-component.ts +110 -17
  104. package/src/components/{particlesystem-component.ts → particle-system-component.ts} +8 -2
  105. package/src/components/render-component.ts +7 -0
  106. package/src/components/{rigidbody-component.ts → rigid-body-component.ts} +9 -2
  107. package/src/components/screen-component.ts +6 -0
  108. package/src/components/script-component.ts +66 -42
  109. package/src/components/{script.ts → script-instance.ts} +18 -14
  110. package/src/components/{scrollview-component.ts → scroll-view-component.ts} +8 -2
  111. package/src/components/scrollbar-component.ts +6 -0
  112. package/src/components/sound-component.ts +8 -2
  113. package/src/components/sound-slot.ts +7 -4
  114. package/src/entity-base.ts +8 -7
  115. package/src/entity-owner.ts +298 -0
  116. package/src/entity.ts +21 -271
  117. package/src/index.ts +38 -25
  118. package/src/material.ts +19 -8
  119. package/src/model.ts +164 -72
  120. package/src/node.ts +15 -6
  121. package/src/scene.ts +3 -0
  122. package/src/sky.ts +4 -0
  123. package/src/{module.ts → wasm.ts} +12 -8
  124. package/dist/components/listener-component.d.cts +0 -20
  125. package/dist/components/listener-component.d.ts +0 -20
  126. package/src/components/listener-component.ts +0 -30
@@ -13,6 +13,7 @@ import {
13
13
  TONEMAP_ACES,
14
14
  TONEMAP_HEJL,
15
15
  TONEMAP_NONE,
16
+ XRTYPE_AR,
16
17
  XRTYPE_VR
17
18
  } from 'playcanvas';
18
19
 
@@ -41,6 +42,12 @@ const tonemaps = new Map<'none' | 'linear' | 'filmic' | 'hejl' | 'aces' | 'aces2
41
42
  * The CameraComponentElement interface also inherits the properties and methods of the
42
43
  * {@link HTMLElement} interface.
43
44
  *
45
+ * Engine component: {@link CameraComponent} (`camera`).
46
+ *
47
+ * @elementSummary The `<pc-camera>` element renders the scene from its entity's transform, with
48
+ * attributes for the projection, field of view, clip planes, clear color and tonemapping. Must be a
49
+ * child of a `<pc-entity>`, `<pc-model>` or `<pc-node>`.
50
+ *
44
51
  * @category Components
45
52
  */
46
53
  class CameraComponentElement extends ComponentElement {
@@ -48,9 +55,11 @@ class CameraComponentElement extends ComponentElement {
48
55
 
49
56
  private _clearColorBuffer = true;
50
57
 
58
+ private _clearDepth = 1;
59
+
51
60
  private _clearDepthBuffer = true;
52
61
 
53
- private _clearStencilBuffer = false;
62
+ private _clearStencilBuffer = true;
54
63
 
55
64
  private _cullFaces = true;
56
65
 
@@ -89,6 +98,7 @@ class CameraComponentElement extends ComponentElement {
89
98
  return {
90
99
  clearColor: this._clearColor,
91
100
  clearColorBuffer: this._clearColorBuffer,
101
+ clearDepth: this._clearDepth,
92
102
  clearDepthBuffer: this._clearDepthBuffer,
93
103
  clearStencilBuffer: this._clearStencilBuffer,
94
104
  cullFaces: this._cullFaces,
@@ -108,9 +118,33 @@ class CameraComponentElement extends ComponentElement {
108
118
  };
109
119
  }
110
120
 
111
- get xrAvailable() {
121
+ /**
122
+ * Whether immersive AR is available. Independent of {@link vrAvailable}: a device can offer
123
+ * either mode without the other.
124
+ * @returns Whether immersive AR is available.
125
+ */
126
+ get arAvailable(): boolean {
127
+ return this._available(XRTYPE_AR);
128
+ }
129
+
130
+ /**
131
+ * Whether immersive VR is available. Independent of {@link arAvailable}: a device can offer
132
+ * either mode without the other.
133
+ * @returns Whether immersive VR is available.
134
+ */
135
+ get vrAvailable(): boolean {
136
+ return this._available(XRTYPE_VR);
137
+ }
138
+
139
+ /**
140
+ * Whether one XR session type is available on this device.
141
+ *
142
+ * @param type - The XR session type to test.
143
+ * @returns Whether that type is available.
144
+ */
145
+ private _available(type: string): boolean {
112
146
  const xrManager = this.component?.system.app.xr;
113
- return xrManager && xrManager.supported && xrManager.isAvailable(XRTYPE_VR);
147
+ return Boolean(xrManager?.supported && xrManager.isAvailable(type));
114
148
  }
115
149
 
116
150
  /**
@@ -122,10 +156,12 @@ class CameraComponentElement extends ComponentElement {
122
156
  type: 'immersive-ar' | 'immersive-vr',
123
157
  space: 'bounded-floor' | 'local' | 'local-floor' | 'unbounded' | 'viewer'
124
158
  ) {
125
- if (this.component && this.xrAvailable) {
159
+ // Gated on the mode being started, not on XR in general: a device that offers only
160
+ // one of the two would otherwise accept a session it cannot serve
161
+ if (this.component && this._available(type)) {
126
162
  this.component.startXr(type, space, {
127
163
  callback: (err: any) => {
128
- if (err) console.error(`WebXR Immersive VR failed to start: ${err.message}`);
164
+ if (err) console.error(`WebXR ${type} failed to start: ${err.message}`);
129
165
  }
130
166
  });
131
167
  }
@@ -186,6 +222,25 @@ class CameraComponentElement extends ComponentElement {
186
222
  return this._clearColorBuffer;
187
223
  }
188
224
 
225
+ /**
226
+ * Sets the depth value the depth buffer is cleared to. Defaults to 1.
227
+ * @param value - The clear depth value.
228
+ */
229
+ set clearDepth(value: number) {
230
+ this._clearDepth = value;
231
+ if (this.component) {
232
+ this.component.clearDepth = value;
233
+ }
234
+ }
235
+
236
+ /**
237
+ * Gets the depth value the depth buffer is cleared to.
238
+ * @returns The clear depth value.
239
+ */
240
+ get clearDepth(): number {
241
+ return this._clearDepth;
242
+ }
243
+
189
244
  /**
190
245
  * Sets the clear depth buffer of the camera.
191
246
  * @param value - The clear depth buffer.
@@ -496,6 +551,7 @@ class CameraComponentElement extends ComponentElement {
496
551
  ...super.observedAttributes,
497
552
  'clear-color',
498
553
  'clear-color-buffer',
554
+ 'clear-depth',
499
555
  'clear-depth-buffer',
500
556
  'clear-stencil-buffer',
501
557
  'cull-faces',
@@ -525,11 +581,14 @@ class CameraComponentElement extends ComponentElement {
525
581
  case 'clear-color-buffer':
526
582
  this.clearColorBuffer = parseBool(newValue, true);
527
583
  break;
584
+ case 'clear-depth':
585
+ this.clearDepth = parseNumber(newValue, 1, name);
586
+ break;
528
587
  case 'clear-depth-buffer':
529
588
  this.clearDepthBuffer = parseBool(newValue, true);
530
589
  break;
531
590
  case 'clear-stencil-buffer':
532
- this.clearStencilBuffer = parseBool(newValue, false);
591
+ this.clearStencilBuffer = parseBool(newValue, true);
533
592
  break;
534
593
  case 'cull-faces':
535
594
  this.cullFaces = parseBool(newValue, true);
@@ -17,6 +17,12 @@ import { ComponentElement } from './component';
17
17
  * retargets or rebinds picks up the new node's geometry. An entity with no asset-backed render
18
18
  * component warns, and the collider has no shape.
19
19
  *
20
+ * Engine component: {@link CollisionComponent} (`collision`).
21
+ *
22
+ * @elementSummary The `<pc-collision>` element gives its entity a collision shape — a box, sphere,
23
+ * capsule, cone, cylinder or mesh — for the physics simulation to collide against. Pair it with a
24
+ * `<pc-rigid-body>`. Must be a child of a `<pc-entity>`, `<pc-model>` or `<pc-node>`.
25
+ *
20
26
  * @category Components
21
27
  */
22
28
  class CollisionComponentElement extends ComponentElement {
@@ -64,7 +70,9 @@ class CollisionComponentElement extends ComponentElement {
64
70
  * no attribute to supply it - so the host's visible geometry, the meaning a mesh collider
65
71
  * on a glTF node carries, fills the gap. Runs on every application (so a rebound `pc-node`
66
72
  * recomputes it) and on a runtime switch to `type="mesh"`; an explicitly assigned
67
- * `renderAsset` is never overwritten.
73
+ * `renderAsset` is never overwritten. A `pc-model` host entity never carries a render
74
+ * component (the instantiated content beneath it does), so a mesh collider that should take
75
+ * an asset's geometry belongs on a bound `pc-node`.
68
76
  */
69
77
  private _applyMeshGeometryDefault() {
70
78
  const component = this.component;
@@ -109,7 +109,7 @@ class ComponentElement extends AsyncElement {
109
109
  // It still becomes ready (with a null `component`), so warn rather than fail silently
110
110
  const label = this.id ? ` '${this.id}'` : '';
111
111
  console.warn(
112
- `${this.tagName.toLowerCase()}${label} must be a descendant of pc-entity - component not added`
112
+ `${this.tagName.toLowerCase()}${label} must be a descendant of pc-entity, pc-model or pc-node - component not added`
113
113
  );
114
114
  return;
115
115
  }
@@ -214,8 +214,9 @@ class ComponentElement extends AsyncElement {
214
214
 
215
215
  /**
216
216
  * The PlayCanvas component instance. `null` until the element is ready, and also for an
217
- * element that is not a descendant of a `<pc-entity>` — await {@link whenReady} or the
218
- * element's `ready()` promise before accessing it.
217
+ * element that is not a descendant of an entity-fronting element (`<pc-entity>`,
218
+ * `<pc-model>` or `<pc-node>`) — await {@link whenReady} or the element's `ready()` promise
219
+ * before accessing it.
219
220
  * @returns The component instance, or `null`.
220
221
  */
221
222
  get component(): Component | null {
@@ -12,6 +12,17 @@ import { ComponentElement } from './component';
12
12
  * The ElementComponentElement interface also inherits the properties and methods of the
13
13
  * {@link HTMLElement} interface.
14
14
  *
15
+ * Despite the name, this is not a base class or a generic wrapper: it is the engine's 2D UI
16
+ * component, which gives its host entity a rectangle in a `<pc-screen>` hierarchy that draws
17
+ * either an image, a line of text or nothing (`type="image"`, `"text"` or `"group"`). The tag
18
+ * spells the engine component it adds, as every component element does.
19
+ *
20
+ * Engine component: {@link ElementComponent} (`element`).
21
+ *
22
+ * @elementSummary The `<pc-element>` element gives its entity a 2D UI rectangle inside a
23
+ * `<pc-screen>` hierarchy, drawing an image, a line of text or nothing (`type="image"`, `"text"` or
24
+ * `"group"`). Must be a child of a `<pc-entity>`, `<pc-model>` or `<pc-node>`.
25
+ *
15
26
  * @category Components
16
27
  */
17
28
  class ElementComponentElement extends ComponentElement {
@@ -11,6 +11,12 @@ import { ComponentElement } from './component';
11
11
  * The GSplatComponentElement interface also inherits the properties and methods of the
12
12
  * {@link HTMLElement} interface.
13
13
  *
14
+ * Engine component: {@link GSplatComponent} (`gsplat`).
15
+ *
16
+ * @elementSummary The `<pc-gsplat>` element renders the 3D Gaussian splats of a `gsplat` asset at
17
+ * its entity, with attributes for shadow casting and level of detail. Must be a child of a
18
+ * `<pc-entity>`, `<pc-model>` or `<pc-node>`.
19
+ *
14
20
  * @category Components
15
21
  */
16
22
  class GSplatComponentElement extends ComponentElement {
@@ -5,9 +5,14 @@ import { getEntity, parseBool, parseEnum, parseNumber, parseVec2, parseVec3 } fr
5
5
 
6
6
  import { ComponentElement } from './component';
7
7
 
8
- type JointType = 'fixed' | 'ball' | 'hinge' | 'slider' | '6dof';
8
+ /** The constraint types supported by the `<pc-joint>` element. */
9
+ export type JointType = 'fixed' | 'ball' | 'hinge' | 'slider' | '6dof';
9
10
 
10
- type MotionMode = 'locked' | 'limited' | 'free';
11
+ /**
12
+ * The motion modes for a single joint axis: fully constrained (`locked`), constrained within
13
+ * limits (`limited`) or unconstrained (`free`).
14
+ */
15
+ export type MotionMode = 'locked' | 'limited' | 'free';
11
16
 
12
17
  /**
13
18
  * The JointComponentElement interface provides properties and methods for manipulating
@@ -22,10 +27,17 @@ type MotionMode = 'locked' | 'limited' | 'free';
22
27
  * a rigid body component; leaving `entity-b` empty constrains `entity-a` to a fixed point in world
23
28
  * space. The underlying engine component is in alpha, so its API may change.
24
29
  *
30
+ * @elementSummary The `<pc-joint>` element constrains two rigid bodies to each other — a hinged
31
+ * door, a swinging chain, a sliding drawer. Its entity's transform is the joint frame, and
32
+ * `entity-a` and `entity-b` name the bodies. Must be a child of a `<pc-entity>`, `<pc-model>` or
33
+ * `<pc-node>`.
34
+ *
25
35
  * @fires {CustomEvent} break - Fired when the impulse on the joint exceeds `break-impulse` and the
26
36
  * constraint breaks. A broken joint no longer constrains its bodies; calling `refreshFrames()` on
27
37
  * the underlying component re-attaches it. Bubbles and is composed.
28
38
  *
39
+ * Engine component: {@link JointComponent} (`joint`).
40
+ *
29
41
  * @category Components
30
42
  */
31
43
  class JointComponentElement extends ComponentElement {
@@ -6,10 +6,16 @@ import { ComponentElement } from './component';
6
6
 
7
7
  /**
8
8
  * The LayoutChildComponentElement interface provides properties and methods for manipulating
9
- * {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-layoutchild/ | `<pc-layoutchild>`} elements.
9
+ * {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-layout-child/ | `<pc-layout-child>`} elements.
10
10
  * The LayoutChildComponentElement interface also inherits the properties and methods of the
11
11
  * {@link HTMLElement} interface.
12
12
  *
13
+ * Engine component: {@link LayoutChildComponent} (`layoutchild`).
14
+ *
15
+ * @elementSummary The `<pc-layout-child>` element controls how its entity is sized by the
16
+ * `<pc-layout-group>` above it, through minimum and maximum sizes and fit proportions. Must be a
17
+ * child of a `<pc-entity>`, `<pc-model>` or `<pc-node>`.
18
+ *
13
19
  * @category Components
14
20
  */
15
21
  class LayoutChildComponentElement extends ComponentElement {
@@ -229,6 +235,6 @@ class LayoutChildComponentElement extends ComponentElement {
229
235
  }
230
236
  }
231
237
 
232
- customElements.define('pc-layoutchild', LayoutChildComponentElement);
238
+ customElements.define('pc-layout-child', LayoutChildComponentElement);
233
239
 
234
240
  export { LayoutChildComponentElement };
@@ -28,10 +28,16 @@ const fittings = new Map<'none' | 'stretch' | 'shrink' | 'both', number>([
28
28
 
29
29
  /**
30
30
  * The LayoutGroupComponentElement interface provides properties and methods for manipulating
31
- * {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-layoutgroup/ | `<pc-layoutgroup>`} elements.
31
+ * {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-layout-group/ | `<pc-layout-group>`} elements.
32
32
  * The LayoutGroupComponentElement interface also inherits the properties and methods of the
33
33
  * {@link HTMLElement} interface.
34
34
  *
35
+ * Engine component: {@link LayoutGroupComponent} (`layoutgroup`).
36
+ *
37
+ * @elementSummary The `<pc-layout-group>` element arranges its entity's children in a row or
38
+ * column, with spacing, padding, alignment and fitting. Must be a child of a `<pc-entity>`,
39
+ * `<pc-model>` or `<pc-node>`.
40
+ *
35
41
  * @category Components
36
42
  */
37
43
  class LayoutGroupComponentElement extends ComponentElement {
@@ -304,6 +310,6 @@ class LayoutGroupComponentElement extends ComponentElement {
304
310
  }
305
311
  }
306
312
 
307
- customElements.define('pc-layoutgroup', LayoutGroupComponentElement);
313
+ customElements.define('pc-layout-group', LayoutGroupComponentElement);
308
314
 
309
315
  export { LayoutGroupComponentElement };
@@ -37,9 +37,19 @@ const shadowTypes = new Map<
37
37
  * The LightComponentElement interface also inherits the properties and methods of the
38
38
  * {@link HTMLElement} interface.
39
39
  *
40
+ * Engine component: {@link LightComponent} (`light`).
41
+ *
42
+ * @elementSummary The `<pc-light>` element lights the scene from its entity — as a directional,
43
+ * omni or spot light — with attributes for color, intensity, range and shadows. Must be a child of
44
+ * a `<pc-entity>`, `<pc-model>` or `<pc-node>`.
45
+ *
40
46
  * @category Components
41
47
  */
42
48
  class LightComponentElement extends ComponentElement {
49
+ private _cascadeBlend = 0;
50
+
51
+ private _cascadeDistribution = 0.5;
52
+
43
53
  private _castShadows = false;
44
54
 
45
55
  private _color = new Color(1, 1, 1);
@@ -48,15 +58,17 @@ class LightComponentElement extends ComponentElement {
48
58
 
49
59
  private _intensity = 1;
50
60
 
51
- private _normalOffsetBias = 0.05;
61
+ private _normalOffsetBias = 0;
62
+
63
+ private _numCascades = 1;
52
64
 
53
65
  private _outerConeAngle = 45;
54
66
 
55
67
  private _range = 10;
56
68
 
57
- private _shadowBias = 0.2;
69
+ private _shadowBias = 0.05;
58
70
 
59
- private _shadowDistance = 16;
71
+ private _shadowDistance = 40;
60
72
 
61
73
  private _shadowIntensity = 1;
62
74
 
@@ -75,7 +87,7 @@ class LightComponentElement extends ComponentElement {
75
87
 
76
88
  private _type: 'directional' | 'omni' | 'spot' = 'directional';
77
89
 
78
- private _vsmBias = 0.01;
90
+ private _vsmBias = 0.0025;
79
91
 
80
92
  private _vsmBlurSize = 11;
81
93
 
@@ -94,11 +106,14 @@ class LightComponentElement extends ComponentElement {
94
106
 
95
107
  protected getInitialComponentData() {
96
108
  return {
109
+ cascadeBlend: this._cascadeBlend,
110
+ cascadeDistribution: this._cascadeDistribution,
97
111
  castShadows: this._castShadows,
98
112
  color: this._color,
99
113
  innerConeAngle: this._innerConeAngle,
100
114
  intensity: this._intensity,
101
115
  normalOffsetBias: this._normalOffsetBias,
116
+ numCascades: this._numCascades,
102
117
  outerConeAngle: this._outerConeAngle,
103
118
  penumbraFalloff: this._penumbraFalloff,
104
119
  penumbraSize: this._penumbraSize,
@@ -109,7 +124,7 @@ class LightComponentElement extends ComponentElement {
109
124
  shadowIntensity: this._shadowIntensity,
110
125
  shadowResolution: this._shadowResolution,
111
126
  shadowSamples: this._shadowSamples,
112
- shadowType: shadowTypes.get(this._shadowType),
127
+ shadowType: shadowTypes.get(this._shadowType) ?? SHADOW_PCF3_32F,
113
128
  type: this._type,
114
129
  vsmBias: this._vsmBias,
115
130
  vsmBlurSize: this._vsmBlurSize
@@ -124,6 +139,51 @@ class LightComponentElement extends ComponentElement {
124
139
  return super.component as LightComponent;
125
140
  }
126
141
 
142
+ /**
143
+ * Sets the fraction of each shadow cascade that is blended into the next one, from 0 (no
144
+ * blending) to 1, which applies only to `directional` lights with `num-cascades` greater than
145
+ * 1. Defaults to 0.
146
+ * @param value - The cascade blend factor.
147
+ */
148
+ set cascadeBlend(value: number) {
149
+ this._cascadeBlend = value;
150
+ if (this.component) {
151
+ this.component.cascadeBlend = value;
152
+ }
153
+ }
154
+
155
+ /**
156
+ * Gets the cascade blend factor of the light, from 0 (no blending) to 1, which applies only to
157
+ * `directional` lights with `num-cascades` greater than 1.
158
+ * @returns The cascade blend factor.
159
+ */
160
+ get cascadeBlend() {
161
+ return this._cascadeBlend;
162
+ }
163
+
164
+ /**
165
+ * Sets the distribution of the camera frustum split between shadow cascades, from 0 (linear
166
+ * split) to 1 (logarithmic split, concentrating shadow resolution near the camera), which
167
+ * applies only to `directional` lights with `num-cascades` greater than 1. Defaults to 0.5.
168
+ * @param value - The cascade distribution.
169
+ */
170
+ set cascadeDistribution(value: number) {
171
+ this._cascadeDistribution = value;
172
+ if (this.component) {
173
+ this.component.cascadeDistribution = value;
174
+ }
175
+ }
176
+
177
+ /**
178
+ * Gets the cascade distribution of the light, from 0 (linear split) to 1 (logarithmic split,
179
+ * concentrating shadow resolution near the camera), which applies only to `directional` lights
180
+ * with `num-cascades` greater than 1.
181
+ * @returns The cascade distribution.
182
+ */
183
+ get cascadeDistribution() {
184
+ return this._cascadeDistribution;
185
+ }
186
+
127
187
  /**
128
188
  * Sets the cast shadows flag of the light.
129
189
  * @param value - The cast shadows flag.
@@ -219,6 +279,27 @@ class LightComponentElement extends ComponentElement {
219
279
  return this._normalOffsetBias;
220
280
  }
221
281
 
282
+ /**
283
+ * Sets the number of shadow cascades of the light, an integer from 1 (no cascades) to 4, which
284
+ * applies only to `directional` lights. Defaults to 1.
285
+ * @param value - The number of shadow cascades.
286
+ */
287
+ set numCascades(value: number) {
288
+ this._numCascades = value;
289
+ if (this.component) {
290
+ this.component.numCascades = value;
291
+ }
292
+ }
293
+
294
+ /**
295
+ * Gets the number of shadow cascades of the light, an integer from 1 (no cascades) to 4, which
296
+ * applies only to `directional` lights.
297
+ * @returns The number of shadow cascades.
298
+ */
299
+ get numCascades() {
300
+ return this._numCascades;
301
+ }
302
+
222
303
  /**
223
304
  * Sets the outer cone angle of the light.
224
305
  * @param value - The outer cone angle.
@@ -510,11 +591,14 @@ class LightComponentElement extends ComponentElement {
510
591
  static get observedAttributes() {
511
592
  return [
512
593
  ...super.observedAttributes,
513
- 'color',
594
+ 'cascade-blend',
595
+ 'cascade-distribution',
514
596
  'cast-shadows',
515
- 'intensity',
597
+ 'color',
516
598
  'inner-cone-angle',
599
+ 'intensity',
517
600
  'normal-offset-bias',
601
+ 'num-cascades',
518
602
  'outer-cone-angle',
519
603
  'penumbra-falloff',
520
604
  'penumbra-size',
@@ -536,12 +620,18 @@ class LightComponentElement extends ComponentElement {
536
620
  super.attributeChangedCallback(name, _oldValue, newValue);
537
621
 
538
622
  switch (name) {
539
- case 'color':
540
- this.color = parseColor(newValue, Color.WHITE, name);
623
+ case 'cascade-blend':
624
+ this.cascadeBlend = parseNumber(newValue, 0, name);
625
+ break;
626
+ case 'cascade-distribution':
627
+ this.cascadeDistribution = parseNumber(newValue, 0.5, name);
541
628
  break;
542
629
  case 'cast-shadows':
543
630
  this.castShadows = parseBool(newValue, false);
544
631
  break;
632
+ case 'color':
633
+ this.color = parseColor(newValue, Color.WHITE, name);
634
+ break;
545
635
  case 'inner-cone-angle':
546
636
  this.innerConeAngle = parseNumber(newValue, 40, name);
547
637
  break;
@@ -549,7 +639,10 @@ class LightComponentElement extends ComponentElement {
549
639
  this.intensity = parseNumber(newValue, 1, name);
550
640
  break;
551
641
  case 'normal-offset-bias':
552
- this.normalOffsetBias = parseNumber(newValue, 0.05, name);
642
+ this.normalOffsetBias = parseNumber(newValue, 0, name);
643
+ break;
644
+ case 'num-cascades':
645
+ this.numCascades = parseNumber(newValue, 1, name);
553
646
  break;
554
647
  case 'outer-cone-angle':
555
648
  this.outerConeAngle = parseNumber(newValue, 45, name);
@@ -564,20 +657,20 @@ class LightComponentElement extends ComponentElement {
564
657
  this.range = parseNumber(newValue, 10, name);
565
658
  break;
566
659
  case 'shadow-bias':
567
- this.shadowBias = parseNumber(newValue, 0.2, name);
568
- break;
569
- case 'shadow-distance':
570
- this.shadowDistance = parseNumber(newValue, 16, name);
660
+ this.shadowBias = parseNumber(newValue, 0.05, name);
571
661
  break;
572
662
  case 'shadow-blocker-samples':
573
663
  this.shadowBlockerSamples = parseNumber(newValue, 16, name);
574
664
  break;
575
- case 'shadow-resolution':
576
- this.shadowResolution = parseNumber(newValue, 1024, name);
665
+ case 'shadow-distance':
666
+ this.shadowDistance = parseNumber(newValue, 40, name);
577
667
  break;
578
668
  case 'shadow-intensity':
579
669
  this.shadowIntensity = parseNumber(newValue, 1, name);
580
670
  break;
671
+ case 'shadow-resolution':
672
+ this.shadowResolution = parseNumber(newValue, 1024, name);
673
+ break;
581
674
  case 'shadow-samples':
582
675
  this.shadowSamples = parseNumber(newValue, 16, name);
583
676
  break;
@@ -588,7 +681,7 @@ class LightComponentElement extends ComponentElement {
588
681
  this.type = parseEnum(newValue, ['directional', 'omni', 'spot'], 'directional', name);
589
682
  break;
590
683
  case 'vsm-bias':
591
- this.vsmBias = parseNumber(newValue, 0.01, name);
684
+ this.vsmBias = parseNumber(newValue, 0.0025, name);
592
685
  break;
593
686
  case 'vsm-blur-size':
594
687
  this.vsmBlurSize = parseNumber(newValue, 11, name);
@@ -6,10 +6,16 @@ import { ComponentElement } from './component';
6
6
 
7
7
  /**
8
8
  * The ParticleSystemComponentElement interface provides properties and methods for manipulating
9
- * {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-particles/ | `<pc-particles>`} elements.
9
+ * {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-particle-system/ | `<pc-particle-system>`} elements.
10
10
  * The ParticleSystemComponentElement interface also inherits the properties and methods of the
11
11
  * {@link HTMLElement} interface.
12
12
  *
13
+ * Engine component: {@link ParticleSystemComponent} (`particlesystem`).
14
+ *
15
+ * @elementSummary The `<pc-particle-system>` element emits particles from its entity, with
16
+ * attributes for the emitter's shape, rate, lifetime, textures and blending. Must be a child of a
17
+ * `<pc-entity>`, `<pc-model>` or `<pc-node>`.
18
+ *
13
19
  * @category Components
14
20
  */
15
21
  class ParticleSystemComponentElement extends ComponentElement {
@@ -147,6 +153,6 @@ class ParticleSystemComponentElement extends ComponentElement {
147
153
  }
148
154
  }
149
155
 
150
- customElements.define('pc-particles', ParticleSystemComponentElement);
156
+ customElements.define('pc-particle-system', ParticleSystemComponentElement);
151
157
 
152
158
  export { ParticleSystemComponentElement };
@@ -15,6 +15,13 @@ import { ComponentElement } from './component';
15
15
  * to `box`). It does not cover the engine's `asset` render type, since there is no way to supply
16
16
  * a render asset here — use `pc-model` for glTF content instead.
17
17
  *
18
+ * Engine component: {@link RenderComponent} (`render`).
19
+ *
20
+ * @elementSummary The `<pc-render>` element renders one of the engine's built-in primitives at its
21
+ * entity — box, sphere, capsule, cone, cylinder or plane — shaded by the `<pc-material>` its
22
+ * `material` attribute names. For glTF content, use `<pc-model>` instead. Must be a child of a
23
+ * `<pc-entity>`, `<pc-model>` or `<pc-node>`.
24
+ *
18
25
  * @category Components
19
26
  */
20
27
  class RenderComponentElement extends ComponentElement {
@@ -7,10 +7,17 @@ import { ComponentElement } from './component';
7
7
 
8
8
  /**
9
9
  * The RigidBodyComponentElement interface provides properties and methods for manipulating
10
- * {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-rigidbody/ | `<pc-rigidbody>`} elements.
10
+ * {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-rigid-body/ | `<pc-rigid-body>`} elements.
11
11
  * The RigidBodyComponentElement interface also inherits the properties and methods of the
12
12
  * {@link HTMLElement} interface.
13
13
  *
14
+ * Engine component: {@link RigidBodyComponent} (`rigidbody`).
15
+ *
16
+ * @elementSummary The `<pc-rigid-body>` element hands its entity to the physics simulation, with
17
+ * attributes for its type, mass, friction and restitution. It needs a sibling `<pc-collision>` for
18
+ * its shape, and `Ammo` loaded through `<pc-wasm>`. Must be a child of a `<pc-entity>`,
19
+ * `<pc-model>` or `<pc-node>`.
20
+ *
14
21
  * @category Components
15
22
  */
16
23
  class RigidBodyComponentElement extends ComponentElement {
@@ -235,6 +242,6 @@ class RigidBodyComponentElement extends ComponentElement {
235
242
  }
236
243
  }
237
244
 
238
- customElements.define('pc-rigidbody', RigidBodyComponentElement);
245
+ customElements.define('pc-rigid-body', RigidBodyComponentElement);
239
246
 
240
247
  export { RigidBodyComponentElement };
@@ -20,6 +20,12 @@ const scaleModes = new Map<'none' | 'blend', string>([
20
20
  * The ScreenComponentElement interface also inherits the properties and methods of the
21
21
  * {@link HTMLElement} interface.
22
22
  *
23
+ * Engine component: {@link ScreenComponent} (`screen`).
24
+ *
25
+ * @elementSummary The `<pc-screen>` element gives its entity a 2D space — in screen space or in the
26
+ * world — that a hierarchy of `<pc-element>` descendants lays out inside. Must be a child of a
27
+ * `<pc-entity>`, `<pc-model>` or `<pc-node>`.
28
+ *
23
29
  * @category Components
24
30
  */
25
31
  class ScreenComponentElement extends ComponentElement {