@zephyr3d/scene 0.9.6 → 0.9.8

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 (205) hide show
  1. package/dist/animation/animationset.js +52 -55
  2. package/dist/animation/animationset.js.map +1 -1
  3. package/dist/animation/joint_dynamics/controller.js +92 -32
  4. package/dist/animation/joint_dynamics/controller.js.map +1 -1
  5. package/dist/animation/joint_dynamics/convex_collider.js +320 -0
  6. package/dist/animation/joint_dynamics/convex_collider.js.map +1 -0
  7. package/dist/animation/joint_dynamics/joint_dynamics_system.js +57 -19
  8. package/dist/animation/joint_dynamics/joint_dynamics_system.js.map +1 -1
  9. package/dist/animation/joint_dynamics/solver.js +71 -27
  10. package/dist/animation/joint_dynamics/solver.js.map +1 -1
  11. package/dist/animation/joint_dynamics_modifier.js +4 -3
  12. package/dist/animation/joint_dynamics_modifier.js.map +1 -1
  13. package/dist/animation/skeleton.js +7 -10
  14. package/dist/animation/skeleton.js.map +1 -1
  15. package/dist/app/engine.js +3 -9
  16. package/dist/app/engine.js.map +1 -1
  17. package/dist/app/scriptregistry.js +47 -16
  18. package/dist/app/scriptregistry.js.map +1 -1
  19. package/dist/asset/assetmanager.js +3 -1
  20. package/dist/asset/assetmanager.js.map +1 -1
  21. package/dist/asset/model.js +346 -7
  22. package/dist/asset/model.js.map +1 -1
  23. package/dist/avatar/wardrobe.js +7 -3
  24. package/dist/avatar/wardrobe.js.map +1 -1
  25. package/dist/camera/camera.js +240 -34
  26. package/dist/camera/camera.js.map +1 -1
  27. package/dist/index.d.ts +1350 -622
  28. package/dist/index.js +6 -11
  29. package/dist/index.js.map +1 -1
  30. package/dist/material/blinn.js +1 -1
  31. package/dist/material/blinn.js.map +1 -1
  32. package/dist/material/lambert.js +1 -1
  33. package/dist/material/lambert.js.map +1 -1
  34. package/dist/material/material.js +23 -1
  35. package/dist/material/material.js.map +1 -1
  36. package/dist/material/meshmaterial.js +178 -23
  37. package/dist/material/meshmaterial.js.map +1 -1
  38. package/dist/material/mixins/albedocolor.js +4 -4
  39. package/dist/material/mixins/albedocolor.js.map +1 -1
  40. package/dist/material/mixins/lightmodel/blinnphong.js +2 -1
  41. package/dist/material/mixins/lightmodel/blinnphong.js.map +1 -1
  42. package/dist/material/mixins/lightmodel/lambert.js +2 -1
  43. package/dist/material/mixins/lightmodel/lambert.js.map +1 -1
  44. package/dist/material/mixins/lightmodel/pbrblueprintmixin.js +63 -16
  45. package/dist/material/mixins/lightmodel/pbrblueprintmixin.js.map +1 -1
  46. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js +100 -27
  47. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -1
  48. package/dist/material/mixins/lightmodel/pbrspecularglossness.js +16 -6
  49. package/dist/material/mixins/lightmodel/pbrspecularglossness.js.map +1 -1
  50. package/dist/material/mixins/lit.js +1 -1
  51. package/dist/material/mixins/lit.js.map +1 -1
  52. package/dist/material/mixins/pbr/common.js +276 -65
  53. package/dist/material/mixins/pbr/common.js.map +1 -1
  54. package/dist/material/mixins/texture.js +3 -3
  55. package/dist/material/mixins/texture.js.map +1 -1
  56. package/dist/material/mixins/vertexcolor.js +2 -2
  57. package/dist/material/mixins/vertexcolor.js.map +1 -1
  58. package/dist/material/mtoon.js +574 -0
  59. package/dist/material/mtoon.js.map +1 -0
  60. package/dist/material/pbrblueprint.js +494 -331
  61. package/dist/material/pbrblueprint.js.map +1 -1
  62. package/dist/material/pbrmr.js +118 -100
  63. package/dist/material/pbrmr.js.map +1 -1
  64. package/dist/material/pbrsg.js +1 -1
  65. package/dist/material/pbrsg.js.map +1 -1
  66. package/dist/material/shader/helper.js +45 -15
  67. package/dist/material/shader/helper.js.map +1 -1
  68. package/dist/material/subsurfaceprofile.js +812 -0
  69. package/dist/material/subsurfaceprofile.js.map +1 -0
  70. package/dist/material/unlit.js +1 -1
  71. package/dist/material/unlit.js.map +1 -1
  72. package/dist/posteffect/compositor.js +46 -11
  73. package/dist/posteffect/compositor.js.map +1 -1
  74. package/dist/posteffect/ssr.js +413 -87
  75. package/dist/posteffect/ssr.js.map +1 -1
  76. package/dist/posteffect/sss.js +1053 -0
  77. package/dist/posteffect/sss.js.map +1 -0
  78. package/dist/posteffect/taa.js +61 -60
  79. package/dist/posteffect/taa.js.map +1 -1
  80. package/dist/render/abuffer_oit.js +63 -12
  81. package/dist/render/abuffer_oit.js.map +1 -1
  82. package/dist/render/cluster_light.js +6 -5
  83. package/dist/render/cluster_light.js.map +1 -1
  84. package/dist/render/drawable.js +1 -5
  85. package/dist/render/drawable.js.map +1 -1
  86. package/dist/render/drawable_mixin.js +2 -1
  87. package/dist/render/drawable_mixin.js.map +1 -1
  88. package/dist/render/fbm_wavegenerator.js +2 -1
  89. package/dist/render/fbm_wavegenerator.js.map +1 -1
  90. package/dist/render/gerstner_wavegenerator.js +2 -1
  91. package/dist/render/gerstner_wavegenerator.js.map +1 -1
  92. package/dist/render/globalbindgroup_allocator.js +2 -1
  93. package/dist/render/globalbindgroup_allocator.js.map +1 -1
  94. package/dist/render/lightpass.js +105 -18
  95. package/dist/render/lightpass.js.map +1 -1
  96. package/dist/render/render_queue.js +51 -8
  97. package/dist/render/render_queue.js.map +1 -1
  98. package/dist/render/renderer.js +73 -59
  99. package/dist/render/renderer.js.map +1 -1
  100. package/dist/render/rendergraph/device_pool_allocator.js +8 -0
  101. package/dist/render/rendergraph/device_pool_allocator.js.map +1 -1
  102. package/dist/render/rendergraph/forward_plus_builder.js +481 -95
  103. package/dist/render/rendergraph/forward_plus_builder.js.map +1 -1
  104. package/dist/render/rendergraph/history_resource_manager.js +55 -0
  105. package/dist/render/rendergraph/history_resource_manager.js.map +1 -1
  106. package/dist/render/rendergraph/history_resources.js +3 -1
  107. package/dist/render/rendergraph/history_resources.js.map +1 -1
  108. package/dist/render/rendergraph/types.js.map +1 -1
  109. package/dist/render/renderpass.js +10 -4
  110. package/dist/render/renderpass.js.map +1 -1
  111. package/dist/render/sky.js +31 -1
  112. package/dist/render/sky.js.map +1 -1
  113. package/dist/render/weightedblended_oit.js +23 -5
  114. package/dist/render/weightedblended_oit.js.map +1 -1
  115. package/dist/scene/basesprite.js +4 -2
  116. package/dist/scene/basesprite.js.map +1 -1
  117. package/dist/scene/batchgroup.js +3 -1
  118. package/dist/scene/batchgroup.js.map +1 -1
  119. package/dist/scene/environment.js +11 -1
  120. package/dist/scene/environment.js.map +1 -1
  121. package/dist/scene/light.js +21 -3
  122. package/dist/scene/light.js.map +1 -1
  123. package/dist/scene/mesh.js +29 -14
  124. package/dist/scene/mesh.js.map +1 -1
  125. package/dist/scene/meshdrawable.js +6 -0
  126. package/dist/scene/meshdrawable.js.map +1 -1
  127. package/dist/scene/msdftext.js +5 -2
  128. package/dist/scene/msdftext.js.map +1 -1
  129. package/dist/scene/msdftextsprite.js +5 -3
  130. package/dist/scene/msdftextsprite.js.map +1 -1
  131. package/dist/scene/particlesys.js +3 -1
  132. package/dist/scene/particlesys.js.map +1 -1
  133. package/dist/scene/scene.js +6 -5
  134. package/dist/scene/scene.js.map +1 -1
  135. package/dist/scene/terrain-cm/grass.js +4 -2
  136. package/dist/scene/terrain-cm/grass.js.map +1 -1
  137. package/dist/scene/terrain-cm/grassmaterial.js +2 -1
  138. package/dist/scene/terrain-cm/grassmaterial.js.map +1 -1
  139. package/dist/scene/terrain-cm/terrain-cm.js +4 -2
  140. package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
  141. package/dist/scene/water.js +4 -2
  142. package/dist/scene/water.js.map +1 -1
  143. package/dist/shaders/shadow.js +26 -393
  144. package/dist/shaders/shadow.js.map +1 -1
  145. package/dist/shadow/esm.js +112 -12
  146. package/dist/shadow/esm.js.map +1 -1
  147. package/dist/shadow/pcf_opt.js +2 -2
  148. package/dist/shadow/pcf_opt.js.map +1 -1
  149. package/dist/shadow/pcf_pd.js +19 -10
  150. package/dist/shadow/pcf_pd.js.map +1 -1
  151. package/dist/shadow/shader.js +58 -7
  152. package/dist/shadow/shader.js.map +1 -1
  153. package/dist/shadow/shadow_impl.js +6 -0
  154. package/dist/shadow/shadow_impl.js.map +1 -1
  155. package/dist/shadow/shadow_region.js +229 -0
  156. package/dist/shadow/shadow_region.js.map +1 -0
  157. package/dist/shadow/shadowmapper.js +67 -59
  158. package/dist/shadow/shadowmapper.js.map +1 -1
  159. package/dist/shadow/vsm.js +45 -19
  160. package/dist/shadow/vsm.js.map +1 -1
  161. package/dist/utility/blueprint/common/constants.js +8 -8
  162. package/dist/utility/blueprint/common/constants.js.map +1 -1
  163. package/dist/utility/blueprint/material/pbr.js +31 -4
  164. package/dist/utility/blueprint/material/pbr.js.map +1 -1
  165. package/dist/utility/blueprint/material/texture.js +1 -17
  166. package/dist/utility/blueprint/material/texture.js.map +1 -1
  167. package/dist/utility/serialization/manager.js +66 -98
  168. package/dist/utility/serialization/manager.js.map +1 -1
  169. package/dist/utility/serialization/scene/animation.js +5 -2
  170. package/dist/utility/serialization/scene/animation.js.map +1 -1
  171. package/dist/utility/serialization/scene/batch.js +4 -1
  172. package/dist/utility/serialization/scene/batch.js.map +1 -1
  173. package/dist/utility/serialization/scene/camera.js +249 -54
  174. package/dist/utility/serialization/scene/camera.js.map +1 -1
  175. package/dist/utility/serialization/scene/common.js +37 -1
  176. package/dist/utility/serialization/scene/common.js.map +1 -1
  177. package/dist/utility/serialization/scene/light.js +42 -3
  178. package/dist/utility/serialization/scene/light.js.map +1 -1
  179. package/dist/utility/serialization/scene/material.js +1112 -646
  180. package/dist/utility/serialization/scene/material.js.map +1 -1
  181. package/dist/utility/serialization/scene/mesh.js +7 -4
  182. package/dist/utility/serialization/scene/mesh.js.map +1 -1
  183. package/dist/utility/serialization/scene/node.js +31 -12
  184. package/dist/utility/serialization/scene/node.js.map +1 -1
  185. package/dist/utility/serialization/scene/particle.js +4 -1
  186. package/dist/utility/serialization/scene/particle.js.map +1 -1
  187. package/dist/utility/serialization/scene/primitive.js +3 -1
  188. package/dist/utility/serialization/scene/primitive.js.map +1 -1
  189. package/dist/utility/serialization/scene/scene.js +18 -0
  190. package/dist/utility/serialization/scene/scene.js.map +1 -1
  191. package/dist/utility/serialization/scene/sprite.js +6 -3
  192. package/dist/utility/serialization/scene/sprite.js.map +1 -1
  193. package/dist/utility/serialization/scene/terrain.js +5 -2
  194. package/dist/utility/serialization/scene/terrain.js.map +1 -1
  195. package/dist/utility/serialization/scene/text.js +3 -1
  196. package/dist/utility/serialization/scene/text.js.map +1 -1
  197. package/dist/utility/serialization/scene/water.js +4 -1
  198. package/dist/utility/serialization/scene/water.js.map +1 -1
  199. package/dist/utility/textures/ltcdata.js +6 -0
  200. package/dist/utility/textures/ltcdata.js.map +1 -0
  201. package/dist/utility/textures/ltclut.js +61 -0
  202. package/dist/utility/textures/ltclut.js.map +1 -0
  203. package/dist/values.js +9 -1
  204. package/dist/values.js.map +1 -1
  205. 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,6 +15,36 @@ 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
 
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
+ };
17
48
  /**
18
49
  * A renderable camera node that manages view/projection math, frusta,
19
50
  * input control, picking, and a post-processing chain via a compositor.
@@ -22,7 +53,7 @@ import { WeightedBlendedOIT } from '../render/weightedblended_oit.js';
22
53
  * - Maintains projection, view, VP, and inverse VP matrices and lazily recomputes them when invalidated.
23
54
  * - Provides world- and view-space frusta for culling and clipping.
24
55
  * - Supports perspective and orthographic projections.
25
- * - Integrates with post effects (Tonemap, FXAA, TAA, Bloom, SSR, SSAO, Motion Blur) through an internal `Compositor`.
56
+ * - Integrates with post effects (Tonemap, FXAA, TAA, Bloom, SSR, SSS, SSAO, Motion Blur) through an internal `Compositor`.
26
57
  * - Handles temporal jitter and history state when TAA or motion blur are enabled.
27
58
  * - Emits picking rays from screen coordinates and supports async GPU picking.
28
59
  * - Optional controller integration for user input handling.
@@ -34,6 +65,7 @@ import { WeightedBlendedOIT } from '../render/weightedblended_oit.js';
34
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;
@@ -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;
@@ -268,6 +336,14 @@ import { WeightedBlendedOIT } from '../render/weightedblended_oit.js';
268
336
  this._HiZ = !!val;
269
337
  }
270
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
+ /**
271
347
  * Whether HDR backbuffer is enabled.
272
348
  *
273
349
  * Tonemap should be disabled when not using HDR backbuffer.
@@ -443,6 +519,14 @@ import { WeightedBlendedOIT } from '../render/weightedblended_oit.js';
443
519
  this._TAADebug = val;
444
520
  }
445
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
+ /**
446
530
  * Gets whether Screen Space Reflections (SSR) is enabled.
447
531
  */ get SSR() {
448
532
  return this._postEffectSSR.get().enabled;
@@ -549,6 +633,85 @@ import { WeightedBlendedOIT } from '../render/weightedblended_oit.js';
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
  }
@@ -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) {
@@ -751,12 +914,10 @@ import { WeightedBlendedOIT } from '../render/weightedblended_oit.js';
751
914
  *
752
915
  * @param x - The x-component of the screen coordinates, relative to the top-left corner of the viewport.
753
916
  * @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
917
  * @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);
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);
@@ -929,31 +1090,39 @@ import { WeightedBlendedOIT } from '../render/weightedblended_oit.js';
929
1090
  return this.getProjectionMatrix().isOrtho();
930
1091
  }
931
1092
  /**
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;
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
1108
  /**
950
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,6 +1202,24 @@ import { WeightedBlendedOIT } from '../render/weightedblended_oit.js';
1027
1202
  this._compositor.appendPostEffect(bloom);
1028
1203
  }
1029
1204
  }
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
+ }
1030
1223
  /**
1031
1224
  * Renders a scene
1032
1225
  * @param scene - The scene to be rendered
@@ -1034,7 +1227,7 @@ import { WeightedBlendedOIT } from '../render/weightedblended_oit.js';
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) {
@@ -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();