@zephyr3d/editor 0.3.8 → 0.3.9

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 (137) hide show
  1. package/dist/assets/{index-BZ1L8ggE.js → index-CO6yA4Rj.js} +313 -11
  2. package/dist/assistant/zephyr-types-index.json +13834 -11679
  3. package/dist/index.html +1 -1
  4. package/dist/modules/zephyr3d_backend-webgpu.js +1 -1
  5. package/dist/modules/zephyr3d_backend-webgpu.js.map +1 -1
  6. package/dist/modules/zephyr3d_device.js +2 -2
  7. package/dist/modules/zephyr3d_device.js.map +1 -1
  8. package/dist/modules/zephyr3d_scene.js +2325 -515
  9. package/dist/modules/zephyr3d_scene.js.map +1 -1
  10. package/dist/vendor/zephyr3d/backend-webgpu/dist/renderpass_webgpu.js +1 -1
  11. package/dist/vendor/zephyr3d/backend-webgpu/dist/renderpass_webgpu.js.map +1 -1
  12. package/dist/vendor/zephyr3d/device/dist/device.js +2 -2
  13. package/dist/vendor/zephyr3d/device/dist/device.js.map +1 -1
  14. package/dist/vendor/zephyr3d/scene/dist/app/engine.js +3 -1
  15. package/dist/vendor/zephyr3d/scene/dist/app/engine.js.map +1 -1
  16. package/dist/vendor/zephyr3d/scene/dist/asset/assetmanager.js +1 -0
  17. package/dist/vendor/zephyr3d/scene/dist/asset/assetmanager.js.map +1 -1
  18. package/dist/vendor/zephyr3d/scene/dist/camera/camera.js +87 -0
  19. package/dist/vendor/zephyr3d/scene/dist/camera/camera.js.map +1 -1
  20. package/dist/vendor/zephyr3d/scene/dist/index.d.ts +158 -4
  21. package/dist/vendor/zephyr3d/scene/dist/index.js +3 -0
  22. package/dist/vendor/zephyr3d/scene/dist/index.js.map +1 -1
  23. package/dist/vendor/zephyr3d/scene/dist/material/meshmaterial.js +8 -1
  24. package/dist/vendor/zephyr3d/scene/dist/material/meshmaterial.js.map +1 -1
  25. package/dist/vendor/zephyr3d/scene/dist/material/shader/helper.js +6 -0
  26. package/dist/vendor/zephyr3d/scene/dist/material/shader/helper.js.map +1 -1
  27. package/dist/vendor/zephyr3d/scene/dist/material/skin.js +263 -0
  28. package/dist/vendor/zephyr3d/scene/dist/material/skin.js.map +1 -0
  29. package/dist/vendor/zephyr3d/scene/dist/posteffect/compositor.js +3 -0
  30. package/dist/vendor/zephyr3d/scene/dist/posteffect/compositor.js.map +1 -1
  31. package/dist/vendor/zephyr3d/scene/dist/posteffect/skinsss.js +194 -0
  32. package/dist/vendor/zephyr3d/scene/dist/posteffect/skinsss.js.map +1 -0
  33. package/dist/vendor/zephyr3d/scene/dist/posteffect/ssr.js +26 -49
  34. package/dist/vendor/zephyr3d/scene/dist/posteffect/ssr.js.map +1 -1
  35. package/dist/vendor/zephyr3d/scene/dist/posteffect/sss.js +1 -0
  36. package/dist/vendor/zephyr3d/scene/dist/posteffect/sss.js.map +1 -1
  37. package/dist/vendor/zephyr3d/scene/dist/posteffect/taa.js +2 -40
  38. package/dist/vendor/zephyr3d/scene/dist/posteffect/taa.js.map +1 -1
  39. package/dist/vendor/zephyr3d/scene/dist/render/abuffer_oit.js +1 -0
  40. package/dist/vendor/zephyr3d/scene/dist/render/abuffer_oit.js.map +1 -1
  41. package/dist/vendor/zephyr3d/scene/dist/render/drawable_mixin.js +1 -0
  42. package/dist/vendor/zephyr3d/scene/dist/render/drawable_mixin.js.map +1 -1
  43. package/dist/vendor/zephyr3d/scene/dist/render/fbm_wavegenerator.js +1 -0
  44. package/dist/vendor/zephyr3d/scene/dist/render/fbm_wavegenerator.js.map +1 -1
  45. package/dist/vendor/zephyr3d/scene/dist/render/gerstner_wavegenerator.js +1 -0
  46. package/dist/vendor/zephyr3d/scene/dist/render/gerstner_wavegenerator.js.map +1 -1
  47. package/dist/vendor/zephyr3d/scene/dist/render/globalbindgroup_allocator.js +1 -0
  48. package/dist/vendor/zephyr3d/scene/dist/render/globalbindgroup_allocator.js.map +1 -1
  49. package/dist/vendor/zephyr3d/scene/dist/render/lightpass.js +4 -1
  50. package/dist/vendor/zephyr3d/scene/dist/render/lightpass.js.map +1 -1
  51. package/dist/vendor/zephyr3d/scene/dist/render/render_queue.js +1 -0
  52. package/dist/vendor/zephyr3d/scene/dist/render/render_queue.js.map +1 -1
  53. package/dist/vendor/zephyr3d/scene/dist/render/renderer.js +1 -0
  54. package/dist/vendor/zephyr3d/scene/dist/render/renderer.js.map +1 -1
  55. package/dist/vendor/zephyr3d/scene/dist/render/rendergraph/device_pool_allocator.js +12 -5
  56. package/dist/vendor/zephyr3d/scene/dist/render/rendergraph/device_pool_allocator.js.map +1 -1
  57. package/dist/vendor/zephyr3d/scene/dist/render/rendergraph/forward_plus_builder.js +78 -8
  58. package/dist/vendor/zephyr3d/scene/dist/render/rendergraph/forward_plus_builder.js.map +1 -1
  59. package/dist/vendor/zephyr3d/scene/dist/scene/basesprite.js +1 -0
  60. package/dist/vendor/zephyr3d/scene/dist/scene/basesprite.js.map +1 -1
  61. package/dist/vendor/zephyr3d/scene/dist/scene/batchgroup.js +1 -0
  62. package/dist/vendor/zephyr3d/scene/dist/scene/batchgroup.js.map +1 -1
  63. package/dist/vendor/zephyr3d/scene/dist/scene/environment.js +1 -0
  64. package/dist/vendor/zephyr3d/scene/dist/scene/environment.js.map +1 -1
  65. package/dist/vendor/zephyr3d/scene/dist/scene/light.js +158 -154
  66. package/dist/vendor/zephyr3d/scene/dist/scene/light.js.map +1 -1
  67. package/dist/vendor/zephyr3d/scene/dist/scene/mesh.js +1 -0
  68. package/dist/vendor/zephyr3d/scene/dist/scene/mesh.js.map +1 -1
  69. package/dist/vendor/zephyr3d/scene/dist/scene/msdftext.js +1 -0
  70. package/dist/vendor/zephyr3d/scene/dist/scene/msdftext.js.map +1 -1
  71. package/dist/vendor/zephyr3d/scene/dist/scene/msdftextsprite.js +1 -0
  72. package/dist/vendor/zephyr3d/scene/dist/scene/msdftextsprite.js.map +1 -1
  73. package/dist/vendor/zephyr3d/scene/dist/scene/particlesys.js +1 -0
  74. package/dist/vendor/zephyr3d/scene/dist/scene/particlesys.js.map +1 -1
  75. package/dist/vendor/zephyr3d/scene/dist/scene/scene.js +1 -0
  76. package/dist/vendor/zephyr3d/scene/dist/scene/scene.js.map +1 -1
  77. package/dist/vendor/zephyr3d/scene/dist/scene/terrain-cm/grass.js +1 -0
  78. package/dist/vendor/zephyr3d/scene/dist/scene/terrain-cm/grass.js.map +1 -1
  79. package/dist/vendor/zephyr3d/scene/dist/scene/terrain-cm/grassmaterial.js +1 -0
  80. package/dist/vendor/zephyr3d/scene/dist/scene/terrain-cm/grassmaterial.js.map +1 -1
  81. package/dist/vendor/zephyr3d/scene/dist/scene/terrain-cm/terrain-cm.js +1 -0
  82. package/dist/vendor/zephyr3d/scene/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
  83. package/dist/vendor/zephyr3d/scene/dist/scene/water.js +1 -0
  84. package/dist/vendor/zephyr3d/scene/dist/scene/water.js.map +1 -1
  85. package/dist/vendor/zephyr3d/scene/dist/shaders/shadow.js +617 -1
  86. package/dist/vendor/zephyr3d/scene/dist/shaders/shadow.js.map +1 -1
  87. package/dist/vendor/zephyr3d/scene/dist/shadow/esm.js +1 -0
  88. package/dist/vendor/zephyr3d/scene/dist/shadow/esm.js.map +1 -1
  89. package/dist/vendor/zephyr3d/scene/dist/shadow/pcf_opt.js +1 -0
  90. package/dist/vendor/zephyr3d/scene/dist/shadow/pcf_opt.js.map +1 -1
  91. package/dist/vendor/zephyr3d/scene/dist/shadow/pcf_pd.js +1 -0
  92. package/dist/vendor/zephyr3d/scene/dist/shadow/pcf_pd.js.map +1 -1
  93. package/dist/vendor/zephyr3d/scene/dist/shadow/pcss.js +182 -0
  94. package/dist/vendor/zephyr3d/scene/dist/shadow/pcss.js.map +1 -0
  95. package/dist/vendor/zephyr3d/scene/dist/shadow/shader.js +1 -0
  96. package/dist/vendor/zephyr3d/scene/dist/shadow/shader.js.map +1 -1
  97. package/dist/vendor/zephyr3d/scene/dist/shadow/shadow_impl.js.map +1 -1
  98. package/dist/vendor/zephyr3d/scene/dist/shadow/shadowmapper.js +183 -105
  99. package/dist/vendor/zephyr3d/scene/dist/shadow/shadowmapper.js.map +1 -1
  100. package/dist/vendor/zephyr3d/scene/dist/shadow/ssm.js +1 -0
  101. package/dist/vendor/zephyr3d/scene/dist/shadow/ssm.js.map +1 -1
  102. package/dist/vendor/zephyr3d/scene/dist/shadow/vsm.js +1 -0
  103. package/dist/vendor/zephyr3d/scene/dist/shadow/vsm.js.map +1 -1
  104. package/dist/vendor/zephyr3d/scene/dist/utility/serialization/manager.js +3 -1
  105. package/dist/vendor/zephyr3d/scene/dist/utility/serialization/manager.js.map +1 -1
  106. package/dist/vendor/zephyr3d/scene/dist/utility/serialization/scene/animation.js +1 -0
  107. package/dist/vendor/zephyr3d/scene/dist/utility/serialization/scene/animation.js.map +1 -1
  108. package/dist/vendor/zephyr3d/scene/dist/utility/serialization/scene/batch.js +1 -0
  109. package/dist/vendor/zephyr3d/scene/dist/utility/serialization/scene/batch.js.map +1 -1
  110. package/dist/vendor/zephyr3d/scene/dist/utility/serialization/scene/camera.js +122 -0
  111. package/dist/vendor/zephyr3d/scene/dist/utility/serialization/scene/camera.js.map +1 -1
  112. package/dist/vendor/zephyr3d/scene/dist/utility/serialization/scene/common.js +1 -0
  113. package/dist/vendor/zephyr3d/scene/dist/utility/serialization/scene/common.js.map +1 -1
  114. package/dist/vendor/zephyr3d/scene/dist/utility/serialization/scene/light.js +102 -21
  115. package/dist/vendor/zephyr3d/scene/dist/utility/serialization/scene/light.js.map +1 -1
  116. package/dist/vendor/zephyr3d/scene/dist/utility/serialization/scene/material.js +195 -3
  117. package/dist/vendor/zephyr3d/scene/dist/utility/serialization/scene/material.js.map +1 -1
  118. package/dist/vendor/zephyr3d/scene/dist/utility/serialization/scene/mesh.js +1 -0
  119. package/dist/vendor/zephyr3d/scene/dist/utility/serialization/scene/mesh.js.map +1 -1
  120. package/dist/vendor/zephyr3d/scene/dist/utility/serialization/scene/node.js +1 -0
  121. package/dist/vendor/zephyr3d/scene/dist/utility/serialization/scene/node.js.map +1 -1
  122. package/dist/vendor/zephyr3d/scene/dist/utility/serialization/scene/particle.js +1 -0
  123. package/dist/vendor/zephyr3d/scene/dist/utility/serialization/scene/particle.js.map +1 -1
  124. package/dist/vendor/zephyr3d/scene/dist/utility/serialization/scene/primitive.js +1 -0
  125. package/dist/vendor/zephyr3d/scene/dist/utility/serialization/scene/primitive.js.map +1 -1
  126. package/dist/vendor/zephyr3d/scene/dist/utility/serialization/scene/sprite.js +1 -0
  127. package/dist/vendor/zephyr3d/scene/dist/utility/serialization/scene/sprite.js.map +1 -1
  128. package/dist/vendor/zephyr3d/scene/dist/utility/serialization/scene/terrain.js +1 -0
  129. package/dist/vendor/zephyr3d/scene/dist/utility/serialization/scene/terrain.js.map +1 -1
  130. package/dist/vendor/zephyr3d/scene/dist/utility/serialization/scene/text.js +1 -0
  131. package/dist/vendor/zephyr3d/scene/dist/utility/serialization/scene/text.js.map +1 -1
  132. package/dist/vendor/zephyr3d/scene/dist/utility/serialization/scene/water.js +1 -0
  133. package/dist/vendor/zephyr3d/scene/dist/utility/serialization/scene/water.js.map +1 -1
  134. package/dist/vendor/zephyr3d/scene/dist/values.js +1 -0
  135. package/dist/vendor/zephyr3d/scene/dist/values.js.map +1 -1
  136. package/electron/main.cjs +30 -6
  137. package/package.json +4 -4
@@ -10182,6 +10182,7 @@ const tmpV3$1 = new Vector3();
10182
10182
  MaterialVaryingFlags[MaterialVaryingFlags["SSS_STORE_DIFFUSE"] = 64] = "SSS_STORE_DIFFUSE";
10183
10183
  MaterialVaryingFlags[MaterialVaryingFlags["SSS_STORE_NORMAL"] = 128] = "SSS_STORE_NORMAL";
10184
10184
  MaterialVaryingFlags[MaterialVaryingFlags["SSS_STORE_TRANSMISSION"] = 256] = "SSS_STORE_TRANSMISSION";
10185
+ MaterialVaryingFlags[MaterialVaryingFlags["SKIN_SSS_STORE"] = 512] = "SKIN_SSS_STORE";
10185
10186
  return MaterialVaryingFlags;
10186
10187
  }({});
10187
10188
  /**
@@ -11392,6 +11393,7 @@ const UNIFORM_NAME_MORPH_INFO = 'Z_UniformMorphInfo';
11392
11393
  depthBiasValues: new Vector4(),
11393
11394
  shadowCameraParams: new Vector4(),
11394
11395
  depthBiasScales: new Vector4(),
11396
+ implParams: new Vector4(),
11395
11397
  shadowMatrices: new Float32Array(16 * 4),
11396
11398
  shadowStrength: 1,
11397
11399
  envLightStrength: 1,
@@ -11547,6 +11549,7 @@ const UNIFORM_NAME_MORPH_INFO = 'Z_UniformMorphInfo';
11547
11549
  pb.vec4('depthBiasValues'),
11548
11550
  pb.vec4('shadowCameraParams'),
11549
11551
  pb.vec4('depthBiasScales'),
11552
+ pb.vec4('implParams'),
11550
11553
  pb.vec4[16]('shadowMatrices'),
11551
11554
  pb.float('shadowStrength'),
11552
11555
  pb.float('envLightStrength'),
@@ -12078,6 +12081,7 @@ const UNIFORM_NAME_MORPH_INFO = 'Z_UniformMorphInfo';
12078
12081
  this._lightUniformShadow.depthBiasValues.set(shadowMapParams.depthBiasValues[0]);
12079
12082
  this._lightUniformShadow.shadowCameraParams.set(shadowMapParams.cameraParams);
12080
12083
  this._lightUniformShadow.depthBiasScales.set(shadowMapParams.depthBiasScales);
12084
+ shadowMapParams.impl.getParams(this._lightUniformShadow.implParams);
12081
12085
  this._lightUniformShadow.shadowMatrices.set(shadowMapParams.shadowMatrices);
12082
12086
  this._lightUniformShadow.shadowStrength = light.shadow.shadowStrength;
12083
12087
  this._lightUniformShadow.envLightStrength = ctx.env?.light.strength ?? 0;
@@ -12326,6 +12330,9 @@ const UNIFORM_NAME_MORPH_INFO = 'Z_UniformMorphInfo';
12326
12330
  /** @internal */ static getCascadeDistances(scope) {
12327
12331
  return scope.light.cascadeDistances;
12328
12332
  }
12333
+ /** @internal */ static getShadowImplParams(scope) {
12334
+ return scope.light.implParams;
12335
+ }
12329
12336
  /** @internal */ static getDepthBiasValues(scope) {
12330
12337
  return scope.light.depthBiasValues;
12331
12338
  }
@@ -13965,6 +13972,9 @@ let FEATURE_DISABLE_TAA = 0;
13965
13972
  if (ctx.materialFlags & MaterialVaryingFlags.SSS_STORE_TRANSMISSION) {
13966
13973
  this.$outputs.zSSSTransmission = pb.vec4();
13967
13974
  }
13975
+ if (ctx.materialFlags & MaterialVaryingFlags.SKIN_SSS_STORE) {
13976
+ this.$outputs.zSkinSSS = pb.vec4();
13977
+ }
13968
13978
  if (ctx.renderPass.type === RENDER_PASS_TYPE_DEPTH && ctx.motionVectors) {
13969
13979
  this.$outputs.zMotionVector = pb.vec4();
13970
13980
  this.zTAAStrength = pb.float().uniform(2);
@@ -14002,7 +14012,7 @@ let FEATURE_DISABLE_TAA = 0;
14002
14012
  * @param sssDiffuse - Optional diffuse-only lighting color for SSS composition.
14003
14013
  * @param sssTransmission - Optional thin-shell transmission lighting color for SSS composition.
14004
14014
  * @returns void
14005
- */ outputFragmentColor(scope, worldPos, color, ssrRoughness, ssrNormal, sssProfile, sssParams, sssDiffuse, sssTransmission, sssProfileEnabled = false) {
14015
+ */ outputFragmentColor(scope, worldPos, color, ssrRoughness, ssrNormal, sssProfile, sssParams, sssDiffuse, sssTransmission, sssProfileEnabled = false, skinSSS) {
14006
14016
  const pb = scope.$builder;
14007
14017
  const that = this;
14008
14018
  const funcName = 'Z_outputFragmentColor';
@@ -14174,6 +14184,10 @@ let FEATURE_DISABLE_TAA = 0;
14174
14184
  const disableSSS = that.drawContext.renderPass.type !== RENDER_PASS_TYPE_LIGHT || that.isTransparentPass(that.pass, that.drawContext) && !that.alphaToCoverage || that.needSceneColor();
14175
14185
  scope.$outputs.zSSSTransmission = disableSSS ? pb.vec4(0) : sssTransmission ?? pb.vec4(0);
14176
14186
  }
14187
+ if (that.drawContext.materialFlags & MaterialVaryingFlags.SKIN_SSS_STORE) {
14188
+ const disableSkinSSS = that.drawContext.renderPass.type !== RENDER_PASS_TYPE_LIGHT || that.isTransparentPass(that.pass, that.drawContext) && !that.alphaToCoverage || that.needSceneColor();
14189
+ scope.$outputs.zSkinSSS = disableSkinSSS ? pb.vec4(0) : skinSSS ?? pb.vec4(0);
14190
+ }
14177
14191
  }
14178
14192
  }
14179
14193
  FEATURE_ALPHATEST = MeshMaterial.defineFeature();
@@ -16394,6 +16408,259 @@ const SUBSURFACE_PROFILE_PRESET_RESPONSE = {
16394
16408
  }
16395
16409
  }
16396
16410
 
16411
+ /**
16412
+ * Stylized realtime skin material.
16413
+ *
16414
+ * @remarks
16415
+ * This material is designed for the {@link SkinSSS} post effect. It renders a regular lit color,
16416
+ * and when `camera.skinSSS` is enabled it also writes a skin lighting multiplier into the
16417
+ * `SkinSSSTexture` MRT. The post effect blurs that side buffer in screen space to create a soft
16418
+ * character-skin look similar to simple game/anime skin renderers.
16419
+ *
16420
+ * The optional `subsurfaceTexture` uses R as skin mask and G as local softness.
16421
+ *
16422
+ * @public
16423
+ */ class SkinMaterial extends applyMaterialMixins(MeshMaterial, mixinLight, mixinVertexColor, mixinTextureProps('subsurface')) {
16424
+ static FEATURE_VERTEX_NORMAL = this.defineFeature();
16425
+ static FEATURE_VERTEX_TANGENT = this.defineFeature();
16426
+ _shininess;
16427
+ _specularStrength;
16428
+ _diffuseWrap;
16429
+ _diffuseSoftness;
16430
+ _scatterWrap;
16431
+ _scatterStrength;
16432
+ _scatterColor;
16433
+ constructor(){
16434
+ super();
16435
+ this._shininess = 72;
16436
+ this._specularStrength = 0.22;
16437
+ this._diffuseWrap = 0.28;
16438
+ this._diffuseSoftness = 0.45;
16439
+ this._scatterWrap = 0.65;
16440
+ this._scatterStrength = 0.7;
16441
+ this._scatterColor = new Vector4(1, 0.42, 0.28, 1);
16442
+ this.useFeature(SkinMaterial.FEATURE_VERTEX_NORMAL, true);
16443
+ }
16444
+ /** Marker used by the forward render graph to allocate the SkinSSS MRT. */ get skinSSS() {
16445
+ return true;
16446
+ }
16447
+ clone() {
16448
+ const other = new SkinMaterial();
16449
+ other.copyFrom(this);
16450
+ return other;
16451
+ }
16452
+ copyFrom(other) {
16453
+ super.copyFrom(other);
16454
+ this.vertexNormal = other.vertexNormal;
16455
+ this.vertexTangent = other.vertexTangent;
16456
+ this.shininess = other.shininess;
16457
+ this.specularStrength = other.specularStrength;
16458
+ this.diffuseWrap = other.diffuseWrap;
16459
+ this.diffuseSoftness = other.diffuseSoftness;
16460
+ this.scatterWrap = other.scatterWrap;
16461
+ this.scatterStrength = other.scatterStrength;
16462
+ this.scatterColor = other.scatterColor;
16463
+ }
16464
+ /** true if vertex normal attribute presents */ get vertexNormal() {
16465
+ return this.featureUsed(SkinMaterial.FEATURE_VERTEX_NORMAL);
16466
+ }
16467
+ set vertexNormal(val) {
16468
+ this.useFeature(SkinMaterial.FEATURE_VERTEX_NORMAL, !!val);
16469
+ }
16470
+ /** true if vertex tangent attribute presents */ get vertexTangent() {
16471
+ return this.featureUsed(SkinMaterial.FEATURE_VERTEX_TANGENT);
16472
+ }
16473
+ set vertexTangent(val) {
16474
+ this.useFeature(SkinMaterial.FEATURE_VERTEX_TANGENT, !!val);
16475
+ }
16476
+ /** Blinn specular exponent. Higher values produce smaller highlights. */ get shininess() {
16477
+ return this._shininess;
16478
+ }
16479
+ set shininess(val) {
16480
+ const next = Math.max(1, val ?? 1);
16481
+ if (next !== this._shininess) {
16482
+ this._shininess = next;
16483
+ this.uniformChanged();
16484
+ }
16485
+ }
16486
+ /** Direct specular strength. Keep this restrained for soft skin. */ get specularStrength() {
16487
+ return this._specularStrength;
16488
+ }
16489
+ set specularStrength(val) {
16490
+ const next = Math.max(0, val ?? 0);
16491
+ if (next !== this._specularStrength) {
16492
+ this._specularStrength = next;
16493
+ this.uniformChanged();
16494
+ }
16495
+ }
16496
+ /** Wrap amount for visible diffuse lighting. */ get diffuseWrap() {
16497
+ return this._diffuseWrap;
16498
+ }
16499
+ set diffuseWrap(val) {
16500
+ const next = Math.max(0, val ?? 0);
16501
+ if (next !== this._diffuseWrap) {
16502
+ this._diffuseWrap = next;
16503
+ this.uniformChanged();
16504
+ }
16505
+ }
16506
+ /** Blend from hard Lambert lighting to wrapped diffuse lighting. */ get diffuseSoftness() {
16507
+ return this._diffuseSoftness;
16508
+ }
16509
+ set diffuseSoftness(val) {
16510
+ const next = Math.max(0, Math.min(1, val ?? 0));
16511
+ if (next !== this._diffuseSoftness) {
16512
+ this._diffuseSoftness = next;
16513
+ this.uniformChanged();
16514
+ }
16515
+ }
16516
+ /** Wider wrap used only for the post-process scattering source. */ get scatterWrap() {
16517
+ return this._scatterWrap;
16518
+ }
16519
+ set scatterWrap(val) {
16520
+ const next = Math.max(0, val ?? 0);
16521
+ if (next !== this._scatterWrap) {
16522
+ this._scatterWrap = next;
16523
+ this.uniformChanged();
16524
+ }
16525
+ }
16526
+ /** Strength of the multiplier written into the SkinSSS side buffer. */ get scatterStrength() {
16527
+ return this._scatterStrength;
16528
+ }
16529
+ set scatterStrength(val) {
16530
+ const next = Math.max(0, val ?? 0);
16531
+ if (next !== this._scatterStrength) {
16532
+ this._scatterStrength = next;
16533
+ this.uniformChanged();
16534
+ }
16535
+ }
16536
+ /** Warm tint for the blurred skin lighting contribution. */ get scatterColor() {
16537
+ return this._scatterColor;
16538
+ }
16539
+ set scatterColor(val) {
16540
+ if (!val.equalsTo(this._scatterColor)) {
16541
+ this._scatterColor.set(val);
16542
+ this.uniformChanged();
16543
+ }
16544
+ }
16545
+ vertexShader(scope) {
16546
+ super.vertexShader(scope);
16547
+ const pb = scope.$builder;
16548
+ scope.$l.oPos = ShaderHelper.resolveVertexPosition(scope);
16549
+ scope.$outputs.worldPos = pb.mul(ShaderHelper.getWorldMatrix(scope), pb.vec4(scope.oPos, 1)).xyz;
16550
+ ShaderHelper.setClipSpacePosition(scope, pb.mul(ShaderHelper.getViewProjectionMatrix(scope), pb.vec4(scope.$outputs.worldPos, 1)));
16551
+ if (this.vertexNormal) {
16552
+ scope.$l.oNorm = ShaderHelper.resolveVertexNormal(scope);
16553
+ scope.$outputs.wNorm = pb.mul(ShaderHelper.getNormalMatrix(scope), pb.vec4(scope.oNorm, 0)).xyz;
16554
+ if (this.vertexTangent) {
16555
+ scope.$l.oTangent = ShaderHelper.resolveVertexTangent(scope);
16556
+ scope.$outputs.wTangent = pb.mul(ShaderHelper.getNormalMatrix(scope), pb.vec4(scope.oTangent.xyz, 0)).xyz;
16557
+ scope.$outputs.wBinormal = pb.mul(pb.cross(scope.$outputs.wNorm, scope.$outputs.wTangent), scope.oTangent.w);
16558
+ }
16559
+ }
16560
+ }
16561
+ fragmentShader(scope) {
16562
+ super.fragmentShader(scope);
16563
+ const pb = scope.$builder;
16564
+ const that = this;
16565
+ if (this.needFragmentColorInput()) {
16566
+ if (this.drawContext.renderPass.type === RENDER_PASS_TYPE_LIGHT) {
16567
+ scope.zSkinShininess = pb.float().uniform(2);
16568
+ scope.zSkinSpecularStrength = pb.float().uniform(2);
16569
+ scope.zSkinDiffuseWrap = pb.float().uniform(2);
16570
+ scope.zSkinDiffuseSoftness = pb.float().uniform(2);
16571
+ scope.zSkinScatterWrap = pb.float().uniform(2);
16572
+ scope.zSkinScatterStrength = pb.float().uniform(2);
16573
+ scope.zSkinScatterColor = pb.vec4().uniform(2);
16574
+ }
16575
+ scope.$l.albedo = this.calculateAlbedoColor(scope);
16576
+ if (this.vertexColor) {
16577
+ scope.albedo = pb.mul(scope.albedo, this.getVertexColor(scope));
16578
+ }
16579
+ if (this.drawContext.renderPass.type === RENDER_PASS_TYPE_LIGHT) {
16580
+ const baseLightPass = !this.drawContext.lightBlending;
16581
+ scope.$l.normal = this.calculateNormal(scope, scope.$inputs.worldPos, scope.$inputs.wNorm, scope.$inputs.wTangent, scope.$inputs.wBinormal);
16582
+ scope.$l.viewVec = this.calculateViewVector(scope, scope.$inputs.worldPos);
16583
+ scope.$l.roughness = pb.sqrt(pb.div(2, pb.add(scope.zSkinShininess, 2)));
16584
+ scope.$l.skinMask = pb.float(1);
16585
+ scope.$l.skinSoftness = pb.float(0);
16586
+ if (this.subsurfaceTexture) {
16587
+ scope.$l.subsurfaceTexel = this.sampleSubsurfaceTexture(scope);
16588
+ scope.skinMask = pb.clamp(scope.subsurfaceTexel.r, 0, 1);
16589
+ scope.skinSoftness = pb.clamp(scope.subsurfaceTexel.g, 0, 1);
16590
+ }
16591
+ scope.$l.diffuseLighting = pb.vec3(0);
16592
+ scope.$l.scatterLighting = pb.vec3(0);
16593
+ scope.$l.specularLighting = pb.vec3(0);
16594
+ if (this.needCalculateEnvLight() && baseLightPass) {
16595
+ scope.$l.envDiffuse = this.getEnvLightIrradiance(scope, scope.normal);
16596
+ scope.diffuseLighting = pb.add(scope.diffuseLighting, scope.envDiffuse);
16597
+ scope.scatterLighting = pb.add(scope.scatterLighting, pb.mul(scope.envDiffuse, pb.add(0.7, pb.mul(scope.skinSoftness, 0.45))));
16598
+ scope.$l.reflectVec = this.calculateReflectionVector(scope, scope.normal, scope.viewVec);
16599
+ scope.specularLighting = pb.add(scope.specularLighting, pb.mul(this.getEnvLightRadiance(scope, scope.reflectVec, scope.roughness), scope.zSkinSpecularStrength));
16600
+ }
16601
+ this.forEachLight(scope, function(type, posRange, dirCutoff, colorIntensity, extra, shadow) {
16602
+ this.$l.diffuseScale = pb.float(1);
16603
+ this.$l.specularScale = pb.float(1);
16604
+ this.$l.sourceRadiusFactor = pb.float(0);
16605
+ this.$if(pb.equal(type, LIGHT_TYPE_POINT), function() {
16606
+ this.diffuseScale = extra.x;
16607
+ this.specularScale = extra.y;
16608
+ this.sourceRadiusFactor = pb.div(extra.z, pb.max(pb.distance(posRange.xyz, this.$inputs.worldPos), 0.0001));
16609
+ });
16610
+ this.$l.lightAtten = that.calculateLightAttenuation(this, type, this.$inputs.worldPos, posRange, dirCutoff);
16611
+ this.$l.lightDir = that.calculateLightDirection(this, type, this.$inputs.worldPos, posRange, dirCutoff);
16612
+ this.$l.rawNoL = pb.dot(this.normal, this.lightDir);
16613
+ this.$l.NoL = pb.clamp(this.rawNoL, 0, 1);
16614
+ this.$l.NoLWrap = pb.clamp(pb.div(pb.add(this.rawNoL, this.zSkinDiffuseWrap), pb.add(1, this.zSkinDiffuseWrap)), 0, 1);
16615
+ this.$l.NoLScatter = pb.clamp(pb.div(pb.add(this.rawNoL, this.zSkinScatterWrap), pb.add(1, this.zSkinScatterWrap)), 0, 1);
16616
+ this.$l.shadowTerm = pb.float(1);
16617
+ if (shadow) {
16618
+ this.$if(pb.greaterThan(this.NoLWrap, 0), function() {
16619
+ this.shadowTerm = that.calculateShadow(this, this.$inputs.worldPos, pb.max(this.NoL, 1e-5));
16620
+ });
16621
+ }
16622
+ this.$l.lightColor = pb.mul(colorIntensity.rgb, colorIntensity.a, this.lightAtten, this.shadowTerm);
16623
+ this.$l.halfVec = pb.normalize(pb.add(this.viewVec, this.lightDir));
16624
+ this.$l.NoH = pb.clamp(pb.dot(this.normal, this.halfVec), 0, 1);
16625
+ this.$l.pointShininess = pb.max(pb.div(this.zSkinShininess, pb.add(1, pb.mul(this.sourceRadiusFactor, 32))), 1);
16626
+ this.$l.hardDiffuse = pb.mul(this.lightColor, this.NoL, this.diffuseScale, 1 / Math.PI);
16627
+ this.$l.softDiffuse = pb.mul(this.lightColor, this.NoLWrap, this.diffuseScale, 1 / Math.PI);
16628
+ this.$l.softness = pb.clamp(pb.add(this.zSkinDiffuseSoftness, pb.mul(this.skinSoftness, 0.35)), 0, 1);
16629
+ this.diffuseLighting = pb.add(this.diffuseLighting, pb.mix(this.hardDiffuse, this.softDiffuse, this.softness));
16630
+ this.scatterLighting = pb.add(this.scatterLighting, pb.mul(this.lightColor, this.NoLScatter, pb.add(0.7, pb.mul(this.skinSoftness, 0.55)), this.diffuseScale, 1 / Math.PI));
16631
+ this.$l.specular = pb.mul(this.lightColor, pb.pow(this.NoH, this.pointShininess), this.zSkinSpecularStrength, this.specularScale, this.NoLWrap);
16632
+ this.specularLighting = pb.add(this.specularLighting, this.specular);
16633
+ });
16634
+ scope.$l.litColor = pb.add(pb.mul(scope.albedo.rgb, scope.diffuseLighting), scope.specularLighting);
16635
+ scope.$l.scatterMultiplier = pb.add(baseLightPass ? pb.vec3(1) : pb.vec3(0), pb.mul(scope.albedo.rgb, scope.scatterLighting, scope.zSkinScatterColor.rgb, scope.zSkinScatterStrength, pb.add(0.75, pb.mul(scope.skinSoftness, 0.45))));
16636
+ scope.$l.skinSSS = pb.vec4(scope.scatterMultiplier, scope.skinMask);
16637
+ if (this.drawContext.materialFlags & MaterialVaryingFlags.SSR_STORE_ROUGHNESS) {
16638
+ scope.$l.outRoughness = pb.vec4(pb.mul(scope.albedo.rgb, pb.sub(1, scope.roughness), scope.zSkinSpecularStrength), pb.mul(scope.roughness, ShaderHelper.getCameraRoughnessFactor(scope)));
16639
+ this.outputFragmentColor(scope, scope.$inputs.worldPos, pb.vec4(scope.litColor, scope.albedo.a), scope.outRoughness, pb.vec4(pb.add(pb.mul(scope.normal, 0.5), pb.vec3(0.5)), 1), undefined, undefined, undefined, undefined, false, scope.skinSSS);
16640
+ } else {
16641
+ this.outputFragmentColor(scope, scope.$inputs.worldPos, pb.vec4(scope.litColor, scope.albedo.a), undefined, undefined, undefined, undefined, undefined, undefined, false, scope.skinSSS);
16642
+ }
16643
+ } else {
16644
+ this.outputFragmentColor(scope, scope.$inputs.worldPos, scope.albedo);
16645
+ }
16646
+ } else {
16647
+ this.outputFragmentColor(scope, scope.$inputs.worldPos, null);
16648
+ }
16649
+ }
16650
+ applyUniformValues(bindGroup, ctx, pass) {
16651
+ super.applyUniformValues(bindGroup, ctx, pass);
16652
+ if (this.needFragmentColor(ctx) && ctx.renderPass.type === RENDER_PASS_TYPE_LIGHT) {
16653
+ bindGroup.setValue('zSkinShininess', this._shininess);
16654
+ bindGroup.setValue('zSkinSpecularStrength', this._specularStrength);
16655
+ bindGroup.setValue('zSkinDiffuseWrap', this._diffuseWrap);
16656
+ bindGroup.setValue('zSkinDiffuseSoftness', this._diffuseSoftness);
16657
+ bindGroup.setValue('zSkinScatterWrap', this._scatterWrap);
16658
+ bindGroup.setValue('zSkinScatterStrength', this._scatterStrength);
16659
+ bindGroup.setValue('zSkinScatterColor', this._scatterColor);
16660
+ }
16661
+ }
16662
+ }
16663
+
16397
16664
  const ggxLut = new Map();
16398
16665
  function getGGXLUT(size) {
16399
16666
  let lut = ggxLut.get(size);
@@ -33134,7 +33401,7 @@ const tmpDrawablePos = new Vector3();
33134
33401
  }
33135
33402
  }
33136
33403
 
33137
- const SURFACE_MRT_FLAGS$1 = MaterialVaryingFlags.SSR_STORE_ROUGHNESS | MaterialVaryingFlags.SSS_STORE_PROFILE | MaterialVaryingFlags.SSS_STORE_DIFFUSE | MaterialVaryingFlags.SSS_STORE_NORMAL | MaterialVaryingFlags.SSS_STORE_TRANSMISSION;
33404
+ const SURFACE_MRT_FLAGS$1 = MaterialVaryingFlags.SSR_STORE_ROUGHNESS | MaterialVaryingFlags.SSS_STORE_PROFILE | MaterialVaryingFlags.SSS_STORE_DIFFUSE | MaterialVaryingFlags.SSS_STORE_NORMAL | MaterialVaryingFlags.SSS_STORE_TRANSMISSION | MaterialVaryingFlags.SKIN_SSS_STORE;
33138
33405
  const ADDITIVE_LIGHT_PASS_OMIT_MRT_FLAGS = MaterialVaryingFlags.SSR_STORE_ROUGHNESS | MaterialVaryingFlags.SSS_STORE_PROFILE | MaterialVaryingFlags.SSS_STORE_NORMAL;
33139
33406
  /**
33140
33407
  * Forward render pass
@@ -33186,6 +33453,9 @@ const ADDITIVE_LIGHT_PASS_OMIT_MRT_FLAGS = MaterialVaryingFlags.SSR_STORE_ROUGHN
33186
33453
  if (materialFlags & MaterialVaryingFlags.SSS_STORE_TRANSMISSION) {
33187
33454
  attachments.push(ctx.SSSTransmissionTexture);
33188
33455
  }
33456
+ if (materialFlags & MaterialVaryingFlags.SKIN_SSS_STORE) {
33457
+ attachments.push(ctx.SkinSSSTexture);
33458
+ }
33189
33459
  return attachments.length === 1 ? attachments[0] : attachments;
33190
33460
  }
33191
33461
  /** @internal */ selectTransparentOITShadowLight(ctx, renderQueue) {
@@ -35276,6 +35546,13 @@ const DEFAULT_PROFILING_OPTIONS = {
35276
35546
  *
35277
35547
  * @public
35278
35548
  */ class DevicePoolAllocator {
35549
+ _device;
35550
+ /**
35551
+ * Creates a new instance of the DevicePoolAllocator.
35552
+ * @param device - Optional device instance to use for resource allocation. If not provided, the global device will be used.
35553
+ */ constructor(device){
35554
+ this._device = device ?? null;
35555
+ }
35279
35556
  /**
35280
35557
  * Allocate a transient texture from the device pool.
35281
35558
  *
@@ -35283,7 +35560,7 @@ const DEFAULT_PROFILING_OPTIONS = {
35283
35560
  * @param size - Resolved pixel dimensions.
35284
35561
  * @returns A pooled Texture2D instance.
35285
35562
  */ allocate(desc, size) {
35286
- const device = getDevice();
35563
+ const device = this._device ?? getDevice();
35287
35564
  const mipmapping = (desc.mipLevels ?? 1) > 1;
35288
35565
  const texture = device.pool.fetchTemporalTexture2D(false, desc.format, size.width, size.height, mipmapping);
35289
35566
  if (desc.mipLevels && texture.mipLevelCount < desc.mipLevels) {
@@ -35297,7 +35574,7 @@ const DEFAULT_PROFILING_OPTIONS = {
35297
35574
  *
35298
35575
  * @param texture - The texture to release.
35299
35576
  */ release(texture) {
35300
- const device = getDevice();
35577
+ const device = this._device ?? getDevice();
35301
35578
  device.pool.releaseTexture(texture);
35302
35579
  }
35303
35580
  /**
@@ -35305,7 +35582,7 @@ const DEFAULT_PROFILING_OPTIONS = {
35305
35582
  *
35306
35583
  * @param texture - The texture to retain.
35307
35584
  */ retain(texture) {
35308
- const device = getDevice();
35585
+ const device = this._device ?? getDevice();
35309
35586
  device.pool.retainTexture(texture);
35310
35587
  }
35311
35588
  /**
@@ -35314,7 +35591,7 @@ const DEFAULT_PROFILING_OPTIONS = {
35314
35591
  * @param desc - Framebuffer descriptor from the render graph pass.
35315
35592
  * @returns A pooled FrameBuffer instance.
35316
35593
  */ allocateFramebuffer(desc) {
35317
- const device = getDevice();
35594
+ const device = this._device ?? getDevice();
35318
35595
  const colors = Array.isArray(desc.colorAttachments) ? desc.colorAttachments : desc.colorAttachments ? [
35319
35596
  desc.colorAttachments
35320
35597
  ] : [];
@@ -35326,7 +35603,7 @@ const DEFAULT_PROFILING_OPTIONS = {
35326
35603
  *
35327
35604
  * @param framebuffer - The framebuffer to release.
35328
35605
  */ releaseFramebuffer(framebuffer) {
35329
- const device = getDevice();
35606
+ const device = this._device ?? getDevice();
35330
35607
  device.pool.releaseFrameBuffer(framebuffer);
35331
35608
  }
35332
35609
  }
@@ -35754,6 +36031,9 @@ const DEFAULT_PROFILING_OPTIONS = {
35754
36031
  if (ctx.materialFlags & MaterialVaryingFlags.SSS_STORE_TRANSMISSION) {
35755
36032
  attachments.push(ctx.SSSTransmissionTexture);
35756
36033
  }
36034
+ if (ctx.materialFlags & MaterialVaryingFlags.SKIN_SSS_STORE) {
36035
+ attachments.push(ctx.SkinSSSTexture);
36036
+ }
35757
36037
  const tmpFramebuffer = device.pool.fetchTemporalFramebuffer(true, w, h, attachments.length === 1 ? attachments[0] : attachments, depth ?? ctx.depthFormat);
35758
36038
  device.setFramebuffer(tmpFramebuffer);
35759
36039
  }
@@ -38311,10 +38591,8 @@ const FLT_MAX = 32767;
38311
38591
  }
38312
38592
  apply(ctx, inputColorTexture, sceneDepthTexture, srgbOutput) {
38313
38593
  const historyManager = ctx.camera.getHistoryResourceManager();
38314
- const useGraphHistory = !!historyManager?.frameActive;
38315
- const data = useGraphHistory ? null : ctx.camera.getHistoryData();
38316
- const prevColorTex = useGraphHistory ? historyManager.tryGetPrevious(RGHistoryResources.TAA_COLOR) : data.prevColorTex;
38317
- const prevMotionVectorTex = useGraphHistory ? historyManager.tryGetPrevious(RGHistoryResources.TAA_MOTION_VECTOR) : data.prevMotionVectorTex;
38594
+ const prevColorTex = historyManager.tryGetPrevious(RGHistoryResources.TAA_COLOR);
38595
+ const prevMotionVectorTex = historyManager.tryGetPrevious(RGHistoryResources.TAA_MOTION_VECTOR);
38318
38596
  if (!prevColorTex || !prevMotionVectorTex || prevColorTex.width !== inputColorTexture.width || prevColorTex.height !== inputColorTexture.height) {
38319
38597
  this.passThrough(ctx, inputColorTexture, srgbOutput);
38320
38598
  } else {
@@ -38339,42 +38617,6 @@ const FLT_MAX = 32767;
38339
38617
  ctx.device.setBindGroup(0, this._bindGroup);
38340
38618
  this.drawFullscreenQuad();
38341
38619
  }
38342
- const currentColorTex = ctx.device.getFramebuffer().getColorAttachments()[0];
38343
- if (useGraphHistory) {
38344
- const colorSize = {
38345
- width: currentColorTex.width,
38346
- height: currentColorTex.height
38347
- };
38348
- historyManager.queueRetainedCommit(RGHistoryResources.TAA_COLOR, {
38349
- format: currentColorTex.format,
38350
- sizeMode: 'absolute',
38351
- width: currentColorTex.width,
38352
- height: currentColorTex.height
38353
- }, colorSize, currentColorTex);
38354
- if (ctx.motionVectorTexture) {
38355
- const motionVectorSize = {
38356
- width: ctx.motionVectorTexture.width,
38357
- height: ctx.motionVectorTexture.height
38358
- };
38359
- historyManager.queueRetainedCommit(RGHistoryResources.TAA_MOTION_VECTOR, {
38360
- format: ctx.motionVectorTexture.format,
38361
- sizeMode: 'absolute',
38362
- width: ctx.motionVectorTexture.width,
38363
- height: ctx.motionVectorTexture.height
38364
- }, motionVectorSize, ctx.motionVectorTexture);
38365
- }
38366
- } else {
38367
- if (data.prevColorTex) {
38368
- ctx.device.pool.releaseTexture(data.prevColorTex);
38369
- }
38370
- ctx.device.pool.retainTexture(currentColorTex);
38371
- data.prevColorTex = currentColorTex;
38372
- if (data.prevMotionVectorTex) {
38373
- ctx.device.pool.releaseTexture(data.prevMotionVectorTex);
38374
- }
38375
- ctx.device.pool.retainTexture(ctx.motionVectorTexture);
38376
- data.prevMotionVectorTex = ctx.motionVectorTexture;
38377
- }
38378
38620
  }
38379
38621
  requireLinearDepthTexture(_ctx) {
38380
38622
  return true;
@@ -39398,11 +39640,9 @@ float3 hi_z_trace(float3 p, float3 v, in uint camera, out uint iterations) {
39398
39640
  this.blurPass(ctx, blitterV, intersectTex, 2, blurSizeScale, kernelRadius, stdDev, depthCutoff, pingpongFramebuffer[1], pingpongFramebuffer[0]);
39399
39641
  }
39400
39642
  const historyManager = ctx.camera.getHistoryResourceManager();
39401
- const useGraphHistory = !!historyManager?.frameActive;
39402
- const history = useGraphHistory ? null : ctx.camera.getHistoryData();
39403
39643
  let reflectanceTex = pingpongFramebuffer[0].getColorAttachments()[0];
39404
- const prevSSRReflectTex = useGraphHistory ? historyManager.tryGetPrevious(RGHistoryResources.SSR_REFLECT) : history.prevSSRReflectTex;
39405
- const prevSSRMotionVectorTex = useGraphHistory ? historyManager.tryGetPrevious(RGHistoryResources.SSR_MOTION_VECTOR) : history.prevSSRMotionVectorTex;
39644
+ const prevSSRReflectTex = historyManager.tryGetPrevious(RGHistoryResources.SSR_REFLECT);
39645
+ const prevSSRMotionVectorTex = historyManager.tryGetPrevious(RGHistoryResources.SSR_MOTION_VECTOR);
39406
39646
  const canTemporal = ctx.camera.ssrTemporal && !!ctx.motionVectorTexture && !!prevSSRReflectTex && !!prevSSRMotionVectorTex && prevSSRReflectTex.width === reflectanceTex.width && prevSSRReflectTex.height === reflectanceTex.height;
39407
39647
  if (canTemporal) {
39408
39648
  this.temporal(ctx, reflectanceTex, sceneDepthTexture, prevSSRReflectTex, prevSSRMotionVectorTex, pingpongFramebuffer[1]);
@@ -39410,51 +39650,29 @@ float3 hi_z_trace(float3 p, float3 v, in uint camera, out uint iterations) {
39410
39650
  }
39411
39651
  device.popDeviceStates();
39412
39652
  this.combine(ctx, inputColorTexture, reflectanceTex, srgbOutput);
39413
- if (useGraphHistory) {
39414
- if (ctx.camera.ssrTemporal) {
39415
- const reflectanceSize = {
39416
- width: reflectanceTex.width,
39417
- height: reflectanceTex.height
39418
- };
39419
- historyManager.queueRetainedCommit(RGHistoryResources.SSR_REFLECT, {
39420
- format: reflectanceTex.format,
39421
- sizeMode: 'absolute',
39422
- width: reflectanceTex.width,
39423
- height: reflectanceTex.height
39424
- }, reflectanceSize, reflectanceTex);
39425
- }
39426
- if (ctx.camera.ssrTemporal && ctx.motionVectorTexture) {
39427
- const motionVectorSize = {
39428
- width: ctx.motionVectorTexture.width,
39429
- height: ctx.motionVectorTexture.height
39430
- };
39431
- historyManager.queueRetainedCommit(RGHistoryResources.SSR_MOTION_VECTOR, {
39432
- format: ctx.motionVectorTexture.format,
39433
- sizeMode: 'absolute',
39434
- width: ctx.motionVectorTexture.width,
39435
- height: ctx.motionVectorTexture.height
39436
- }, motionVectorSize, ctx.motionVectorTexture);
39437
- }
39438
- } else {
39439
- if (history.prevSSRReflectTex) {
39440
- device.pool.releaseTexture(history.prevSSRReflectTex);
39441
- history.prevSSRReflectTex = null;
39442
- }
39443
- if (history.prevSSRMotionVectorTex) {
39444
- device.pool.releaseTexture(history.prevSSRMotionVectorTex);
39445
- history.prevSSRMotionVectorTex = null;
39446
- }
39447
- if (ctx.camera.ssrTemporal) {
39448
- device.pool.retainTexture(reflectanceTex);
39449
- history.prevSSRReflectTex = reflectanceTex;
39450
- }
39451
- if (ctx.camera.ssrTemporal && ctx.motionVectorTexture) {
39452
- if (history.prevSSRMotionVectorTex) {
39453
- device.pool.releaseTexture(history.prevSSRMotionVectorTex);
39454
- }
39455
- device.pool.retainTexture(ctx.motionVectorTexture);
39456
- history.prevSSRMotionVectorTex = ctx.motionVectorTexture;
39457
- }
39653
+ if (ctx.camera.ssrTemporal) {
39654
+ const reflectanceSize = {
39655
+ width: reflectanceTex.width,
39656
+ height: reflectanceTex.height
39657
+ };
39658
+ historyManager.queueRetainedCommit(RGHistoryResources.SSR_REFLECT, {
39659
+ format: reflectanceTex.format,
39660
+ sizeMode: 'absolute',
39661
+ width: reflectanceTex.width,
39662
+ height: reflectanceTex.height
39663
+ }, reflectanceSize, reflectanceTex);
39664
+ }
39665
+ if (ctx.camera.ssrTemporal && ctx.motionVectorTexture) {
39666
+ const motionVectorSize = {
39667
+ width: ctx.motionVectorTexture.width,
39668
+ height: ctx.motionVectorTexture.height
39669
+ };
39670
+ historyManager.queueRetainedCommit(RGHistoryResources.SSR_MOTION_VECTOR, {
39671
+ format: ctx.motionVectorTexture.format,
39672
+ sizeMode: 'absolute',
39673
+ width: ctx.motionVectorTexture.width,
39674
+ height: ctx.motionVectorTexture.height
39675
+ }, motionVectorSize, ctx.motionVectorTexture);
39458
39676
  }
39459
39677
  device.pool.releaseFrameBuffer(intersectFramebuffer);
39460
39678
  device.pool.releaseFrameBuffer(pingpongFramebuffer[0]);
@@ -40986,6 +41204,174 @@ float3 hi_z_trace(float3 p, float3 v, in uint camera, out uint iterations) {
40986
41204
  }
40987
41205
  }
40988
41206
 
41207
+ /**
41208
+ * Stylized screen-space skin scattering pass.
41209
+ *
41210
+ * @remarks
41211
+ * This is intentionally separate from the profile-based {@link SSS} pass. It follows the simpler
41212
+ * depth-aware blur used by many character renderers: a skin material writes a lighting multiplier
41213
+ * into a side buffer, then this pass performs a fixed 9x9 depth-aware blur and composites it back
41214
+ * over the opaque color.
41215
+ *
41216
+ * @public
41217
+ */ class SkinSSS extends AbstractPostEffect {
41218
+ static _program = null;
41219
+ _bindGroup;
41220
+ _strength;
41221
+ _opacity;
41222
+ _sampleStep;
41223
+ _depthScale;
41224
+ _colorBoost;
41225
+ constructor(){
41226
+ super();
41227
+ this._layer = PostEffectLayer.opaque;
41228
+ this._bindGroup = null;
41229
+ this._strength = 1;
41230
+ this._opacity = 0.18;
41231
+ this._sampleStep = 2;
41232
+ this._depthScale = 80;
41233
+ this._colorBoost = 1;
41234
+ }
41235
+ /** Final blend strength. */ get strength() {
41236
+ return this._strength;
41237
+ }
41238
+ set strength(val) {
41239
+ this._strength = Math.max(0, val ?? 0);
41240
+ }
41241
+ /** Bias subtracted from the blurred skin mask before compositing. */ get opacity() {
41242
+ return this._opacity;
41243
+ }
41244
+ set opacity(val) {
41245
+ this._opacity = Math.max(0, Math.min(1, val ?? 0));
41246
+ }
41247
+ /** Pixel spacing between blur taps. The reference shader uses 2. */ get sampleStep() {
41248
+ return this._sampleStep;
41249
+ }
41250
+ set sampleStep(val) {
41251
+ this._sampleStep = Math.max(0.25, val ?? 0.25);
41252
+ }
41253
+ /** Depth rejection scale. The reference shader uses 80. */ get depthScale() {
41254
+ return this._depthScale;
41255
+ }
41256
+ set depthScale(val) {
41257
+ this._depthScale = Math.max(0, val ?? 0);
41258
+ }
41259
+ /** Multiplier applied to the blurred skin lighting multiplier before compositing. */ get colorBoost() {
41260
+ return this._colorBoost;
41261
+ }
41262
+ set colorBoost(val) {
41263
+ this._colorBoost = Math.max(0, val ?? 0);
41264
+ }
41265
+ requireLinearDepthTexture() {
41266
+ return true;
41267
+ }
41268
+ apply(ctx, inputColorTexture, sceneDepthTexture, srgbOutput) {
41269
+ if (!ctx.SkinSSSTexture || this._strength <= 0) {
41270
+ this.passThrough(ctx, inputColorTexture, srgbOutput);
41271
+ return;
41272
+ }
41273
+ const device = ctx.device;
41274
+ let program = SkinSSS._program;
41275
+ if (!program) {
41276
+ program = this.createProgram(ctx);
41277
+ SkinSSS._program = program;
41278
+ }
41279
+ if (!this._bindGroup) {
41280
+ this._bindGroup = device.createBindGroup(program.bindGroupLayouts[0]);
41281
+ }
41282
+ this._bindGroup.setTexture('colorTex', inputColorTexture, fetchSampler('clamp_linear'));
41283
+ this._bindGroup.setTexture('skinTex', ctx.SkinSSSTexture, fetchSampler('clamp_linear'));
41284
+ this._bindGroup.setTexture('depthTex', sceneDepthTexture, fetchSampler('clamp_nearest_nomip'));
41285
+ this._bindGroup.setValue('cameraNearFar', new Vector2(ctx.camera.getNearPlane(), ctx.camera.getFarPlane()));
41286
+ this._bindGroup.setValue('targetSize', new Vector4(inputColorTexture.width, inputColorTexture.height, inputColorTexture.width, inputColorTexture.height));
41287
+ this._bindGroup.setValue('strength', this._strength);
41288
+ this._bindGroup.setValue('opacity', this._opacity);
41289
+ this._bindGroup.setValue('sampleStep', this._sampleStep);
41290
+ this._bindGroup.setValue('depthScale', this._depthScale);
41291
+ this._bindGroup.setValue('colorBoost', this._colorBoost);
41292
+ this._bindGroup.setValue('flip', this.needFlip(device) ? 1 : 0);
41293
+ this._bindGroup.setValue('srgbOut', srgbOutput ? 1 : 0);
41294
+ device.setProgram(program);
41295
+ device.setBindGroup(0, this._bindGroup);
41296
+ this.drawFullscreenQuad();
41297
+ }
41298
+ createProgram(ctx) {
41299
+ const program = ctx.device.buildRenderProgram({
41300
+ vertex (pb) {
41301
+ this.flip = pb.int().uniform(0);
41302
+ this.$inputs.pos = pb.vec2().attrib('position');
41303
+ this.$outputs.uv = pb.vec2();
41304
+ pb.main(function() {
41305
+ this.$builtins.position = pb.vec4(this.$inputs.pos, 1, 1);
41306
+ this.$outputs.uv = pb.add(pb.mul(this.$inputs.pos.xy, 0.5), pb.vec2(0.5));
41307
+ this.$if(pb.notEqual(this.flip, 0), function() {
41308
+ this.$builtins.position.y = pb.neg(this.$builtins.position.y);
41309
+ });
41310
+ });
41311
+ },
41312
+ fragment (pb) {
41313
+ this.colorTex = pb.tex2D().uniform(0);
41314
+ this.skinTex = pb.tex2D().uniform(0);
41315
+ this.depthTex = pb.tex2D().uniform(0);
41316
+ this.cameraNearFar = pb.vec2().uniform(0);
41317
+ this.targetSize = pb.vec4().uniform(0);
41318
+ this.strength = pb.float().uniform(0);
41319
+ this.opacity = pb.float().uniform(0);
41320
+ this.sampleStep = pb.float().uniform(0);
41321
+ this.depthScale = pb.float().uniform(0);
41322
+ this.colorBoost = pb.float().uniform(0);
41323
+ this.srgbOut = pb.int().uniform(0);
41324
+ this.$outputs.outColor = pb.vec4();
41325
+ pb.func('readDepth01', [
41326
+ pb.vec2('uv')
41327
+ ], function() {
41328
+ this.$return(ShaderHelper.sampleLinearDepth(this, this.depthTex, this.uv, 0));
41329
+ });
41330
+ pb.main(function() {
41331
+ this.$l.uv = this.$inputs.uv;
41332
+ this.$l.baseColor = pb.textureSampleLevel(this.colorTex, this.uv, 0);
41333
+ this.$l.result = this.baseColor.rgb;
41334
+ this.$l.centerDepth01 = this.readDepth01(this.uv);
41335
+ this.$if(pb.lessThan(this.centerDepth01, 1), function() {
41336
+ this.$l.centerDepth = pb.max(pb.mul(this.centerDepth01, this.cameraNearFar.y), 1e-4);
41337
+ this.$l.sum = pb.vec4(0);
41338
+ this.$l.weightSum = pb.float(0);
41339
+ this.$for(pb.int('y'), -4, 5, function() {
41340
+ this.$for(pb.int('x'), -4, 5, function() {
41341
+ this.$l.offsetPx = pb.mul(pb.vec2(pb.float(this.x), pb.float(this.y)), this.sampleStep);
41342
+ this.$l.sampleUV = pb.clamp(pb.add(this.uv, pb.div(this.offsetPx, this.targetSize.xy)), pb.vec2(0), pb.vec2(1));
41343
+ this.$l.skinSample = pb.textureSampleLevel(this.skinTex, this.sampleUV, 0);
41344
+ this.$if(pb.lessThanEqual(this.skinSample.a, 1e-4), function() {
41345
+ this.skinSample = pb.vec4(0, 0, 0, this.opacity);
41346
+ });
41347
+ this.$l.sampleDepth01 = this.readDepth01(this.sampleUV);
41348
+ this.$l.sampleDepth = pb.max(pb.mul(this.sampleDepth01, this.cameraNearFar.y), 1e-4);
41349
+ this.$l.depthWeight = pb.clamp(pb.sub(1, pb.div(pb.mul(pb.abs(pb.sub(this.centerDepth, this.sampleDepth)), this.depthScale), this.centerDepth)), 0, 1);
41350
+ this.depthWeight = pb.mul(this.depthWeight, this.depthWeight, pb.sub(3, pb.mul(this.depthWeight, 2)));
41351
+ this.sum = pb.add(this.sum, pb.mul(this.skinSample, this.depthWeight));
41352
+ this.weightSum = pb.add(this.weightSum, this.depthWeight);
41353
+ });
41354
+ });
41355
+ this.$if(pb.greaterThan(this.weightSum, 1e-4), function() {
41356
+ this.$l.blurredSkin = pb.div(this.sum, this.weightSum);
41357
+ this.$l.alphaDelta = pb.sub(this.blurredSkin.a, this.opacity);
41358
+ this.$l.referenceLit = pb.mul(this.baseColor.rgb, pb.add(pb.vec3(pb.sub(1, this.alphaDelta)), pb.mul(this.blurredSkin.rgb, pb.max(pb.sub(1, this.opacity), 0), this.colorBoost)));
41359
+ this.result = pb.add(this.baseColor.rgb, pb.mul(pb.sub(this.referenceLit, this.baseColor.rgb), this.strength));
41360
+ });
41361
+ });
41362
+ this.$if(pb.equal(this.srgbOut, 0), function() {
41363
+ this.$outputs.outColor = pb.vec4(this.result, this.baseColor.a);
41364
+ }).$else(function() {
41365
+ this.$outputs.outColor = pb.vec4(linearToGamma(this, this.result), this.baseColor.a);
41366
+ });
41367
+ });
41368
+ }
41369
+ });
41370
+ program.name = '@SkinSSS';
41371
+ return program;
41372
+ }
41373
+ }
41374
+
40989
41375
  /**
40990
41376
  * The tonemap post effect
40991
41377
  * @public
@@ -43274,6 +43660,13 @@ const SSS_QUALITY_PRESET_SETTINGS = {
43274
43660
  /** @internal SSS multi-scatter energy compensation. */ _sssMultiScatter;
43275
43661
  /** @internal Cached runtime SSS settings after applying the quality preset. */ _sssResolvedSettings;
43276
43662
  /** @internal SSS debug visualization mode. */ _sssDebugView;
43663
+ /** @internal Skin SSS enable flag (via post effect). */ _skinSSS;
43664
+ /** @internal Skin SSS post effect reference. */ _postEffectSkinSSS;
43665
+ /** @internal Skin SSS final blend strength. */ _skinSSSStrength;
43666
+ /** @internal Skin SSS mask opacity bias. */ _skinSSSOpacity;
43667
+ /** @internal Skin SSS blur tap spacing in pixels. */ _skinSSSSampleStep;
43668
+ /** @internal Skin SSS depth rejection scale. */ _skinSSSDepthScale;
43669
+ /** @internal Skin SSS blurred multiplier boost. */ _skinSSSColorBoost;
43277
43670
  /** @internal SSAO enable flag (via post effect). */ _SSAO;
43278
43671
  /** @internal SSAO post effect reference. */ _postEffectSSAO;
43279
43672
  /** @internal SSAO scale (sampling radius multiplier). */ _SSAOScale;
@@ -43390,6 +43783,13 @@ const SSS_QUALITY_PRESET_SETTINGS = {
43390
43783
  };
43391
43784
  this.updateSSSResolvedSettings();
43392
43785
  this._sssDebugView = 'none';
43786
+ this._skinSSS = false;
43787
+ this._postEffectSkinSSS = new DRef();
43788
+ this._skinSSSStrength = 1;
43789
+ this._skinSSSOpacity = 0.18;
43790
+ this._skinSSSSampleStep = 2;
43791
+ this._skinSSSDepthScale = 80;
43792
+ this._skinSSSColorBoost = 1;
43393
43793
  this._SSAO = false;
43394
43794
  this._postEffectSSAO = new DRef();
43395
43795
  this._SSAOScale = 10;
@@ -43842,6 +44242,57 @@ const SSS_QUALITY_PRESET_SETTINGS = {
43842
44242
  set sssDebugView(val) {
43843
44243
  this._sssDebugView = val ?? 'none';
43844
44244
  }
44245
+ /** Gets whether the dedicated Skin SSS post effect is enabled. */ get skinSSS() {
44246
+ return this._postEffectSkinSSS.get().enabled;
44247
+ }
44248
+ set skinSSS(val) {
44249
+ this._postEffectSkinSSS.get().enabled = !!val;
44250
+ }
44251
+ /** Final blend strength for the dedicated Skin SSS post effect. */ get skinSSSStrength() {
44252
+ return this._skinSSSStrength;
44253
+ }
44254
+ set skinSSSStrength(val) {
44255
+ this._skinSSSStrength = Math.max(0, val ?? 0);
44256
+ if (this._postEffectSkinSSS.get()) {
44257
+ this._postEffectSkinSSS.get().strength = this._skinSSSStrength;
44258
+ }
44259
+ }
44260
+ /** Bias subtracted from the blurred skin mask before compositing. */ get skinSSSOpacity() {
44261
+ return this._skinSSSOpacity;
44262
+ }
44263
+ set skinSSSOpacity(val) {
44264
+ this._skinSSSOpacity = Math.max(0, Math.min(1, val ?? 0));
44265
+ if (this._postEffectSkinSSS.get()) {
44266
+ this._postEffectSkinSSS.get().opacity = this._skinSSSOpacity;
44267
+ }
44268
+ }
44269
+ /** Pixel spacing between blur taps. The reference shader uses 2. */ get skinSSSSampleStep() {
44270
+ return this._skinSSSSampleStep;
44271
+ }
44272
+ set skinSSSSampleStep(val) {
44273
+ this._skinSSSSampleStep = Math.max(0.25, val ?? 0.25);
44274
+ if (this._postEffectSkinSSS.get()) {
44275
+ this._postEffectSkinSSS.get().sampleStep = this._skinSSSSampleStep;
44276
+ }
44277
+ }
44278
+ /** Depth rejection scale. The reference shader uses 80. */ get skinSSSDepthScale() {
44279
+ return this._skinSSSDepthScale;
44280
+ }
44281
+ set skinSSSDepthScale(val) {
44282
+ this._skinSSSDepthScale = Math.max(0, val ?? 0);
44283
+ if (this._postEffectSkinSSS.get()) {
44284
+ this._postEffectSkinSSS.get().depthScale = this._skinSSSDepthScale;
44285
+ }
44286
+ }
44287
+ /** Multiplier applied to the blurred skin lighting multiplier before compositing. */ get skinSSSColorBoost() {
44288
+ return this._skinSSSColorBoost;
44289
+ }
44290
+ set skinSSSColorBoost(val) {
44291
+ this._skinSSSColorBoost = Math.max(0, val ?? 0);
44292
+ if (this._postEffectSkinSSS.get()) {
44293
+ this._postEffectSkinSSS.get().colorBoost = this._skinSSSColorBoost;
44294
+ }
44295
+ }
43845
44296
  /** @internal */ get ssrParams() {
43846
44297
  return this._ssrParams;
43847
44298
  }
@@ -44254,6 +44705,11 @@ const SSS_QUALITY_PRESET_SETTINGS = {
44254
44705
  }
44255
44706
  Camera._historyData.delete(this);
44256
44707
  }
44708
+ const historyResourceManager = Camera._historyResourceManager.get(this);
44709
+ if (historyResourceManager) {
44710
+ historyResourceManager.dispose();
44711
+ Camera._historyResourceManager.delete(this);
44712
+ }
44257
44713
  this._prevVPMatrix = null;
44258
44714
  this._prevPosition = null;
44259
44715
  this._prevJitteredVPMatrix = null;
@@ -44273,6 +44729,17 @@ const SSS_QUALITY_PRESET_SETTINGS = {
44273
44729
  this._postEffectSSS.set(sss);
44274
44730
  this._compositor.appendPostEffect(sss);
44275
44731
  }
44732
+ if (!this._postEffectSkinSSS.get()) {
44733
+ const skinSSS = new SkinSSS();
44734
+ skinSSS.enabled = false;
44735
+ skinSSS.strength = this._skinSSSStrength;
44736
+ skinSSS.opacity = this._skinSSSOpacity;
44737
+ skinSSS.sampleStep = this._skinSSSSampleStep;
44738
+ skinSSS.depthScale = this._skinSSSDepthScale;
44739
+ skinSSS.colorBoost = this._skinSSSColorBoost;
44740
+ this._postEffectSkinSSS.set(skinSSS);
44741
+ this._compositor.appendPostEffect(skinSSS);
44742
+ }
44276
44743
  if (!this._postEffectSSAO.get()) {
44277
44744
  const ssao = new SAO();
44278
44745
  ssao.enabled = false;
@@ -44468,6 +44935,10 @@ const SSS_QUALITY_PRESET_SETTINGS = {
44468
44935
  *
44469
44936
  * @internal
44470
44937
  */ setHistoryResourceManager(manager) {
44938
+ const current = Camera._historyResourceManager.get(this);
44939
+ if (current && current !== manager) {
44940
+ current.dispose();
44941
+ }
44471
44942
  Camera._historyResourceManager.set(this, manager);
44472
44943
  }
44473
44944
  /** @internal */ setController(controller) {
@@ -44512,6 +44983,7 @@ const SSS_QUALITY_PRESET_SETTINGS = {
44512
44983
  this._postEffectMotionBlur.dispose();
44513
44984
  this._postEffectSSAO.dispose();
44514
44985
  this._postEffectSSS.dispose();
44986
+ this._postEffectSkinSSS.dispose();
44515
44987
  this._postEffectSSR.dispose();
44516
44988
  this._postEffectTAA.dispose();
44517
44989
  this._postEffectTonemap.dispose();
@@ -44766,7 +45238,7 @@ const _clusters = [];
44766
45238
  const _devicePoolAllocator = new DevicePoolAllocator();
44767
45239
  let _backDepthColorState = null;
44768
45240
  let _frontDepthColorState = null;
44769
- const SURFACE_MRT_FLAGS = MaterialVaryingFlags.SSR_STORE_ROUGHNESS | MaterialVaryingFlags.SSS_STORE_PROFILE | MaterialVaryingFlags.SSS_STORE_DIFFUSE | MaterialVaryingFlags.SSS_STORE_NORMAL | MaterialVaryingFlags.SSS_STORE_TRANSMISSION;
45241
+ const SURFACE_MRT_FLAGS = MaterialVaryingFlags.SSR_STORE_ROUGHNESS | MaterialVaryingFlags.SSS_STORE_PROFILE | MaterialVaryingFlags.SSS_STORE_DIFFUSE | MaterialVaryingFlags.SSS_STORE_NORMAL | MaterialVaryingFlags.SSS_STORE_TRANSMISSION | MaterialVaryingFlags.SKIN_SSS_STORE;
44770
45242
  function getClusteredLight() {
44771
45243
  return _clusters.length > 0 ? _clusters.pop() : new ClusteredLight();
44772
45244
  }
@@ -44779,6 +45251,9 @@ function getCoreMaterial(material) {
44779
45251
  function hasSSSMaterialCore(material) {
44780
45252
  return !!getCoreMaterial(material)?.subsurfaceProfile;
44781
45253
  }
45254
+ function hasSkinSSSMaterialCore(material) {
45255
+ return !!getCoreMaterial(material)?.skinSSS;
45256
+ }
44782
45257
  function renderQueueHasActiveSSS(renderQueue) {
44783
45258
  const itemList = renderQueue.itemList;
44784
45259
  if (!itemList) {
@@ -44797,6 +45272,24 @@ function renderQueueHasActiveSSS(renderQueue) {
44797
45272
  }
44798
45273
  return false;
44799
45274
  }
45275
+ function renderQueueHasActiveSkinSSS(renderQueue) {
45276
+ const itemList = renderQueue.itemList;
45277
+ if (!itemList) {
45278
+ return false;
45279
+ }
45280
+ const lists = [
45281
+ ...itemList.opaque.lit,
45282
+ ...itemList.opaque.unlit
45283
+ ];
45284
+ for (const list of lists){
45285
+ for (const material of list.materialList){
45286
+ if (hasSkinSSSMaterialCore(material)) {
45287
+ return true;
45288
+ }
45289
+ }
45290
+ }
45291
+ return false;
45292
+ }
44800
45293
  function filterActualSSSItemList(items) {
44801
45294
  return items.filter((item)=>hasSSSMaterialCore(item.drawable.getMaterial?.()));
44802
45295
  }
@@ -44918,6 +45411,9 @@ function getLightPassColorAttachments(ctx, colorAttachment) {
44918
45411
  if (ctx.materialFlags & MaterialVaryingFlags.SSS_STORE_TRANSMISSION) {
44919
45412
  attachments.push(ctx.SSSTransmissionTexture);
44920
45413
  }
45414
+ if (ctx.materialFlags & MaterialVaryingFlags.SKIN_SSS_STORE) {
45415
+ attachments.push(ctx.SkinSSSTexture);
45416
+ }
44921
45417
  return attachments.length === 1 ? attachments[0] : attachments;
44922
45418
  }
44923
45419
  /**
@@ -44926,6 +45422,7 @@ function getLightPassColorAttachments(ctx, colorAttachment) {
44926
45422
  */ function deriveForwardPlusOptions(scene, camera, deviceType, renderQueue) {
44927
45423
  const ssr = camera.SSR && scene.env.light.envLight && scene.env.light.envLight.hasRadiance();
44928
45424
  const sss = camera.SSS && renderQueueHasActiveSSS(renderQueue);
45425
+ const skinSSS = camera.skinSSS && renderQueueHasActiveSkinSSS(renderQueue);
44929
45426
  const needSceneColor = renderQueue.needSceneColor();
44930
45427
  const needSceneColorWithDepth = renderQueue.needSceneColorWithDepth();
44931
45428
  return {
@@ -44938,7 +45435,8 @@ function getLightPassColorAttachments(ctx, colorAttachment) {
44938
45435
  needSceneColor,
44939
45436
  needSceneColorWithDepth,
44940
45437
  needsTransmissionDepthForSSR: !!ssr && needSceneColor && !needSceneColorWithDepth,
44941
- sss: !!sss
45438
+ sss: !!sss,
45439
+ skinSSS: !!skinSSS
44942
45440
  };
44943
45441
  }
44944
45442
  // ─── Forward+ Graph Builder ─────────────────────────────────────────
@@ -44962,6 +45460,7 @@ function getLightPassColorAttachments(ctx, colorAttachment) {
44962
45460
  function buildForwardPlusGraphInternal(graph, ctx, renderQueue, options) {
44963
45461
  const backbuffer = graph.importTexture('backbuffer');
44964
45462
  ctx.SSS = !!options.sss;
45463
+ ctx.SkinSSSTexture = null;
44965
45464
  // Shared mutable frame state
44966
45465
  const frame = {
44967
45466
  ctx,
@@ -45081,6 +45580,7 @@ function buildForwardPlusGraphInternal(graph, ctx, renderQueue, options) {
45081
45580
  const depthHandle = depthPassResult.depthHandle;
45082
45581
  const motionVectorHandle = depthPassResult.motionVectorHandle;
45083
45582
  const renderDepthAttachment = depthPassResult.graphDepthAttachmentHandle ?? depthPassResult.externalDepthAttachment ?? null;
45583
+ const useFinalFramebufferAsIntermediate = !!depthPassResult.externalDepthAttachment && depthPassResult.externalDepthAttachment === ctx.finalFramebuffer?.getDepthAttachment();
45084
45584
  let preLightTransmissionDepthToken;
45085
45585
  if (options.needsTransmissionDepthForSSR) {
45086
45586
  preLightTransmissionDepthToken = graph.addPass('TransmissionDepthForSSR', (builder)=>{
@@ -45267,7 +45767,8 @@ function buildForwardPlusGraphInternal(graph, ctx, renderQueue, options) {
45267
45767
  if (writeSSSDiffuse && writeSSSTransmission && includeSSRSurfaceMRT && getSSSLightingTextureFormat(ctx, 2, includeSSRSurfaceMRT) !== ctx.colorFormat) {
45268
45768
  writeSSSTransmission = false;
45269
45769
  }
45270
- const sssLightingAttachmentCount = (writeSSSDiffuse ? 1 : 0) + (writeSSSTransmission ? 1 : 0);
45770
+ const writeSkinSSS = options.skinSSS;
45771
+ const sssLightingAttachmentCount = (writeSSSDiffuse ? 1 : 0) + (writeSSSTransmission ? 1 : 0) + (writeSkinSSS ? 1 : 0);
45271
45772
  const sssLightingFormat = getSSSLightingTextureFormat(ctx, sssLightingAttachmentCount, includeSSRSurfaceMRT);
45272
45773
  const sssDiffuseHandle = writeSSSDiffuse ? builder.createTexture({
45273
45774
  format: sssLightingFormat,
@@ -45277,7 +45778,10 @@ function buildForwardPlusGraphInternal(graph, ctx, renderQueue, options) {
45277
45778
  format: sssLightingFormat,
45278
45779
  label: 'sssTransmission'
45279
45780
  }) : undefined;
45280
- const useFinalFramebufferAsIntermediate = !!depthPassResult.externalDepthAttachment && depthPassResult.externalDepthAttachment === ctx.finalFramebuffer?.getDepthAttachment();
45781
+ const skinSSSHandle = writeSkinSSS ? builder.createTexture({
45782
+ format: sssLightingFormat,
45783
+ label: 'skinSSS'
45784
+ }) : undefined;
45281
45785
  const sceneColorFramebufferHandle = useFinalFramebufferAsIntermediate ? undefined : builder.createFramebuffer({
45282
45786
  label: 'SceneColorFramebuffer',
45283
45787
  width: ctx.renderWidth,
@@ -45308,6 +45812,7 @@ function buildForwardPlusGraphInternal(graph, ctx, renderQueue, options) {
45308
45812
  }
45309
45813
  ctx.SSSDiffuseTexture = sssDiffuseHandle ? rgCtx.getTexture(sssDiffuseHandle) : null;
45310
45814
  ctx.SSSTransmissionTexture = sssTransmissionHandle ? rgCtx.getTexture(sssTransmissionHandle) : null;
45815
+ ctx.SkinSSSTexture = skinSSSHandle ? rgCtx.getTexture(skinSSSHandle) : null;
45311
45816
  const renderLightPass = ()=>renderMainLightPass(frame, sceneColorTex, sceneColorCopyTex, rgCtx, sceneColorFramebufferHandle, sceneColorCopyFramebufferHandle);
45312
45817
  if (historyManager && lightHistoryReadBindings.length > 0) {
45313
45818
  historyManager.beginReadScope(lightHistoryReadBindings.map((binding)=>({
@@ -45364,19 +45869,24 @@ function buildForwardPlusGraphInternal(graph, ctx, renderQueue, options) {
45364
45869
  builder.read(binding.handle);
45365
45870
  }
45366
45871
  const outputBackbuffer = builder.write(backbuffer);
45872
+ const taaHistoryColorHandle = useFinalFramebufferAsIntermediate ? outputBackbuffer : sceneColorHandle;
45367
45873
  builder.setExecute((rgCtx)=>{
45874
+ const renderAndCommitComposite = ()=>{
45875
+ renderComposite(frame);
45876
+ queueTAAHistoryCommit(frame, rgCtx, historyManager, taaHistoryColorHandle, motionVectorHandle);
45877
+ };
45368
45878
  if (historyManager && compositeHistoryReadBindings.length > 0) {
45369
45879
  historyManager.beginReadScope(compositeHistoryReadBindings.map((binding)=>({
45370
45880
  name: binding.name,
45371
45881
  texture: rgCtx.getTexture(binding.handle)
45372
45882
  })));
45373
45883
  try {
45374
- renderComposite(frame);
45884
+ renderAndCommitComposite();
45375
45885
  } finally{
45376
45886
  historyManager.endReadScope();
45377
45887
  }
45378
45888
  } else {
45379
- renderComposite(frame);
45889
+ renderAndCommitComposite();
45380
45890
  }
45381
45891
  });
45382
45892
  return outputBackbuffer;
@@ -45435,7 +45945,7 @@ function renderForwardSSSProfile(frame, profileFramebuffer, profileTexture, para
45435
45945
  ctx.SSRNormalTexture = normalTexture;
45436
45946
  ctx.compositor = null;
45437
45947
  ctx.camera.commandBufferReuse = false;
45438
- ctx.materialFlags = ctx.materialFlags & ~(MaterialVaryingFlags.SSR_STORE_ROUGHNESS | MaterialVaryingFlags.SSS_STORE_PROFILE | MaterialVaryingFlags.SSS_STORE_NORMAL | MaterialVaryingFlags.SSS_STORE_DIFFUSE | MaterialVaryingFlags.SSS_STORE_TRANSMISSION) | profileFlags;
45948
+ ctx.materialFlags = ctx.materialFlags & ~(MaterialVaryingFlags.SSR_STORE_ROUGHNESS | MaterialVaryingFlags.SSS_STORE_PROFILE | MaterialVaryingFlags.SSS_STORE_NORMAL | MaterialVaryingFlags.SSS_STORE_DIFFUSE | MaterialVaryingFlags.SSS_STORE_TRANSMISSION | MaterialVaryingFlags.SKIN_SSS_STORE) | profileFlags;
45439
45949
  _scenePass.transmission = false;
45440
45950
  _scenePass.renderOpaque = true;
45441
45951
  _scenePass.renderTransparent = false;
@@ -45665,7 +46175,7 @@ function blitToCurrentColorAttachment(ctx, source) {
45665
46175
  const device = ctx.device;
45666
46176
  // Use RenderGraph-allocated scene color texture
45667
46177
  const depthTex = frame.depthFramebuffer?.getDepthAttachment();
45668
- ctx.materialFlags &= ~(MaterialVaryingFlags.SSR_STORE_ROUGHNESS | MaterialVaryingFlags.SSS_STORE_PROFILE | MaterialVaryingFlags.SSS_STORE_DIFFUSE | MaterialVaryingFlags.SSS_STORE_NORMAL | MaterialVaryingFlags.SSS_STORE_TRANSMISSION);
46178
+ ctx.materialFlags &= ~(MaterialVaryingFlags.SSR_STORE_ROUGHNESS | MaterialVaryingFlags.SSS_STORE_PROFILE | MaterialVaryingFlags.SSS_STORE_DIFFUSE | MaterialVaryingFlags.SSS_STORE_NORMAL | MaterialVaryingFlags.SSS_STORE_TRANSMISSION | MaterialVaryingFlags.SKIN_SSS_STORE);
45669
46179
  if (ctx.SSR) {
45670
46180
  ctx.materialFlags |= MaterialVaryingFlags.SSR_STORE_ROUGHNESS;
45671
46181
  }
@@ -45677,6 +46187,9 @@ function blitToCurrentColorAttachment(ctx, source) {
45677
46187
  ctx.materialFlags |= MaterialVaryingFlags.SSS_STORE_TRANSMISSION;
45678
46188
  }
45679
46189
  }
46190
+ if (ctx.SkinSSSTexture) {
46191
+ ctx.materialFlags |= MaterialVaryingFlags.SKIN_SSS_STORE;
46192
+ }
45680
46193
  if (depthTex === ctx.finalFramebuffer?.getDepthAttachment()) {
45681
46194
  ctx.intermediateFramebuffer = ctx.finalFramebuffer;
45682
46195
  } else if (sceneColorFramebufferHandle && !hasSurfaceMRT(ctx)) {
@@ -45755,6 +46268,34 @@ function blitToCurrentColorAttachment(ctx, source) {
45755
46268
  /** @internal */ function renderTransmissionDepthPass(frame, rgCtx) {
45756
46269
  renderSceneDepth(frame, frame.depthFramebuffer, rgCtx);
45757
46270
  }
46271
+ function queueTAAHistoryCommit(frame, rgCtx, historyManager, colorHandle, motionVectorHandle) {
46272
+ const { ctx } = frame;
46273
+ if (!historyManager?.frameActive || !ctx.camera.TAA || !frame.options.motionVectors || !motionVectorHandle) {
46274
+ return;
46275
+ }
46276
+ const colorTexture = rgCtx.getTexture(colorHandle);
46277
+ const colorSize = {
46278
+ width: colorTexture.width,
46279
+ height: colorTexture.height
46280
+ };
46281
+ historyManager.queueRetainedCommit(RGHistoryResources.TAA_COLOR, {
46282
+ format: colorTexture.format,
46283
+ sizeMode: 'absolute',
46284
+ width: colorTexture.width,
46285
+ height: colorTexture.height
46286
+ }, colorSize, colorTexture);
46287
+ const motionVectorTexture = rgCtx.getTexture(motionVectorHandle);
46288
+ const motionVectorSize = {
46289
+ width: motionVectorTexture.width,
46290
+ height: motionVectorTexture.height
46291
+ };
46292
+ historyManager.queueRetainedCommit(RGHistoryResources.TAA_MOTION_VECTOR, {
46293
+ format: motionVectorTexture.format,
46294
+ sizeMode: 'absolute',
46295
+ width: motionVectorTexture.width,
46296
+ height: motionVectorTexture.height
46297
+ }, motionVectorSize, motionVectorTexture);
46298
+ }
45758
46299
  /** @internal */ function renderComposite(frame) {
45759
46300
  const { ctx } = frame;
45760
46301
  ctx.compositor?.drawPostEffects(ctx, PostEffectLayer.end, ctx.linearDepthTexture);
@@ -45765,6 +46306,7 @@ function blitToCurrentColorAttachment(ctx, source) {
45765
46306
  ctx.materialFlags &= ~MaterialVaryingFlags.SSS_STORE_DIFFUSE;
45766
46307
  ctx.materialFlags &= ~MaterialVaryingFlags.SSS_STORE_NORMAL;
45767
46308
  ctx.materialFlags &= ~MaterialVaryingFlags.SSS_STORE_TRANSMISSION;
46309
+ ctx.materialFlags &= ~MaterialVaryingFlags.SKIN_SSS_STORE;
45768
46310
  if (ctx.intermediateFramebuffer && ctx.intermediateFramebuffer !== ctx.finalFramebuffer) {
45769
46311
  const blitter = new CopyBlitter();
45770
46312
  blitter.srgbOut = !ctx.finalFramebuffer;
@@ -48721,6 +49263,7 @@ class GlobalBindGroupAllocator {
48721
49263
  SSSParamTexture: null,
48722
49264
  SSSDiffuseTexture: null,
48723
49265
  SSSTransmissionTexture: null,
49266
+ SkinSSSTexture: null,
48724
49267
  ssrSDFBoxBuffer: null,
48725
49268
  ssrSDFBoxCount: 0,
48726
49269
  finalFramebuffer: device.getFramebuffer(),
@@ -49279,6 +49822,321 @@ class GlobalBindGroupAllocator {
49279
49822
  }
49280
49823
  }
49281
49824
 
49825
+ /*
49826
+ const PCF_KERNEL_3x3 = [
49827
+ [0.5, 1.0, 0.5],
49828
+ [1.0, 1.0, 1.0],
49829
+ [0.5, 1.0, 0.5]
49830
+ ];
49831
+ const PCF_KERNEL_SUM_3x3 = 7;
49832
+
49833
+ const PCF_KERNEL_5x5 = [
49834
+ [0.0, 0.5, 1.0, 0.5, 0.0],
49835
+ [0.5, 1.0, 1.0, 1.0, 0.5],
49836
+ [1.0, 1.0, 1.0, 1.0, 1.0],
49837
+ [0.5, 1.0, 1.0, 1.0, 0.5],
49838
+ [0.0, 0.5, 1.0, 0.5, 0.0]
49839
+ ];
49840
+ const PCF_KERNEL_SUM_5x5 = 17;
49841
+
49842
+ const PCF_KERNEL_7x7 = [
49843
+ [0.0, 0.0, 0.5, 1.0, 0.5, 0.0, 0.0],
49844
+ [0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0],
49845
+ [0.5, 1.0, 1.0, 1.0, 1.0, 1.0, 0.5],
49846
+ [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0],
49847
+ [0.5, 1.0, 1.0, 1.0, 1.0, 1.0, 0.5],
49848
+ [0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0],
49849
+ [0.0, 0.0, 0.5, 1.0, 0.5, 0.0, 0.0]
49850
+ ];
49851
+ const PCF_KERNEL_SUM_7x7 = 33;
49852
+
49853
+ const PCF_KERNEL_9x9 = [
49854
+ [0.0, 0.0, 0.0, 0.5, 1.0, 0.5, 0.0, 0.0, 0.0],
49855
+ [0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0],
49856
+ [0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0],
49857
+ [0.5, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.5],
49858
+ [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0],
49859
+ [0.5, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.5],
49860
+ [0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0],
49861
+ [0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0],
49862
+ [0.0, 0.0, 0.0, 0.5, 1.0, 0.5, 0.0, 0.0, 0.0]
49863
+ ];
49864
+ const PCF_KERNEL_SUM_9x9 = 53;
49865
+ */ const PCF_POISSON_DISC = [
49866
+ [
49867
+ 0.511749,
49868
+ 0.547686
49869
+ ],
49870
+ [
49871
+ 0.58929,
49872
+ 0.257224
49873
+ ],
49874
+ [
49875
+ 0.165018,
49876
+ 0.57663
49877
+ ],
49878
+ [
49879
+ 0.407692,
49880
+ 0.742285
49881
+ ],
49882
+ [
49883
+ 0.707012,
49884
+ 0.646523
49885
+ ],
49886
+ [
49887
+ 0.31463,
49888
+ 0.466825
49889
+ ],
49890
+ [
49891
+ 0.801257,
49892
+ 0.485186
49893
+ ],
49894
+ [
49895
+ 0.418136,
49896
+ 0.146517
49897
+ ],
49898
+ [
49899
+ 0.579889,
49900
+ 0.0368284
49901
+ ],
49902
+ [
49903
+ 0.79801,
49904
+ 0.140114
49905
+ ],
49906
+ [
49907
+ -0.0413185,
49908
+ 0.371455
49909
+ ],
49910
+ [
49911
+ -0.0529108,
49912
+ 0.627352
49913
+ ],
49914
+ [
49915
+ 0.0821375,
49916
+ 0.882071
49917
+ ],
49918
+ [
49919
+ 0.17308,
49920
+ 0.301207
49921
+ ],
49922
+ [
49923
+ -0.120452,
49924
+ 0.867216
49925
+ ],
49926
+ [
49927
+ 0.371096,
49928
+ 0.916454
49929
+ ],
49930
+ [
49931
+ -0.178381,
49932
+ 0.146101
49933
+ ],
49934
+ [
49935
+ -0.276489,
49936
+ 0.550525
49937
+ ],
49938
+ [
49939
+ 0.12542,
49940
+ 0.126643
49941
+ ],
49942
+ [
49943
+ -0.296654,
49944
+ 0.286879
49945
+ ],
49946
+ [
49947
+ 0.261744,
49948
+ -604975e-8
49949
+ ],
49950
+ [
49951
+ -0.213417,
49952
+ 0.715776
49953
+ ],
49954
+ [
49955
+ 0.425684,
49956
+ -0.153211
49957
+ ],
49958
+ [
49959
+ -0.480054,
49960
+ 0.321357
49961
+ ],
49962
+ [
49963
+ -0.0717878,
49964
+ -0.0250567
49965
+ ],
49966
+ [
49967
+ -0.328775,
49968
+ -0.169666
49969
+ ],
49970
+ [
49971
+ -0.394923,
49972
+ 0.130802
49973
+ ],
49974
+ [
49975
+ -0.553681,
49976
+ -0.176777
49977
+ ],
49978
+ [
49979
+ -0.722615,
49980
+ 0.120616
49981
+ ],
49982
+ [
49983
+ -0.693065,
49984
+ 0.309017
49985
+ ],
49986
+ [
49987
+ 0.603193,
49988
+ 0.791471
49989
+ ],
49990
+ [
49991
+ -0.0754941,
49992
+ -0.297988
49993
+ ],
49994
+ [
49995
+ 0.109303,
49996
+ -0.156472
49997
+ ],
49998
+ [
49999
+ 0.260605,
50000
+ -0.280111
50001
+ ],
50002
+ [
50003
+ 0.129731,
50004
+ -0.487954
50005
+ ],
50006
+ [
50007
+ -0.537315,
50008
+ 0.520494
50009
+ ],
50010
+ [
50011
+ -0.42758,
50012
+ 0.800607
50013
+ ],
50014
+ [
50015
+ 0.77309,
50016
+ -0.0728102
50017
+ ],
50018
+ [
50019
+ 0.908777,
50020
+ 0.328356
50021
+ ],
50022
+ [
50023
+ 0.985341,
50024
+ 0.0759158
50025
+ ],
50026
+ [
50027
+ 0.947536,
50028
+ -0.11837
50029
+ ],
50030
+ [
50031
+ -0.103315,
50032
+ -0.610747
50033
+ ],
50034
+ [
50035
+ 0.337171,
50036
+ -0.584
50037
+ ],
50038
+ [
50039
+ 0.210919,
50040
+ -0.720055
50041
+ ],
50042
+ [
50043
+ 0.41894,
50044
+ -0.36769
50045
+ ],
50046
+ [
50047
+ -0.254228,
50048
+ -0.49368
50049
+ ],
50050
+ [
50051
+ -0.428562,
50052
+ -0.404037
50053
+ ],
50054
+ [
50055
+ -0.831732,
50056
+ -0.189615
50057
+ ],
50058
+ [
50059
+ -0.922642,
50060
+ 0.0888026
50061
+ ],
50062
+ [
50063
+ -0.865914,
50064
+ 0.427795
50065
+ ],
50066
+ [
50067
+ 0.706117,
50068
+ -0.311662
50069
+ ],
50070
+ [
50071
+ 0.545465,
50072
+ -0.520942
50073
+ ],
50074
+ [
50075
+ -0.695738,
50076
+ 0.664492
50077
+ ],
50078
+ [
50079
+ 0.389421,
50080
+ -0.899007
50081
+ ],
50082
+ [
50083
+ 0.48842,
50084
+ -0.708054
50085
+ ],
50086
+ [
50087
+ 0.760298,
50088
+ -0.62735
50089
+ ],
50090
+ [
50091
+ -0.390788,
50092
+ -0.707388
50093
+ ],
50094
+ [
50095
+ -0.591046,
50096
+ -0.686721
50097
+ ],
50098
+ [
50099
+ -0.769903,
50100
+ -0.413775
50101
+ ],
50102
+ [
50103
+ -0.604457,
50104
+ -0.502571
50105
+ ],
50106
+ [
50107
+ -0.557234,
50108
+ 0.00451362
50109
+ ],
50110
+ [
50111
+ 0.147572,
50112
+ -0.924353
50113
+ ],
50114
+ [
50115
+ -0.0662488,
50116
+ -0.892081
50117
+ ],
50118
+ [
50119
+ 0.863832,
50120
+ -0.4072
50121
+ ]
50122
+ ];
50123
+ function getPCSSRotationMatrix(scope, sampleCoord, temporalJitter) {
50124
+ const funcName = `lib_getPCSSRotationMatrix_${temporalJitter ? 1 : 0}`;
50125
+ const pb = scope.$builder;
50126
+ pb.func(funcName, [
50127
+ pb.vec2('sampleCoord')
50128
+ ], function() {
50129
+ if (temporalJitter) {
50130
+ this.$l.frame = pb.mod(pb.float(ShaderHelper.getFramestamp(this)), 64);
50131
+ this.$l.randomAngle = pb.mul(smoothNoise3D(this, pb.vec3(pb.mul(this.sampleCoord, 0.35), pb.mul(this.frame, 0.61803398875))), 2 * Math.PI);
50132
+ this.$l.randomBase = pb.vec2(pb.cos(this.randomAngle), pb.sin(this.randomAngle));
50133
+ this.$return(pb.mat2(this.randomBase.x, this.randomBase.y, pb.neg(this.randomBase.y), this.randomBase.x));
50134
+ } else {
50135
+ this.$return(pb.mat2(0.8660254, 0.5, -0.5, 0.8660254));
50136
+ }
50137
+ });
50138
+ return pb.getGlobalScope()[funcName](sampleCoord);
50139
+ }
49282
50140
  function getShadowMapTexelSize(scope) {
49283
50141
  return scope.$builder.div(1, ShaderHelper.getShadowCameraParams(scope).z);
49284
50142
  }
@@ -49359,6 +50217,216 @@ function sampleShadowMapPCF(scope, shadowMapFormat, pos, offset, depth, cascade)
49359
50217
  cascade
49360
50218
  ] : []);
49361
50219
  }
50220
+ function sampleShadowDepthPCSS(scope, shadowMapFormat, pos, bounds, cascade) {
50221
+ const funcName = `lib_sampleShadowDepthPCSS_${shadowMapFormat}_${cascade ? 1 : 0}`;
50222
+ const pb = scope.$builder;
50223
+ pb.func(funcName, [
50224
+ pb.vec2('coords'),
50225
+ pb.vec4('bounds'),
50226
+ ...cascade ? [
50227
+ pb.int('cascade')
50228
+ ] : []
50229
+ ], function() {
50230
+ this.$l.depth = pb.float(1);
50231
+ this.$l.sampleInside = pb.all(pb.bvec4(pb.greaterThanEqual(this.coords.x, this.bounds.x), pb.lessThanEqual(this.coords.x, this.bounds.z), pb.greaterThanEqual(this.coords.y, this.bounds.y), pb.lessThanEqual(this.coords.y, this.bounds.w)));
50232
+ this.$if(this.sampleInside, function() {
50233
+ this.$l.boundsPadding = pb.mul(pb.sub(this.bounds.zw, this.bounds.xy), getShadowMapTexelSize(this), 0.5);
50234
+ this.$l.sampleCoord = pb.clamp(this.coords, pb.add(this.bounds.xy, this.boundsPadding), pb.sub(this.bounds.zw, this.boundsPadding));
50235
+ this.$l.shadowTex = cascade && getDevice().type !== 'webgl' ? pb.textureArraySampleLevel(ShaderHelper.getShadowMap(this), this.sampleCoord, this.cascade, 0) : pb.textureSampleLevel(ShaderHelper.getShadowMap(this), this.sampleCoord, 0);
50236
+ this.depth = shadowMapFormat === 'rgba8unorm' ? decodeNormalizedFloatFromRGBA(this, this.shadowTex) : this.shadowTex.x;
50237
+ });
50238
+ this.$return(this.depth);
50239
+ });
50240
+ return pb.getGlobalScope()[funcName](pos, bounds, ...cascade ? [
50241
+ cascade
50242
+ ] : []);
50243
+ }
50244
+ function samplePointShadowDepthPCSS(scope, shadowMapFormat, dir) {
50245
+ const funcName = `lib_samplePointShadowDepthPCSS_${shadowMapFormat}`;
50246
+ const pb = scope.$builder;
50247
+ pb.func(funcName, [
50248
+ pb.vec3('dir')
50249
+ ], function() {
50250
+ this.$l.shadowTex = pb.textureSampleLevel(ShaderHelper.getShadowMap(this), this.dir, 0);
50251
+ this.$return(shadowMapFormat === 'rgba8unorm' ? decodeNormalizedFloatFromRGBA(this, this.shadowTex) : this.shadowTex.x);
50252
+ });
50253
+ return pb.getGlobalScope()[funcName](dir);
50254
+ }
50255
+ function compareShadowDepthPCSS(scope, sampleDepth, compareDepth, transitionWidth) {
50256
+ const funcName = 'lib_compareShadowDepthPCSS';
50257
+ const pb = scope.$builder;
50258
+ pb.func(funcName, [
50259
+ pb.float('sampleDepth'),
50260
+ pb.float('compareDepth'),
50261
+ pb.float('transitionWidth')
50262
+ ], function() {
50263
+ this.$l.depthDelta = pb.sub(this.sampleDepth, this.compareDepth);
50264
+ this.$return(pb.smoothStep(pb.neg(this.transitionWidth), this.transitionWidth, this.depthDelta));
50265
+ });
50266
+ return pb.getGlobalScope()[funcName](sampleDepth, compareDepth, transitionWidth);
50267
+ }
50268
+ function sampleShadowPCFPCSS(scope, shadowMapFormat, pos, bounds, compareDepth, texelSize, receiverPlaneDepthBias, cascade) {
50269
+ const funcName = `lib_sampleShadowPCFPCSS_${shadowMapFormat}_${receiverPlaneDepthBias ? 1 : 0}_${cascade ? 1 : 0}`;
50270
+ const pb = scope.$builder;
50271
+ pb.func(funcName, [
50272
+ pb.vec2('coords'),
50273
+ pb.vec4('bounds'),
50274
+ pb.float('compareDepth'),
50275
+ pb.vec2('texelSize'),
50276
+ ...receiverPlaneDepthBias ? [
50277
+ pb.vec3('receiverPlaneDepthBias')
50278
+ ] : [],
50279
+ ...cascade ? [
50280
+ pb.int('cascade')
50281
+ ] : []
50282
+ ], function() {
50283
+ this.$l.shadow = pb.float(0);
50284
+ this.$l.transitionWidth = receiverPlaneDepthBias ? pb.max(pb.dot(pb.abs(this.receiverPlaneDepthBias.xy), this.texelSize), 1 / 65535) : pb.float(1 / 65535);
50285
+ this.$l.offset = pb.vec2();
50286
+ this.$l.tapCoord = pb.vec2();
50287
+ this.$l.sampleDepth = pb.float();
50288
+ this.$l.tapCompareDepth = pb.float();
50289
+ const offsets = [
50290
+ [
50291
+ -0.35,
50292
+ -0.35
50293
+ ],
50294
+ [
50295
+ 0.35,
50296
+ -0.35
50297
+ ],
50298
+ [
50299
+ -0.35,
50300
+ 0.35
50301
+ ],
50302
+ [
50303
+ 0.35,
50304
+ 0.35
50305
+ ]
50306
+ ];
50307
+ for (const [ox, oy] of offsets){
50308
+ this.offset = pb.mul(pb.vec2(ox, oy), this.texelSize);
50309
+ this.tapCoord = pb.add(this.coords, this.offset);
50310
+ this.sampleDepth = sampleShadowDepthPCSS(this, shadowMapFormat, this.tapCoord, this.bounds, this.cascade);
50311
+ this.tapCompareDepth = receiverPlaneDepthBias ? pb.add(this.compareDepth, pb.dot(this.offset, this.receiverPlaneDepthBias.xy)) : this.compareDepth;
50312
+ this.shadow = pb.add(this.shadow, compareShadowDepthPCSS(this, this.sampleDepth, this.tapCompareDepth, this.transitionWidth));
50313
+ }
50314
+ this.$return(pb.mul(this.shadow, 0.25));
50315
+ });
50316
+ return pb.getGlobalScope()[funcName](pos, bounds, compareDepth, texelSize, ...receiverPlaneDepthBias ? [
50317
+ receiverPlaneDepthBias
50318
+ ] : [], ...cascade ? [
50319
+ cascade
50320
+ ] : []);
50321
+ }
50322
+ function samplePointShadowPCFPCSS(scope, shadowMapFormat, dir, compareDepth, texelSize, tangent, bitangent) {
50323
+ const funcName = `lib_samplePointShadowPCFPCSS_${shadowMapFormat}`;
50324
+ const pb = scope.$builder;
50325
+ pb.func(funcName, [
50326
+ pb.vec3('dir'),
50327
+ pb.float('compareDepth'),
50328
+ pb.float('texelSize'),
50329
+ pb.vec3('tangent'),
50330
+ pb.vec3('bitangent')
50331
+ ], function() {
50332
+ this.$l.shadow = pb.float(0);
50333
+ this.$l.transitionWidth = pb.float(1 / 65535);
50334
+ this.$l.offset = pb.vec2();
50335
+ this.$l.sampleDir = pb.vec3();
50336
+ this.$l.sampleDepth = pb.float();
50337
+ const offsets = [
50338
+ [
50339
+ -0.35,
50340
+ -0.35
50341
+ ],
50342
+ [
50343
+ 0.35,
50344
+ -0.35
50345
+ ],
50346
+ [
50347
+ -0.35,
50348
+ 0.35
50349
+ ],
50350
+ [
50351
+ 0.35,
50352
+ 0.35
50353
+ ]
50354
+ ];
50355
+ for (const [ox, oy] of offsets){
50356
+ this.offset = pb.mul(pb.vec2(ox, oy), this.texelSize);
50357
+ this.sampleDir = pb.normalize(pb.add(this.dir, pb.add(pb.mul(this.tangent, this.offset.x), pb.mul(this.bitangent, this.offset.y))));
50358
+ this.sampleDepth = samplePointShadowDepthPCSS(this, shadowMapFormat, this.sampleDir);
50359
+ this.shadow = pb.add(this.shadow, compareShadowDepthPCSS(this, this.sampleDepth, this.compareDepth, this.transitionWidth));
50360
+ }
50361
+ this.$return(pb.mul(this.shadow, 0.25));
50362
+ });
50363
+ return pb.getGlobalScope()[funcName](dir, compareDepth, texelSize, tangent, bitangent);
50364
+ }
50365
+ function findBlockerPCSS(scope, shadowMapFormat, tapCount, texCoord, bounds, searchRadius, transitionWidth, matrix, cascade) {
50366
+ const funcName = `lib_findBlockerPCSS_${shadowMapFormat}_${cascade ? 1 : 0}`;
50367
+ const pb = scope.$builder;
50368
+ pb.func(funcName, [
50369
+ pb.vec4('texCoord'),
50370
+ pb.vec4('bounds'),
50371
+ pb.vec2('searchRadius'),
50372
+ pb.float('tapCount'),
50373
+ pb.float('transitionWidth'),
50374
+ pb.mat2('matrix'),
50375
+ ...cascade ? [
50376
+ pb.int('cascade')
50377
+ ] : []
50378
+ ], function() {
50379
+ this.$l.blockerDepthSum = pb.float(0);
50380
+ this.$l.blockerCount = pb.float(0);
50381
+ this.$l.duv = pb.vec2();
50382
+ this.$l.sampleCoord = pb.vec2();
50383
+ this.$l.sampleDepth = pb.float();
50384
+ this.$l.blockerWeight = pb.float();
50385
+ this.$for(pb.float('i'), 0, this.tapCount, function() {
50386
+ this.duv = pb.mul(pb.mul(this.matrix, this.PCSSpdSamples.at(pb.mod(pb.mul(pb.int(this.i), 19), PCF_POISSON_DISC.length))), this.searchRadius);
50387
+ this.sampleCoord = pb.add(this.texCoord.xy, this.duv);
50388
+ this.sampleDepth = sampleShadowDepthPCSS(this, shadowMapFormat, this.sampleCoord, this.bounds, this.cascade);
50389
+ this.blockerWeight = pb.sub(1, pb.smoothStep(pb.neg(this.transitionWidth), this.transitionWidth, pb.sub(this.sampleDepth, this.texCoord.z)));
50390
+ this.blockerDepthSum = pb.add(this.blockerDepthSum, pb.mul(this.sampleDepth, this.blockerWeight));
50391
+ this.blockerCount = pb.add(this.blockerCount, this.blockerWeight);
50392
+ });
50393
+ this.$return(pb.vec2(this.$choice(pb.greaterThan(this.blockerCount, 0), pb.div(this.blockerDepthSum, pb.max(this.blockerCount, 0.0001)), -1), this.blockerCount));
50394
+ });
50395
+ return pb.getGlobalScope()[funcName](texCoord, bounds, searchRadius, tapCount, transitionWidth, matrix, ...cascade ? [
50396
+ cascade
50397
+ ] : []);
50398
+ }
50399
+ function findPointBlockerPCSS(scope, shadowMapFormat, tapCount, dir, compareDepth, searchRadius, transitionWidth, matrix, tangent, bitangent) {
50400
+ const funcName = `lib_findPointBlockerPCSS_${shadowMapFormat}`;
50401
+ const pb = scope.$builder;
50402
+ pb.func(funcName, [
50403
+ pb.vec3('dir'),
50404
+ pb.float('compareDepth'),
50405
+ pb.float('searchRadius'),
50406
+ pb.float('tapCount'),
50407
+ pb.float('transitionWidth'),
50408
+ pb.mat2('matrix'),
50409
+ pb.vec3('tangent'),
50410
+ pb.vec3('bitangent')
50411
+ ], function() {
50412
+ this.$l.blockerDepthSum = pb.float(0);
50413
+ this.$l.blockerCount = pb.float(0);
50414
+ this.$l.duv = pb.vec2();
50415
+ this.$l.sampleDir = pb.vec3();
50416
+ this.$l.sampleDepth = pb.float();
50417
+ this.$l.blockerWeight = pb.float();
50418
+ this.$for(pb.float('i'), 0, this.tapCount, function() {
50419
+ this.duv = pb.mul(pb.mul(this.matrix, this.PCSSpdSamples.at(pb.mod(pb.mul(pb.int(this.i), 19), PCF_POISSON_DISC.length))), this.searchRadius);
50420
+ this.sampleDir = pb.normalize(pb.add(this.dir, pb.add(pb.mul(this.tangent, this.duv.x), pb.mul(this.bitangent, this.duv.y))));
50421
+ this.sampleDepth = samplePointShadowDepthPCSS(this, shadowMapFormat, this.sampleDir);
50422
+ this.blockerWeight = pb.sub(1, pb.smoothStep(pb.neg(this.transitionWidth), this.transitionWidth, pb.sub(this.sampleDepth, this.compareDepth)));
50423
+ this.blockerDepthSum = pb.add(this.blockerDepthSum, pb.mul(this.sampleDepth, this.blockerWeight));
50424
+ this.blockerCount = pb.add(this.blockerCount, this.blockerWeight);
50425
+ });
50426
+ this.$return(pb.vec2(this.$choice(pb.greaterThan(this.blockerCount, 0), pb.div(this.blockerDepthSum, pb.max(this.blockerCount, 0.0001)), -1), this.blockerCount));
50427
+ });
50428
+ return pb.getGlobalScope()[funcName](dir, compareDepth, searchRadius, tapCount, transitionWidth, matrix, tangent, bitangent);
50429
+ }
49362
50430
  function chebyshevUpperBound(scope, distance, occluder) {
49363
50431
  const funcNameChebyshevUpperBound = 'lib_chebyshevUpperBound';
49364
50432
  const pb = scope.$builder;
@@ -49539,6 +50607,96 @@ function chebyshevUpperBound(scope, distance, occluder) {
49539
50607
  cascade
49540
50608
  ] : []);
49541
50609
  }
50610
+ /** @internal */ function filterShadowPCSS(scope, lightType, shadowMapFormat, texCoord, receiverPlaneDepthBias, cascade, temporalJitter = true, numCascades = 1) {
50611
+ const funcNameFilterShadowPCSS = `lib_filterShadowPCSS_${lightType}_${shadowMapFormat}_${receiverPlaneDepthBias ? 1 : 0}_${cascade ? 1 : 0}_${temporalJitter ? 1 : 0}_${numCascades}`;
50612
+ const pb = scope.$builder;
50613
+ pb.func(funcNameFilterShadowPCSS, [
50614
+ pb.vec4('texCoord'),
50615
+ ...receiverPlaneDepthBias ? [
50616
+ pb.vec3('receiverPlaneDepthBias')
50617
+ ] : [],
50618
+ ...cascade ? [
50619
+ pb.int('cascade')
50620
+ ] : []
50621
+ ], function() {
50622
+ this.$l.PCSSblockerSampleCount = ShaderHelper.getShadowImplParams(this).y;
50623
+ this.$l.PCSSfilterSampleCount = ShaderHelper.getShadowImplParams(this).z;
50624
+ this.$l.PCSSlightRadius = ShaderHelper.getShadowImplParams(this).x;
50625
+ this.$l.PCSSmaxFilterRadius = ShaderHelper.getShadowImplParams(this).w;
50626
+ this.$l.PCSSsearchRadius = this.$choice(pb.greaterThan(this.PCSSlightRadius, 0), pb.max(this.PCSSlightRadius, this.PCSSmaxFilterRadius), 0);
50627
+ if (!pb.getGlobalScope().PCSSpdSamples) {
50628
+ pb.getGlobalScope().PCSSpdSamples = PCF_POISSON_DISC.map((s)=>pb.vec2(s[0], s[1]));
50629
+ }
50630
+ if (lightType === LIGHT_TYPE_POINT) {
50631
+ this.$l.lightDepth = this.texCoord.w;
50632
+ this.$l.sampleDir = pb.normalize(this.texCoord.xyz);
50633
+ this.$l.shadowMapTexelSize = pb.mul(getShadowMapTexelSize(this), 2);
50634
+ this.$l.matrix = getPCSSRotationMatrix(this, pb.mul(this.sampleDir.xy, pb.vec2(getShadowMapSize(this))), temporalJitter);
50635
+ this.$l.searchRadius = pb.mul(pb.clamp(this.PCSSsearchRadius, 0, pb.max(0, this.PCSSmaxFilterRadius)), this.shadowMapTexelSize);
50636
+ this.$l.blockerTransitionWidth = pb.float(1 / 65535);
50637
+ this.$l.up = this.$choice(pb.lessThan(pb.abs(this.sampleDir.y), 0.999), pb.vec3(0, 1, 0), pb.vec3(1, 0, 0));
50638
+ this.$l.tangent = pb.normalize(pb.cross(this.up, this.sampleDir));
50639
+ this.$l.bitangent = pb.cross(this.sampleDir, this.tangent);
50640
+ this.$l.blocker = findPointBlockerPCSS(this, shadowMapFormat, this.PCSSblockerSampleCount, this.sampleDir, this.lightDepth, this.searchRadius, this.blockerTransitionWidth, this.matrix, this.tangent, this.bitangent);
50641
+ this.$if(pb.lessThanEqual(this.blocker.y, 0), function() {
50642
+ this.$return(pb.float(1));
50643
+ });
50644
+ this.$l.penumbra = pb.div(pb.max(pb.sub(this.lightDepth, this.blocker.x), 0), pb.max(this.blocker.x, 0.0001));
50645
+ this.$l.filterRadius = pb.mul(pb.clamp(pb.mul(this.penumbra, this.PCSSlightRadius), 0, pb.max(0, this.PCSSmaxFilterRadius)), this.shadowMapTexelSize);
50646
+ this.$l.shadow = pb.float(0);
50647
+ this.$l.duv = pb.vec2();
50648
+ this.$l.samplePointDir = pb.vec3();
50649
+ this.$for(pb.float('i'), 0, this.PCSSfilterSampleCount, function() {
50650
+ this.duv = pb.mul(pb.mul(this.matrix, this.PCSSpdSamples.at(pb.mod(pb.mul(pb.int(this.i), 19), PCF_POISSON_DISC.length))), this.filterRadius);
50651
+ this.samplePointDir = pb.normalize(pb.add(this.sampleDir, pb.add(pb.mul(this.tangent, this.duv.x), pb.mul(this.bitangent, this.duv.y))));
50652
+ this.shadow = pb.add(this.shadow, samplePointShadowPCFPCSS(this, shadowMapFormat, this.samplePointDir, this.lightDepth, this.shadowMapTexelSize, this.tangent, this.bitangent));
50653
+ });
50654
+ this.shadow = pb.div(this.shadow, this.PCSSfilterSampleCount);
50655
+ this.$return(this.shadow);
50656
+ return;
50657
+ }
50658
+ this.$l.lightDepth = this.texCoord.z;
50659
+ if (receiverPlaneDepthBias) {
50660
+ this.lightDepth = pb.sub(this.lightDepth, this.receiverPlaneDepthBias.z);
50661
+ }
50662
+ this.$l.sampleBounds = pb.vec4(0, 0, 1, 1);
50663
+ if (cascade && getDevice().type === 'webgl' && numCascades > 1) {
50664
+ const numCols = numCascades > 1 ? 2 : 1;
50665
+ const numRows = numCascades > 2 ? 2 : 1;
50666
+ this.$l.cascadeIndex = pb.float(this.cascade);
50667
+ this.$l.cascadeCol = pb.mod(this.cascadeIndex, 2);
50668
+ this.$l.cascadeRow = pb.floor(pb.mul(this.cascadeIndex, 0.5));
50669
+ this.sampleBounds = pb.vec4(pb.mul(this.cascadeCol, 1 / numCols), pb.mul(this.cascadeRow, 1 / numRows), pb.mul(pb.add(this.cascadeCol, 1), 1 / numCols), pb.mul(pb.add(this.cascadeRow, 1), 1 / numRows));
50670
+ }
50671
+ this.$l.shadowMapTexelSize = pb.mul(pb.sub(this.sampleBounds.zw, this.sampleBounds.xy), getShadowMapTexelSize(this));
50672
+ this.$l.matrix = getPCSSRotationMatrix(this, pb.mul(this.texCoord.xy, pb.vec2(getShadowMapSize(this))), temporalJitter);
50673
+ this.$l.searchRadius = pb.mul(pb.clamp(this.PCSSsearchRadius, 0, pb.max(0, this.PCSSmaxFilterRadius)), this.shadowMapTexelSize);
50674
+ this.$l.blockerTransitionWidth = receiverPlaneDepthBias ? pb.max(pb.dot(pb.abs(this.receiverPlaneDepthBias.xy), this.searchRadius), 1 / 65535) : pb.float(1 / 65535);
50675
+ this.$l.blocker = findBlockerPCSS(this, shadowMapFormat, this.PCSSblockerSampleCount, pb.vec4(this.texCoord.xy, this.lightDepth, this.texCoord.w), this.sampleBounds, this.searchRadius, this.blockerTransitionWidth, this.matrix, this.cascade);
50676
+ this.$if(pb.lessThanEqual(this.blocker.y, 0), function() {
50677
+ this.$return(pb.float(1));
50678
+ });
50679
+ this.$l.penumbra = pb.div(pb.max(pb.sub(this.lightDepth, this.blocker.x), 0), pb.max(this.blocker.x, 0.0001));
50680
+ this.$l.filterRadius = pb.mul(pb.clamp(pb.mul(this.penumbra, this.PCSSlightRadius), 0, pb.max(0, this.PCSSmaxFilterRadius)), this.shadowMapTexelSize);
50681
+ this.$l.shadow = pb.float(0);
50682
+ this.$l.duv = pb.vec2();
50683
+ this.$l.sampleCoord = pb.vec2();
50684
+ this.$l.compareDepth = pb.float();
50685
+ this.$for(pb.float('i'), 0, this.PCSSfilterSampleCount, function() {
50686
+ this.duv = pb.mul(pb.mul(this.matrix, this.PCSSpdSamples.at(pb.mod(pb.mul(pb.int(this.i), 19), PCF_POISSON_DISC.length))), this.filterRadius);
50687
+ this.sampleCoord = pb.add(this.texCoord.xy, this.duv);
50688
+ this.compareDepth = receiverPlaneDepthBias ? pb.add(this.lightDepth, pb.dot(this.duv, this.receiverPlaneDepthBias.xy)) : this.lightDepth;
50689
+ this.shadow = pb.add(this.shadow, sampleShadowPCFPCSS(this, shadowMapFormat, this.sampleCoord, this.sampleBounds, this.compareDepth, this.shadowMapTexelSize, this.receiverPlaneDepthBias, this.cascade));
50690
+ });
50691
+ this.shadow = pb.div(this.shadow, this.PCSSfilterSampleCount);
50692
+ this.$return(this.shadow);
50693
+ });
50694
+ return pb.getGlobalScope()[funcNameFilterShadowPCSS](texCoord, ...receiverPlaneDepthBias ? [
50695
+ receiverPlaneDepthBias
50696
+ ] : [], ...cascade ? [
50697
+ cascade
50698
+ ] : []);
50699
+ }
49542
50700
 
49543
50701
  function getShadowReceiverBiasFactors(scope) {
49544
50702
  const pb = scope.$builder;
@@ -49624,6 +50782,7 @@ function computeShadowBias(lightType, scope, z, NdotL, linear) {
49624
50782
  getShadowMapBorder(_shadowMapParams) {
49625
50783
  return 0;
49626
50784
  }
50785
+ getParams() {}
49627
50786
  getShadowMap(shadowMapParams) {
49628
50787
  return this.useNativeShadowMap(shadowMapParams) ? shadowMapParams.shadowMapFramebuffer.getDepthAttachment() : shadowMapParams.shadowMapFramebuffer.getColorAttachments()[0];
49629
50788
  }
@@ -50241,6 +51400,7 @@ class BlurBlitter extends GaussianBlurBlitter {
50241
51400
  getShaderHash() {
50242
51401
  return `${this._blur ? 1 : 0}${this._logSpace ? 1 : 0}`;
50243
51402
  }
51403
+ getParams() {}
50244
51404
  getShadowMapColorFormat(_shadowMapParams) {
50245
51405
  const device = getDevice();
50246
51406
  return device.getDeviceCaps().textureCaps.supportFloatColorBuffer && device.getDeviceCaps().textureCaps.supportLinearFloatTexture ? device.type === 'webgl' ? 'rgba32f' : 'rg32f' : device.getDeviceCaps().textureCaps.supportHalfFloatColorBuffer && device.getDeviceCaps().textureCaps.supportLinearHalfFloatTexture ? device.type === 'webgl' ? 'rgba16f' : 'rg16f' : 'rgba8unorm';
@@ -50545,6 +51705,7 @@ class VSMBlitter extends Blitter {
50545
51705
  getShaderHash() {
50546
51706
  return '';
50547
51707
  }
51708
+ getParams() {}
50548
51709
  getShadowMapColorFormat(_shadowMapParams) {
50549
51710
  const device = getDevice();
50550
51711
  return device.getDeviceCaps().textureCaps.supportFloatColorBuffer && device.getDeviceCaps().textureCaps.supportLinearFloatTexture ? 'rgba32f' : device.getDeviceCaps().textureCaps.supportHalfFloatColorBuffer && device.getDeviceCaps().textureCaps.supportLinearHalfFloatTexture ? 'rgba16f' : 'rgba8unorm';
@@ -50617,25 +51778,23 @@ class VSMBlitter extends Blitter {
50617
51778
  }
50618
51779
  }
50619
51780
 
50620
- /** @internal */ class PCFPD extends ShadowImpl {
50621
- static SHADER_VERSION = 3;
50622
- _tapCount;
50623
- _sampleRadius;
51781
+ /** @internal */ class PCFOPT extends ShadowImpl {
51782
+ _kernelSize;
50624
51783
  _shadowSampler;
50625
- constructor(tapCount, sampleRadius){
51784
+ constructor(kernelSize){
50626
51785
  super();
50627
- this._tapCount = tapCount ?? 3;
50628
- this._sampleRadius = sampleRadius ?? 1;
51786
+ this._kernelSize = kernelSize ?? 5;
50629
51787
  this._shadowSampler = null;
50630
51788
  }
50631
- get tapCount() {
50632
- return this._tapCount;
51789
+ get kernelSize() {
51790
+ return this._kernelSize;
50633
51791
  }
50634
- set tapCount(val) {
50635
- this._tapCount = val;
51792
+ set kernelSize(val) {
51793
+ val = val !== 3 && val !== 5 && val !== 7 ? 5 : val;
51794
+ this._kernelSize = val;
50636
51795
  }
50637
51796
  getType() {
50638
- return 'pcf-pd';
51797
+ return 'pcf-opt';
50639
51798
  }
50640
51799
  dispose() {
50641
51800
  this._shadowSampler = null;
@@ -50643,18 +51802,10 @@ class VSMBlitter extends Blitter {
50643
51802
  resourceDirty() {
50644
51803
  return false;
50645
51804
  }
50646
- getPCFKernelSize() {
50647
- if (this._sampleRadius >= 4 || this._tapCount >= 32) {
50648
- return 7;
50649
- }
50650
- if (this._sampleRadius >= 2 || this._tapCount >= 12) {
50651
- return 5;
50652
- }
50653
- return 3;
50654
- }
50655
51805
  getShadowMapBorder(_shadowMapParams) {
50656
- return Math.max(this._sampleRadius + 1, this.getPCFKernelSize());
51806
+ return this._kernelSize;
50657
51807
  }
51808
+ getParams() {}
50658
51809
  getShadowMap(shadowMapParams) {
50659
51810
  return this.useNativeShadowMap(shadowMapParams) ? shadowMapParams.shadowMapFramebuffer.getDepthAttachment() : shadowMapParams.shadowMapFramebuffer.getColorAttachments()[0];
50660
51811
  }
@@ -50664,21 +51815,14 @@ class VSMBlitter extends Blitter {
50664
51815
  }
50665
51816
  postRenderShadowMap() {}
50666
51817
  getDepthScale() {
50667
- return this._sampleRadius;
50668
- }
50669
- setDepthScale(val) {
50670
- this._sampleRadius = val;
51818
+ return 1;
50671
51819
  }
51820
+ setDepthScale(_val) {}
50672
51821
  getShaderHash() {
50673
- return `${PCFPD.SHADER_VERSION}-${this._tapCount}-${this._sampleRadius}`;
51822
+ return `${this._kernelSize}`;
50674
51823
  }
50675
51824
  getShadowMapColorFormat(shadowMapParams) {
50676
- if (this.useNativeShadowMap(shadowMapParams)) {
50677
- return null;
50678
- } else {
50679
- const device = getDevice();
50680
- return device.getDeviceCaps().textureCaps.supportHalfFloatColorBuffer ? device.type === 'webgl' ? 'rgba16f' : 'r16f' : device.getDeviceCaps().textureCaps.supportFloatColorBuffer ? device.type === 'webgl' ? 'rgba32f' : 'r32f' : 'rgba8unorm';
50681
- }
51825
+ return this.useNativeShadowMap(shadowMapParams) ? null : 'rgba8unorm';
50682
51826
  }
50683
51827
  getShadowMapDepthFormat(_shadowMapParams) {
50684
51828
  return getDevice().type === 'webgl' ? 'd24s8' : 'd32f';
@@ -50689,7 +51833,7 @@ class VSMBlitter extends Blitter {
50689
51833
  computeShadowCSM(shadowMapParams, scope, shadowVertex, NdotL, split) {
50690
51834
  const funcNameComputeShadowCSM = 'lib_computeShadowCSM';
50691
51835
  const pb = scope.$builder;
50692
- const kernelSize = this.getPCFKernelSize();
51836
+ const that = this;
50693
51837
  pb.func(funcNameComputeShadowCSM, [
50694
51838
  pb.vec4('shadowVertex'),
50695
51839
  pb.float('NdotL'),
@@ -50699,10 +51843,11 @@ class VSMBlitter extends Blitter {
50699
51843
  this.$l.shadowCoord = pb.add(pb.mul(this.shadowCoord, 0.5), 0.5);
50700
51844
  this.$l.inShadow = pb.all(pb.bvec2(pb.all(pb.bvec4(pb.greaterThanEqual(this.shadowCoord.x, 0), pb.lessThanEqual(this.shadowCoord.x, 1), pb.greaterThanEqual(this.shadowCoord.y, 0), pb.lessThanEqual(this.shadowCoord.y, 1))), pb.lessThanEqual(this.shadowCoord.z, 1)));
50701
51845
  this.$l.shadow = pb.float(1);
51846
+ this.$l.receiverPlaneDepthBias = computeReceiverPlaneDepthBias(this, this.shadowCoord);
50702
51847
  this.$if(this.inShadow, function() {
50703
51848
  this.$l.shadowBias = computeShadowBiasCSM(this, this.NdotL, this.split);
50704
51849
  this.shadowCoord.z = pb.sub(this.shadowCoord.z, this.shadowBias);
50705
- this.shadow = filterShadowPCF(this, shadowMapParams.lightType, shadowMapParams.shadowMap.format, kernelSize, this.shadowCoord, undefined, this.split);
51850
+ this.shadow = filterShadowPCF(this, shadowMapParams.lightType, shadowMapParams.shadowMap.format, that._kernelSize, this.shadowCoord, this.receiverPlaneDepthBias, this.split);
50706
51851
  });
50707
51852
  this.$return(this.shadow);
50708
51853
  });
@@ -50712,7 +51857,6 @@ class VSMBlitter extends Blitter {
50712
51857
  const funcNameComputeShadow = 'lib_computeShadow';
50713
51858
  const pb = scope.$builder;
50714
51859
  const that = this;
50715
- const kernelSize = this.getPCFKernelSize();
50716
51860
  pb.func(funcNameComputeShadow, [
50717
51861
  pb.vec4('shadowVertex'),
50718
51862
  pb.float('NdotL')
@@ -50735,10 +51879,11 @@ class VSMBlitter extends Blitter {
50735
51879
  this.$l.shadowCoord = pb.add(pb.mul(this.shadowCoord, 0.5), 0.5);
50736
51880
  this.$l.inShadow = pb.all(pb.bvec2(pb.all(pb.bvec4(pb.greaterThanEqual(this.shadowCoord.x, 0), pb.lessThanEqual(this.shadowCoord.x, 1), pb.greaterThanEqual(this.shadowCoord.y, 0), pb.lessThanEqual(this.shadowCoord.y, 1))), pb.lessThanEqual(this.shadowCoord.z, 1)));
50737
51881
  this.$l.shadow = pb.float(1);
51882
+ this.$l.receiverPlaneDepthBias = computeReceiverPlaneDepthBias(this, this.shadowCoord);
50738
51883
  this.$if(this.inShadow, function() {
50739
51884
  this.$l.shadowBias = computeShadowBias(shadowMapParams.lightType, this, this.shadowCoord.z, this.NdotL, false);
50740
51885
  this.shadowCoord.z = pb.sub(this.shadowCoord.z, this.shadowBias);
50741
- this.shadow = filterShadowPCF(this, shadowMapParams.lightType, shadowMapParams.shadowMap.format, kernelSize, this.shadowCoord);
51886
+ this.shadow = filterShadowPCF(this, shadowMapParams.lightType, shadowMapParams.shadowMap.format, that._kernelSize, this.shadowCoord, this.receiverPlaneDepthBias);
50742
51887
  });
50743
51888
  this.$return(this.shadow);
50744
51889
  }
@@ -50749,7 +51894,7 @@ class VSMBlitter extends Blitter {
50749
51894
  return getDevice().type !== 'webgl';
50750
51895
  }
50751
51896
  /** @internal */ sampleShadowMap(shadowMapParams, scope, coords, z, bias) {
50752
- const funcNameSampleShadowMap = 'lib_sampleShadowMapPD';
51897
+ const funcNameSampleShadowMap = `lib_sampleShadowMapOPT`;
50753
51898
  const pb = scope.$builder;
50754
51899
  const that = this;
50755
51900
  pb.func(funcNameSampleShadowMap, [
@@ -50772,7 +51917,7 @@ class VSMBlitter extends Blitter {
50772
51917
  return pb.getGlobalScope()[funcNameSampleShadowMap](coords, z, bias);
50773
51918
  }
50774
51919
  /** @internal */ sampleShadowMapCSM(shadowMapParams, scope, coords, split, z, bias) {
50775
- const funcNameSampleShadowMapCSM = 'lib_sampleShadowMapCSMPD';
51920
+ const funcNameSampleShadowMapCSM = 'lib_sampleShadowMapCSMOPT';
50776
51921
  const pb = scope.$builder;
50777
51922
  const that = this;
50778
51923
  pb.func(funcNameSampleShadowMapCSM, [
@@ -50805,39 +51950,69 @@ class VSMBlitter extends Blitter {
50805
51950
  }
50806
51951
  }
50807
51952
 
50808
- /** @internal */ class PCFOPT extends ShadowImpl {
50809
- _kernelSize;
50810
- _shadowSampler;
50811
- constructor(kernelSize){
51953
+ /** @internal */ class PCSS extends ShadowImpl {
51954
+ _lightRadius;
51955
+ _blockerSampleCount;
51956
+ _filterSampleCount;
51957
+ _maxFilterRadius;
51958
+ _temporalJitter;
51959
+ constructor(lightRadius, blockerSampleCount, filterSampleCount, maxFilterRadius, temporalJitter){
50812
51960
  super();
50813
- this._kernelSize = kernelSize ?? 5;
50814
- this._shadowSampler = null;
51961
+ this._lightRadius = lightRadius ?? 8;
51962
+ this._blockerSampleCount = blockerSampleCount ?? 24;
51963
+ this._filterSampleCount = filterSampleCount ?? 32;
51964
+ this._maxFilterRadius = maxFilterRadius ?? 32;
51965
+ this._temporalJitter = temporalJitter ?? true;
50815
51966
  }
50816
- get kernelSize() {
50817
- return this._kernelSize;
51967
+ get lightRadius() {
51968
+ return this._lightRadius;
50818
51969
  }
50819
- set kernelSize(val) {
50820
- val = val !== 3 && val !== 5 && val !== 7 ? 5 : val;
50821
- this._kernelSize = val;
51970
+ set lightRadius(val) {
51971
+ this._lightRadius = Math.max(0, Number(val) || 0);
50822
51972
  }
50823
- getType() {
50824
- return 'pcf-opt';
51973
+ get blockerSampleCount() {
51974
+ return this._blockerSampleCount;
50825
51975
  }
50826
- dispose() {
50827
- this._shadowSampler = null;
51976
+ set blockerSampleCount(val) {
51977
+ this._blockerSampleCount = Math.min(Math.max(1, Number(val) >> 0), 64);
51978
+ }
51979
+ get filterSampleCount() {
51980
+ return this._filterSampleCount;
51981
+ }
51982
+ set filterSampleCount(val) {
51983
+ this._filterSampleCount = Math.min(Math.max(1, Number(val) >> 0), 64);
51984
+ }
51985
+ get maxFilterRadius() {
51986
+ return this._maxFilterRadius;
50828
51987
  }
51988
+ set maxFilterRadius(val) {
51989
+ this._maxFilterRadius = Math.max(1, Number(val) || 1);
51990
+ }
51991
+ get temporalJitter() {
51992
+ return this._temporalJitter;
51993
+ }
51994
+ set temporalJitter(val) {
51995
+ this._temporalJitter = !!val;
51996
+ }
51997
+ getType() {
51998
+ return 'pcss';
51999
+ }
52000
+ dispose() {}
50829
52001
  resourceDirty() {
50830
52002
  return false;
50831
52003
  }
50832
52004
  getShadowMapBorder(_shadowMapParams) {
50833
- return this._kernelSize;
52005
+ return this._lightRadius > 0 ? Math.ceil(Math.max(this._lightRadius, this._maxFilterRadius) + 2) : 0;
52006
+ }
52007
+ getShadowMapClearColor(_shadowMapParams) {
52008
+ return new Vector4(1, 1, 1, 1);
50834
52009
  }
50835
52010
  getShadowMap(shadowMapParams) {
50836
- return this.useNativeShadowMap(shadowMapParams) ? shadowMapParams.shadowMapFramebuffer.getDepthAttachment() : shadowMapParams.shadowMapFramebuffer.getColorAttachments()[0];
52011
+ return shadowMapParams.shadowMapFramebuffer.getColorAttachments()[0];
50837
52012
  }
50838
52013
  doUpdateResources(shadowMapParams) {
50839
52014
  shadowMapParams.shadowMap = this.getShadowMap(shadowMapParams);
50840
- shadowMapParams.shadowMapSampler = shadowMapParams.shadowMap?.getDefaultSampler(this.useNativeShadowMap(shadowMapParams)) || null;
52015
+ shadowMapParams.shadowMapSampler = shadowMapParams.shadowMap?.getDefaultSampler(false) ?? null;
50841
52016
  }
50842
52017
  postRenderShadowMap() {}
50843
52018
  getDepthScale() {
@@ -50845,10 +52020,17 @@ class VSMBlitter extends Blitter {
50845
52020
  }
50846
52021
  setDepthScale(_val) {}
50847
52022
  getShaderHash() {
50848
- return `${this._kernelSize}`;
52023
+ return `${Number(this._temporalJitter)}`;
50849
52024
  }
50850
- getShadowMapColorFormat(shadowMapParams) {
50851
- return this.useNativeShadowMap(shadowMapParams) ? null : 'rgba8unorm';
52025
+ getShadowMapColorFormat(_shadowMapParams) {
52026
+ const device = getDevice();
52027
+ if (device.type === 'webgl') {
52028
+ return device.getDeviceCaps().textureCaps.supportHalfFloatColorBuffer ? 'rgba16f' : device.getDeviceCaps().textureCaps.supportFloatColorBuffer ? 'rgba32f' : 'rgba8unorm';
52029
+ }
52030
+ return device.getDeviceCaps().textureCaps.supportHalfFloatColorBuffer ? 'r16f' : device.getDeviceCaps().textureCaps.supportFloatColorBuffer ? 'r32f' : 'rgba8unorm';
52031
+ }
52032
+ getParams(out) {
52033
+ out.setXYZW(this._lightRadius, this._blockerSampleCount, this._filterSampleCount, this._maxFilterRadius);
50852
52034
  }
50853
52035
  getShadowMapDepthFormat(_shadowMapParams) {
50854
52036
  return getDevice().type === 'webgl' ? 'd24s8' : 'd32f';
@@ -50873,7 +52055,7 @@ class VSMBlitter extends Blitter {
50873
52055
  this.$if(this.inShadow, function() {
50874
52056
  this.$l.shadowBias = computeShadowBiasCSM(this, this.NdotL, this.split);
50875
52057
  this.shadowCoord.z = pb.sub(this.shadowCoord.z, this.shadowBias);
50876
- this.shadow = filterShadowPCF(this, shadowMapParams.lightType, shadowMapParams.shadowMap.format, that._kernelSize, this.shadowCoord, this.receiverPlaneDepthBias, this.split);
52058
+ this.shadow = filterShadowPCSS(this, shadowMapParams.lightType, shadowMapParams.shadowMap.format, this.shadowCoord, this.receiverPlaneDepthBias, this.split, that._temporalJitter, shadowMapParams.numShadowCascades);
50877
52059
  });
50878
52060
  this.$return(this.shadow);
50879
52061
  });
@@ -50889,90 +52071,53 @@ class VSMBlitter extends Blitter {
50889
52071
  ], function() {
50890
52072
  if (shadowMapParams.lightType === LIGHT_TYPE_POINT) {
50891
52073
  this.$l.dir = pb.sub(this.shadowVertex.xyz, ShaderHelper.getLightPositionAndRangeForShadow(this).xyz);
50892
- if (that.useNativeShadowMap(shadowMapParams)) {
50893
- this.$l.nearFar = ShaderHelper.getShadowCameraParams(this).xy;
50894
- this.$l.maxZ = pb.max(pb.max(pb.abs(this.dir.x), pb.abs(this.dir.y)), pb.abs(this.dir.z));
50895
- this.$l.distance = ShaderHelper.linearDepthToNonLinear(this, this.maxZ, this.nearFar);
50896
- this.$l.shadowBias = computeShadowBias(shadowMapParams.lightType, this, pb.div(this.maxZ, ShaderHelper.getLightPositionAndRangeForShadow(this).w), this.NdotL, true);
50897
- this.$return(that.sampleShadowMap(shadowMapParams, this, this.dir, this.distance, this.shadowBias));
52074
+ this.$l.distance = pb.div(pb.length(this.dir), ShaderHelper.getLightPositionAndRangeForShadow(this).w);
52075
+ this.$l.shadowBias = computeShadowBias(shadowMapParams.lightType, this, this.distance, this.NdotL, true);
52076
+ this.$l.shadowCoord = pb.vec4(this.dir, pb.sub(this.distance, this.shadowBias));
52077
+ this.$return(filterShadowPCSS(this, shadowMapParams.lightType, shadowMapParams.shadowMap.format, this.shadowCoord, undefined, undefined, that._temporalJitter));
52078
+ }
52079
+ this.$l.shadowCoord = pb.div(this.shadowVertex, this.shadowVertex.w);
52080
+ this.$l.shadowCoord = pb.add(pb.mul(this.shadowCoord, 0.5), 0.5);
52081
+ this.$l.inShadow = pb.all(pb.bvec2(pb.all(pb.bvec4(pb.greaterThanEqual(this.shadowCoord.x, 0), pb.lessThanEqual(this.shadowCoord.x, 1), pb.greaterThanEqual(this.shadowCoord.y, 0), pb.lessThanEqual(this.shadowCoord.y, 1))), pb.lessThanEqual(this.shadowCoord.z, 1)));
52082
+ this.$l.shadow = pb.float(1);
52083
+ if (shadowMapParams.lightType === LIGHT_TYPE_SPOT) {
52084
+ this.$l.nearFar = ShaderHelper.getShadowCameraParams(this).xy;
52085
+ this.shadowCoord.z = ShaderHelper.nonLinearDepthToLinearNormalized(this, this.shadowCoord.z, this.nearFar);
52086
+ }
52087
+ this.$l.receiverPlaneDepthBias = computeReceiverPlaneDepthBias(this, this.shadowCoord);
52088
+ this.$if(this.inShadow, function() {
52089
+ if (shadowMapParams.lightType === LIGHT_TYPE_SPOT) {
52090
+ this.$l.shadowBias = computeShadowBias(shadowMapParams.lightType, this, this.shadowCoord.z, this.NdotL, true);
50898
52091
  } else {
50899
- this.$l.distance = pb.div(pb.length(this.dir), ShaderHelper.getLightPositionAndRangeForShadow(this).w);
50900
- this.$l.shadowBias = computeShadowBias(shadowMapParams.lightType, this, this.distance, this.NdotL, true);
50901
- this.$return(that.sampleShadowMap(shadowMapParams, this, this.dir, this.distance, this.shadowBias));
50902
- }
50903
- } else {
50904
- this.$l.shadowCoord = pb.div(this.shadowVertex, this.shadowVertex.w);
50905
- this.$l.shadowCoord = pb.add(pb.mul(this.shadowCoord, 0.5), 0.5);
50906
- this.$l.inShadow = pb.all(pb.bvec2(pb.all(pb.bvec4(pb.greaterThanEqual(this.shadowCoord.x, 0), pb.lessThanEqual(this.shadowCoord.x, 1), pb.greaterThanEqual(this.shadowCoord.y, 0), pb.lessThanEqual(this.shadowCoord.y, 1))), pb.lessThanEqual(this.shadowCoord.z, 1)));
50907
- this.$l.shadow = pb.float(1);
50908
- this.$l.receiverPlaneDepthBias = computeReceiverPlaneDepthBias(this, this.shadowCoord);
50909
- this.$if(this.inShadow, function() {
50910
52092
  this.$l.shadowBias = computeShadowBias(shadowMapParams.lightType, this, this.shadowCoord.z, this.NdotL, false);
50911
- this.shadowCoord.z = pb.sub(this.shadowCoord.z, this.shadowBias);
50912
- this.shadow = filterShadowPCF(this, shadowMapParams.lightType, shadowMapParams.shadowMap.format, that._kernelSize, this.shadowCoord, this.receiverPlaneDepthBias);
50913
- });
50914
- this.$return(this.shadow);
50915
- }
52093
+ }
52094
+ this.shadowCoord.z = pb.sub(this.shadowCoord.z, this.shadowBias);
52095
+ this.shadow = filterShadowPCSS(this, shadowMapParams.lightType, shadowMapParams.shadowMap.format, this.shadowCoord, this.receiverPlaneDepthBias, undefined, that._temporalJitter);
52096
+ });
52097
+ this.$return(this.shadow);
50916
52098
  });
50917
52099
  return pb.getGlobalScope()[funcNameComputeShadow](shadowVertex, NdotL);
50918
52100
  }
50919
52101
  useNativeShadowMap(_shadowMapParams) {
50920
- return getDevice().type !== 'webgl';
52102
+ return false;
50921
52103
  }
50922
- /** @internal */ sampleShadowMap(shadowMapParams, scope, coords, z, bias) {
50923
- const funcNameSampleShadowMap = `lib_sampleShadowMapOPT`;
52104
+ /** @internal */ samplePointShadowMap(shadowMapParams, scope, coords, z, bias) {
52105
+ const funcNameSampleShadowMap = 'lib_samplePointShadowMapPCSS';
50924
52106
  const pb = scope.$builder;
50925
- const that = this;
50926
52107
  pb.func(funcNameSampleShadowMap, [
50927
52108
  pb.vec3('coords'),
50928
52109
  pb.float('z'),
50929
52110
  pb.float('bias')
50930
52111
  ], function() {
50931
52112
  const floatDepthTexture = shadowMapParams.shadowMap.format !== 'rgba8unorm';
50932
- if (that.useNativeShadowMap(shadowMapParams)) {
50933
- this.$return(pb.clamp(pb.textureSampleCompareLevel(ShaderHelper.getShadowMap(this), this.coords, pb.sub(this.z, this.bias)), 0, 1));
50934
- } else {
50935
- this.$l.shadowTex = pb.textureSampleLevel(ShaderHelper.getShadowMap(this), this.coords, 0);
50936
- if (!floatDepthTexture) {
50937
- this.shadowTex.x = decodeNormalizedFloatFromRGBA(this, this.shadowTex);
50938
- }
50939
- this.$l.distance = pb.sub(this.z, this.bias);
50940
- this.$return(pb.step(this.distance, this.shadowTex.x));
52113
+ this.$l.shadowTex = pb.textureSampleLevel(ShaderHelper.getShadowMap(this), this.coords, 0);
52114
+ if (!floatDepthTexture) {
52115
+ this.shadowTex.x = decodeNormalizedFloatFromRGBA(this, this.shadowTex);
50941
52116
  }
50942
- });
50943
- return pb.getGlobalScope()[funcNameSampleShadowMap](coords, z, bias);
50944
- }
50945
- /** @internal */ sampleShadowMapCSM(shadowMapParams, scope, coords, split, z, bias) {
50946
- const funcNameSampleShadowMapCSM = 'lib_sampleShadowMapCSMOPT';
50947
- const pb = scope.$builder;
50948
- const that = this;
50949
- pb.func(funcNameSampleShadowMapCSM, [
50950
- pb.vec4('coords'),
50951
- pb.int('split'),
50952
- pb.float('z'),
50953
- pb.float('bias')
50954
- ], function() {
50955
- const floatDepthTexture = shadowMapParams.shadowMap.format !== 'rgba8unorm';
50956
52117
  this.$l.distance = pb.sub(this.z, this.bias);
50957
- if (that.useNativeShadowMap(shadowMapParams)) {
50958
- if (shadowMapParams.shadowMap.isTexture2DArray()) {
50959
- this.$return(pb.clamp(pb.textureArraySampleCompareLevel(ShaderHelper.getShadowMap(this), this.coords.xy, this.split, this.distance), 0, 1));
50960
- } else {
50961
- this.$return(pb.clamp(pb.textureSampleCompareLevel(ShaderHelper.getShadowMap(this), this.coords.xy, this.distance), 0, 1));
50962
- }
50963
- } else {
50964
- if (shadowMapParams.shadowMap.isTexture2DArray()) {
50965
- this.$l.shadowTex = pb.textureArraySampleLevel(ShaderHelper.getShadowMap(this), this.coords.xy, this.split, 0);
50966
- } else {
50967
- this.$l.shadowTex = pb.textureSampleLevel(ShaderHelper.getShadowMap(this), this.coords.xy, 0);
50968
- }
50969
- if (!floatDepthTexture) {
50970
- this.shadowTex.x = decodeNormalizedFloatFromRGBA(this, this.shadowTex);
50971
- }
50972
- this.$return(pb.step(this.distance, this.shadowTex.x));
50973
- }
52118
+ this.$return(pb.step(this.distance, this.shadowTex.x));
50974
52119
  });
50975
- return pb.getGlobalScope()[funcNameSampleShadowMapCSM](coords, split, z, bias);
52120
+ return pb.getGlobalScope()[funcNameSampleShadowMap](coords, z, bias);
50976
52121
  }
50977
52122
  }
50978
52123
 
@@ -51204,9 +52349,9 @@ class VSMBlitter extends Blitter {
51204
52349
  const tmpMatrix$1 = new Matrix4x4();
51205
52350
  const tmpFrustum = new Frustum(Matrix4x4.identity());
51206
52351
  // const zeroPosition = Vector3.zero();
51207
- /**
51208
- * The shadow map generator
51209
- * @public
52352
+ /**
52353
+ * The shadow map generator
52354
+ * @public
51210
52355
  */ class ShadowMapper extends Disposable {
51211
52356
  /** @internal */ static _snapMatrix = new Matrix4x4();
51212
52357
  /** @internal */ static _target = new Vector3();
@@ -51225,6 +52370,11 @@ const tmpFrustum = new Frustum(Matrix4x4.identity());
51225
52370
  /** @internal */ _pdSampleCount;
51226
52371
  /** @internal */ _pdSampleRadius;
51227
52372
  /** @internal */ _pcfKernelSize;
52373
+ /** @internal */ _pcssLightRadius;
52374
+ /** @internal */ _pcssBlockerSampleCount;
52375
+ /** @internal */ _pcssFilterSampleCount;
52376
+ /** @internal */ _pcssMaxFilterRadius;
52377
+ /** @internal */ _pcssTemporalJitter;
51228
52378
  /** @internal */ _vsmBlurKernelSize;
51229
52379
  /** @internal */ _vsmBlurRadius;
51230
52380
  /** @internal */ _vsmDarkness;
@@ -51235,9 +52385,9 @@ const tmpFrustum = new Frustum(Matrix4x4.identity());
51235
52385
  /** @internal */ _esmDepthScale;
51236
52386
  /** @internal */ _shadowStrength;
51237
52387
  /** @internal */ _shadowRegion;
51238
- /**
51239
- * Creates an instance of ShadowMapper
51240
- * @param light - The light that is used to generate shadow map
52388
+ /**
52389
+ * Creates an instance of ShadowMapper
52390
+ * @param light - The light that is used to generate shadow map
51241
52391
  */ constructor(light){
51242
52392
  super();
51243
52393
  this._light = light;
@@ -51250,12 +52400,17 @@ const tmpFrustum = new Frustum(Matrix4x4.identity());
51250
52400
  nearClip: 1
51251
52401
  };
51252
52402
  this._resourceDirty = true;
51253
- this._shadowMode = 'pcf-pd';
52403
+ this._shadowMode = 'pcf';
51254
52404
  this._shadowDistance = 2000;
51255
52405
  this._impl = null;
51256
52406
  this._pdSampleCount = 24;
51257
52407
  this._pdSampleRadius = 3;
51258
52408
  this._pcfKernelSize = 7;
52409
+ this._pcssLightRadius = 8;
52410
+ this._pcssBlockerSampleCount = 24;
52411
+ this._pcssFilterSampleCount = 32;
52412
+ this._pcssMaxFilterRadius = 32;
52413
+ this._pcssTemporalJitter = true;
51259
52414
  this._vsmBlurKernelSize = 5;
51260
52415
  this._vsmBlurRadius = 4;
51261
52416
  this._vsmDarkness = 0.3;
@@ -51385,14 +52540,14 @@ const tmpFrustum = new Frustum(Matrix4x4.identity());
51385
52540
  this.applyMode(this._shadowMode);
51386
52541
  }
51387
52542
  }
51388
- /**
51389
- * Applies a practical shadow preset for common scenarios.
51390
- *
51391
- * `character-small`: higher contact quality and tighter distance for character-centric scenes.
51392
- * `outdoor-large`: longer distance coverage for open scenes.
52543
+ /**
52544
+ * Applies a practical shadow preset for common scenarios.
52545
+ *
52546
+ * `character-small`: higher contact quality and tighter distance for character-centric scenes.
52547
+ * `outdoor-large`: longer distance coverage for open scenes.
51393
52548
  */ applyQualityPreset(preset) {
51394
52549
  if (preset === 'character-small') {
51395
- this.mode = 'pcf-opt';
52550
+ this.mode = 'pcf';
51396
52551
  this.shadowMapSize = 2048;
51397
52552
  this.shadowDistance = 120;
51398
52553
  this.splitLambda = 0.75;
@@ -51403,7 +52558,7 @@ const tmpFrustum = new Frustum(Matrix4x4.identity());
51403
52558
  this.numShadowCascades = this._light.isDirectionLight() ? 3 : 1;
51404
52559
  return;
51405
52560
  }
51406
- this.mode = 'pcf-opt';
52561
+ this.mode = 'pcf';
51407
52562
  this.shadowMapSize = 2048;
51408
52563
  this.shadowDistance = 800;
51409
52564
  this.splitLambda = 0.6;
@@ -51452,6 +52607,71 @@ const tmpFrustum = new Frustum(Matrix4x4.identity());
51452
52607
  }
51453
52608
  }
51454
52609
  }
52610
+ /** Light radius for PCSS shadow, measured in shadow-map texels */ get pcssLightRadius() {
52611
+ return this._pcssLightRadius;
52612
+ }
52613
+ set pcssLightRadius(val) {
52614
+ val = Math.max(0, Number(val) || 0);
52615
+ if (val !== this._pcssLightRadius) {
52616
+ this._pcssLightRadius = val;
52617
+ const pcss = this.asPCSS();
52618
+ if (pcss) {
52619
+ pcss.lightRadius = this._pcssLightRadius;
52620
+ }
52621
+ }
52622
+ }
52623
+ /** Blocker search sample count for PCSS shadow */ get pcssBlockerSampleCount() {
52624
+ return this._pcssBlockerSampleCount;
52625
+ }
52626
+ set pcssBlockerSampleCount(val) {
52627
+ val = Math.min(Math.max(1, Number(val) >> 0), 64);
52628
+ if (val !== this._pcssBlockerSampleCount) {
52629
+ this._pcssBlockerSampleCount = val;
52630
+ const pcss = this.asPCSS();
52631
+ if (pcss) {
52632
+ pcss.blockerSampleCount = this._pcssBlockerSampleCount;
52633
+ }
52634
+ }
52635
+ }
52636
+ /** Filter sample count for PCSS shadow */ get pcssFilterSampleCount() {
52637
+ return this._pcssFilterSampleCount;
52638
+ }
52639
+ set pcssFilterSampleCount(val) {
52640
+ val = Math.min(Math.max(1, Number(val) >> 0), 64);
52641
+ if (val !== this._pcssFilterSampleCount) {
52642
+ this._pcssFilterSampleCount = val;
52643
+ const pcss = this.asPCSS();
52644
+ if (pcss) {
52645
+ pcss.filterSampleCount = this._pcssFilterSampleCount;
52646
+ }
52647
+ }
52648
+ }
52649
+ /** Maximum PCSS filter radius, measured in shadow-map texels */ get pcssMaxFilterRadius() {
52650
+ return this._pcssMaxFilterRadius;
52651
+ }
52652
+ set pcssMaxFilterRadius(val) {
52653
+ val = Math.max(1, Number(val) || 1);
52654
+ if (val !== this._pcssMaxFilterRadius) {
52655
+ this._pcssMaxFilterRadius = val;
52656
+ const pcss = this.asPCSS();
52657
+ if (pcss) {
52658
+ pcss.maxFilterRadius = this._pcssMaxFilterRadius;
52659
+ }
52660
+ }
52661
+ }
52662
+ /** If true, rotates PCSS sampling pattern over frames for TAA accumulation */ get pcssTemporalJitter() {
52663
+ return this._pcssTemporalJitter;
52664
+ }
52665
+ set pcssTemporalJitter(val) {
52666
+ val = !!val;
52667
+ if (val !== this._pcssTemporalJitter) {
52668
+ this._pcssTemporalJitter = val;
52669
+ const pcss = this.asPCSS();
52670
+ if (pcss) {
52671
+ pcss.temporalJitter = this._pcssTemporalJitter;
52672
+ }
52673
+ }
52674
+ }
51455
52675
  /** Kernel size of VSM */ get vsmBlurKernelSize() {
51456
52676
  return this._vsmBlurKernelSize;
51457
52677
  }
@@ -51639,28 +52859,28 @@ const tmpFrustum = new Frustum(Matrix4x4.identity());
51639
52859
  const useTextureArray = numCascades > 1 && device.type !== 'webgl';
51640
52860
  const shadowMapWidth = numCascades > 1 && !useTextureArray ? 2 * this._config.shadowMapSize : this._config.shadowMapSize;
51641
52861
  const shadowMapHeight = numCascades > 2 && !useTextureArray ? 2 * this._config.shadowMapSize : this._config.shadowMapSize;
51642
- /*
51643
- const colorAttachments = colorFormat
51644
- ? useTextureArray
51645
- ? [device.pool.fetchTemporalTexture2DArray(false, colorFormat, shadowMapWidth, shadowMapHeight, numCascades, false)]
51646
- : this._light.isPointLight()
51647
- ? [device.pool.fetchTemporalTextureCube(false, colorFormat, shadowMapWidth, false)]
51648
- : [device.pool.fetchTemporalTexture2D(false, colorFormat, shadowMapWidth, shadowMapHeight, false)]
51649
- : null;
51650
- const depthAttachment = depthFormat
51651
- ? useTextureArray
51652
- ? device.pool.fetchTemporalTexture2DArray(false, depthFormat, shadowMapWidth, shadowMapHeight, numCascades, false)
51653
- : device.type !== 'webgl' && this._light.isPointLight()
51654
- ? device.pool.fetchTemporalTextureCube(false, depthFormat, shadowMapWidth, false)
51655
- : device.pool.fetchTemporalTexture2D(false, depthFormat, shadowMapWidth, shadowMapHeight, false)
51656
- : null;
51657
- shadowMapParams.shadowMapFramebuffer = device.pool.createTemporalFramebuffer(false, colorAttachments, depthAttachment);
51658
- if (colorAttachments) {
51659
- device.pool.releaseTexture(colorAttachments[0]);
51660
- }
51661
- if (depthAttachment) {
51662
- device.pool.releaseTexture(depthAttachment);
51663
- }
52862
+ /*
52863
+ const colorAttachments = colorFormat
52864
+ ? useTextureArray
52865
+ ? [device.pool.fetchTemporalTexture2DArray(false, colorFormat, shadowMapWidth, shadowMapHeight, numCascades, false)]
52866
+ : this._light.isPointLight()
52867
+ ? [device.pool.fetchTemporalTextureCube(false, colorFormat, shadowMapWidth, false)]
52868
+ : [device.pool.fetchTemporalTexture2D(false, colorFormat, shadowMapWidth, shadowMapHeight, false)]
52869
+ : null;
52870
+ const depthAttachment = depthFormat
52871
+ ? useTextureArray
52872
+ ? device.pool.fetchTemporalTexture2DArray(false, depthFormat, shadowMapWidth, shadowMapHeight, numCascades, false)
52873
+ : device.type !== 'webgl' && this._light.isPointLight()
52874
+ ? device.pool.fetchTemporalTextureCube(false, depthFormat, shadowMapWidth, false)
52875
+ : device.pool.fetchTemporalTexture2D(false, depthFormat, shadowMapWidth, shadowMapHeight, false)
52876
+ : null;
52877
+ shadowMapParams.shadowMapFramebuffer = device.pool.createTemporalFramebuffer(false, colorAttachments, depthAttachment);
52878
+ if (colorAttachments) {
52879
+ device.pool.releaseTexture(colorAttachments[0]);
52880
+ }
52881
+ if (depthAttachment) {
52882
+ device.pool.releaseTexture(depthAttachment);
52883
+ }
51664
52884
  */ shadowMapParams.shadowMapFramebuffer = ShadowMapper.fetchTemporalFramebuffer(true, this._light.lightType, numCascades, shadowMapWidth, shadowMapHeight, colorFormat, depthFormat);
51665
52885
  shadowMapParams.impl = this._impl;
51666
52886
  this._impl.updateResources(shadowMapParams);
@@ -51671,14 +52891,14 @@ const tmpFrustum = new Frustum(Matrix4x4.identity());
51671
52891
  lightCamera.position.setXYZ(0, 0, 0);
51672
52892
  lightCamera.rotation.identity();
51673
52893
  lightCamera.scale.setXYZ(1, 1, 1);
51674
- lightCamera.setPerspective(Math.PI / 2, 1, this._config.nearClip, Math.min(this._shadowDistance, this._light.range));
52894
+ lightCamera.setPerspective(Math.PI / 2, 1, this._config.nearClip, Math.min(this._shadowDistance, this._light.positionAndRange.w));
51675
52895
  lightCamera.position.set(this._light.positionAndRange.xyz());
51676
52896
  }
51677
52897
  /** @internal */ createLightCameraSpot(lightCamera) {
51678
52898
  this._light.worldMatrix.decompose(null, lightCamera.rotation, lightCamera.position);
51679
52899
  lightCamera.parent = this._light.scene?.rootNode ?? null;
51680
52900
  lightCamera.scale.setXYZ(1, 1, 1);
51681
- lightCamera.setPerspective(2 * Math.acos(this._light.cutoff), 1, this._config.nearClip, Math.min(this._shadowDistance, this._light.range));
52901
+ lightCamera.setPerspective(2 * Math.acos(this._light.cutoff), 1, this._config.nearClip, Math.min(this._shadowDistance, this._light.positionAndRange.w));
51682
52902
  }
51683
52903
  /** @internal */ createLightCameraRect(lightCamera) {
51684
52904
  const rect = this._light;
@@ -51738,68 +52958,68 @@ const tmpFrustum = new Frustum(Matrix4x4.identity());
51738
52958
  center.setXYZ((rx - tx) * 2 / this.shadowMapSize, (ry - ty) * 2 / this.shadowMapSize, 0);
51739
52959
  cropMatrix.translation(center);
51740
52960
  }
51741
- /*
51742
- const minx = frustumMin.x;
51743
- const maxx = frustumMax.x;
51744
- const miny = frustumMin.y;
51745
- const maxy = frustumMax.y;
51746
- const minz = frustumMin.z;
51747
- const maxz = frustumMax.z;
51748
- const texelSizeW = (maxx - minx) / this.shadowMapSize;
51749
- const texelSizeH = (maxy - miny) / this.shadowMapSize;
51750
- const cx = Math.floor((minx + maxx) / 2 / texelSizeW) * texelSizeW;
51751
- const cy = Math.floor((miny + maxy) / 2 / texelSizeH) * texelSizeH;
51752
- const cz = (minz + maxz) / 2;
51753
- const hx = Math.floor(((maxx - minx) * (expand + 0.5)) / texelSizeW) * texelSizeW;
51754
- const hy = Math.floor(((maxy - miny) * (expand + 0.5)) / texelSizeH) * texelSizeH;
51755
- lightCamera.position.setXYZ(cx, cy, cz);
51756
- lightCamera.setOrtho(
51757
- -hx,
51758
- hx,
51759
- -hy,
51760
- hy,
51761
- sceneMax.z - maxz,
51762
- sceneMax.z - minz + 1
51763
- );
51764
- if (cropMatrix) {
51765
- // compute crop matrix
51766
- let clipMaxX = 0,
51767
- clipMaxY = 0;
51768
- let clipMinX = Number.MAX_VALUE,
51769
- clipMinY = Number.MAX_VALUE;
51770
- frustum.corners.forEach((p) => {
51771
- const clipPos = lightCamera.viewProjectionMatrix.transformPoint(p);
51772
- clipPos.x = Math.min(1, Math.max(-1, clipPos.x / clipPos.w));
51773
- clipPos.y = Math.min(1, Math.max(-1, clipPos.y / clipPos.w));
51774
- if (clipPos.x > clipMaxX) {
51775
- clipMaxX = clipPos.x;
51776
- }
51777
- if (clipPos.x < clipMinX) {
51778
- clipMinX = clipPos.x;
51779
- }
51780
- if (clipPos.y > clipMaxY) {
51781
- clipMaxY = clipPos.y;
51782
- }
51783
- if (clipPos.y < clipMinY) {
51784
- clipMinY = clipPos.y;
51785
- }
51786
- });
51787
- const clipW = clipMaxX - clipMinX;
51788
- const clipH = clipMaxY - clipMinY;
51789
- clipMinX -= expand * clipW;
51790
- clipMinY -= expand * clipH;
51791
- clipMaxX += expand * clipW;
51792
- clipMaxY += expand * clipH;
51793
- const scaleX = 2 / (clipMaxX - clipMinX);
51794
- const scaleY = 2 / (clipMaxY - clipMinY);
51795
- const offsetX = -0.5 * (clipMaxX + clipMinX) * scaleX;
51796
- const offsetY = -0.5 * (clipMaxY + clipMinY) * scaleY;
51797
- cropMatrix.identity();
51798
- cropMatrix.m00 = scaleX;
51799
- cropMatrix.m11 = scaleY;
51800
- cropMatrix.m03 = offsetX;
51801
- cropMatrix.m13 = offsetY;
51802
- }
52961
+ /*
52962
+ const minx = frustumMin.x;
52963
+ const maxx = frustumMax.x;
52964
+ const miny = frustumMin.y;
52965
+ const maxy = frustumMax.y;
52966
+ const minz = frustumMin.z;
52967
+ const maxz = frustumMax.z;
52968
+ const texelSizeW = (maxx - minx) / this.shadowMapSize;
52969
+ const texelSizeH = (maxy - miny) / this.shadowMapSize;
52970
+ const cx = Math.floor((minx + maxx) / 2 / texelSizeW) * texelSizeW;
52971
+ const cy = Math.floor((miny + maxy) / 2 / texelSizeH) * texelSizeH;
52972
+ const cz = (minz + maxz) / 2;
52973
+ const hx = Math.floor(((maxx - minx) * (expand + 0.5)) / texelSizeW) * texelSizeW;
52974
+ const hy = Math.floor(((maxy - miny) * (expand + 0.5)) / texelSizeH) * texelSizeH;
52975
+ lightCamera.position.setXYZ(cx, cy, cz);
52976
+ lightCamera.setOrtho(
52977
+ -hx,
52978
+ hx,
52979
+ -hy,
52980
+ hy,
52981
+ sceneMax.z - maxz,
52982
+ sceneMax.z - minz + 1
52983
+ );
52984
+ if (cropMatrix) {
52985
+ // compute crop matrix
52986
+ let clipMaxX = 0,
52987
+ clipMaxY = 0;
52988
+ let clipMinX = Number.MAX_VALUE,
52989
+ clipMinY = Number.MAX_VALUE;
52990
+ frustum.corners.forEach((p) => {
52991
+ const clipPos = lightCamera.viewProjectionMatrix.transformPoint(p);
52992
+ clipPos.x = Math.min(1, Math.max(-1, clipPos.x / clipPos.w));
52993
+ clipPos.y = Math.min(1, Math.max(-1, clipPos.y / clipPos.w));
52994
+ if (clipPos.x > clipMaxX) {
52995
+ clipMaxX = clipPos.x;
52996
+ }
52997
+ if (clipPos.x < clipMinX) {
52998
+ clipMinX = clipPos.x;
52999
+ }
53000
+ if (clipPos.y > clipMaxY) {
53001
+ clipMaxY = clipPos.y;
53002
+ }
53003
+ if (clipPos.y < clipMinY) {
53004
+ clipMinY = clipPos.y;
53005
+ }
53006
+ });
53007
+ const clipW = clipMaxX - clipMinX;
53008
+ const clipH = clipMaxY - clipMinY;
53009
+ clipMinX -= expand * clipW;
53010
+ clipMinY -= expand * clipH;
53011
+ clipMaxX += expand * clipW;
53012
+ clipMaxY += expand * clipH;
53013
+ const scaleX = 2 / (clipMaxX - clipMinX);
53014
+ const scaleY = 2 / (clipMaxY - clipMinY);
53015
+ const offsetX = -0.5 * (clipMaxX + clipMinX) * scaleX;
53016
+ const offsetY = -0.5 * (clipMaxY + clipMinY) * scaleY;
53017
+ cropMatrix.identity();
53018
+ cropMatrix.m00 = scaleX;
53019
+ cropMatrix.m11 = scaleY;
53020
+ cropMatrix.m03 = offsetX;
53021
+ cropMatrix.m13 = offsetY;
53022
+ }
51803
53023
  */ }
51804
53024
  /** {@inheritDoc Disposable.onDispose} */ onDispose() {
51805
53025
  this._shadowRegion.dispose();
@@ -52007,7 +53227,7 @@ const tmpFrustum = new Frustum(Matrix4x4.identity());
52007
53227
  this.postRenderShadowMap(shadowMapParams);
52008
53228
  }
52009
53229
  /** @internal */ applyMode(mode) {
52010
- if (mode !== 'hard' && mode !== 'vsm' && mode !== 'esm' && mode !== 'pcf-pd' && mode !== 'pcf-opt') {
53230
+ if (mode !== 'hard' && mode !== 'vsm' && mode !== 'esm' && mode !== 'pcf' && mode !== 'pcf-pd' && mode !== 'pcf-opt' && mode !== 'pcss') {
52011
53231
  console.error(`ShadowMapper.setShadowMode() failed: invalid mode: ${mode}`);
52012
53232
  return;
52013
53233
  }
@@ -52021,10 +53241,10 @@ const tmpFrustum = new Frustum(Matrix4x4.identity());
52021
53241
  const esm = this._impl;
52022
53242
  esm.blur = this._esmBlur;
52023
53243
  esm.logSpace = this._esmLogSpace;
52024
- } else if (mode === 'pcf-pd') {
52025
- this._impl = new PCFPD(this._pdSampleCount, this._pdSampleRadius);
52026
- } else if (mode === 'pcf-opt') {
53244
+ } else if (mode === 'pcf' || mode === 'pcf-opt' || mode === 'pcf-pd') {
52027
53245
  this._impl = new PCFOPT(this._pcfKernelSize);
53246
+ } else if (mode === 'pcss') {
53247
+ this._impl = new PCSS(this._pcssLightRadius, this._pcssBlockerSampleCount, this._pcssFilterSampleCount, this._pcssMaxFilterRadius, this._pcssTemporalJitter);
52028
53248
  }
52029
53249
  }
52030
53250
  /** @internal */ asVSM() {
@@ -52039,6 +53259,9 @@ const tmpFrustum = new Frustum(Matrix4x4.identity());
52039
53259
  /** @internal */ asPCFOPT() {
52040
53260
  return this._impl?.getType() === 'pcf-opt' ? this._impl : null;
52041
53261
  }
53262
+ /** @internal */ asPCSS() {
53263
+ return this._impl?.getType() === 'pcss' ? this._impl : null;
53264
+ }
52042
53265
  }
52043
53266
 
52044
53267
  let _drawableId = 0;
@@ -57694,6 +58917,127 @@ class HeightBoundingGenerator extends RenderMipmap {
57694
58917
  return this.SSS;
57695
58918
  }
57696
58919
  },
58920
+ {
58921
+ name: 'SkinSSSEnabled',
58922
+ type: 'bool',
58923
+ phase: 0,
58924
+ default: false,
58925
+ options: {
58926
+ label: 'Enabled',
58927
+ group: 'PostProcessing/SkinSSS'
58928
+ },
58929
+ get (value) {
58930
+ value.bool[0] = this.skinSSS;
58931
+ },
58932
+ set (value) {
58933
+ this.skinSSS = value.bool[0];
58934
+ }
58935
+ },
58936
+ {
58937
+ name: 'SkinSSSStrength',
58938
+ type: 'float',
58939
+ phase: 0,
58940
+ default: 1,
58941
+ options: {
58942
+ label: 'Strength',
58943
+ group: 'PostProcessing/SkinSSS',
58944
+ minValue: 0,
58945
+ maxValue: 4
58946
+ },
58947
+ get (value) {
58948
+ value.num[0] = this.skinSSSStrength;
58949
+ },
58950
+ set (value) {
58951
+ this.skinSSSStrength = value.num[0];
58952
+ },
58953
+ isValid () {
58954
+ return this.skinSSS;
58955
+ }
58956
+ },
58957
+ {
58958
+ name: 'SkinSSSOpacity',
58959
+ type: 'float',
58960
+ phase: 0,
58961
+ default: 0.18,
58962
+ options: {
58963
+ label: 'Opacity',
58964
+ group: 'PostProcessing/SkinSSS',
58965
+ minValue: 0,
58966
+ maxValue: 1
58967
+ },
58968
+ get (value) {
58969
+ value.num[0] = this.skinSSSOpacity;
58970
+ },
58971
+ set (value) {
58972
+ this.skinSSSOpacity = value.num[0];
58973
+ },
58974
+ isValid () {
58975
+ return this.skinSSS;
58976
+ }
58977
+ },
58978
+ {
58979
+ name: 'SkinSSSSampleStep',
58980
+ type: 'float',
58981
+ phase: 0,
58982
+ default: 2,
58983
+ options: {
58984
+ label: 'SampleStep',
58985
+ group: 'PostProcessing/SkinSSS',
58986
+ minValue: 0.25,
58987
+ maxValue: 8
58988
+ },
58989
+ get (value) {
58990
+ value.num[0] = this.skinSSSSampleStep;
58991
+ },
58992
+ set (value) {
58993
+ this.skinSSSSampleStep = value.num[0];
58994
+ },
58995
+ isValid () {
58996
+ return this.skinSSS;
58997
+ }
58998
+ },
58999
+ {
59000
+ name: 'SkinSSSDepthScale',
59001
+ type: 'float',
59002
+ phase: 0,
59003
+ default: 80,
59004
+ options: {
59005
+ label: 'DepthScale',
59006
+ group: 'PostProcessing/SkinSSS',
59007
+ minValue: 0,
59008
+ maxValue: 256
59009
+ },
59010
+ get (value) {
59011
+ value.num[0] = this.skinSSSDepthScale;
59012
+ },
59013
+ set (value) {
59014
+ this.skinSSSDepthScale = value.num[0];
59015
+ },
59016
+ isValid () {
59017
+ return this.skinSSS;
59018
+ }
59019
+ },
59020
+ {
59021
+ name: 'SkinSSSColorBoost',
59022
+ type: 'float',
59023
+ phase: 0,
59024
+ default: 1,
59025
+ options: {
59026
+ label: 'ColorBoost',
59027
+ group: 'PostProcessing/SkinSSS',
59028
+ minValue: 0,
59029
+ maxValue: 4
59030
+ },
59031
+ get (value) {
59032
+ value.num[0] = this.skinSSSColorBoost;
59033
+ },
59034
+ set (value) {
59035
+ this.skinSSSColorBoost = value.num[0];
59036
+ },
59037
+ isValid () {
59038
+ return this.skinSSS;
59039
+ }
59040
+ },
57697
59041
  {
57698
59042
  name: 'SSAOEnabled',
57699
59043
  type: 'bool',
@@ -57929,9 +59273,9 @@ class HeightBoundingGenerator extends RenderMipmap {
57929
59273
  };
57930
59274
  }
57931
59275
 
57932
- /**
57933
- * Base class for any kind of light node
57934
- * @public
59276
+ /**
59277
+ * Base class for any kind of light node
59278
+ * @public
57935
59279
  */ class BaseLight extends GraphNode {
57936
59280
  /** @internal */ _type;
57937
59281
  /** @internal */ _intensity;
@@ -57939,10 +59283,10 @@ class HeightBoundingGenerator extends RenderMipmap {
57939
59283
  /** @internal */ _directionCutoff;
57940
59284
  /** @internal */ _diffuseIntensity;
57941
59285
  /** @internal */ _extraParams;
57942
- /**
57943
- * Creates a light node
57944
- * @param scene - The scene to which the light node belongs
57945
- * @param type - Type of the light node
59286
+ /**
59287
+ * Creates a light node
59288
+ * @param scene - The scene to which the light node belongs
59289
+ * @param type - Type of the light node
57946
59290
  */ constructor(scene, type){
57947
59291
  super(scene);
57948
59292
  this._intensity = 1;
@@ -57961,66 +59305,66 @@ class HeightBoundingGenerator extends RenderMipmap {
57961
59305
  set intensity(val) {
57962
59306
  this.setIntensity(val);
57963
59307
  }
57964
- /**
57965
- * Position and range of the light
57966
- *
57967
- * @remarks
57968
- * Gets the position in world space of the light.
57969
- * Light range is encoded into the W component.
59308
+ /**
59309
+ * Position and range of the light
59310
+ *
59311
+ * @remarks
59312
+ * Gets the position in world space of the light.
59313
+ * Light range is encoded into the W component.
57970
59314
  */ get positionAndRange() {
57971
59315
  if (!this._positionRange) {
57972
59316
  this.computeUniforms();
57973
59317
  }
57974
59318
  return this._positionRange;
57975
59319
  }
57976
- /**
57977
- * Direction and cutoff of the light
57978
- *
57979
- * @remarks
57980
- * Gets the direction in world space of the light
57981
- * Light cutoff (for spot light only) is encoded into the W component.
59320
+ /**
59321
+ * Direction and cutoff of the light
59322
+ *
59323
+ * @remarks
59324
+ * Gets the direction in world space of the light
59325
+ * Light cutoff (for spot light only) is encoded into the W component.
57982
59326
  */ get directionAndCutoff() {
57983
59327
  if (!this._directionCutoff) {
57984
59328
  this.computeUniforms();
57985
59329
  }
57986
59330
  return this._directionCutoff;
57987
59331
  }
57988
- /**
57989
- * Color and intensity of the light
57990
- *
57991
- * @remarks
57992
- * Gets the color of the light.
57993
- * Light intensity is encoded into the W component.
59332
+ /**
59333
+ * Color and intensity of the light
59334
+ *
59335
+ * @remarks
59336
+ * Gets the color of the light.
59337
+ * Light intensity is encoded into the W component.
57994
59338
  */ get diffuseAndIntensity() {
57995
59339
  if (!this._diffuseIntensity) {
57996
59340
  this.computeUniforms();
57997
59341
  }
57998
59342
  return this._diffuseIntensity;
57999
59343
  }
58000
- /**
58001
- * Extra parameters of the light
58002
- *
58003
- * @remarks
58004
- * Custom data for advanced light types.
59344
+ /**
59345
+ * Extra parameters of the light
59346
+ *
59347
+ * @remarks
59348
+ * Custom data for advanced light types.
58005
59349
  */ get extraParams() {
58006
59350
  if (!this._extraParams) {
58007
59351
  this.computeUniforms();
58008
59352
  }
58009
59353
  return this._extraParams;
58010
59354
  }
58011
- /**
58012
- * View matrix of the light
58013
- *
58014
- * @remarks
58015
- * The view matrix of the light is used to transform a point
58016
- * from the world space to the light space.
59355
+ /**
59356
+ * View matrix of the light
59357
+ *
59358
+ * @remarks
59359
+ * The view matrix of the light is used to transform a point
59360
+ * from the world space to the light space.
58017
59361
  */ get viewMatrix() {
58018
59362
  return this.invWorldMatrix;
58019
59363
  }
58020
- /**
58021
- * Sets the intensity of the light
58022
- * @param val - Intensity of the light
58023
- * @returns self
59364
+ /**
59365
+ * Sets the intensity of the light
59366
+ * @param val - Intensity of the light
59367
+ * @returns self
58024
59368
  */ setIntensity(val) {
58025
59369
  if (this._intensity !== val) {
58026
59370
  this._intensity = val;
@@ -58053,26 +59397,26 @@ class HeightBoundingGenerator extends RenderMipmap {
58053
59397
  return false;
58054
59398
  }
58055
59399
  }
58056
- /*
58057
- export abstract class AmbientLight extends BaseLight {
58058
- constructor(scene: Scene, type: number) {
58059
- super(scene, type);
58060
- }
58061
- isAmbientLight(): this is AmbientLight {
58062
- return true;
58063
- }
58064
- }
58065
- */ /**
58066
- * Base class for any kind of puncual light
58067
- * @public
59400
+ /*
59401
+ export abstract class AmbientLight extends BaseLight {
59402
+ constructor(scene: Scene, type: number) {
59403
+ super(scene, type);
59404
+ }
59405
+ isAmbientLight(): this is AmbientLight {
59406
+ return true;
59407
+ }
59408
+ }
59409
+ */ /**
59410
+ * Base class for any kind of puncual light
59411
+ * @public
58068
59412
  */ class PunctualLight extends BaseLight {
58069
59413
  /** @internal */ _color;
58070
59414
  /** @internal */ _castShadow;
58071
59415
  /** @internal */ _shadowMapper;
58072
- /**
58073
- * Creates an instance of punctual light
58074
- * @param scene - The scene to which the punctual light belongs
58075
- * @param type - The light type
59416
+ /**
59417
+ * Creates an instance of punctual light
59418
+ * @param scene - The scene to which the punctual light belongs
59419
+ * @param type - The light type
58076
59420
  */ constructor(scene, type){
58077
59421
  super(scene, type);
58078
59422
  this.ensurePunctualState();
@@ -58095,10 +59439,10 @@ export abstract class AmbientLight extends BaseLight {
58095
59439
  set color(color) {
58096
59440
  this.setColor(color);
58097
59441
  }
58098
- /**
58099
- * Sets color of the light
58100
- * @param color - The color to set
58101
- * @returns self
59442
+ /**
59443
+ * Sets color of the light
59444
+ * @param color - The color to set
59445
+ * @returns self
58102
59446
  */ setColor(color) {
58103
59447
  this.ensurePunctualState();
58104
59448
  this._color.set(color);
@@ -58112,10 +59456,10 @@ export abstract class AmbientLight extends BaseLight {
58112
59456
  set castShadow(b) {
58113
59457
  this.setCastShadow(b);
58114
59458
  }
58115
- /**
58116
- * Sets whether this light casts shadows
58117
- * @param b - true if the light casts shadows
58118
- * @returns self
59459
+ /**
59460
+ * Sets whether this light casts shadows
59461
+ * @param b - true if the light casts shadows
59462
+ * @returns self
58119
59463
  */ setCastShadow(b) {
58120
59464
  this.ensurePunctualState();
58121
59465
  if (this._castShadow !== !!b) {
@@ -58130,9 +59474,9 @@ export abstract class AmbientLight extends BaseLight {
58130
59474
  this.ensurePunctualState();
58131
59475
  return this._shadowMapper;
58132
59476
  }
58133
- /**
58134
- * {@inheritDoc BaseLight.isPunctualLight}
58135
- * @override
59477
+ /**
59478
+ * {@inheritDoc BaseLight.isPunctualLight}
59479
+ * @override
58136
59480
  */ isPunctualLight() {
58137
59481
  return true;
58138
59482
  }
@@ -58147,14 +59491,14 @@ export abstract class AmbientLight extends BaseLight {
58147
59491
  }
58148
59492
  /** @internal */ computeUniforms() {}
58149
59493
  }
58150
- /**
58151
- * Directional light
58152
- * @public
59494
+ /**
59495
+ * Directional light
59496
+ * @public
58153
59497
  */ class DirectionalLight extends PunctualLight {
58154
59498
  static _currentSunLight = new WeakMap();
58155
- /**
58156
- * Creates an instance of directional light
58157
- * @param scene - The scene to which the light belongs
59499
+ /**
59500
+ * Creates an instance of directional light
59501
+ * @param scene - The scene to which the light belongs
58158
59502
  */ constructor(scene){
58159
59503
  super(scene, LIGHT_TYPE_DIRECTIONAL);
58160
59504
  this.intensity = 10;
@@ -58176,11 +59520,11 @@ export abstract class AmbientLight extends BaseLight {
58176
59520
  ref.set(light);
58177
59521
  }
58178
59522
  }
58179
- /**
58180
- * true if the light was defined as sun light
58181
- *
58182
- * @remarks
58183
- * Only one directional light will be marked as sun light.
59523
+ /**
59524
+ * true if the light was defined as sun light
59525
+ *
59526
+ * @remarks
59527
+ * Only one directional light will be marked as sun light.
58184
59528
  **/ get sunLight() {
58185
59529
  return DirectionalLight.getSunLight(this.scene) === this;
58186
59530
  }
@@ -58191,9 +59535,9 @@ export abstract class AmbientLight extends BaseLight {
58191
59535
  DirectionalLight.setSunLight(this.scene, null);
58192
59536
  }
58193
59537
  }
58194
- /**
58195
- * {@inheritDoc BaseLight.isDirectionLight}
58196
- * @override
59538
+ /**
59539
+ * {@inheritDoc BaseLight.isDirectionLight}
59540
+ * @override
58197
59541
  */ isDirectionLight() {
58198
59542
  return true;
58199
59543
  }
@@ -58209,20 +59553,20 @@ export abstract class AmbientLight extends BaseLight {
58209
59553
  this._extraParams = new Vector4(0, 0, 0, this.lightType);
58210
59554
  }
58211
59555
  }
58212
- /**
58213
- * Point light
58214
- * @public
59556
+ /**
59557
+ * Point light
59558
+ * @public
58215
59559
  */ class PointLight extends PunctualLight {
58216
59560
  /** @internal */ _range;
58217
59561
  /** @internal */ _diffuseScale;
58218
59562
  /** @internal */ _specularScale;
58219
59563
  /** @internal */ _sourceRadius;
58220
- /**
58221
- * Creates an instance of point light
58222
- * @param scene - The scene to which the light belongs
59564
+ /**
59565
+ * Creates an instance of point light
59566
+ * @param scene - The scene to which the light belongs
58223
59567
  */ constructor(scene){
58224
59568
  super(scene, LIGHT_TYPE_POINT);
58225
- this._range = 10;
59569
+ this._range = 0;
58226
59570
  this._diffuseScale = 1;
58227
59571
  this._specularScale = 1;
58228
59572
  this._sourceRadius = 0;
@@ -58252,10 +59596,10 @@ export abstract class AmbientLight extends BaseLight {
58252
59596
  set sourceRadius(val) {
58253
59597
  this.setSourceRadius(val);
58254
59598
  }
58255
- /**
58256
- * Sets the range of the light
58257
- * @param val - The value to set
58258
- * @returns self
59599
+ /**
59600
+ * Sets the range of the light
59601
+ * @param val - The value to set
59602
+ * @returns self
58259
59603
  */ setRange(val) {
58260
59604
  val = val < 0 ? 0 : val;
58261
59605
  if (this._range !== val) {
@@ -58265,10 +59609,10 @@ export abstract class AmbientLight extends BaseLight {
58265
59609
  }
58266
59610
  return this;
58267
59611
  }
58268
- /**
58269
- * Sets the diffuse scale of the light
58270
- * @param val - The value to set
58271
- * @returns self
59612
+ /**
59613
+ * Sets the diffuse scale of the light
59614
+ * @param val - The value to set
59615
+ * @returns self
58272
59616
  */ setDiffuseScale(val) {
58273
59617
  val = val < 0 ? 0 : val;
58274
59618
  if (this._diffuseScale !== val) {
@@ -58277,10 +59621,10 @@ export abstract class AmbientLight extends BaseLight {
58277
59621
  }
58278
59622
  return this;
58279
59623
  }
58280
- /**
58281
- * Sets the specular scale of the light
58282
- * @param val - The value to set
58283
- * @returns self
59624
+ /**
59625
+ * Sets the specular scale of the light
59626
+ * @param val - The value to set
59627
+ * @returns self
58284
59628
  */ setSpecularScale(val) {
58285
59629
  val = val < 0 ? 0 : val;
58286
59630
  if (this._specularScale !== val) {
@@ -58289,10 +59633,10 @@ export abstract class AmbientLight extends BaseLight {
58289
59633
  }
58290
59634
  return this;
58291
59635
  }
58292
- /**
58293
- * Sets the source radius of the light
58294
- * @param val - The value to set
58295
- * @returns self
59636
+ /**
59637
+ * Sets the source radius of the light
59638
+ * @param val - The value to set
59639
+ * @returns self
58296
59640
  */ setSourceRadius(val) {
58297
59641
  val = val < 0 ? 0 : val;
58298
59642
  if (this._sourceRadius !== val) {
@@ -58301,39 +59645,41 @@ export abstract class AmbientLight extends BaseLight {
58301
59645
  }
58302
59646
  return this;
58303
59647
  }
58304
- /**
58305
- * {@inheritDoc BaseLight.isPointLight}
58306
- * @override
59648
+ /**
59649
+ * {@inheritDoc BaseLight.isPointLight}
59650
+ * @override
58307
59651
  */ isPointLight() {
58308
59652
  return true;
58309
59653
  }
58310
59654
  /** @internal */ computeBoundingVolume() {
59655
+ const range = this.positionAndRange.w;
58311
59656
  const bbox = new BoundingBox();
58312
- bbox.minPoint = new Vector3(-this._range, -this._range, -this._range);
58313
- bbox.maxPoint = new Vector3(this._range, this._range, this._range);
59657
+ bbox.minPoint = new Vector3(-range, -range, -range);
59658
+ bbox.maxPoint = new Vector3(range, range, range);
58314
59659
  return bbox;
58315
59660
  }
58316
59661
  /** @internal */ computeUniforms() {
58317
59662
  const a = this.worldMatrix.getRow(3);
58318
59663
  const b = this.worldMatrix.getRow(2);
58319
- this._positionRange = new Vector4(a.x, a.y, a.z, this.range);
59664
+ const range = this.range <= 0 ? 32 * Math.sqrt(Math.max(0.0001, this.intensity * Math.max(this._diffuseScale, this._specularScale))) : this.range;
59665
+ this._positionRange = new Vector4(a.x, a.y, a.z, range);
58320
59666
  this._directionCutoff = new Vector4(b.x, b.y, b.z, -1);
58321
59667
  this._diffuseIntensity = new Vector4(this.color.x, this.color.y, this.color.z, this.intensity);
58322
59668
  this._extraParams = new Vector4(this._diffuseScale, this._specularScale, this._sourceRadius, this.lightType);
58323
59669
  }
58324
59670
  }
58325
- /**
58326
- * Spot light
58327
- * @public
59671
+ /**
59672
+ * Spot light
59673
+ * @public
58328
59674
  */ class SpotLight extends PunctualLight {
58329
59675
  /** @internal */ _range;
58330
59676
  /** @internal */ _cutoff;
58331
- /**
58332
- * Creates an instance of spot light
58333
- * @param scene - The scene to which the light belongs
59677
+ /**
59678
+ * Creates an instance of spot light
59679
+ * @param scene - The scene to which the light belongs
58334
59680
  */ constructor(scene){
58335
59681
  super(scene, LIGHT_TYPE_SPOT);
58336
- this._range = 10;
59682
+ this._range = 0;
58337
59683
  this._cutoff = Math.cos(Math.PI / 4);
58338
59684
  this.invalidateBoundingVolume();
58339
59685
  }
@@ -58343,10 +59689,10 @@ export abstract class AmbientLight extends BaseLight {
58343
59689
  set range(val) {
58344
59690
  this.setRange(val);
58345
59691
  }
58346
- /**
58347
- * Sets the range of the light
58348
- * @param val - The value to set
58349
- * @returns self
59692
+ /**
59693
+ * Sets the range of the light
59694
+ * @param val - The value to set
59695
+ * @returns self
58350
59696
  */ setRange(val) {
58351
59697
  val = val < 0 ? 0 : val;
58352
59698
  if (this._range !== val) {
@@ -58362,10 +59708,10 @@ export abstract class AmbientLight extends BaseLight {
58362
59708
  set cutoff(val) {
58363
59709
  this.setCutoff(val);
58364
59710
  }
58365
- /**
58366
- * Sets the cutoff of the light
58367
- * @param val - The value to set
58368
- * @returns self
59711
+ /**
59712
+ * Sets the cutoff of the light
59713
+ * @param val - The value to set
59714
+ * @returns self
58369
59715
  */ setCutoff(val) {
58370
59716
  val = val < 0 ? 0 : val;
58371
59717
  if (this._cutoff !== val) {
@@ -58375,39 +59721,41 @@ export abstract class AmbientLight extends BaseLight {
58375
59721
  }
58376
59722
  return this;
58377
59723
  }
58378
- /**
58379
- * {@inheritDoc BaseLight.isSpotLight}
58380
- * @override
59724
+ /**
59725
+ * {@inheritDoc BaseLight.isSpotLight}
59726
+ * @override
58381
59727
  */ isSpotLight() {
58382
59728
  return true;
58383
59729
  }
58384
59730
  /** @internal */ computeBoundingVolume() {
58385
59731
  const bbox = new BoundingBox();
58386
59732
  const cosCutoff = Math.cos(this._cutoff);
58387
- const r = this._range / cosCutoff * Math.sqrt(1 - cosCutoff * cosCutoff);
59733
+ const range = this.positionAndRange.w;
59734
+ const r = range / cosCutoff * Math.sqrt(1 - cosCutoff * cosCutoff);
58388
59735
  bbox.minPoint = new Vector3(-r, -r, 0);
58389
- bbox.maxPoint = new Vector3(r, r, this._range);
59736
+ bbox.maxPoint = new Vector3(r, r, range);
58390
59737
  return bbox;
58391
59738
  }
58392
59739
  /** @internal */ computeUniforms() {
58393
59740
  const a = this.worldMatrix.getRow(3);
58394
59741
  const b = this.worldMatrix.getRow(2).scaleBy(-1);
58395
- this._positionRange = new Vector4(a.x, a.y, a.z, this.range);
59742
+ const range = this.range <= 0 ? 32 * Math.sqrt(Math.max(0.0001, this.intensity)) : this.range;
59743
+ this._positionRange = new Vector4(a.x, a.y, a.z, range);
58396
59744
  this._directionCutoff = new Vector4(b.x, b.y, b.z, this.cutoff);
58397
59745
  this._diffuseIntensity = new Vector4(this.color.x, this.color.y, this.color.z, this.intensity);
58398
59746
  this._extraParams = new Vector4(0, 0, 0, this.lightType);
58399
59747
  }
58400
59748
  }
58401
- /**
58402
- * Rectangular area light
58403
- * @public
59749
+ /**
59750
+ * Rectangular area light
59751
+ * @public
58404
59752
  */ class RectLight extends PunctualLight {
58405
59753
  /** @internal */ _range;
58406
59754
  /** @internal */ _width;
58407
59755
  /** @internal */ _height;
58408
- /**
58409
- * Creates an instance of rect light
58410
- * @param scene - The scene to which the light belongs
59756
+ /**
59757
+ * Creates an instance of rect light
59758
+ * @param scene - The scene to which the light belongs
58411
59759
  */ constructor(scene){
58412
59760
  super(scene, LIGHT_TYPE_RECT);
58413
59761
  this._range = 10;
@@ -58421,10 +59769,10 @@ export abstract class AmbientLight extends BaseLight {
58421
59769
  set range(val) {
58422
59770
  this.setRange(val);
58423
59771
  }
58424
- /**
58425
- * Sets the range of the light
58426
- * @param val - The value to set
58427
- * @returns self
59772
+ /**
59773
+ * Sets the range of the light
59774
+ * @param val - The value to set
59775
+ * @returns self
58428
59776
  */ setRange(val) {
58429
59777
  val = val < 0 ? 0 : val;
58430
59778
  if (this._range !== val) {
@@ -58440,10 +59788,10 @@ export abstract class AmbientLight extends BaseLight {
58440
59788
  set width(val) {
58441
59789
  this.setWidth(val);
58442
59790
  }
58443
- /**
58444
- * Sets the width of the light
58445
- * @param val - The value to set
58446
- * @returns self
59791
+ /**
59792
+ * Sets the width of the light
59793
+ * @param val - The value to set
59794
+ * @returns self
58447
59795
  */ setWidth(val) {
58448
59796
  val = val < 0 ? 0 : val;
58449
59797
  if (this._width !== val) {
@@ -58459,10 +59807,10 @@ export abstract class AmbientLight extends BaseLight {
58459
59807
  set height(val) {
58460
59808
  this.setHeight(val);
58461
59809
  }
58462
- /**
58463
- * Sets the height of the light
58464
- * @param val - The value to set
58465
- * @returns self
59810
+ /**
59811
+ * Sets the height of the light
59812
+ * @param val - The value to set
59813
+ * @returns self
58466
59814
  */ setHeight(val) {
58467
59815
  val = val < 0 ? 0 : val;
58468
59816
  if (this._height !== val) {
@@ -58472,14 +59820,14 @@ export abstract class AmbientLight extends BaseLight {
58472
59820
  }
58473
59821
  return this;
58474
59822
  }
58475
- /**
58476
- * {@inheritDoc BaseLight.isRectLight}
58477
- * @override
59823
+ /**
59824
+ * {@inheritDoc BaseLight.isRectLight}
59825
+ * @override
58478
59826
  */ isRectLight() {
58479
59827
  return true;
58480
59828
  }
58481
- /**
58482
- * Rect light supports shadow in current pipeline
59829
+ /**
59830
+ * Rect light supports shadow in current pipeline
58483
59831
  */ /** @internal */ computeBoundingVolume() {
58484
59832
  const bbox = new BoundingBox();
58485
59833
  const r = this._range;
@@ -58567,16 +59915,20 @@ export abstract class AmbientLight extends BaseLight {
58567
59915
  labels: [
58568
59916
  'Hard',
58569
59917
  'PCF',
58570
- 'PCF-PD',
59918
+ 'PCSS',
58571
59919
  'VSM',
58572
- 'ESM'
59920
+ 'ESM',
59921
+ 'PCF-OPT (deprecated)',
59922
+ 'PCF-PD (deprecated)'
58573
59923
  ],
58574
59924
  values: [
58575
59925
  'hard',
58576
- 'pcf-opt',
58577
- 'pcf-pd',
59926
+ 'pcf',
59927
+ 'pcss',
58578
59928
  'vsm',
58579
- 'esm'
59929
+ 'esm',
59930
+ 'pcf-opt',
59931
+ 'pcf-pd'
58580
59932
  ]
58581
59933
  }
58582
59934
  },
@@ -58729,6 +60081,26 @@ export abstract class AmbientLight extends BaseLight {
58729
60081
  return !!this.castShadow;
58730
60082
  }
58731
60083
  },
60084
+ {
60085
+ name: 'ShadowNearClip',
60086
+ description: 'Near clip distance for shadow camera',
60087
+ type: 'float',
60088
+ phase: 1,
60089
+ default: 1,
60090
+ options: {
60091
+ minValue: 0.01,
60092
+ maxValue: 10
60093
+ },
60094
+ get (value) {
60095
+ value.num[0] = this.shadow.nearClip;
60096
+ },
60097
+ set (value) {
60098
+ this.shadow.nearClip = value.num[0];
60099
+ },
60100
+ isValid () {
60101
+ return !!this.castShadow && !this.isDirectionLight();
60102
+ }
60103
+ },
58732
60104
  {
58733
60105
  name: 'ShadowStrength',
58734
60106
  description: 'Shadow strength, 0 means disabled and 1 means full effect',
@@ -58796,47 +60168,103 @@ export abstract class AmbientLight extends BaseLight {
58796
60168
  this.shadow.pcfKernelSize = value.num[0];
58797
60169
  },
58798
60170
  isValid () {
58799
- return !!this.castShadow && this.shadow.mode === 'pcf-opt';
60171
+ return !!this.castShadow && (this.shadow.mode === 'pcf' || this.shadow.mode === 'pcf-opt');
58800
60172
  }
58801
60173
  },
58802
60174
  {
58803
- name: 'PCFSampleCount',
58804
- description: 'Sample count for PCF shadow',
60175
+ name: 'PCSSLightRadius',
60176
+ description: 'Light radius for PCSS shadow',
60177
+ type: 'float',
60178
+ phase: 2,
60179
+ options: {
60180
+ minValue: 0,
60181
+ maxValue: 64
60182
+ },
60183
+ default: 8,
60184
+ get (value) {
60185
+ value.num[0] = this.shadow.pcssLightRadius;
60186
+ },
60187
+ set (value) {
60188
+ this.shadow.pcssLightRadius = value.num[0];
60189
+ },
60190
+ isValid () {
60191
+ return !!this.castShadow && this.shadow.mode === 'pcss';
60192
+ }
60193
+ },
60194
+ {
60195
+ name: 'PCSSBlockerSampleCount',
60196
+ description: 'Blocker search sample count for PCSS shadow',
58805
60197
  type: 'int',
58806
60198
  phase: 2,
58807
60199
  options: {
58808
60200
  minValue: 1,
58809
- maxValue: 128
60201
+ maxValue: 64
58810
60202
  },
58811
- default: 12,
60203
+ default: 24,
58812
60204
  get (value) {
58813
- value.num[0] = this.shadow.pdSampleCount;
60205
+ value.num[0] = this.shadow.pcssBlockerSampleCount;
58814
60206
  },
58815
60207
  set (value) {
58816
- this.shadow.pdSampleCount = value.num[0];
60208
+ this.shadow.pcssBlockerSampleCount = value.num[0];
58817
60209
  },
58818
60210
  isValid () {
58819
- return !!this.castShadow && this.shadow.mode === 'pcf-pd';
60211
+ return !!this.castShadow && this.shadow.mode === 'pcss';
58820
60212
  }
58821
60213
  },
58822
60214
  {
58823
- name: 'PCFSampleRadius',
58824
- description: 'Sample radius for PCF shadow',
58825
- type: 'float',
60215
+ name: 'PCSSFilterSampleCount',
60216
+ description: 'Filter sample count for PCSS shadow',
60217
+ type: 'int',
58826
60218
  phase: 2,
58827
60219
  options: {
58828
- minValue: 0,
60220
+ minValue: 1,
58829
60221
  maxValue: 64
58830
60222
  },
58831
- default: 4,
60223
+ default: 32,
60224
+ get (value) {
60225
+ value.num[0] = this.shadow.pcssFilterSampleCount;
60226
+ },
60227
+ set (value) {
60228
+ this.shadow.pcssFilterSampleCount = value.num[0];
60229
+ },
60230
+ isValid () {
60231
+ return !!this.castShadow && this.shadow.mode === 'pcss';
60232
+ }
60233
+ },
60234
+ {
60235
+ name: 'PCSSMaxFilterRadius',
60236
+ description: 'Maximum filter radius for PCSS shadow',
60237
+ type: 'float',
60238
+ phase: 2,
60239
+ options: {
60240
+ minValue: 1,
60241
+ maxValue: 128
60242
+ },
60243
+ default: 32,
58832
60244
  get (value) {
58833
- value.num[0] = this.shadow.pdSampleRadius;
60245
+ value.num[0] = this.shadow.pcssMaxFilterRadius;
58834
60246
  },
58835
60247
  set (value) {
58836
- this.shadow.pdSampleRadius = value.num[0];
60248
+ this.shadow.pcssMaxFilterRadius = value.num[0];
58837
60249
  },
58838
60250
  isValid () {
58839
- return !!this.castShadow && this.shadow.mode === 'pcf-pd';
60251
+ return !!this.castShadow && this.shadow.mode === 'pcss';
60252
+ }
60253
+ },
60254
+ {
60255
+ name: 'PCSSTemporalJitter',
60256
+ description: 'If true, rotate PCSS sampling pattern over frames for TAA accumulation',
60257
+ type: 'bool',
60258
+ phase: 2,
60259
+ default: true,
60260
+ get (value) {
60261
+ value.bool[0] = this.shadow.pcssTemporalJitter;
60262
+ },
60263
+ set (value) {
60264
+ this.shadow.pcssTemporalJitter = value.bool[0];
60265
+ },
60266
+ isValid () {
60267
+ return !!this.castShadow && this.shadow.mode === 'pcss';
58840
60268
  }
58841
60269
  },
58842
60270
  {
@@ -69081,9 +70509,9 @@ function getLitMaterialProps(manager) {
69081
70509
  name: 'doubleSidedLighting',
69082
70510
  description: 'If true, lighting is evaluated on both sides of the surface',
69083
70511
  type: 'bool',
69084
- default: false,
70512
+ default: true,
69085
70513
  isValid () {
69086
- return !this.$isInstance && this.cullMode !== 'back';
70514
+ return !this.$isInstance;
69087
70515
  },
69088
70516
  get (value) {
69089
70517
  value.bool[0] = this.doubleSidedLighting;
@@ -69092,6 +70520,27 @@ function getLitMaterialProps(manager) {
69092
70520
  this.doubleSidedLighting = value.bool[0];
69093
70521
  }
69094
70522
  },
70523
+ {
70524
+ name: 'NormalScale',
70525
+ description: 'Scalar applied to the normal texture',
70526
+ type: 'float',
70527
+ phase: 1,
70528
+ default: 1,
70529
+ options: {
70530
+ animatable: true,
70531
+ minValue: 0,
70532
+ maxValue: 2
70533
+ },
70534
+ get (value) {
70535
+ value.num[0] = this.normalScale;
70536
+ },
70537
+ set (value) {
70538
+ this.normalScale = value.num[0];
70539
+ },
70540
+ isValid () {
70541
+ return !this.$isInstance && !!this.normalTexture;
70542
+ }
70543
+ },
69095
70544
  {
69096
70545
  name: 'vertexNormal',
69097
70546
  description: 'If true, uses vertex normals for lighting and normal mapping',
@@ -70183,6 +71632,176 @@ function getMToonMaterialProps(manager) {
70183
71632
  getMeshMaterialInstanceUniformsClass(BlinnMaterial)
70184
71633
  ];
70185
71634
  }
71635
+ /** @internal */ function getSkinMaterialClass(manager) {
71636
+ return [
71637
+ {
71638
+ ctor: SkinMaterial,
71639
+ parent: MeshMaterial,
71640
+ name: 'SkinMaterial',
71641
+ getProps () {
71642
+ return defineProps([
71643
+ {
71644
+ name: 'Shininess',
71645
+ description: 'Blinn specular exponent for skin highlights',
71646
+ type: 'float',
71647
+ default: 72,
71648
+ options: {
71649
+ animatable: true,
71650
+ minValue: 1,
71651
+ maxValue: 2048
71652
+ },
71653
+ get (value) {
71654
+ value.num[0] = this.shininess;
71655
+ },
71656
+ set (value) {
71657
+ this.shininess = value.num[0];
71658
+ },
71659
+ getDefaultValue () {
71660
+ return this.$isInstance ? this.coreMaterial.shininess : 72;
71661
+ }
71662
+ },
71663
+ {
71664
+ name: 'SpecularStrength',
71665
+ description: 'Direct specular strength for restrained skin highlights',
71666
+ type: 'float',
71667
+ default: 0.22,
71668
+ options: {
71669
+ animatable: true,
71670
+ minValue: 0,
71671
+ maxValue: 4
71672
+ },
71673
+ get (value) {
71674
+ value.num[0] = this.specularStrength;
71675
+ },
71676
+ set (value) {
71677
+ this.specularStrength = value.num[0];
71678
+ },
71679
+ getDefaultValue () {
71680
+ return this.$isInstance ? this.coreMaterial.specularStrength : 0.22;
71681
+ }
71682
+ },
71683
+ {
71684
+ name: 'DiffuseWrap',
71685
+ description: 'Wrap amount for visible diffuse lighting',
71686
+ type: 'float',
71687
+ default: 0.28,
71688
+ options: {
71689
+ animatable: true,
71690
+ minValue: 0,
71691
+ maxValue: 2
71692
+ },
71693
+ get (value) {
71694
+ value.num[0] = this.diffuseWrap;
71695
+ },
71696
+ set (value) {
71697
+ this.diffuseWrap = value.num[0];
71698
+ },
71699
+ getDefaultValue () {
71700
+ return this.$isInstance ? this.coreMaterial.diffuseWrap : 0.28;
71701
+ }
71702
+ },
71703
+ {
71704
+ name: 'DiffuseSoftness',
71705
+ description: 'Blend from hard Lambert lighting to wrapped diffuse lighting',
71706
+ type: 'float',
71707
+ default: 0.45,
71708
+ options: {
71709
+ animatable: true,
71710
+ minValue: 0,
71711
+ maxValue: 1
71712
+ },
71713
+ get (value) {
71714
+ value.num[0] = this.diffuseSoftness;
71715
+ },
71716
+ set (value) {
71717
+ this.diffuseSoftness = value.num[0];
71718
+ },
71719
+ getDefaultValue () {
71720
+ return this.$isInstance ? this.coreMaterial.diffuseSoftness : 0.45;
71721
+ }
71722
+ },
71723
+ {
71724
+ name: 'ScatterWrap',
71725
+ description: 'Wide wrap amount written to the Skin SSS scattering source',
71726
+ type: 'float',
71727
+ default: 0.65,
71728
+ options: {
71729
+ animatable: true,
71730
+ minValue: 0,
71731
+ maxValue: 2
71732
+ },
71733
+ get (value) {
71734
+ value.num[0] = this.scatterWrap;
71735
+ },
71736
+ set (value) {
71737
+ this.scatterWrap = value.num[0];
71738
+ },
71739
+ getDefaultValue () {
71740
+ return this.$isInstance ? this.coreMaterial.scatterWrap : 0.65;
71741
+ }
71742
+ },
71743
+ {
71744
+ name: 'ScatterStrength',
71745
+ description: 'Strength of the lighting multiplier written to the Skin SSS side buffer',
71746
+ type: 'float',
71747
+ default: 0.7,
71748
+ options: {
71749
+ animatable: true,
71750
+ minValue: 0,
71751
+ maxValue: 4
71752
+ },
71753
+ get (value) {
71754
+ value.num[0] = this.scatterStrength;
71755
+ },
71756
+ set (value) {
71757
+ this.scatterStrength = value.num[0];
71758
+ },
71759
+ getDefaultValue () {
71760
+ return this.$isInstance ? this.coreMaterial.scatterStrength : 0.7;
71761
+ }
71762
+ },
71763
+ {
71764
+ name: 'ScatterColor',
71765
+ description: 'Warm tint for the blurred skin scattering contribution',
71766
+ type: 'rgba',
71767
+ default: [
71768
+ 1,
71769
+ 0.42,
71770
+ 0.28,
71771
+ 1
71772
+ ],
71773
+ options: {
71774
+ animatable: true,
71775
+ minValue: 0,
71776
+ maxValue: 1
71777
+ },
71778
+ get (value) {
71779
+ value.num[0] = this.scatterColor.x;
71780
+ value.num[1] = this.scatterColor.y;
71781
+ value.num[2] = this.scatterColor.z;
71782
+ value.num[3] = this.scatterColor.w;
71783
+ },
71784
+ set (value) {
71785
+ this.scatterColor = new Vector4(value.num[0], value.num[1], value.num[2], value.num[3]);
71786
+ },
71787
+ getDefaultValue () {
71788
+ const color = this.$isInstance ? this.coreMaterial.scatterColor : new Vector4(1, 0.42, 0.28, 1);
71789
+ return [
71790
+ color.x,
71791
+ color.y,
71792
+ color.z,
71793
+ color.w
71794
+ ];
71795
+ }
71796
+ },
71797
+ ...getTextureProps(manager, 'subsurfaceTexture', '2D', false, 1),
71798
+ ...getLitMaterialProps(manager)
71799
+ ]);
71800
+ }
71801
+ },
71802
+ getMeshMaterialInstanceUniformsClass(SkinMaterial)
71803
+ ];
71804
+ }
70186
71805
  /** @internal */ function getPBRMetallicRoughnessMaterialClass(manager) {
70187
71806
  return [
70188
71807
  {
@@ -80491,6 +82110,7 @@ const defaultValues = {
80491
82110
  ...getMToonMaterialClass(this),
80492
82111
  ...getLambertMaterialClass(this),
80493
82112
  ...getBlinnMaterialClass(this),
82113
+ ...getSkinMaterialClass(this),
80494
82114
  ...getPBRMetallicRoughnessMaterialClass(this),
80495
82115
  ...getPBRSpecularGlossinessMaterialClass(this),
80496
82116
  ...getParticleMaterialClass(this),
@@ -91244,6 +92864,195 @@ class GPUClothWrapBinding {
91244
92864
  }
91245
92865
  }
91246
92866
 
92867
+ /** @internal */ class PCFPD extends ShadowImpl {
92868
+ static SHADER_VERSION = 3;
92869
+ _tapCount;
92870
+ _sampleRadius;
92871
+ _shadowSampler;
92872
+ constructor(tapCount, sampleRadius){
92873
+ super();
92874
+ this._tapCount = tapCount ?? 3;
92875
+ this._sampleRadius = sampleRadius ?? 1;
92876
+ this._shadowSampler = null;
92877
+ }
92878
+ get tapCount() {
92879
+ return this._tapCount;
92880
+ }
92881
+ set tapCount(val) {
92882
+ this._tapCount = val;
92883
+ }
92884
+ getType() {
92885
+ return 'pcf-pd';
92886
+ }
92887
+ dispose() {
92888
+ this._shadowSampler = null;
92889
+ }
92890
+ resourceDirty() {
92891
+ return false;
92892
+ }
92893
+ getPCFKernelSize() {
92894
+ if (this._sampleRadius >= 4 || this._tapCount >= 32) {
92895
+ return 7;
92896
+ }
92897
+ if (this._sampleRadius >= 2 || this._tapCount >= 12) {
92898
+ return 5;
92899
+ }
92900
+ return 3;
92901
+ }
92902
+ getParams() {}
92903
+ getShadowMapBorder(_shadowMapParams) {
92904
+ return Math.max(this._sampleRadius + 1, this.getPCFKernelSize());
92905
+ }
92906
+ getShadowMap(shadowMapParams) {
92907
+ return this.useNativeShadowMap(shadowMapParams) ? shadowMapParams.shadowMapFramebuffer.getDepthAttachment() : shadowMapParams.shadowMapFramebuffer.getColorAttachments()[0];
92908
+ }
92909
+ doUpdateResources(shadowMapParams) {
92910
+ shadowMapParams.shadowMap = this.getShadowMap(shadowMapParams);
92911
+ shadowMapParams.shadowMapSampler = shadowMapParams.shadowMap?.getDefaultSampler(this.useNativeShadowMap(shadowMapParams)) || null;
92912
+ }
92913
+ postRenderShadowMap() {}
92914
+ getDepthScale() {
92915
+ return this._sampleRadius;
92916
+ }
92917
+ setDepthScale(val) {
92918
+ this._sampleRadius = val;
92919
+ }
92920
+ getShaderHash() {
92921
+ return `${PCFPD.SHADER_VERSION}-${this._tapCount}-${this._sampleRadius}`;
92922
+ }
92923
+ getShadowMapColorFormat(shadowMapParams) {
92924
+ if (this.useNativeShadowMap(shadowMapParams)) {
92925
+ return null;
92926
+ } else {
92927
+ const device = getDevice();
92928
+ return device.getDeviceCaps().textureCaps.supportHalfFloatColorBuffer ? device.type === 'webgl' ? 'rgba16f' : 'r16f' : device.getDeviceCaps().textureCaps.supportFloatColorBuffer ? device.type === 'webgl' ? 'rgba32f' : 'r32f' : 'rgba8unorm';
92929
+ }
92930
+ }
92931
+ getShadowMapDepthFormat(_shadowMapParams) {
92932
+ return getDevice().type === 'webgl' ? 'd24s8' : 'd32f';
92933
+ }
92934
+ computeShadowMapDepth(shadowMapParams, scope, worldPos) {
92935
+ return computeShadowMapDepth(scope, worldPos, shadowMapParams.shadowMap.format);
92936
+ }
92937
+ computeShadowCSM(shadowMapParams, scope, shadowVertex, NdotL, split) {
92938
+ const funcNameComputeShadowCSM = 'lib_computeShadowCSM';
92939
+ const pb = scope.$builder;
92940
+ const kernelSize = this.getPCFKernelSize();
92941
+ pb.func(funcNameComputeShadowCSM, [
92942
+ pb.vec4('shadowVertex'),
92943
+ pb.float('NdotL'),
92944
+ pb.int('split')
92945
+ ], function() {
92946
+ this.$l.shadowCoord = pb.div(this.shadowVertex, this.shadowVertex.w);
92947
+ this.$l.shadowCoord = pb.add(pb.mul(this.shadowCoord, 0.5), 0.5);
92948
+ this.$l.inShadow = pb.all(pb.bvec2(pb.all(pb.bvec4(pb.greaterThanEqual(this.shadowCoord.x, 0), pb.lessThanEqual(this.shadowCoord.x, 1), pb.greaterThanEqual(this.shadowCoord.y, 0), pb.lessThanEqual(this.shadowCoord.y, 1))), pb.lessThanEqual(this.shadowCoord.z, 1)));
92949
+ this.$l.shadow = pb.float(1);
92950
+ this.$if(this.inShadow, function() {
92951
+ this.$l.shadowBias = computeShadowBiasCSM(this, this.NdotL, this.split);
92952
+ this.shadowCoord.z = pb.sub(this.shadowCoord.z, this.shadowBias);
92953
+ this.shadow = filterShadowPCF(this, shadowMapParams.lightType, shadowMapParams.shadowMap.format, kernelSize, this.shadowCoord, undefined, this.split);
92954
+ });
92955
+ this.$return(this.shadow);
92956
+ });
92957
+ return pb.getGlobalScope()[funcNameComputeShadowCSM](shadowVertex, NdotL, split);
92958
+ }
92959
+ computeShadow(shadowMapParams, scope, shadowVertex, NdotL) {
92960
+ const funcNameComputeShadow = 'lib_computeShadow';
92961
+ const pb = scope.$builder;
92962
+ const that = this;
92963
+ const kernelSize = this.getPCFKernelSize();
92964
+ pb.func(funcNameComputeShadow, [
92965
+ pb.vec4('shadowVertex'),
92966
+ pb.float('NdotL')
92967
+ ], function() {
92968
+ if (shadowMapParams.lightType === LIGHT_TYPE_POINT) {
92969
+ this.$l.dir = pb.sub(this.shadowVertex.xyz, ShaderHelper.getLightPositionAndRangeForShadow(this).xyz);
92970
+ if (that.useNativeShadowMap(shadowMapParams)) {
92971
+ this.$l.nearFar = ShaderHelper.getShadowCameraParams(this).xy;
92972
+ this.$l.maxZ = pb.max(pb.max(pb.abs(this.dir.x), pb.abs(this.dir.y)), pb.abs(this.dir.z));
92973
+ this.$l.distance = ShaderHelper.linearDepthToNonLinear(this, this.maxZ, this.nearFar);
92974
+ this.$l.shadowBias = computeShadowBias(shadowMapParams.lightType, this, pb.div(this.maxZ, ShaderHelper.getLightPositionAndRangeForShadow(this).w), this.NdotL, true);
92975
+ this.$return(that.sampleShadowMap(shadowMapParams, this, this.dir, this.distance, this.shadowBias));
92976
+ } else {
92977
+ this.$l.distance = pb.div(pb.length(this.dir), ShaderHelper.getLightPositionAndRangeForShadow(this).w);
92978
+ this.$l.shadowBias = computeShadowBias(shadowMapParams.lightType, this, this.distance, this.NdotL, true);
92979
+ this.$return(that.sampleShadowMap(shadowMapParams, this, this.dir, this.distance, this.shadowBias));
92980
+ }
92981
+ } else {
92982
+ this.$l.shadowCoord = pb.div(this.shadowVertex, this.shadowVertex.w);
92983
+ this.$l.shadowCoord = pb.add(pb.mul(this.shadowCoord, 0.5), 0.5);
92984
+ this.$l.inShadow = pb.all(pb.bvec2(pb.all(pb.bvec4(pb.greaterThanEqual(this.shadowCoord.x, 0), pb.lessThanEqual(this.shadowCoord.x, 1), pb.greaterThanEqual(this.shadowCoord.y, 0), pb.lessThanEqual(this.shadowCoord.y, 1))), pb.lessThanEqual(this.shadowCoord.z, 1)));
92985
+ this.$l.shadow = pb.float(1);
92986
+ this.$if(this.inShadow, function() {
92987
+ this.$l.shadowBias = computeShadowBias(shadowMapParams.lightType, this, this.shadowCoord.z, this.NdotL, false);
92988
+ this.shadowCoord.z = pb.sub(this.shadowCoord.z, this.shadowBias);
92989
+ this.shadow = filterShadowPCF(this, shadowMapParams.lightType, shadowMapParams.shadowMap.format, kernelSize, this.shadowCoord);
92990
+ });
92991
+ this.$return(this.shadow);
92992
+ }
92993
+ });
92994
+ return pb.getGlobalScope()[funcNameComputeShadow](shadowVertex, NdotL);
92995
+ }
92996
+ useNativeShadowMap(_shadowMapParams) {
92997
+ return getDevice().type !== 'webgl';
92998
+ }
92999
+ /** @internal */ sampleShadowMap(shadowMapParams, scope, coords, z, bias) {
93000
+ const funcNameSampleShadowMap = 'lib_sampleShadowMapPD';
93001
+ const pb = scope.$builder;
93002
+ const that = this;
93003
+ pb.func(funcNameSampleShadowMap, [
93004
+ pb.vec3('coords'),
93005
+ pb.float('z'),
93006
+ pb.float('bias')
93007
+ ], function() {
93008
+ const floatDepthTexture = shadowMapParams.shadowMap.format !== 'rgba8unorm';
93009
+ if (that.useNativeShadowMap(shadowMapParams)) {
93010
+ this.$return(pb.clamp(pb.textureSampleCompareLevel(ShaderHelper.getShadowMap(this), this.coords, pb.sub(this.z, this.bias)), 0, 1));
93011
+ } else {
93012
+ this.$l.shadowTex = pb.textureSampleLevel(ShaderHelper.getShadowMap(this), this.coords, 0);
93013
+ if (!floatDepthTexture) {
93014
+ this.shadowTex.x = decodeNormalizedFloatFromRGBA(this, this.shadowTex);
93015
+ }
93016
+ this.$l.distance = pb.sub(this.z, this.bias);
93017
+ this.$return(pb.step(this.distance, this.shadowTex.x));
93018
+ }
93019
+ });
93020
+ return pb.getGlobalScope()[funcNameSampleShadowMap](coords, z, bias);
93021
+ }
93022
+ /** @internal */ sampleShadowMapCSM(shadowMapParams, scope, coords, split, z, bias) {
93023
+ const funcNameSampleShadowMapCSM = 'lib_sampleShadowMapCSMPD';
93024
+ const pb = scope.$builder;
93025
+ const that = this;
93026
+ pb.func(funcNameSampleShadowMapCSM, [
93027
+ pb.vec4('coords'),
93028
+ pb.int('split'),
93029
+ pb.float('z'),
93030
+ pb.float('bias')
93031
+ ], function() {
93032
+ const floatDepthTexture = shadowMapParams.shadowMap.format !== 'rgba8unorm';
93033
+ this.$l.distance = pb.sub(this.z, this.bias);
93034
+ if (that.useNativeShadowMap(shadowMapParams)) {
93035
+ if (shadowMapParams.shadowMap.isTexture2DArray()) {
93036
+ this.$return(pb.clamp(pb.textureArraySampleCompareLevel(ShaderHelper.getShadowMap(this), this.coords.xy, this.split, this.distance), 0, 1));
93037
+ } else {
93038
+ this.$return(pb.clamp(pb.textureSampleCompareLevel(ShaderHelper.getShadowMap(this), this.coords.xy, this.distance), 0, 1));
93039
+ }
93040
+ } else {
93041
+ if (shadowMapParams.shadowMap.isTexture2DArray()) {
93042
+ this.$l.shadowTex = pb.textureArraySampleLevel(ShaderHelper.getShadowMap(this), this.coords.xy, this.split, 0);
93043
+ } else {
93044
+ this.$l.shadowTex = pb.textureSampleLevel(ShaderHelper.getShadowMap(this), this.coords.xy, 0);
93045
+ }
93046
+ if (!floatDepthTexture) {
93047
+ this.shadowTex.x = decodeNormalizedFloatFromRGBA(this, this.shadowTex);
93048
+ }
93049
+ this.$return(pb.step(this.distance, this.shadowTex.x));
93050
+ }
93051
+ });
93052
+ return pb.getGlobalScope()[funcNameSampleShadowMapCSM](coords, split, z, bias);
93053
+ }
93054
+ }
93055
+
91247
93056
  /**
91248
93057
  * Named object interface for model loading
91249
93058
  * @public
@@ -95677,7 +97486,8 @@ const DEFAULT_PADDING = 6;
95677
97486
  '/materials/blinnphong.zmtl': BlinnMaterial,
95678
97487
  '/materials/pbr_metallic_roughness.zmtl': PBRMetallicRoughnessMaterial,
95679
97488
  '/materials/pbr_specular_glossiness.zmtl': PBRSpecularGlossinessMaterial,
95680
- '/materials/sprite_std.zmtl': StandardSpriteMaterial
97489
+ '/materials/sprite_std.zmtl': StandardSpriteMaterial,
97490
+ '/materials/skin.zmtl': SkinMaterial
95681
97491
  };
95682
97492
  for (const [key] of objectEntries(shapeClsMap)){
95683
97493
  const obj = new shapeClsMap[key]();
@@ -95914,5 +97724,5 @@ const DEFAULT_PADDING = 6;
95914
97724
  }
95915
97725
  }
95916
97726
 
95917
- export { AABBTree, ABufferOIT, ATMOSPHERIC_FOG_BIT, AbsNode, AbstractPostEffect, AllConditionNode, AnimationClip, AnimationController, AnimationPlayback, AnimationSet, AnimationTimeline, AnimationTimelineRunner, AnimationTrack, AnyConditionNode, Application, ArcCosNode, ArcSinNode, ArcTan2Node, ArcTanNode, ArccosineHNode, ArcsineHNode, ArctangentHNode, AssetHierarchyNode, AssetManager, AssetScene, AssetSkeleton, AvatarOutfitInstance, AvatarWardrobe, BUILTIN_ASSET_TEST_CUBEMAP, BUILTIN_ASSET_TEXTURE_SHEEN_LUT, BaseCameraController, BaseGraphNode, BaseLight, BaseSprite, BaseTextureNode, BatchGroup, BillboardMatrixNode, BlinnMaterial, Blitter, Bloom, BoundingBox, BoxFilterBlitter, BoxFrameShape, BoxShape, CAMERA_POS_Y, CCDSolver, Camera, CameraNearFarNode, CameraPositionNode, CameraVectorNode, CapsuleShape, CeilNode, ClampNode, Clipmap, ClipmapTerrain, ClipmapTerrainMaterial, ColliderForce, ColorAdjust, CompAddNode, CompComparisonNode, CompDivNode, CompMulNode, CompSubNode, Compositor, ConstantBVec2Node, ConstantBVec3Node, ConstantBVec4Node, ConstantBooleanNode, ConstantScalarNode, ConstantTexture2DArrayNode, ConstantTexture2DNode, ConstantTextureCubeNode, ConstantVec2Node, ConstantVec3Node, ConstantVec4Node, ConstraintType, CopyBlitter, CosHNode, CosNode, CrossProductNode, CubemapSHProjector, CullVisitor, CylinderShape, DDXNode, DDYNode, Degrees2RadiansNode, DepthPass, DevicePoolAllocator, DirectionalLight, DistanceNode, DotProductNode, DracoMeshDecoder, EPSILON$1 as EPSILON, ESM, ElapsedTimeNode, Engine, EnvConstantAmbient, EnvHemisphericAmbient, EnvLightWrapper, EnvShIBL, Environment, EnvironmentLighting, EqualNode, Exp2Node, ExpNode, FABRIKSolver, FBMWaveGenerator, FFTWaveGenerator, FPSCameraController, FWidthNode, FXAA, FaceForwardNode, FixedGeometryCacheTrack, FloorNode, FmaNode, Fog, FontAsset, FractNode, FunctionCallNode, FunctionInputNode, FunctionOutputNode, GPUClothSystem, GaussianBlurBlitter, GenericMathNode, GerstnerWaveGenerator, GraphNode, GrassInstances, GrassLayer, GrassMaterial, GrassQuadtreeNode, GrassRenderer, Grayscale, HEIGHT_FOG_BIT, Hash1Node, Hash2Node, Hash3Node, HistoryResourceManager, HumanoidBodyRig, HumanoidHandRig, IKAngleConstraint, IKChain, IKConstraint, IKModifier, IKSolver, InputManager, InstanceBindGroupAllocator, InstanceIndexNode, InvProjMatrixNode, InvSqrtNode, InvViewProjMatrixNode, JointDynamicsModifier, JointDynamicsSystem, JointDynamicsSystemController, LIGHT_TYPE_DIRECTIONAL, LIGHT_TYPE_NONE, LIGHT_TYPE_POINT, LIGHT_TYPE_RECT, LIGHT_TYPE_SPOT, LambertMaterial, LengthNode, LightPass, Log2Node, LogNode, LogicallyAndNode, LogicallyOrNode, MAX_CLUSTERED_LIGHTS, MAX_GERSTNER_WAVE_COUNT, MAX_MORPH_ATTRIBUTES, MAX_MORPH_TARGETS, MAX_TERRAIN_MIPMAP_LEVELS, MORPH_ATTRIBUTE_VECTOR_COUNT, MORPH_TARGET_COLOR, MORPH_TARGET_NORMAL, MORPH_TARGET_POSITION, MORPH_TARGET_TANGENT, MORPH_TARGET_TEX0, MORPH_TARGET_TEX1, MORPH_TARGET_TEX2, MORPH_TARGET_TEX3, MORPH_WEIGHTS_VECTOR_COUNT, MSDFText, MSDFTextAtlasManager, MSDFTextSprite, MToonMaterial, MakeVectorNode, Material, MaterialBlueprintIR, MaterialVaryingFlags, MaxNode, Mesh, MeshMaterial, MinNode, MixNode, ModNode, MorphTargetGroupTrack, MorphTargetTrack, MultiChainSpringSystem, NamedObject, NodeEulerRotationTrack, NodeRotationTrack, NodeScaleTrack, NodeTranslationTrack, NormalizeNode, NotEqualNode, Octree, OctreeNode, OctreeNodeChunk, OctreePlacement, OrbitCameraController, OrthoCamera, PBRBlockNode, PBRBluePrintMaterial, PBRMetallicRoughnessMaterial, PBRSpecularGlossinessMaterial, PCAGeometryCacheTrack, PCFOPT, PCFPD, PannerNode, ParticleMaterial, ParticleSystem, PerlinNoise2DNode, PerspectiveCamera, PixelNormalNode, PixelWorldPositionNode, PlaneShape, PointLight, PostEffectLayer, PowNode, Primitive, ProjectionMatrixNode, PropertyTrack, PunctualLight, QUEUE_OPAQUE, QUEUE_TRANSPARENT, RENDER_PASS_TYPE_DEPTH, RENDER_PASS_TYPE_LIGHT, RENDER_PASS_TYPE_OBJECT_COLOR, RENDER_PASS_TYPE_SHADOWMAP, RGHandle, RGHistoryResources, RGSubpass, Radians2DegreesNode, RaycastVisitor, RectLight, ReflectNode, RefractNode, RenderGraph, RenderGraphExecutor, RenderPass, RenderQueue, RenderTarget, ResolveVertexNormalNode, ResolveVertexPositionNode, ResolveVertexTangentNode, ResourceManager, RotateAboutAxisNode, RuntimeScript, SAO, SSS, SaturateNode, Scene, SceneNode, SceneRenderer, ScreenAdapter, ScreenRenderTarget, ScriptAttachment, ScriptRegistry, ScriptingSystem, SelectionNode, ShaderHelper, ShadowMapPass, ShadowMapper, ShadowRegion, Shape, SharedModel, SignNode, SimplexNoise2DNode, SinHNode, SinNode, Skeleton, SkeletonModifier, SkeletonRig, SkinBinding, SkyEnvTextureNode, SkyRenderer, SmoothStepNode, SphereShape, SpotLight, SpringChain, SpringModifier, SpringSystem, Sprite, SpriteBlockNode, SpriteBlueprintMaterial, SpriteMaterial, SqrtNode, StandardSpriteMaterial, StepNode, SubsurfaceProfile, SwizzleNode, TAA, TAA_DEBUG_ALAPH, TAA_DEBUG_CURRENT_COLOR, TAA_DEBUG_EDGE, TAA_DEBUG_HISTORY_COLOR, TAA_DEBUG_MOTION_VECTOR, TAA_DEBUG_NONE, TAA_DEBUG_STRENGTH, TAA_DEBUG_VELOCITY, TanHNode, TanNode, TetrahedronFrameShape, TetrahedronShape, TextSprite, TextureSampleGrad, TextureSampleNode, Tonemap, TorusShape, TransformNode, TwoBoneIKSolver, UnlitMaterial, VSM, VertexBinormalNode, VertexBlockNode, VertexColorNode, VertexIndexNode, VertexNormalNode, VertexOutputNode, VertexPositionNode, VertexTangentNode, VertexUVNode, ViewMatrixNode, ViewProjMatrixNode, Water, WaterShaderImpl, WeightedBlendedOIT, aerialPerspective, aerialPerspectiveLut, appInstance, applyAngleLimits, applyMaterialMixins, applyResult, applyRuntimeScriptConfig, atmosphereLUTRendered, buildConstraints, buildForwardPlusGraph, buildMSDFShape, buildSurfaceFaces, checkSurfaceCollision, collisionDetection, collisionDetectionCapsule, collisionDetectionSphere, computeMaxDepth, computeNearestPoints, copyTexture, createAPLutProgram, createCapsuleCollider, createGPUClothWrapBindingData, createGeometryCacheState, createGradientNoiseTexture, createMultiScatteringLutProgram, createPlaneCollider, createProgramFFT2H, createProgramFFT2V, createProgramH0, createProgramHk, createProgramOcean, createProgramPostFFT2, createRandomNoiseTexture, createSkyViewLutProgram, createSphereCollider, createSpringConstraint, createSpringParticle, createTransformAccess, createTransmittanceLutProgram, debugTexture, decode2HalfFromRGBA, decodeFloatFromRGBA, decodeNormalizedFloatFromRGBA, decodeRGBM, defineProps, encode2HalfToRGBA, encodeFloatToRGBA, encodeNormalizedFloatToRGBA, encodeRGBM, ensureGeometryCacheMeshBinding, executeForwardPlusGraph, extractLocalTwist, fetchNormalizedFloatForDevice, fetchSampler, gammaToLinear, generateMSDF, getAerialPerspectiveLut, getApp, getAtmosphereParamsStruct, getBatchGroupClass, getCameraClass, getDefaultAtmosphereParams, getDefaultTexture2D, getDefaultTexture2DArray, getDefaultTextureCube, getDevice, getDirectionalLightClass, getEngine, getGraphNodeClass, getInput, getMeshClass, getMultiScattering, getMultiScatteringLut, getNodeTypeComponents, getOrthoCameraClass, getParticleNodeClass, getPerspectiveCameraClass, getPointLightClass, getPunctualLightClass, getRectLightClass, getRuntimeScriptProperties, getSceneNodeClass, getSkyView, getSkyViewLut, getSpotLightClass, getTransmittanceLut, gradient, hash11, hash12, hash13, hash21, hash22, hash23, hash31, hash32, hash33, integralMultiScattering, interleavedGradientNoise, isGPUClothSupported, linearToGamma, mieAbsorption, mieCoefficient, miePhase, mixGeometryCacheBoundingBox, mixinAlbedoColor, mixinBlinnPhong, mixinFoliage, mixinLambert, mixinLight, mixinPBRBluePrint, mixinPBRCommon, mixinPBRMetallicRoughness, mixinPBRSpecularGlossness, mixinTextureProps, mixinVertexColor, multiScatteringLut, noise3D, normalizeRuntimeScriptConfig, normalizeScriptAttachmentConfig, normalizeScriptAttachments, ozoneAbsorption, panoramaToCubemap, perlinNoise2D, perlinNoise3D, prefilterCubemap, pushInCollisionDetection, pushInFromCapsule, pushInFromCollider, pushInFromSphere, pushoutFromCapsule, pushoutFromCollider, pushoutFromSphere, rayIntersectSphere, rayleighCoefficient, rayleighPhase, renderAPLut, renderAtmosphereLUTs, renderMultiScatteringLut, renderSkyViewLut, renderTransmittanceLut, resolveCapsuleCollision, resolvePlaneCollision, resolveSphereCollision, restoreGeometryCacheMeshBinding, scattering, scriptProp, setApp, setSceneMeshAssetBinding, simulate, skyBox, skyViewLut, smoothNoise3D, sortRootPointsByProximity, temporalResolve, transmittance, transmittanceLut, transmittanceLutToUV, transmittanceToSky, tryGetApp, uniformSphereSamples, updateColliderFromNode, uvToTransmittanceLut, uvToViewDir, valueNoise, viewDirToUV, whiteNoise, worleyFBM, worleyNoise };
97727
+ export { AABBTree, ABufferOIT, ATMOSPHERIC_FOG_BIT, AbsNode, AbstractPostEffect, AllConditionNode, AnimationClip, AnimationController, AnimationPlayback, AnimationSet, AnimationTimeline, AnimationTimelineRunner, AnimationTrack, AnyConditionNode, Application, ArcCosNode, ArcSinNode, ArcTan2Node, ArcTanNode, ArccosineHNode, ArcsineHNode, ArctangentHNode, AssetHierarchyNode, AssetManager, AssetScene, AssetSkeleton, AvatarOutfitInstance, AvatarWardrobe, BUILTIN_ASSET_TEST_CUBEMAP, BUILTIN_ASSET_TEXTURE_SHEEN_LUT, BaseCameraController, BaseGraphNode, BaseLight, BaseSprite, BaseTextureNode, BatchGroup, BillboardMatrixNode, BlinnMaterial, Blitter, Bloom, BoundingBox, BoxFilterBlitter, BoxFrameShape, BoxShape, CAMERA_POS_Y, CCDSolver, Camera, CameraNearFarNode, CameraPositionNode, CameraVectorNode, CapsuleShape, CeilNode, ClampNode, Clipmap, ClipmapTerrain, ClipmapTerrainMaterial, ColliderForce, ColorAdjust, CompAddNode, CompComparisonNode, CompDivNode, CompMulNode, CompSubNode, Compositor, ConstantBVec2Node, ConstantBVec3Node, ConstantBVec4Node, ConstantBooleanNode, ConstantScalarNode, ConstantTexture2DArrayNode, ConstantTexture2DNode, ConstantTextureCubeNode, ConstantVec2Node, ConstantVec3Node, ConstantVec4Node, ConstraintType, CopyBlitter, CosHNode, CosNode, CrossProductNode, CubemapSHProjector, CullVisitor, CylinderShape, DDXNode, DDYNode, Degrees2RadiansNode, DepthPass, DevicePoolAllocator, DirectionalLight, DistanceNode, DotProductNode, DracoMeshDecoder, EPSILON$1 as EPSILON, ESM, ElapsedTimeNode, Engine, EnvConstantAmbient, EnvHemisphericAmbient, EnvLightWrapper, EnvShIBL, Environment, EnvironmentLighting, EqualNode, Exp2Node, ExpNode, FABRIKSolver, FBMWaveGenerator, FFTWaveGenerator, FPSCameraController, FWidthNode, FXAA, FaceForwardNode, FixedGeometryCacheTrack, FloorNode, FmaNode, Fog, FontAsset, FractNode, FunctionCallNode, FunctionInputNode, FunctionOutputNode, GPUClothSystem, GaussianBlurBlitter, GenericMathNode, GerstnerWaveGenerator, GraphNode, GrassInstances, GrassLayer, GrassMaterial, GrassQuadtreeNode, GrassRenderer, Grayscale, HEIGHT_FOG_BIT, Hash1Node, Hash2Node, Hash3Node, HistoryResourceManager, HumanoidBodyRig, HumanoidHandRig, IKAngleConstraint, IKChain, IKConstraint, IKModifier, IKSolver, InputManager, InstanceBindGroupAllocator, InstanceIndexNode, InvProjMatrixNode, InvSqrtNode, InvViewProjMatrixNode, JointDynamicsModifier, JointDynamicsSystem, JointDynamicsSystemController, LIGHT_TYPE_DIRECTIONAL, LIGHT_TYPE_NONE, LIGHT_TYPE_POINT, LIGHT_TYPE_RECT, LIGHT_TYPE_SPOT, LambertMaterial, LengthNode, LightPass, Log2Node, LogNode, LogicallyAndNode, LogicallyOrNode, MAX_CLUSTERED_LIGHTS, MAX_GERSTNER_WAVE_COUNT, MAX_MORPH_ATTRIBUTES, MAX_MORPH_TARGETS, MAX_TERRAIN_MIPMAP_LEVELS, MORPH_ATTRIBUTE_VECTOR_COUNT, MORPH_TARGET_COLOR, MORPH_TARGET_NORMAL, MORPH_TARGET_POSITION, MORPH_TARGET_TANGENT, MORPH_TARGET_TEX0, MORPH_TARGET_TEX1, MORPH_TARGET_TEX2, MORPH_TARGET_TEX3, MORPH_WEIGHTS_VECTOR_COUNT, MSDFText, MSDFTextAtlasManager, MSDFTextSprite, MToonMaterial, MakeVectorNode, Material, MaterialBlueprintIR, MaterialVaryingFlags, MaxNode, Mesh, MeshMaterial, MinNode, MixNode, ModNode, MorphTargetGroupTrack, MorphTargetTrack, MultiChainSpringSystem, NamedObject, NodeEulerRotationTrack, NodeRotationTrack, NodeScaleTrack, NodeTranslationTrack, NormalizeNode, NotEqualNode, Octree, OctreeNode, OctreeNodeChunk, OctreePlacement, OrbitCameraController, OrthoCamera, PBRBlockNode, PBRBluePrintMaterial, PBRMetallicRoughnessMaterial, PBRSpecularGlossinessMaterial, PCAGeometryCacheTrack, PCFOPT, PCFPD, PCSS, PannerNode, ParticleMaterial, ParticleSystem, PerlinNoise2DNode, PerspectiveCamera, PixelNormalNode, PixelWorldPositionNode, PlaneShape, PointLight, PostEffectLayer, PowNode, Primitive, ProjectionMatrixNode, PropertyTrack, PunctualLight, QUEUE_OPAQUE, QUEUE_TRANSPARENT, RENDER_PASS_TYPE_DEPTH, RENDER_PASS_TYPE_LIGHT, RENDER_PASS_TYPE_OBJECT_COLOR, RENDER_PASS_TYPE_SHADOWMAP, RGHandle, RGHistoryResources, RGSubpass, Radians2DegreesNode, RaycastVisitor, RectLight, ReflectNode, RefractNode, RenderGraph, RenderGraphExecutor, RenderPass, RenderQueue, RenderTarget, ResolveVertexNormalNode, ResolveVertexPositionNode, ResolveVertexTangentNode, ResourceManager, RotateAboutAxisNode, RuntimeScript, SAO, SSS, SaturateNode, Scene, SceneNode, SceneRenderer, ScreenAdapter, ScreenRenderTarget, ScriptAttachment, ScriptRegistry, ScriptingSystem, SelectionNode, ShaderHelper, ShadowMapPass, ShadowMapper, ShadowRegion, Shape, SharedModel, SignNode, SimplexNoise2DNode, SinHNode, SinNode, Skeleton, SkeletonModifier, SkeletonRig, SkinBinding, SkinMaterial, SkinSSS, SkyEnvTextureNode, SkyRenderer, SmoothStepNode, SphereShape, SpotLight, SpringChain, SpringModifier, SpringSystem, Sprite, SpriteBlockNode, SpriteBlueprintMaterial, SpriteMaterial, SqrtNode, StandardSpriteMaterial, StepNode, SubsurfaceProfile, SwizzleNode, TAA, TAA_DEBUG_ALAPH, TAA_DEBUG_CURRENT_COLOR, TAA_DEBUG_EDGE, TAA_DEBUG_HISTORY_COLOR, TAA_DEBUG_MOTION_VECTOR, TAA_DEBUG_NONE, TAA_DEBUG_STRENGTH, TAA_DEBUG_VELOCITY, TanHNode, TanNode, TetrahedronFrameShape, TetrahedronShape, TextSprite, TextureSampleGrad, TextureSampleNode, Tonemap, TorusShape, TransformNode, TwoBoneIKSolver, UnlitMaterial, VSM, VertexBinormalNode, VertexBlockNode, VertexColorNode, VertexIndexNode, VertexNormalNode, VertexOutputNode, VertexPositionNode, VertexTangentNode, VertexUVNode, ViewMatrixNode, ViewProjMatrixNode, Water, WaterShaderImpl, WeightedBlendedOIT, aerialPerspective, aerialPerspectiveLut, appInstance, applyAngleLimits, applyMaterialMixins, applyResult, applyRuntimeScriptConfig, atmosphereLUTRendered, buildConstraints, buildForwardPlusGraph, buildMSDFShape, buildSurfaceFaces, checkSurfaceCollision, collisionDetection, collisionDetectionCapsule, collisionDetectionSphere, computeMaxDepth, computeNearestPoints, copyTexture, createAPLutProgram, createCapsuleCollider, createGPUClothWrapBindingData, createGeometryCacheState, createGradientNoiseTexture, createMultiScatteringLutProgram, createPlaneCollider, createProgramFFT2H, createProgramFFT2V, createProgramH0, createProgramHk, createProgramOcean, createProgramPostFFT2, createRandomNoiseTexture, createSkyViewLutProgram, createSphereCollider, createSpringConstraint, createSpringParticle, createTransformAccess, createTransmittanceLutProgram, debugTexture, decode2HalfFromRGBA, decodeFloatFromRGBA, decodeNormalizedFloatFromRGBA, decodeRGBM, defineProps, encode2HalfToRGBA, encodeFloatToRGBA, encodeNormalizedFloatToRGBA, encodeRGBM, ensureGeometryCacheMeshBinding, executeForwardPlusGraph, extractLocalTwist, fetchNormalizedFloatForDevice, fetchSampler, gammaToLinear, generateMSDF, getAerialPerspectiveLut, getApp, getAtmosphereParamsStruct, getBatchGroupClass, getCameraClass, getDefaultAtmosphereParams, getDefaultTexture2D, getDefaultTexture2DArray, getDefaultTextureCube, getDevice, getDirectionalLightClass, getEngine, getGraphNodeClass, getInput, getMeshClass, getMultiScattering, getMultiScatteringLut, getNodeTypeComponents, getOrthoCameraClass, getParticleNodeClass, getPerspectiveCameraClass, getPointLightClass, getPunctualLightClass, getRectLightClass, getRuntimeScriptProperties, getSceneNodeClass, getSkyView, getSkyViewLut, getSpotLightClass, getTransmittanceLut, gradient, hash11, hash12, hash13, hash21, hash22, hash23, hash31, hash32, hash33, integralMultiScattering, interleavedGradientNoise, isGPUClothSupported, linearToGamma, mieAbsorption, mieCoefficient, miePhase, mixGeometryCacheBoundingBox, mixinAlbedoColor, mixinBlinnPhong, mixinFoliage, mixinLambert, mixinLight, mixinPBRBluePrint, mixinPBRCommon, mixinPBRMetallicRoughness, mixinPBRSpecularGlossness, mixinTextureProps, mixinVertexColor, multiScatteringLut, noise3D, normalizeRuntimeScriptConfig, normalizeScriptAttachmentConfig, normalizeScriptAttachments, ozoneAbsorption, panoramaToCubemap, perlinNoise2D, perlinNoise3D, prefilterCubemap, pushInCollisionDetection, pushInFromCapsule, pushInFromCollider, pushInFromSphere, pushoutFromCapsule, pushoutFromCollider, pushoutFromSphere, rayIntersectSphere, rayleighCoefficient, rayleighPhase, renderAPLut, renderAtmosphereLUTs, renderMultiScatteringLut, renderSkyViewLut, renderTransmittanceLut, resolveCapsuleCollision, resolvePlaneCollision, resolveSphereCollision, restoreGeometryCacheMeshBinding, scattering, scriptProp, setApp, setSceneMeshAssetBinding, simulate, skyBox, skyViewLut, smoothNoise3D, sortRootPointsByProximity, temporalResolve, transmittance, transmittanceLut, transmittanceLutToUV, transmittanceToSky, tryGetApp, uniformSphereSamples, updateColliderFromNode, uvToTransmittanceLut, uvToViewDir, valueNoise, viewDirToUV, whiteNoise, worleyFBM, worleyNoise };
95918
97728
  //# sourceMappingURL=zephyr3d_scene.js.map