@zephyr3d/scene 0.9.6 → 0.9.7

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 (203) hide show
  1. package/dist/animation/joint_dynamics/controller.js +92 -32
  2. package/dist/animation/joint_dynamics/controller.js.map +1 -1
  3. package/dist/animation/joint_dynamics/convex_collider.js +320 -0
  4. package/dist/animation/joint_dynamics/convex_collider.js.map +1 -0
  5. package/dist/animation/joint_dynamics/joint_dynamics_system.js +57 -19
  6. package/dist/animation/joint_dynamics/joint_dynamics_system.js.map +1 -1
  7. package/dist/animation/joint_dynamics/solver.js +71 -27
  8. package/dist/animation/joint_dynamics/solver.js.map +1 -1
  9. package/dist/animation/joint_dynamics_modifier.js +21 -20
  10. package/dist/animation/joint_dynamics_modifier.js.map +1 -1
  11. package/dist/animation/skeleton.js +7 -10
  12. package/dist/animation/skeleton.js.map +1 -1
  13. package/dist/app/engine.js +134 -140
  14. package/dist/app/engine.js.map +1 -1
  15. package/dist/app/scriptregistry.js +47 -16
  16. package/dist/app/scriptregistry.js.map +1 -1
  17. package/dist/asset/assetmanager.js +3 -1
  18. package/dist/asset/assetmanager.js.map +1 -1
  19. package/dist/asset/model.js +346 -7
  20. package/dist/asset/model.js.map +1 -1
  21. package/dist/avatar/wardrobe.js +20 -16
  22. package/dist/avatar/wardrobe.js.map +1 -1
  23. package/dist/camera/camera.js +416 -210
  24. package/dist/camera/camera.js.map +1 -1
  25. package/dist/index.d.ts +1349 -621
  26. package/dist/index.js +6 -11
  27. package/dist/index.js.map +1 -1
  28. package/dist/material/blinn.js +1 -1
  29. package/dist/material/blinn.js.map +1 -1
  30. package/dist/material/lambert.js +1 -1
  31. package/dist/material/lambert.js.map +1 -1
  32. package/dist/material/material.js +23 -1
  33. package/dist/material/material.js.map +1 -1
  34. package/dist/material/meshmaterial.js +178 -23
  35. package/dist/material/meshmaterial.js.map +1 -1
  36. package/dist/material/mixins/albedocolor.js +4 -4
  37. package/dist/material/mixins/albedocolor.js.map +1 -1
  38. package/dist/material/mixins/lightmodel/blinnphong.js +2 -1
  39. package/dist/material/mixins/lightmodel/blinnphong.js.map +1 -1
  40. package/dist/material/mixins/lightmodel/lambert.js +2 -1
  41. package/dist/material/mixins/lightmodel/lambert.js.map +1 -1
  42. package/dist/material/mixins/lightmodel/pbrblueprintmixin.js +63 -16
  43. package/dist/material/mixins/lightmodel/pbrblueprintmixin.js.map +1 -1
  44. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js +105 -32
  45. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -1
  46. package/dist/material/mixins/lightmodel/pbrspecularglossness.js +16 -6
  47. package/dist/material/mixins/lightmodel/pbrspecularglossness.js.map +1 -1
  48. package/dist/material/mixins/lit.js +1 -1
  49. package/dist/material/mixins/lit.js.map +1 -1
  50. package/dist/material/mixins/pbr/common.js +276 -65
  51. package/dist/material/mixins/pbr/common.js.map +1 -1
  52. package/dist/material/mixins/texture.js +3 -3
  53. package/dist/material/mixins/texture.js.map +1 -1
  54. package/dist/material/mixins/vertexcolor.js +2 -2
  55. package/dist/material/mixins/vertexcolor.js.map +1 -1
  56. package/dist/material/mtoon.js +574 -0
  57. package/dist/material/mtoon.js.map +1 -0
  58. package/dist/material/pbrblueprint.js +499 -336
  59. package/dist/material/pbrblueprint.js.map +1 -1
  60. package/dist/material/pbrmr.js +118 -100
  61. package/dist/material/pbrmr.js.map +1 -1
  62. package/dist/material/pbrsg.js +1 -1
  63. package/dist/material/pbrsg.js.map +1 -1
  64. package/dist/material/shader/helper.js +324 -294
  65. package/dist/material/shader/helper.js.map +1 -1
  66. package/dist/material/subsurfaceprofile.js +812 -0
  67. package/dist/material/subsurfaceprofile.js.map +1 -0
  68. package/dist/material/unlit.js +1 -1
  69. package/dist/material/unlit.js.map +1 -1
  70. package/dist/posteffect/compositor.js +46 -11
  71. package/dist/posteffect/compositor.js.map +1 -1
  72. package/dist/posteffect/ssr.js +422 -96
  73. package/dist/posteffect/ssr.js.map +1 -1
  74. package/dist/posteffect/sss.js +1053 -0
  75. package/dist/posteffect/sss.js.map +1 -0
  76. package/dist/posteffect/taa.js +61 -60
  77. package/dist/posteffect/taa.js.map +1 -1
  78. package/dist/render/abuffer_oit.js +63 -12
  79. package/dist/render/abuffer_oit.js.map +1 -1
  80. package/dist/render/cluster_light.js +6 -5
  81. package/dist/render/cluster_light.js.map +1 -1
  82. package/dist/render/drawable.js +1 -5
  83. package/dist/render/drawable.js.map +1 -1
  84. package/dist/render/drawable_mixin.js +2 -1
  85. package/dist/render/drawable_mixin.js.map +1 -1
  86. package/dist/render/fbm_wavegenerator.js +2 -1
  87. package/dist/render/fbm_wavegenerator.js.map +1 -1
  88. package/dist/render/gerstner_wavegenerator.js +2 -1
  89. package/dist/render/gerstner_wavegenerator.js.map +1 -1
  90. package/dist/render/globalbindgroup_allocator.js +2 -1
  91. package/dist/render/globalbindgroup_allocator.js.map +1 -1
  92. package/dist/render/lightpass.js +110 -23
  93. package/dist/render/lightpass.js.map +1 -1
  94. package/dist/render/render_queue.js +51 -8
  95. package/dist/render/render_queue.js.map +1 -1
  96. package/dist/render/renderer.js +80 -66
  97. package/dist/render/renderer.js.map +1 -1
  98. package/dist/render/rendergraph/device_pool_allocator.js +8 -0
  99. package/dist/render/rendergraph/device_pool_allocator.js.map +1 -1
  100. package/dist/render/rendergraph/forward_plus_builder.js +481 -95
  101. package/dist/render/rendergraph/forward_plus_builder.js.map +1 -1
  102. package/dist/render/rendergraph/history_resource_manager.js +55 -0
  103. package/dist/render/rendergraph/history_resource_manager.js.map +1 -1
  104. package/dist/render/rendergraph/history_resources.js +3 -1
  105. package/dist/render/rendergraph/history_resources.js.map +1 -1
  106. package/dist/render/rendergraph/types.js.map +1 -1
  107. package/dist/render/renderpass.js +10 -4
  108. package/dist/render/renderpass.js.map +1 -1
  109. package/dist/render/sky.js +31 -1
  110. package/dist/render/sky.js.map +1 -1
  111. package/dist/render/weightedblended_oit.js +23 -5
  112. package/dist/render/weightedblended_oit.js.map +1 -1
  113. package/dist/scene/basesprite.js +4 -2
  114. package/dist/scene/basesprite.js.map +1 -1
  115. package/dist/scene/batchgroup.js +3 -1
  116. package/dist/scene/batchgroup.js.map +1 -1
  117. package/dist/scene/environment.js +11 -1
  118. package/dist/scene/environment.js.map +1 -1
  119. package/dist/scene/light.js +21 -3
  120. package/dist/scene/light.js.map +1 -1
  121. package/dist/scene/mesh.js +29 -14
  122. package/dist/scene/mesh.js.map +1 -1
  123. package/dist/scene/meshdrawable.js +6 -0
  124. package/dist/scene/meshdrawable.js.map +1 -1
  125. package/dist/scene/msdftext.js +5 -2
  126. package/dist/scene/msdftext.js.map +1 -1
  127. package/dist/scene/msdftextsprite.js +5 -3
  128. package/dist/scene/msdftextsprite.js.map +1 -1
  129. package/dist/scene/particlesys.js +3 -1
  130. package/dist/scene/particlesys.js.map +1 -1
  131. package/dist/scene/scene.js +6 -5
  132. package/dist/scene/scene.js.map +1 -1
  133. package/dist/scene/terrain-cm/grass.js +4 -2
  134. package/dist/scene/terrain-cm/grass.js.map +1 -1
  135. package/dist/scene/terrain-cm/grassmaterial.js +2 -1
  136. package/dist/scene/terrain-cm/grassmaterial.js.map +1 -1
  137. package/dist/scene/terrain-cm/terrain-cm.js +4 -2
  138. package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
  139. package/dist/scene/water.js +4 -2
  140. package/dist/scene/water.js.map +1 -1
  141. package/dist/shaders/shadow.js +26 -393
  142. package/dist/shaders/shadow.js.map +1 -1
  143. package/dist/shadow/esm.js +112 -12
  144. package/dist/shadow/esm.js.map +1 -1
  145. package/dist/shadow/pcf_opt.js +2 -2
  146. package/dist/shadow/pcf_opt.js.map +1 -1
  147. package/dist/shadow/pcf_pd.js +19 -10
  148. package/dist/shadow/pcf_pd.js.map +1 -1
  149. package/dist/shadow/shader.js +58 -7
  150. package/dist/shadow/shader.js.map +1 -1
  151. package/dist/shadow/shadow_impl.js +6 -0
  152. package/dist/shadow/shadow_impl.js.map +1 -1
  153. package/dist/shadow/shadow_region.js +229 -0
  154. package/dist/shadow/shadow_region.js.map +1 -0
  155. package/dist/shadow/shadowmapper.js +67 -59
  156. package/dist/shadow/shadowmapper.js.map +1 -1
  157. package/dist/shadow/vsm.js +45 -19
  158. package/dist/shadow/vsm.js.map +1 -1
  159. package/dist/utility/blueprint/common/constants.js +8 -8
  160. package/dist/utility/blueprint/common/constants.js.map +1 -1
  161. package/dist/utility/blueprint/material/pbr.js +31 -4
  162. package/dist/utility/blueprint/material/pbr.js.map +1 -1
  163. package/dist/utility/blueprint/material/texture.js +1 -17
  164. package/dist/utility/blueprint/material/texture.js.map +1 -1
  165. package/dist/utility/serialization/manager.js +327 -359
  166. package/dist/utility/serialization/manager.js.map +1 -1
  167. package/dist/utility/serialization/scene/animation.js +5 -2
  168. package/dist/utility/serialization/scene/animation.js.map +1 -1
  169. package/dist/utility/serialization/scene/batch.js +4 -1
  170. package/dist/utility/serialization/scene/batch.js.map +1 -1
  171. package/dist/utility/serialization/scene/camera.js +249 -54
  172. package/dist/utility/serialization/scene/camera.js.map +1 -1
  173. package/dist/utility/serialization/scene/common.js +37 -1
  174. package/dist/utility/serialization/scene/common.js.map +1 -1
  175. package/dist/utility/serialization/scene/light.js +42 -3
  176. package/dist/utility/serialization/scene/light.js.map +1 -1
  177. package/dist/utility/serialization/scene/material.js +1112 -646
  178. package/dist/utility/serialization/scene/material.js.map +1 -1
  179. package/dist/utility/serialization/scene/mesh.js +7 -4
  180. package/dist/utility/serialization/scene/mesh.js.map +1 -1
  181. package/dist/utility/serialization/scene/node.js +31 -12
  182. package/dist/utility/serialization/scene/node.js.map +1 -1
  183. package/dist/utility/serialization/scene/particle.js +4 -1
  184. package/dist/utility/serialization/scene/particle.js.map +1 -1
  185. package/dist/utility/serialization/scene/primitive.js +3 -1
  186. package/dist/utility/serialization/scene/primitive.js.map +1 -1
  187. package/dist/utility/serialization/scene/scene.js +18 -0
  188. package/dist/utility/serialization/scene/scene.js.map +1 -1
  189. package/dist/utility/serialization/scene/sprite.js +6 -3
  190. package/dist/utility/serialization/scene/sprite.js.map +1 -1
  191. package/dist/utility/serialization/scene/terrain.js +5 -2
  192. package/dist/utility/serialization/scene/terrain.js.map +1 -1
  193. package/dist/utility/serialization/scene/text.js +3 -1
  194. package/dist/utility/serialization/scene/text.js.map +1 -1
  195. package/dist/utility/serialization/scene/water.js +4 -1
  196. package/dist/utility/serialization/scene/water.js.map +1 -1
  197. package/dist/utility/textures/ltcdata.js +6 -0
  198. package/dist/utility/textures/ltcdata.js.map +1 -0
  199. package/dist/utility/textures/ltclut.js +61 -0
  200. package/dist/utility/textures/ltclut.js.map +1 -0
  201. package/dist/values.js +9 -1
  202. package/dist/values.js.map +1 -1
  203. package/package.json +3 -3
@@ -3,6 +3,7 @@ import { SceneNode } from '../scene/scene_node.js';
3
3
  import { Compositor } from '../posteffect/compositor.js';
4
4
  import { TAA } from '../posteffect/taa.js';
5
5
  import { SSR } from '../posteffect/ssr.js';
6
+ import { SSS } from '../posteffect/sss.js';
6
7
  import { Tonemap } from '../posteffect/tonemap.js';
7
8
  import { FXAA } from '../posteffect/fxaa.js';
8
9
  import { Bloom } from '../posteffect/bloom.js';
@@ -14,26 +15,57 @@ import { ScreenAdapter } from '../app/screen.js';
14
15
  import { ABufferOIT } from '../render/abuffer_oit.js';
15
16
  import { WeightedBlendedOIT } from '../render/weightedblended_oit.js';
16
17
 
17
- /**
18
- * A renderable camera node that manages view/projection math, frusta,
19
- * input control, picking, and a post-processing chain via a compositor.
20
- *
21
- * Key features:
22
- * - Maintains projection, view, VP, and inverse VP matrices and lazily recomputes them when invalidated.
23
- * - Provides world- and view-space frusta for culling and clipping.
24
- * - Supports perspective and orthographic projections.
25
- * - Integrates with post effects (Tonemap, FXAA, TAA, Bloom, SSR, SSAO, Motion Blur) through an internal `Compositor`.
26
- * - Handles temporal jitter and history state when TAA or motion blur are enabled.
27
- * - Emits picking rays from screen coordinates and supports async GPU picking.
28
- * - Optional controller integration for user input handling.
29
- *
30
- * Performance notes:
31
- * - Matrices/frusta are computed on demand and cached until invalidation.
32
- * - Temporal jitter and history are set up only when required by enabled features and device support.
33
- *
34
- * @public
18
+ const SSS_DEFAULT_SETTINGS = {
19
+ blurScale: 11,
20
+ strength: 0.65,
21
+ transmissionStrength: 0.18,
22
+ transmissionPower: 2.1,
23
+ multiScatter: 0.08
24
+ };
25
+ const SSS_QUALITY_PRESET_SETTINGS = {
26
+ quality: {
27
+ halfRes: false,
28
+ blurKernelSize: 11,
29
+ blurStdDev: 3.5,
30
+ blurDepthCutoff: 0.24,
31
+ normalCutoff: 0.82
32
+ },
33
+ balanced: {
34
+ halfRes: false,
35
+ blurKernelSize: 9,
36
+ blurStdDev: 3,
37
+ blurDepthCutoff: 0.26,
38
+ normalCutoff: 0.78
39
+ },
40
+ performance: {
41
+ halfRes: true,
42
+ blurKernelSize: 7,
43
+ blurStdDev: 2.4,
44
+ blurDepthCutoff: 0.32,
45
+ normalCutoff: 0.72
46
+ }
47
+ };
48
+ /**
49
+ * A renderable camera node that manages view/projection math, frusta,
50
+ * input control, picking, and a post-processing chain via a compositor.
51
+ *
52
+ * Key features:
53
+ * - Maintains projection, view, VP, and inverse VP matrices and lazily recomputes them when invalidated.
54
+ * - Provides world- and view-space frusta for culling and clipping.
55
+ * - Supports perspective and orthographic projections.
56
+ * - Integrates with post effects (Tonemap, FXAA, TAA, Bloom, SSR, SSS, SSAO, Motion Blur) through an internal `Compositor`.
57
+ * - Handles temporal jitter and history state when TAA or motion blur are enabled.
58
+ * - Emits picking rays from screen coordinates and supports async GPU picking.
59
+ * - Optional controller integration for user input handling.
60
+ *
61
+ * Performance notes:
62
+ * - Matrices/frusta are computed on demand and cached until invalidation.
63
+ * - Temporal jitter and history are set up only when required by enabled features and device support.
64
+ *
65
+ * @public
35
66
  */ class Camera extends SceneNode {
36
67
  /** @internal Halton 2-3 sequence used for TAA jittering. */ static _halton23 = halton23(16);
68
+ /** @internal Per-camera history resources. */ static _historyData = new WeakMap();
37
69
  /** @internal Per-camera history resource manager. */ static _historyResourceManager = new WeakMap();
38
70
  /** @internal Screen adapter for this camera */ _screenAdapter;
39
71
  /** @internal Whether the camera is adapted */ _adapted;
@@ -60,6 +92,7 @@ import { WeightedBlendedOIT } from '../render/weightedblended_oit.js';
60
92
  /** @internal OIT algorithm selection mode. */ _oitMode;
61
93
  /** @internal ABuffer OIT layer budget. */ _oitABufferLayers;
62
94
  /** @internal Whether to perform a depth pre-pass. */ _depthPrePass;
95
+ /** @internal Render path selection for scene renderer. */ _renderPath;
63
96
  /** @internal Whether command buffers may be reused for optimization. */ _commandBufferReuse;
64
97
  /** @internal Hi-Z acceleration enable (primarily for SSR). */ _HiZ;
65
98
  /** @internal If true, a float point backbuffer will be used. The default value is true */ _HDR;
@@ -87,6 +120,7 @@ import { WeightedBlendedOIT } from '../render/weightedblended_oit.js';
87
120
  /** @internal TAA enable flag (via post effect). */ _TAA;
88
121
  /** @internal TAA post effect reference. */ _postEffectTAA;
89
122
  /** @internal TAA debug mode (implementation-defined). */ _TAADebug;
123
+ /** @internal Cascaded shadow debug visualization flag. */ _shadowDebugCascades;
90
124
  /** @internal SSR enable flag (via post effect). */ _SSR;
91
125
  /** @internal SSR post effect reference. */ _postEffectSSR;
92
126
  /** @internal SSR parameter vector: (maxDistance, iterations, thickness, reserved). */ _ssrParams;
@@ -98,6 +132,18 @@ import { WeightedBlendedOIT } from '../render/weightedblended_oit.js';
98
132
  /** @internal SSR blur depth cutoff. */ _ssrBlurDepthCutoff;
99
133
  /** @internal SSR blur kernel size. */ _ssrBlurKernelSize;
100
134
  /** @internal SSR Gaussian blur standard deviation. */ _ssrBlurStdDev;
135
+ /** @internal Whether SSR temporal accumulation is enabled. */ _ssrTemporal;
136
+ /** @internal SSR temporal blending weight in [0, 1]. */ _ssrTemporalWeight;
137
+ /** @internal SSS enable flag (via post effect). */ _SSS;
138
+ /** @internal SSS post effect reference. */ _postEffectSSS;
139
+ /** @internal SSS blur scale in pixels per authored width unit. */ _sssBlurScale;
140
+ /** @internal High-level preset that resolves SSS blur quality controls. */ _sssQualityPreset;
141
+ /** @internal SSS composite strength. */ _sssStrength;
142
+ /** @internal SSS thin-shell transmission strength. */ _sssTransmissionStrength;
143
+ /** @internal SSS thin-shell transmission exponent. */ _sssTransmissionPower;
144
+ /** @internal SSS multi-scatter energy compensation. */ _sssMultiScatter;
145
+ /** @internal Cached runtime SSS settings after applying the quality preset. */ _sssResolvedSettings;
146
+ /** @internal SSS debug visualization mode. */ _sssDebugView;
101
147
  /** @internal SSAO enable flag (via post effect). */ _SSAO;
102
148
  /** @internal SSAO post effect reference. */ _postEffectSSAO;
103
149
  /** @internal SSAO scale (sampling radius multiplier). */ _SSAOScale;
@@ -120,14 +166,14 @@ import { WeightedBlendedOIT } from '../render/weightedblended_oit.js';
120
166
  /** @internal Post-processing compositor attached to this camera. */ _compositor;
121
167
  /** @internal Pointer interaction rectangle in css pixels (relative to canvas) */ _interactionRect;
122
168
  /** @internal captured by which mouse button (-1 if not captured) */ _capturedButton;
123
- /**
124
- * Creates a new camera node.
125
- *
126
- * Initializes projection/view matrices, temporal fields, controller linkage, and
127
- * builds the default post-processing pipeline on the internal compositor.
128
- *
129
- * @param scene - The scene that owns this camera.
130
- * @param projectionMatrix - Optional projection matrix to initialize with.
169
+ /**
170
+ * Creates a new camera node.
171
+ *
172
+ * Initializes projection/view matrices, temporal fields, controller linkage, and
173
+ * builds the default post-processing pipeline on the internal compositor.
174
+ *
175
+ * @param scene - The scene that owns this camera.
176
+ * @param projectionMatrix - Optional projection matrix to initialize with.
131
177
  */ constructor(scene, projectionMatrix){
132
178
  super(scene);
133
179
  this._projMatrix = projectionMatrix || Matrix4x4.identity();
@@ -153,6 +199,7 @@ import { WeightedBlendedOIT } from '../render/weightedblended_oit.js';
153
199
  this._oitMode = 'none';
154
200
  this._oitABufferLayers = 20;
155
201
  this._depthPrePass = false;
202
+ this._renderPath = 'forward';
156
203
  this._screenAdapter = new ScreenAdapter();
157
204
  this._adapted = false;
158
205
  this._HiZ = false;
@@ -181,17 +228,38 @@ import { WeightedBlendedOIT } from '../render/weightedblended_oit.js';
181
228
  this._TAA = false;
182
229
  this._postEffectTAA = new DRef();
183
230
  this._TAADebug = 0;
231
+ this._shadowDebugCascades = false;
184
232
  this._SSR = false;
185
233
  this._postEffectSSR = new DRef();
186
- this._ssrParams = new Vector4(100, 120, 0.5, 0);
187
- this._ssrMaxRoughness = 0.8;
234
+ this._ssrParams = new Vector4(64, 96, 0.9, 0);
235
+ this._ssrMaxRoughness = 0.55;
188
236
  this._ssrRoughnessFactor = 1;
189
- this._ssrStride = 2;
237
+ this._ssrStride = 1;
190
238
  this._ssrCalcThickness = false;
191
- this._ssrBlurriness = 0.01;
239
+ this._ssrBlurriness = 0.008;
192
240
  this._ssrBlurDepthCutoff = 2;
193
- this._ssrBlurKernelSize = 10;
194
- this._ssrBlurStdDev = 10;
241
+ this._ssrBlurKernelSize = 5;
242
+ this._ssrBlurStdDev = 4;
243
+ this._ssrTemporal = true;
244
+ this._ssrTemporalWeight = 0.85;
245
+ this._SSS = false;
246
+ this._postEffectSSS = new DRef();
247
+ this._sssBlurScale = SSS_DEFAULT_SETTINGS.blurScale;
248
+ this._sssQualityPreset = 'balanced';
249
+ this._sssStrength = SSS_DEFAULT_SETTINGS.strength;
250
+ this._sssTransmissionStrength = SSS_DEFAULT_SETTINGS.transmissionStrength;
251
+ this._sssTransmissionPower = SSS_DEFAULT_SETTINGS.transmissionPower;
252
+ this._sssMultiScatter = SSS_DEFAULT_SETTINGS.multiScatter;
253
+ const defaultSSSQualityPreset = SSS_QUALITY_PRESET_SETTINGS.balanced;
254
+ this._sssResolvedSettings = {
255
+ halfRes: defaultSSSQualityPreset.halfRes,
256
+ blurKernelSize: defaultSSSQualityPreset.blurKernelSize,
257
+ blurStdDev: defaultSSSQualityPreset.blurStdDev,
258
+ blurDepthCutoff: defaultSSSQualityPreset.blurDepthCutoff,
259
+ normalCutoff: defaultSSSQualityPreset.normalCutoff
260
+ };
261
+ this.updateSSSResolvedSettings();
262
+ this._sssDebugView = 'none';
195
263
  this._SSAO = false;
196
264
  this._postEffectSSAO = new DRef();
197
265
  this._SSAOScale = 10;
@@ -220,73 +288,81 @@ import { WeightedBlendedOIT } from '../render/weightedblended_oit.js';
220
288
  scene.mainCamera = this;
221
289
  }
222
290
  }
223
- /**
224
- * The compositor that owns and runs the camera's post-processing chain.
291
+ /**
292
+ * The compositor that owns and runs the camera's post-processing chain.
225
293
  */ get compositor() {
226
294
  return this._compositor;
227
295
  }
228
- /**
229
- * Pointer interaction rectangle in css pixels (relative to canvas)
296
+ /**
297
+ * Pointer interaction rectangle in css pixels (relative to canvas)
230
298
  */ get interactionRect() {
231
299
  return this._interactionRect;
232
300
  }
233
301
  set interactionRect(rect) {
234
302
  this._interactionRect = rect;
235
303
  }
236
- /**
237
- * Framebuffer clear color, or `null` to disable.
304
+ /**
305
+ * Framebuffer clear color, or `null` to disable.
238
306
  */ get clearColor() {
239
307
  return this._clearColor;
240
308
  }
241
309
  set clearColor(v) {
242
310
  this._clearColor = v?.clone() ?? null;
243
311
  }
244
- /**
245
- * Framebuffer stencil clear value, disabled when null. Default is 0.
312
+ /**
313
+ * Framebuffer stencil clear value, disabled when null. Default is 0.
246
314
  */ get clearDepth() {
247
315
  return this._clearDepth;
248
316
  }
249
317
  set clearDepth(v) {
250
318
  this._clearDepth = v;
251
319
  }
252
- /**
253
- * Framebuffer stencil clear value, disabled when null. Default is 0.
320
+ /**
321
+ * Framebuffer stencil clear value, disabled when null. Default is 0.
254
322
  */ get clearStencil() {
255
323
  return this._clearStencil;
256
324
  }
257
325
  set clearStencil(v) {
258
326
  this._clearStencil = v;
259
327
  }
260
- /**
261
- * Whether Hi-Z acceleration is enabled.
262
- *
263
- * Often improves SSR performance with little quality impact when supported.
328
+ /**
329
+ * Whether Hi-Z acceleration is enabled.
330
+ *
331
+ * Often improves SSR performance with little quality impact when supported.
264
332
  */ get HiZ() {
265
333
  return this._HiZ;
266
334
  }
267
335
  set HiZ(val) {
268
336
  this._HiZ = !!val;
269
337
  }
270
- /**
271
- * Whether HDR backbuffer is enabled.
272
- *
273
- * Tonemap should be disabled when not using HDR backbuffer.
338
+ /**
339
+ * Render path used by the scene renderer.
340
+ */ get renderPath() {
341
+ return this._renderPath;
342
+ }
343
+ set renderPath(_val) {
344
+ this._renderPath = 'forward';
345
+ }
346
+ /**
347
+ * Whether HDR backbuffer is enabled.
348
+ *
349
+ * Tonemap should be disabled when not using HDR backbuffer.
274
350
  */ get HDR() {
275
351
  return this._HDR;
276
352
  }
277
353
  set HDR(val) {
278
354
  this._HDR = !!val;
279
355
  }
280
- /**
281
- * Whether tonemapping is enabled via the post effect.
356
+ /**
357
+ * Whether tonemapping is enabled via the post effect.
282
358
  */ get toneMap() {
283
359
  return this._postEffectTonemap.get().enabled;
284
360
  }
285
361
  set toneMap(val) {
286
362
  this._postEffectTonemap.get().enabled = !!val;
287
363
  }
288
- /**
289
- * Whether motion blur is enabled via the post effect.
364
+ /**
365
+ * Whether motion blur is enabled via the post effect.
290
366
  */ get motionBlur() {
291
367
  return this._postEffectMotionBlur.get().enabled;
292
368
  }
@@ -302,16 +378,16 @@ import { WeightedBlendedOIT } from '../render/weightedblended_oit.js';
302
378
  this._postEffectMotionBlur.get().strength = this._motionBlurStrength;
303
379
  }
304
380
  }
305
- /**
306
- * Gets whether Bloom is enabled.
381
+ /**
382
+ * Gets whether Bloom is enabled.
307
383
  */ get bloom() {
308
384
  return this._postEffectBloom.get().enabled;
309
385
  }
310
386
  set bloom(val) {
311
387
  this._postEffectBloom.get().enabled = !!val;
312
388
  }
313
- /**
314
- * Maximum bloom downsample levels
389
+ /**
390
+ * Maximum bloom downsample levels
315
391
  */ get bloomMaxDownsampleLevels() {
316
392
  return this._bloomMaxDownsampleLevels;
317
393
  }
@@ -321,8 +397,8 @@ import { WeightedBlendedOIT } from '../render/weightedblended_oit.js';
321
397
  this._postEffectBloom.get().maxDownsampleLevel = val;
322
398
  }
323
399
  }
324
- /**
325
- * Bloom downsample limit
400
+ /**
401
+ * Bloom downsample limit
326
402
  */ get bloomDownsampleLimit() {
327
403
  return this._bloomDownsampleLimit;
328
404
  }
@@ -332,8 +408,8 @@ import { WeightedBlendedOIT } from '../render/weightedblended_oit.js';
332
408
  this._postEffectBloom.get().downsampleLimit = val;
333
409
  }
334
410
  }
335
- /**
336
- * Bloom threshold
411
+ /**
412
+ * Bloom threshold
337
413
  */ get bloomThreshold() {
338
414
  return this._bloomThreshold;
339
415
  }
@@ -343,8 +419,8 @@ import { WeightedBlendedOIT } from '../render/weightedblended_oit.js';
343
419
  this._postEffectBloom.get().threshold = val;
344
420
  }
345
421
  }
346
- /**
347
- * Bloom threshold knee
422
+ /**
423
+ * Bloom threshold knee
348
424
  */ get bloomThresholdKnee() {
349
425
  return this._bloomThresholdKnee;
350
426
  }
@@ -354,8 +430,8 @@ import { WeightedBlendedOIT } from '../render/weightedblended_oit.js';
354
430
  this._postEffectBloom.get().thresholdKnee = val;
355
431
  }
356
432
  }
357
- /**
358
- * Bloom intensity
433
+ /**
434
+ * Bloom intensity
359
435
  */ get bloomIntensity() {
360
436
  return this._bloomIntensity;
361
437
  }
@@ -407,16 +483,16 @@ import { WeightedBlendedOIT } from '../render/weightedblended_oit.js';
407
483
  this._postEffectColorAdjust.get().sharpen = val;
408
484
  }
409
485
  }
410
- /**
411
- * Gets whether FXAA is enabled.
486
+ /**
487
+ * Gets whether FXAA is enabled.
412
488
  */ get FXAA() {
413
489
  return this._postEffectFXAA.get().enabled;
414
490
  }
415
491
  set FXAA(val) {
416
492
  this._postEffectFXAA.get().enabled = !!val;
417
493
  }
418
- /**
419
- * Tonemap exposure
494
+ /**
495
+ * Tonemap exposure
420
496
  */ get toneMapExposure() {
421
497
  return this._tonemapExposure;
422
498
  }
@@ -426,134 +502,221 @@ import { WeightedBlendedOIT } from '../render/weightedblended_oit.js';
426
502
  this._postEffectTonemap.get().exposure = val;
427
503
  }
428
504
  }
429
- /**
430
- * Gets whether TAA is enabled.
505
+ /**
506
+ * Gets whether TAA is enabled.
431
507
  */ get TAA() {
432
508
  return this._postEffectTAA.get().enabled;
433
509
  }
434
510
  set TAA(val) {
435
511
  this._postEffectTAA.get().enabled = !!val;
436
512
  }
437
- /**
438
- * Gets the debug flag for TAA
513
+ /**
514
+ * Gets the debug flag for TAA
439
515
  */ get TAADebug() {
440
516
  return this._TAADebug;
441
517
  }
442
518
  set TAADebug(val) {
443
519
  this._TAADebug = val;
444
520
  }
445
- /**
446
- * Gets whether Screen Space Reflections (SSR) is enabled.
521
+ /**
522
+ * Enables cascade debug visualization for directional shadows.
523
+ */ get shadowDebugCascades() {
524
+ return this._shadowDebugCascades;
525
+ }
526
+ set shadowDebugCascades(val) {
527
+ this._shadowDebugCascades = !!val;
528
+ }
529
+ /**
530
+ * Gets whether Screen Space Reflections (SSR) is enabled.
447
531
  */ get SSR() {
448
532
  return this._postEffectSSR.get().enabled;
449
533
  }
450
534
  set SSR(val) {
451
535
  this._postEffectSSR.get().enabled = !!val;
452
536
  }
453
- /**
454
- * Gets the maximum roughness value for screen space reflections.
455
- * Controls the cutoff point where surfaces are considered too rough for SSR.
537
+ /**
538
+ * Gets the maximum roughness value for screen space reflections.
539
+ * Controls the cutoff point where surfaces are considered too rough for SSR.
456
540
  */ get ssrMaxRoughness() {
457
541
  return this._ssrMaxRoughness;
458
542
  }
459
543
  set ssrMaxRoughness(val) {
460
544
  this._ssrMaxRoughness = val;
461
545
  }
462
- /**
463
- * Gets the roughness factor for SSR calculations.
464
- * Affects how surface roughness influences reflection clarity.
546
+ /**
547
+ * Gets the roughness factor for SSR calculations.
548
+ * Affects how surface roughness influences reflection clarity.
465
549
  */ get ssrRoughnessFactor() {
466
550
  return this._ssrRoughnessFactor;
467
551
  }
468
552
  set ssrRoughnessFactor(val) {
469
553
  this._ssrRoughnessFactor = val;
470
554
  }
471
- /**
472
- * Gets the stride value for SSR ray marching.
473
- * Controls the step size during ray marching. Larger values improve performance but may miss details.
555
+ /**
556
+ * Gets the stride value for SSR ray marching.
557
+ * Controls the step size during ray marching. Larger values improve performance but may miss details.
474
558
  */ get ssrStride() {
475
559
  return this._ssrStride;
476
560
  }
477
561
  set ssrStride(val) {
478
562
  this._ssrStride = val;
479
563
  }
480
- /**
481
- * Gets the maximum distance for SSR ray marching.
482
- * Defines how far rays will travel when searching for reflection intersections.
564
+ /**
565
+ * Gets the maximum distance for SSR ray marching.
566
+ * Defines how far rays will travel when searching for reflection intersections.
483
567
  */ get ssrMaxDistance() {
484
568
  return this._ssrParams.x;
485
569
  }
486
570
  set ssrMaxDistance(val) {
487
571
  this._ssrParams.x = val;
488
572
  }
489
- /**
490
- * Gets the number of iterations for SSR ray marching.
491
- * Higher values provide more accurate reflections but impact performance.
573
+ /**
574
+ * Gets the number of iterations for SSR ray marching.
575
+ * Higher values provide more accurate reflections but impact performance.
492
576
  */ get ssrIterations() {
493
577
  return this._ssrParams.y;
494
578
  }
495
579
  set ssrIterations(val) {
496
580
  this._ssrParams.y = val;
497
581
  }
498
- /**
499
- * Gets the thickness value for SSR calculations.
500
- * Determines the thickness threshold for surfaces when calculating reflections.
582
+ /**
583
+ * Gets the thickness value for SSR calculations.
584
+ * Determines the thickness threshold for surfaces when calculating reflections.
501
585
  */ get ssrThickness() {
502
586
  return this._ssrParams.z;
503
587
  }
504
588
  set ssrThickness(val) {
505
589
  this._ssrParams.z = val;
506
590
  }
507
- /**
508
- * Gets whether SSR should calculate thickness automatically.
509
- * When enabled, the system will dynamically compute surface thickness for reflections.
591
+ /**
592
+ * Gets whether SSR should calculate thickness automatically.
593
+ * When enabled, the system will dynamically compute surface thickness for reflections.
510
594
  */ get ssrCalcThickness() {
511
595
  return this._ssrCalcThickness;
512
596
  }
513
597
  set ssrCalcThickness(val) {
514
598
  this._ssrCalcThickness = !!val;
515
599
  }
516
- /**
517
- * Gets the blur scale factor for SSR.
518
- * Controls the overall intensity of the blur effect applied to reflections.
600
+ /**
601
+ * Gets the blur scale factor for SSR.
602
+ * Controls the overall intensity of the blur effect applied to reflections.
519
603
  */ get ssrBlurScale() {
520
604
  return this._ssrBlurriness;
521
605
  }
522
606
  set ssrBlurScale(val) {
523
607
  this._ssrBlurriness = val;
524
608
  }
525
- /**
526
- * Gets the depth cutoff value for SSR blur.
527
- * Determines at what depth difference the blur effect should be reduced or eliminated.
609
+ /**
610
+ * Gets the depth cutoff value for SSR blur.
611
+ * Determines at what depth difference the blur effect should be reduced or eliminated.
528
612
  */ get ssrBlurDepthCutoff() {
529
613
  return this._ssrBlurDepthCutoff;
530
614
  }
531
615
  set ssrBlurDepthCutoff(val) {
532
616
  this._ssrBlurDepthCutoff = val;
533
617
  }
534
- /**
535
- * Gets the kernel size for the SSR blur effect.
536
- * Defines the size of the blur kernel. Larger values create softer, more spread-out blur.
618
+ /**
619
+ * Gets the kernel size for the SSR blur effect.
620
+ * Defines the size of the blur kernel. Larger values create softer, more spread-out blur.
537
621
  */ get ssrBlurKernelSize() {
538
622
  return this._ssrBlurKernelSize;
539
623
  }
540
624
  set ssrBlurKernelSize(val) {
541
625
  this._ssrBlurKernelSize = val;
542
626
  }
543
- /**
544
- * Gets the standard deviation for the SSR Gaussian blur.
545
- * Controls the distribution of the blur effect. Higher values create more pronounced blur.
627
+ /**
628
+ * Gets the standard deviation for the SSR Gaussian blur.
629
+ * Controls the distribution of the blur effect. Higher values create more pronounced blur.
546
630
  */ get ssrBlurStdDev() {
547
631
  return this._ssrBlurStdDev;
548
632
  }
549
633
  set ssrBlurStdDev(val) {
550
634
  this._ssrBlurStdDev = val;
551
635
  }
636
+ /**
637
+ * Gets whether SSR temporal accumulation is enabled.
638
+ */ get ssrTemporal() {
639
+ return this._ssrTemporal;
640
+ }
641
+ set ssrTemporal(val) {
642
+ this._ssrTemporal = !!val;
643
+ }
644
+ /**
645
+ * Gets SSR temporal blending weight in [0, 1].
646
+ * Higher values rely more on reprojected history.
647
+ */ get ssrTemporalWeight() {
648
+ return this._ssrTemporalWeight;
649
+ }
650
+ set ssrTemporalWeight(val) {
651
+ this._ssrTemporalWeight = Math.max(0, Math.min(1, val ?? 0));
652
+ }
653
+ /**
654
+ * Gets whether Screen Space Subsurface Scattering (SSS) is enabled.
655
+ */ get SSS() {
656
+ return this._postEffectSSS.get().enabled;
657
+ }
658
+ set SSS(val) {
659
+ this._postEffectSSS.get().enabled = !!val;
660
+ }
661
+ /** Global blur scale for screen-space SSS. */ get sssBlurScale() {
662
+ return this._sssBlurScale;
663
+ }
664
+ set sssBlurScale(val) {
665
+ this._sssBlurScale = Math.max(0, val ?? 0);
666
+ }
667
+ /**
668
+ * High-level quality preset for SSS blur controls.
669
+ *
670
+ * This is the primary user-facing SSS quality control and only affects
671
+ * the blur sampling quality/performance tradeoff, not the authored look.
672
+ */ get sssQualityPreset() {
673
+ return this._sssQualityPreset;
674
+ }
675
+ set sssQualityPreset(val) {
676
+ const next = Camera.resolveSSSQualityPreset(val);
677
+ if (next !== this._sssQualityPreset) {
678
+ this._sssQualityPreset = next;
679
+ this.updateSSSResolvedSettings();
680
+ }
681
+ }
682
+ /** Final SSS composite strength. */ get sssStrength() {
683
+ return this._sssStrength;
684
+ }
685
+ set sssStrength(val) {
686
+ this._sssStrength = Math.max(0, val ?? 0);
687
+ }
688
+ /** Thin-shell transmission strength. */ get sssTransmissionStrength() {
689
+ return this._sssTransmissionStrength;
690
+ }
691
+ set sssTransmissionStrength(val) {
692
+ this._sssTransmissionStrength = Math.max(0, val ?? 0);
693
+ }
694
+ /** Thin-shell transmission exponent. */ get sssTransmissionPower() {
695
+ return this._sssTransmissionPower;
696
+ }
697
+ set sssTransmissionPower(val) {
698
+ this._sssTransmissionPower = Math.max(0.1, val ?? 0.1);
699
+ }
700
+ /** Multi-scatter energy compensation factor. */ get sssMultiScatter() {
701
+ return this._sssMultiScatter;
702
+ }
703
+ set sssMultiScatter(val) {
704
+ this._sssMultiScatter = Math.max(0, val ?? 0);
705
+ }
706
+ /** Resolved SSS blur settings after applying the quality preset. */ get sssResolvedSettings() {
707
+ return this._sssResolvedSettings;
708
+ }
709
+ /** Debug visualization for screen-space SSS buffers. */ get sssDebugView() {
710
+ return this._sssDebugView;
711
+ }
712
+ set sssDebugView(val) {
713
+ this._sssDebugView = val ?? 'none';
714
+ }
552
715
  /** @internal */ get ssrParams() {
553
716
  return this._ssrParams;
554
717
  }
555
- /**
556
- * Gets whether SSAO is enabled.
718
+ /**
719
+ * Gets whether SSAO is enabled.
557
720
  */ get SSAO() {
558
721
  return this._postEffectSSAO.get().enabled;
559
722
  }
@@ -617,7 +780,7 @@ import { WeightedBlendedOIT } from '../render/weightedblended_oit.js';
617
780
  set commandBufferReuse(val) {
618
781
  this._commandBufferReuse = !!val;
619
782
  }
620
- /** Whether this camera is adapted to screen settings */ get adapted() {
783
+ /** Whether this camera is adapted to screen settins */ get adapted() {
621
784
  return this._adapted;
622
785
  }
623
786
  set adapted(val) {
@@ -693,27 +856,27 @@ import { WeightedBlendedOIT } from '../render/weightedblended_oit.js';
693
856
  }
694
857
  return this._viewport;
695
858
  }
696
- /**
697
- * Screen configuration used for adapting the camera viewport
859
+ /**
860
+ * Screen configuration used for adapting the camera viewport
698
861
  */ get screenConfig() {
699
862
  return this._screenAdapter.config;
700
863
  }
701
864
  set screenConfig(config) {
702
865
  this._screenAdapter.config = config;
703
866
  }
704
- /**
705
- * Screen viewport used for adapting the camera viewport
867
+ /**
868
+ * Screen viewport used for adapting the camera viewport
706
869
  */ get screenViewport() {
707
870
  return this._screenAdapter.viewport;
708
871
  }
709
872
  set screenViewport(viewport) {
710
873
  this._screenAdapter.viewport = viewport;
711
874
  }
712
- /**
713
- * Handle input events
714
- * @param ev - input event object
715
- * @param type - event type, default to ev.type
716
- * @returns Boolean value indicates whether the event was handled.
875
+ /**
876
+ * Handle input events
877
+ * @param ev - input event object
878
+ * @param type - event type, default to ev.type
879
+ * @returns Boolean value indicates whether the event was handled.
717
880
  */ handleEvent(ev, type) {
718
881
  let handled = false;
719
882
  if (this._controller) {
@@ -746,17 +909,15 @@ import { WeightedBlendedOIT } from '../render/weightedblended_oit.js';
746
909
  }
747
910
  return handled;
748
911
  }
749
- /**
750
- * Constructs a ray based on the given screen coordinates.
751
- *
752
- * @param x - The x-component of the screen coordinates, relative to the top-left corner of the viewport.
753
- * @param y - The y-component of the screen coordinates, relative to the top-left corner of the viewport.
754
- * @param viewportWidth - Optional width of the viewport for normalizing screen coordinates. If not provided, it will be derived from the camera's viewport or the device's viewport.
755
- * @param viewportHeight - Optional height of the viewport for normalizing screen coordinates. If not provided, it will be derived from the camera's viewport or the device's viewport.
756
- * @returns The ray originating from the camera position and passing through the given screen coordinates.
757
- */ constructRay(x, y, viewportWidth, viewportHeight) {
758
- const width = viewportWidth ?? (this.viewport ? this.viewport[2] : getDevice().getViewport().width);
759
- const height = viewportHeight ?? (this.viewport ? this.viewport[3] : getDevice().getViewport().height);
912
+ /**
913
+ * Constructs a ray based on the given screen coordinates.
914
+ *
915
+ * @param x - The x-component of the screen coordinates, relative to the top-left corner of the viewport.
916
+ * @param y - The y-component of the screen coordinates, relative to the top-left corner of the viewport.
917
+ * @returns The ray originating from the camera position and passing through the given screen coordinates.
918
+ */ constructRay(x, y) {
919
+ const width = this.viewport ? this.viewport[2] : getDevice().getViewport().width;
920
+ const height = this.viewport ? this.viewport[3] : getDevice().getViewport().height;
760
921
  const ndcX = 2 * x / width - 1;
761
922
  const ndcY = 1 - 2 * y / height;
762
923
  const nearClip = new Vector4(ndcX, ndcY, -1, 1);
@@ -771,54 +932,54 @@ import { WeightedBlendedOIT } from '../render/weightedblended_oit.js';
771
932
  const vDir = Vector3.sub(farWorld.xyz(), vEye).inplaceNormalize();
772
933
  return new Ray(vEye, vDir);
773
934
  }
774
- /**
775
- * Place the camera by specifying the camera position and the target point
776
- * @param eye - The camera position
777
- * @param target - The target point to look at
778
- * @param up - The up vector
779
- * @returns self
935
+ /**
936
+ * Place the camera by specifying the camera position and the target point
937
+ * @param eye - The camera position
938
+ * @param target - The target point to look at
939
+ * @param up - The up vector
940
+ * @returns self
780
941
  */ lookAt(eye, target, up) {
781
942
  return this.setLocalTransform(Matrix4x4.lookAt(eye, target, up));
782
943
  }
783
- /**
784
- * Place the camera to look at a given cube face at a given camera position
785
- * @param face - The cube face to look at
786
- * @param position - The camera position
787
- * @returns self
944
+ /**
945
+ * Place the camera to look at a given cube face at a given camera position
946
+ * @param face - The cube face to look at
947
+ * @param position - The camera position
948
+ * @returns self
788
949
  */ lookAtCubeFace(face, position) {
789
950
  return this.setLocalTransform(Matrix4x4.lookAtCubeFace(face, position ?? this.position));
790
951
  }
791
- /**
792
- * Setup a perspective projection matrix for the camera
793
- * @param fovY - The vertical field of view in radians.
794
- * @param aspect - The aspect ratio
795
- * @param zNear - The near clip plane
796
- * @param zFar - The far clip plane
797
- * @returns self
952
+ /**
953
+ * Setup a perspective projection matrix for the camera
954
+ * @param fovY - The vertical field of view in radians.
955
+ * @param aspect - The aspect ratio
956
+ * @param zNear - The near clip plane
957
+ * @param zFar - The far clip plane
958
+ * @returns self
798
959
  */ setPerspective(fovY, aspect, zNear, zFar) {
799
960
  this._projMatrix.perspective(fovY, aspect, zNear, zFar);
800
961
  Matrix4x4.invert(this._projMatrix, this._invProjMatrix);
801
962
  this._invalidate(true);
802
963
  return this;
803
964
  }
804
- /**
805
- * Setup a orthogonal projection matrix for the camera
806
- * @param left - Left bound of the frustum
807
- * @param right - Right bound of the frustum
808
- * @param bottom - Bottom bound of the frustum
809
- * @param top - Top bound of the frustum
810
- * @param near - Near bound of the frustum.
811
- * @param far - Far bound of the frustum.
812
- * @returns self
965
+ /**
966
+ * Setup a orthogonal projection matrix for the camera
967
+ * @param left - Left bound of the frustum
968
+ * @param right - Right bound of the frustum
969
+ * @param bottom - Bottom bound of the frustum
970
+ * @param top - Top bound of the frustum
971
+ * @param near - Near bound of the frustum.
972
+ * @param far - Far bound of the frustum.
973
+ * @returns self
813
974
  */ setOrtho(left, right, bottom, top, near, far) {
814
975
  this._projMatrix.ortho(left, right, bottom, top, near, far);
815
976
  Matrix4x4.invert(this._projMatrix, this._invProjMatrix);
816
977
  this._invalidate(true);
817
978
  return this;
818
979
  }
819
- /**
820
- * Setup a projection matrix for the camera
821
- * @param matrix - The projection matrix
980
+ /**
981
+ * Setup a projection matrix for the camera
982
+ * @param matrix - The projection matrix
822
983
  */ setProjectionMatrix(matrix) {
823
984
  if (matrix && matrix !== this._projMatrix) {
824
985
  this._projMatrix = matrix;
@@ -826,18 +987,18 @@ import { WeightedBlendedOIT } from '../render/weightedblended_oit.js';
826
987
  this._invalidate(true);
827
988
  }
828
989
  }
829
- /**
830
- * Gets the projection matrix of the camera
831
- * @returns The projection matrix
990
+ /**
991
+ * Gets the projection matrix of the camera
992
+ * @returns The projection matrix
832
993
  */ getProjectionMatrix() {
833
994
  if (this.dirtyCheck()) {
834
995
  this._compute();
835
996
  }
836
997
  return this._projMatrix;
837
998
  }
838
- /**
839
- * Gets the inverse projection matrix of the camera
840
- * @returns The projection matrix
999
+ /**
1000
+ * Gets the inverse projection matrix of the camera
1001
+ * @returns The projection matrix
841
1002
  */ getInvProjectionMatrix() {
842
1003
  if (this.dirtyCheck()) {
843
1004
  this._compute();
@@ -855,11 +1016,11 @@ import { WeightedBlendedOIT } from '../render/weightedblended_oit.js';
855
1016
  rotationMatrix.setRow(2, new Vector4(zAxis.x, zAxis.y, zAxis.z, 0));
856
1017
  return rotationMatrix;
857
1018
  }
858
- /**
859
- * View matrix of the camera
860
- *
861
- * @remarks
862
- * Camera's view matrix will transform a point from the world space to the camera space
1019
+ /**
1020
+ * View matrix of the camera
1021
+ *
1022
+ * @remarks
1023
+ * Camera's view matrix will transform a point from the world space to the camera space
863
1024
  */ get viewMatrix() {
864
1025
  if (this.dirtyCheck()) {
865
1026
  this._compute();
@@ -872,11 +1033,11 @@ import { WeightedBlendedOIT } from '../render/weightedblended_oit.js';
872
1033
  }
873
1034
  return this._viewProjMatrix;
874
1035
  }
875
- /**
876
- * The inverse-view-projection matrix of the camera
877
- *
878
- * @remarks
879
- * The inverse-view-projection matrix transforms a point from the clip space to the camera space
1036
+ /**
1037
+ * The inverse-view-projection matrix of the camera
1038
+ *
1039
+ * @remarks
1040
+ * The inverse-view-projection matrix transforms a point from the clip space to the camera space
880
1041
  */ get invViewProjectionMatrix() {
881
1042
  if (this.dirtyCheck()) {
882
1043
  this._compute();
@@ -928,32 +1089,40 @@ import { WeightedBlendedOIT } from '../render/weightedblended_oit.js';
928
1089
  /** Returns true if the camera is orthographic */ isOrtho() {
929
1090
  return this.getProjectionMatrix().isOrtho();
930
1091
  }
931
- /**
932
- * Gets the camera history resource manager for temporal effects
933
- * @returns History resource manager
934
- */ getHistoryResourceManager() {
935
- let manager = Camera._historyResourceManager.get(this);
936
- if (!manager) {
937
- // Import dynamically to avoid circular dependency
938
- // The actual import happens in forward_plus_builder.ts
939
- return null;
1092
+ /**
1093
+ * Gets the camera history data which is used in temporal reprojection
1094
+ * @returns Camera history data
1095
+ */ getHistoryData() {
1096
+ let data = Camera._historyData.get(this);
1097
+ if (!data) {
1098
+ data = {
1099
+ prevColorTex: null,
1100
+ prevMotionVectorTex: null,
1101
+ prevSSRReflectTex: null,
1102
+ prevSSRMotionVectorTex: null
1103
+ };
1104
+ Camera._historyData.set(this, data);
940
1105
  }
941
- return manager;
942
- }
943
- /**
944
- * Sets the camera history resource manager for temporal effects
945
- * @internal
946
- */ setHistoryResourceManager(manager) {
947
- Camera._historyResourceManager.set(this, manager);
1106
+ return data;
948
1107
  }
949
- /**
950
- * Clears the camera history data which is used in temporal reprojection
1108
+ /**
1109
+ * Clears the camera history data which is used in temporal reprojection
951
1110
  */ clearHistoryData() {
952
- // Clear history resource manager
953
- const manager = Camera._historyResourceManager.get(this);
954
- if (manager) {
955
- manager.dispose();
956
- Camera._historyResourceManager.delete(this);
1111
+ const data = Camera._historyData.get(this);
1112
+ if (data) {
1113
+ if (data.prevColorTex) {
1114
+ getDevice().pool.releaseTexture(data.prevColorTex);
1115
+ }
1116
+ if (data.prevMotionVectorTex) {
1117
+ getDevice().pool.releaseTexture(data.prevMotionVectorTex);
1118
+ }
1119
+ if (data.prevSSRReflectTex) {
1120
+ getDevice().pool.releaseTexture(data.prevSSRReflectTex);
1121
+ }
1122
+ if (data.prevSSRMotionVectorTex) {
1123
+ getDevice().pool.releaseTexture(data.prevSSRMotionVectorTex);
1124
+ }
1125
+ Camera._historyData.delete(this);
957
1126
  }
958
1127
  this._prevVPMatrix = null;
959
1128
  this._prevPosition = null;
@@ -968,6 +1137,12 @@ import { WeightedBlendedOIT } from '../render/weightedblended_oit.js';
968
1137
  this._postEffectSSR.set(ssr);
969
1138
  this._compositor.appendPostEffect(ssr);
970
1139
  }
1140
+ if (!this._postEffectSSS.get()) {
1141
+ const sss = new SSS();
1142
+ sss.enabled = false;
1143
+ this._postEffectSSS.set(sss);
1144
+ this._compositor.appendPostEffect(sss);
1145
+ }
971
1146
  if (!this._postEffectSSAO.get()) {
972
1147
  const ssao = new SAO();
973
1148
  ssao.enabled = false;
@@ -1027,14 +1202,32 @@ import { WeightedBlendedOIT } from '../render/weightedblended_oit.js';
1027
1202
  this._compositor.appendPostEffect(bloom);
1028
1203
  }
1029
1204
  }
1030
- /**
1031
- * Renders a scene
1032
- * @param scene - The scene to be rendered
1033
- * @param compositor - Compositor instance that will be used to apply postprocess effects
1205
+ static resolveSSSQualityPreset(val) {
1206
+ switch(val){
1207
+ case 'quality':
1208
+ case 'balanced':
1209
+ case 'performance':
1210
+ return val;
1211
+ default:
1212
+ return 'balanced';
1213
+ }
1214
+ }
1215
+ updateSSSResolvedSettings() {
1216
+ const source = SSS_QUALITY_PRESET_SETTINGS[this._sssQualityPreset];
1217
+ this._sssResolvedSettings.halfRes = source.halfRes;
1218
+ this._sssResolvedSettings.blurKernelSize = source.blurKernelSize;
1219
+ this._sssResolvedSettings.blurStdDev = source.blurStdDev;
1220
+ this._sssResolvedSettings.blurDepthCutoff = source.blurDepthCutoff;
1221
+ this._sssResolvedSettings.normalCutoff = source.normalCutoff;
1222
+ }
1223
+ /**
1224
+ * Renders a scene
1225
+ * @param scene - The scene to be rendered
1226
+ * @param compositor - Compositor instance that will be used to apply postprocess effects
1034
1227
  */ render(scene) {
1035
1228
  const device = getDevice();
1036
1229
  //this.updatePostProcessing(device);
1037
- const useMotionVector = (this.TAA || this.motionBlur) && device.type !== 'webgl';
1230
+ const useMotionVector = (this.TAA || this.motionBlur || this.SSR && this.ssrTemporal) && device.type !== 'webgl';
1038
1231
  const useTAA = useMotionVector && this.TAA;
1039
1232
  scene.dispatchEvent('startrender', scene, this, this._compositor);
1040
1233
  if (useMotionVector) {
@@ -1104,13 +1297,13 @@ import { WeightedBlendedOIT } from '../render/weightedblended_oit.js';
1104
1297
  /** @internal */ getPickPosY() {
1105
1298
  return this._pickPosY;
1106
1299
  }
1107
- /**
1108
- * Updates the controller state
1300
+ /**
1301
+ * Updates the controller state
1109
1302
  */ updateController() {
1110
1303
  this._controller?.update();
1111
1304
  }
1112
- /**
1113
- * Reset the controller
1305
+ /**
1306
+ * Reset the controller
1114
1307
  */ resetController() {
1115
1308
  this._controller?.reset();
1116
1309
  }
@@ -1135,6 +1328,18 @@ import { WeightedBlendedOIT } from '../render/weightedblended_oit.js';
1135
1328
  /** @internal */ get prevPosition() {
1136
1329
  return this._prevPosition;
1137
1330
  }
1331
+ /**
1332
+ * Gets the camera history resource manager for temporal effects.
1333
+ */ getHistoryResourceManager() {
1334
+ return Camera._historyResourceManager.get(this) ?? null;
1335
+ }
1336
+ /**
1337
+ * Sets the camera history resource manager for temporal effects.
1338
+ *
1339
+ * @internal
1340
+ */ setHistoryResourceManager(manager) {
1341
+ Camera._historyResourceManager.set(this, manager);
1342
+ }
1138
1343
  /** @internal */ setController(controller) {
1139
1344
  if (this._controller !== controller) {
1140
1345
  if (controller && controller._getCamera() && controller._getCamera() !== this) {
@@ -1176,6 +1381,7 @@ import { WeightedBlendedOIT } from '../render/weightedblended_oit.js';
1176
1381
  this._postEffectFXAA.dispose();
1177
1382
  this._postEffectMotionBlur.dispose();
1178
1383
  this._postEffectSSAO.dispose();
1384
+ this._postEffectSSS.dispose();
1179
1385
  this._postEffectSSR.dispose();
1180
1386
  this._postEffectTAA.dispose();
1181
1387
  this._postEffectTonemap.dispose();