@zephyr3d/scene 0.9.22 → 0.9.24

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 (234) hide show
  1. package/dist/animation/joint_dynamics/collision.js +1 -7
  2. package/dist/animation/joint_dynamics/collision.js.map +1 -1
  3. package/dist/animation/joint_dynamics/constraints.js +2 -17
  4. package/dist/animation/joint_dynamics/constraints.js.map +1 -1
  5. package/dist/animation/joint_dynamics/controller.js +2 -20
  6. package/dist/animation/joint_dynamics/controller.js.map +1 -1
  7. package/dist/animation/joint_dynamics/joint_dynamics_system.js +1 -3
  8. package/dist/animation/joint_dynamics/joint_dynamics_system.js.map +1 -1
  9. package/dist/animation/joint_dynamics/solver.js +14 -60
  10. package/dist/animation/joint_dynamics/solver.js.map +1 -1
  11. package/dist/animation/joint_dynamics/types.js +3 -3
  12. package/dist/animation/joint_dynamics/types.js.map +1 -1
  13. package/dist/app/app.js +23 -0
  14. package/dist/app/app.js.map +1 -1
  15. package/dist/app/scriptregistry.js +16 -53
  16. package/dist/app/scriptregistry.js.map +1 -1
  17. package/dist/asset/assetmanager.js +2 -0
  18. package/dist/asset/assetmanager.js.map +1 -1
  19. package/dist/asset/model.js +22 -0
  20. package/dist/asset/model.js.map +1 -1
  21. package/dist/blitter/bilateralblur.js +3 -1
  22. package/dist/blitter/bilateralblur.js.map +1 -1
  23. package/dist/blitter/blitter.js +3 -3
  24. package/dist/blitter/blitter.js.map +1 -1
  25. package/dist/camera/camera.js +398 -45
  26. package/dist/camera/camera.js.map +1 -1
  27. package/dist/camera/perspectivecamera.js +69 -2
  28. package/dist/camera/perspectivecamera.js.map +1 -1
  29. package/dist/index.d.ts +9113 -8740
  30. package/dist/index.js +10 -2
  31. package/dist/index.js.map +1 -1
  32. package/dist/material/blinn.js +1 -1
  33. package/dist/material/blinn.js.map +1 -1
  34. package/dist/material/lambert.js +3 -3
  35. package/dist/material/lambert.js.map +1 -1
  36. package/dist/material/material.js +8 -5
  37. package/dist/material/material.js.map +1 -1
  38. package/dist/material/meshmaterial.js +17 -10
  39. package/dist/material/meshmaterial.js.map +1 -1
  40. package/dist/material/mixins/lightmodel/blinnphong.js +1 -1
  41. package/dist/material/mixins/lightmodel/blinnphong.js.map +1 -1
  42. package/dist/material/mixins/lightmodel/lambert.js +1 -1
  43. package/dist/material/mixins/lightmodel/lambert.js.map +1 -1
  44. package/dist/material/mixins/lightmodel/pbrblueprintmixin.js +21 -6
  45. package/dist/material/mixins/lightmodel/pbrblueprintmixin.js.map +1 -1
  46. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js +1 -1
  47. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -1
  48. package/dist/material/mixins/lightmodel/pbrspecularglossness.js +1 -1
  49. package/dist/material/mixins/lightmodel/pbrspecularglossness.js.map +1 -1
  50. package/dist/material/mixins/lit.js +33 -11
  51. package/dist/material/mixins/lit.js.map +1 -1
  52. package/dist/material/mixins/pbr/brdf.js +44 -12
  53. package/dist/material/mixins/pbr/brdf.js.map +1 -1
  54. package/dist/material/mixins/pbr/common.js +149 -14
  55. package/dist/material/mixins/pbr/common.js.map +1 -1
  56. package/dist/material/mtoon.js +7 -4
  57. package/dist/material/mtoon.js.map +1 -1
  58. package/dist/material/pbrblueprint.js +5 -1
  59. package/dist/material/pbrblueprint.js.map +1 -1
  60. package/dist/material/pbrmr.js +1 -1
  61. package/dist/material/pbrmr.js.map +1 -1
  62. package/dist/material/pbrsg.js +1 -1
  63. package/dist/material/pbrsg.js.map +1 -1
  64. package/dist/material/shader/helper.js +512 -334
  65. package/dist/material/shader/helper.js.map +1 -1
  66. package/dist/material/skin.js +2 -2
  67. package/dist/material/skin.js.map +1 -1
  68. package/dist/material/terrain-cm.js +5 -5
  69. package/dist/material/terrain-cm.js.map +1 -1
  70. package/dist/material/water.js +6 -4
  71. package/dist/material/water.js.map +1 -1
  72. package/dist/posteffect/bloom.js +54 -4
  73. package/dist/posteffect/bloom.js.map +1 -1
  74. package/dist/posteffect/compositor.js +41 -0
  75. package/dist/posteffect/compositor.js.map +1 -1
  76. package/dist/posteffect/posteffect.js +35 -0
  77. package/dist/posteffect/posteffect.js.map +1 -1
  78. package/dist/posteffect/sao.js +7 -6
  79. package/dist/posteffect/sao.js.map +1 -1
  80. package/dist/posteffect/skinsss.js +3 -3
  81. package/dist/posteffect/skinsss.js.map +1 -1
  82. package/dist/posteffect/ssgi.js +988 -436
  83. package/dist/posteffect/ssgi.js.map +1 -1
  84. package/dist/posteffect/ssr.js +83 -45
  85. package/dist/posteffect/ssr.js.map +1 -1
  86. package/dist/posteffect/sss.js +18 -15
  87. package/dist/posteffect/sss.js.map +1 -1
  88. package/dist/posteffect/taa.js +5 -4
  89. package/dist/posteffect/taa.js.map +1 -1
  90. package/dist/posteffect/tonemap.js +15 -3
  91. package/dist/posteffect/tonemap.js.map +1 -1
  92. package/dist/render/abuffer_oit.js +2 -2
  93. package/dist/render/abuffer_oit.js.map +1 -1
  94. package/dist/render/cluster_light.js +22 -16
  95. package/dist/render/cluster_light.js.map +1 -1
  96. package/dist/render/drawable_mixin.js +8 -5
  97. package/dist/render/drawable_mixin.js.map +1 -1
  98. package/dist/render/dualdepthpeeling_oit.js +10 -5
  99. package/dist/render/dualdepthpeeling_oit.js.map +1 -1
  100. package/dist/render/envlight.js +298 -5
  101. package/dist/render/envlight.js.map +1 -1
  102. package/dist/render/gpu_picking.js +7 -5
  103. package/dist/render/gpu_picking.js.map +1 -1
  104. package/dist/render/hzb.js +28 -19
  105. package/dist/render/hzb.js.map +1 -1
  106. package/dist/render/lightpass.js +18 -4
  107. package/dist/render/lightpass.js.map +1 -1
  108. package/dist/render/render_queue.js +37 -4
  109. package/dist/render/render_queue.js.map +1 -1
  110. package/dist/render/renderer.js +8 -3
  111. package/dist/render/renderer.js.map +1 -1
  112. package/dist/render/rendergraph/blackboard.js +20 -48
  113. package/dist/render/rendergraph/blackboard.js.map +1 -1
  114. package/dist/render/rendergraph/device_pool_allocator.js +18 -58
  115. package/dist/render/rendergraph/device_pool_allocator.js.map +1 -1
  116. package/dist/render/rendergraph/executor.js +89 -115
  117. package/dist/render/rendergraph/executor.js.map +1 -1
  118. package/dist/render/rendergraph/forward_plus_builder.js +1003 -715
  119. package/dist/render/rendergraph/forward_plus_builder.js.map +1 -1
  120. package/dist/render/rendergraph/frame_graph_context.js +1 -1
  121. package/dist/render/rendergraph/frame_graph_context.js.map +1 -1
  122. package/dist/render/rendergraph/frame_resource_requirements.js +14 -0
  123. package/dist/render/rendergraph/frame_resource_requirements.js.map +1 -0
  124. package/dist/render/rendergraph/history_resource_manager.js +74 -140
  125. package/dist/render/rendergraph/history_resource_manager.js.map +1 -1
  126. package/dist/render/rendergraph/history_resources.js +7 -5
  127. package/dist/render/rendergraph/history_resources.js.map +1 -1
  128. package/dist/render/rendergraph/render_context.js +19 -0
  129. package/dist/render/rendergraph/render_context.js.map +1 -0
  130. package/dist/render/rendergraph/render_pipeline.js +315 -0
  131. package/dist/render/rendergraph/render_pipeline.js.map +1 -0
  132. package/dist/render/rendergraph/rendergraph.js +158 -141
  133. package/dist/render/rendergraph/rendergraph.js.map +1 -1
  134. package/dist/render/rendergraph/scene_render_context.js +267 -0
  135. package/dist/render/rendergraph/scene_render_context.js.map +1 -0
  136. package/dist/render/rendergraph/texture_affinity_cache.js +19 -0
  137. package/dist/render/rendergraph/texture_affinity_cache.js.map +1 -0
  138. package/dist/render/rendergraph/types.js +19 -31
  139. package/dist/render/rendergraph/types.js.map +1 -1
  140. package/dist/render/renderpass.js +3 -3
  141. package/dist/render/renderpass.js.map +1 -1
  142. package/dist/render/shadow_mask_pass.js +7 -6
  143. package/dist/render/shadow_mask_pass.js.map +1 -1
  144. package/dist/render/sky.js +257 -95
  145. package/dist/render/sky.js.map +1 -1
  146. package/dist/render/weightedblended_oit.js +4 -3
  147. package/dist/render/weightedblended_oit.js.map +1 -1
  148. package/dist/scene/basesprite.js +2 -0
  149. package/dist/scene/basesprite.js.map +1 -1
  150. package/dist/scene/batchgroup.js +10 -0
  151. package/dist/scene/batchgroup.js.map +1 -1
  152. package/dist/scene/environment.js +61 -2
  153. package/dist/scene/environment.js.map +1 -1
  154. package/dist/scene/light.js +178 -10
  155. package/dist/scene/light.js.map +1 -1
  156. package/dist/scene/meshdrawable.js +89 -2
  157. package/dist/scene/meshdrawable.js.map +1 -1
  158. package/dist/scene/msdftext.js +2 -0
  159. package/dist/scene/msdftext.js.map +1 -1
  160. package/dist/scene/msdftextsprite.js +2 -0
  161. package/dist/scene/msdftextsprite.js.map +1 -1
  162. package/dist/scene/particlesys.js +2 -0
  163. package/dist/scene/particlesys.js.map +1 -1
  164. package/dist/scene/scene.js +34 -1
  165. package/dist/scene/scene.js.map +1 -1
  166. package/dist/scene/terrain-cm/grass.js +2 -1
  167. package/dist/scene/terrain-cm/grass.js.map +1 -1
  168. package/dist/scene/terrain-cm/terrain-cm.js +2 -0
  169. package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
  170. package/dist/scene/water.js +2 -0
  171. package/dist/scene/water.js.map +1 -1
  172. package/dist/shaders/atmosphere.js +5 -4
  173. package/dist/shaders/atmosphere.js.map +1 -1
  174. package/dist/shaders/fog.js +10 -3
  175. package/dist/shaders/fog.js.map +1 -1
  176. package/dist/shaders/shadow.js +149 -40
  177. package/dist/shaders/shadow.js.map +1 -1
  178. package/dist/shaders/ssgi_reprojection.js +118 -0
  179. package/dist/shaders/ssgi_reprojection.js.map +1 -0
  180. package/dist/shaders/ssr.js +322 -154
  181. package/dist/shaders/ssr.js.map +1 -1
  182. package/dist/shadow/esm.js +10 -7
  183. package/dist/shadow/esm.js.map +1 -1
  184. package/dist/shadow/pcf_opt.js +12 -12
  185. package/dist/shadow/pcf_opt.js.map +1 -1
  186. package/dist/shadow/pcf_pd.js +12 -12
  187. package/dist/shadow/pcf_pd.js.map +1 -1
  188. package/dist/shadow/pcss.js +16 -11
  189. package/dist/shadow/pcss.js.map +1 -1
  190. package/dist/shadow/shadow_impl.js +29 -3
  191. package/dist/shadow/shadow_impl.js.map +1 -1
  192. package/dist/shadow/shadowmapper.js +5 -2
  193. package/dist/shadow/shadowmapper.js.map +1 -1
  194. package/dist/shadow/ssm.js +13 -13
  195. package/dist/shadow/ssm.js.map +1 -1
  196. package/dist/shadow/vsm.js +7 -7
  197. package/dist/shadow/vsm.js.map +1 -1
  198. package/dist/utility/physical.js +74 -0
  199. package/dist/utility/physical.js.map +1 -0
  200. package/dist/utility/rendermipmap.js +2 -2
  201. package/dist/utility/rendermipmap.js.map +1 -1
  202. package/dist/utility/serialization/manager.js +3 -1
  203. package/dist/utility/serialization/manager.js.map +1 -1
  204. package/dist/utility/serialization/scene/animation.js +3 -1
  205. package/dist/utility/serialization/scene/animation.js.map +1 -1
  206. package/dist/utility/serialization/scene/batch.js +3 -1
  207. package/dist/utility/serialization/scene/batch.js.map +1 -1
  208. package/dist/utility/serialization/scene/camera.js +598 -2
  209. package/dist/utility/serialization/scene/camera.js.map +1 -1
  210. package/dist/utility/serialization/scene/light.js +180 -9
  211. package/dist/utility/serialization/scene/light.js.map +1 -1
  212. package/dist/utility/serialization/scene/material.js +43 -3
  213. package/dist/utility/serialization/scene/material.js.map +1 -1
  214. package/dist/utility/serialization/scene/mesh.js +3 -1
  215. package/dist/utility/serialization/scene/mesh.js.map +1 -1
  216. package/dist/utility/serialization/scene/node.js +3 -1
  217. package/dist/utility/serialization/scene/node.js.map +1 -1
  218. package/dist/utility/serialization/scene/particle.js +3 -1
  219. package/dist/utility/serialization/scene/particle.js.map +1 -1
  220. package/dist/utility/serialization/scene/primitive.js +2 -0
  221. package/dist/utility/serialization/scene/primitive.js.map +1 -1
  222. package/dist/utility/serialization/scene/scene.js +70 -0
  223. package/dist/utility/serialization/scene/scene.js.map +1 -1
  224. package/dist/utility/serialization/scene/sprite.js +3 -1
  225. package/dist/utility/serialization/scene/sprite.js.map +1 -1
  226. package/dist/utility/serialization/scene/terrain.js +3 -1
  227. package/dist/utility/serialization/scene/terrain.js.map +1 -1
  228. package/dist/utility/serialization/scene/text.js +3 -0
  229. package/dist/utility/serialization/scene/text.js.map +1 -1
  230. package/dist/utility/serialization/scene/water.js +3 -1
  231. package/dist/utility/serialization/scene/water.js.map +1 -1
  232. package/dist/values.js +59 -65
  233. package/dist/values.js.map +1 -1
  234. package/package.json +3 -3
@@ -10,7 +10,8 @@ import { Fog } from '../values.js';
10
10
  parameter3: new Vector4(0.8, 1, 0, 4),
11
11
  parameter4: new Vector4(0, 0, 0, 0),
12
12
  lightDir: new Vector3(0, 1, 0),
13
- lightColor: new Vector3(0, 0, 0)
13
+ lightColor: new Vector3(0, 0, 0),
14
+ preExposure: 1
14
15
  };
15
16
  }
16
17
  /** @internal */ function getHeightFogParamsStruct(pb) {
@@ -22,7 +23,8 @@ import { Fog } from '../values.js';
22
23
  pb.float('dirInscatteringStartDistance'),
23
24
  pb.vec3('dirInscatteringColor'),
24
25
  pb.vec3('lightDir'),
25
- pb.vec3('lightColor')
26
+ pb.vec3('lightColor'),
27
+ pb.float('preExposure')
26
28
  ]);
27
29
  }
28
30
  function calculateFog(scope, aerialperspective, fogType, atmosphereParams, heightFogParams, uv, isSky, cameraPos, worldPos, additive, apLut, distantLightLut) {
@@ -47,6 +49,9 @@ function calculateFog(scope, aerialperspective, fogType, atmosphereParams, heigh
47
49
  });
48
50
  this.$if(pb.and(pb.notEqual(this.withAerialPerspective, 0), pb.not(this.isSky)), function() {
49
51
  this.$l.atmosphericFogging = aerialPerspective(this, this.uv, this.atmosphereParams, this.cameraPos, this.worldPos, pb.vec3(32), apLut);
52
+ // rgb is inscattered radiance from the exposure-independent AP LUT, so it takes the camera
53
+ // pre-exposure; alpha is transmittance and must stay unscaled.
54
+ this.atmosphericFogging = pb.vec4(pb.mul(this.atmosphericFogging.rgb, this.heightFogParams.preExposure), this.atmosphericFogging.a);
50
55
  this.$if(pb.notEqual(this.fogType, Fog.FOG_TYPE_NONE), function() {
51
56
  this.fogging = combineAerialPerspectiveFog(this, this.fogging, this.atmosphericFogging);
52
57
  }).$else(function() {
@@ -102,7 +107,9 @@ function calculateHeightFog(scope, params, cameraPos, worldPos, isSky, skyDistan
102
107
  this.$l.directionalInscattering = pb.mul(this.$l.directionalInscattering, pb.max(this.fogFactor, this.fading));
103
108
  this.$l.fogColor = this.params.parameter1.rgb;
104
109
  this.$if(pb.greaterThan(this.params.parameter3.y, 0), function() {
105
- this.$l.skyContrib = pb.textureSampleLevel(skyDistantColorLut, pb.vec2(0.5), 0).rgb;
110
+ // The distant-sky LUT is baked exposure-independently (it feeds the cached IBL), so the
111
+ // camera pre-exposure is applied here. The authored fogColor above is already pre-exposed.
112
+ this.$l.skyContrib = pb.mul(pb.textureSampleLevel(skyDistantColorLut, pb.vec2(0.5), 0).rgb, this.params.preExposure);
106
113
  this.fogColor = pb.add(this.fogColor, pb.mul(this.skyContrib, this.params.parameter3.y));
107
114
  });
108
115
  this.$l.fogFactor = pb.max(pb.min(this.fogFactor, this.params.parameter3.x), this.fading);
@@ -1 +1 @@
1
- {"version":3,"file":"fog.js","sources":["../../src/shaders/fog.ts"],"sourcesContent":["import { Vector3, Vector4 } from '@zephyr3d/base';\r\nimport type { PBInsideFunctionScope, PBShaderExp, ProgramBuilder } from '@zephyr3d/device';\r\nimport { aerialPerspective, getAtmosphereParamsStruct } from './atmosphere';\r\nimport { Fog } from '../values';\r\n\r\n/** @internal */\r\nexport const MAX_FOG_HEIGHT = 100;\r\n\r\n/** @internal */\r\nexport type HeightFogParams = {\r\n parameter1: Vector4; // [rgb=fogColor a=heightFalloff]\r\n parameter2: Vector4; // [r=density g=startHeight b=startDistance a=maxHeight]\r\n parameter3: Vector4; // [r=maxOpacity g=atmosphereStrength b=rayOriginTerm a=dirInscatteringExponent]\r\n parameter4: Vector4; // [rgb=directionalInscatteringColor a=UNUSED]\r\n lightDir: Vector3;\r\n lightColor: Vector3;\r\n};\r\n\r\n/** @internal */\r\nexport function getDefaultHeightFogParams() {\r\n return {\r\n parameter1: new Vector4(0, 0, 0, 0.1),\r\n parameter2: new Vector4(0.01, 0, 0, 10000),\r\n parameter3: new Vector4(0.8, 1, 0, 4),\r\n parameter4: new Vector4(0, 0, 0, 0),\r\n lightDir: new Vector3(0, 1, 0),\r\n lightColor: new Vector3(0, 0, 0)\r\n } as HeightFogParams;\r\n}\r\n\r\n/** @internal */\r\nexport function getHeightFogParamsStruct(pb: ProgramBuilder) {\r\n return pb.defineStruct([\r\n pb.vec4('parameter1'),\r\n pb.vec4('parameter2'),\r\n pb.vec4('parameter3'),\r\n pb.vec4('parameter4'),\r\n pb.float('dirInscatteringStartDistance'),\r\n pb.vec3('dirInscatteringColor'),\r\n pb.vec3('lightDir'),\r\n pb.vec3('lightColor')\r\n ]);\r\n}\r\n\r\nexport function calculateFog(\r\n scope: PBInsideFunctionScope,\r\n aerialperspective: PBShaderExp,\r\n fogType: PBShaderExp,\r\n atmosphereParams: PBShaderExp,\r\n heightFogParams: PBShaderExp,\r\n uv: PBShaderExp,\r\n isSky: PBShaderExp | boolean,\r\n cameraPos: PBShaderExp,\r\n worldPos: PBShaderExp,\r\n additive: PBShaderExp | number,\r\n apLut: PBShaderExp,\r\n distantLightLut: PBShaderExp\r\n) {\r\n const pb = scope.$builder;\r\n const funcName = 'Z_calculateFog';\r\n const AtmosphereParams = getAtmosphereParamsStruct(pb);\r\n const HeightFogParams = getHeightFogParamsStruct(pb);\r\n pb.func(\r\n funcName,\r\n [\r\n pb.int('withAerialPerspective'),\r\n pb.int('fogType'),\r\n AtmosphereParams('atmosphereParams'),\r\n HeightFogParams('heightFogParams'),\r\n pb.bool('isSky'),\r\n pb.vec2('uv'),\r\n pb.vec3('cameraPos'),\r\n pb.vec3('worldPos'),\r\n pb.int('additive')\r\n ],\r\n function () {\r\n this.$l.fogging = pb.vec4(0, 0, 0, 1);\r\n this.$if(pb.equal(this.fogType, Fog.FOG_TYPE_HEIGHT), function () {\r\n this.fogging = calculateHeightFog(\r\n this,\r\n this.heightFogParams,\r\n this.cameraPos,\r\n this.worldPos,\r\n this.isSky,\r\n distantLightLut\r\n );\r\n });\r\n this.$if(pb.and(pb.notEqual(this.withAerialPerspective, 0), pb.not(this.isSky)), function () {\r\n this.$l.atmosphericFogging = aerialPerspective(\r\n this,\r\n this.uv,\r\n this.atmosphereParams,\r\n this.cameraPos,\r\n this.worldPos,\r\n pb.vec3(32),\r\n apLut\r\n );\r\n this.$if(pb.notEqual(this.fogType, Fog.FOG_TYPE_NONE), function () {\r\n this.fogging = combineAerialPerspectiveFog(this, this.fogging, this.atmosphericFogging);\r\n }).$else(function () {\r\n this.fogging = this.atmosphericFogging;\r\n });\r\n });\r\n this.$if(pb.notEqual(this.additive, 0), function () {\r\n this.fogging = pb.vec4(pb.vec3(0), this.fogging.a);\r\n });\r\n this.$return(this.fogging);\r\n }\r\n );\r\n return scope[funcName](\r\n aerialperspective,\r\n fogType,\r\n atmosphereParams,\r\n heightFogParams,\r\n isSky,\r\n uv,\r\n cameraPos,\r\n worldPos,\r\n additive\r\n );\r\n}\r\n\r\nexport function combineAerialPerspectiveFog(\r\n scope: PBInsideFunctionScope,\r\n fogging: PBShaderExp,\r\n aerialPerspectiveFog: PBShaderExp\r\n) {\r\n const pb = scope.$builder;\r\n const funcName = 'Z_combineAerialPerspectiveFog';\r\n pb.func(funcName, [pb.vec4('fogging'), pb.vec4('aerialPerspectiveFog')], function () {\r\n this.$l.rgb = pb.add(this.fogging.rgb, pb.mul(this.aerialPerspectiveFog.rgb, this.fogging.a));\r\n this.$l.a = pb.mul(this.fogging.a, this.aerialPerspectiveFog.a);\r\n this.$return(pb.vec4(this.rgb, this.a));\r\n });\r\n return scope[funcName](fogging, aerialPerspectiveFog);\r\n}\r\n\r\nexport function calculateHeightFog(\r\n scope: PBInsideFunctionScope,\r\n params: PBShaderExp,\r\n cameraPos: PBShaderExp,\r\n worldPos: PBShaderExp,\r\n isSky: PBShaderExp | boolean,\r\n skyDistantColorLut: PBShaderExp\r\n) {\r\n const pb = scope.$builder;\r\n const funcName = 'Z_calcHeightFog';\r\n const Params = getHeightFogParamsStruct(pb);\r\n pb.func(\r\n funcName,\r\n [Params('params'), pb.vec3('cameraPosition'), pb.vec3('worldPosition'), pb.bool('isSky')],\r\n function () {\r\n this.$l.cameraPos = this.$choice(\r\n this.isSky,\r\n this.cameraPosition,\r\n pb.vec3(\r\n this.cameraPosition.x,\r\n pb.min(this.cameraPosition.y, pb.add(this.params.parameter2.y, MAX_FOG_HEIGHT)),\r\n this.cameraPosition.z\r\n )\r\n );\r\n this.$l.ray = pb.sub(this.worldPosition, this.cameraPos);\r\n this.$l.d = pb.length(this.ray);\r\n this.$l.rayNorm = pb.div(this.ray, this.d);\r\n this.$l.origin = pb.add(this.cameraPos, pb.mul(this.rayNorm, this.params.parameter2.z));\r\n this.$l.term = this.params.parameter3.z;\r\n this.$l.worldPos = this.$choice(\r\n this.isSky,\r\n pb.add(this.cameraPosition, pb.mul(this.rayNorm, 1e8)),\r\n this.worldPosition\r\n );\r\n this.$l.falloff = pb.clamp(\r\n pb.mul(this.params.parameter1.w, pb.sub(this.worldPos.y, this.origin.y)),\r\n -125,\r\n 126\r\n );\r\n this.$l.fading = this.$choice(this.isSky, pb.smoothStep(5e6, 0, this.worldPos.y), 0);\r\n this.$l.factor = this.$choice(\r\n pb.greaterThan(pb.abs(this.falloff), 0.01),\r\n pb.div(pb.sub(1, pb.exp2(pb.neg(this.falloff))), this.falloff),\r\n pb.sub(Math.log(2), pb.mul(0.5 * Math.log(2) * Math.log(2), this.falloff))\r\n );\r\n this.$l.worldDistance = pb.dot(pb.sub(this.worldPos, this.origin), this.rayNorm);\r\n this.$l.lineIntegral = pb.mul(\r\n this.term,\r\n this.factor,\r\n pb.max(0, this.worldDistance) /*pb.distance(this.origin, this.worldPos)*/\r\n );\r\n\r\n this.$l.directionalInscattering = pb.mul(\r\n pb.add(this.params.parameter4.rgb, pb.mul(this.params.lightColor, this.params.parameter3.y)),\r\n pb.pow(pb.clamp(pb.dot(this.rayNorm, this.params.lightDir), 0, 1), this.params.parameter3.w)\r\n );\r\n this.$l.fogFactor = pb.sub(1, pb.clamp(pb.exp2(pb.neg(this.lineIntegral)), 0, 1));\r\n this.$l.distanceFactor = pb.clamp(pb.div(this.worldDistance, this.params.parameter2.w), 0, 1);\r\n this.fogFactor = pb.mul(this.fogFactor, pb.sub(1, this.distanceFactor));\r\n this.$l.directionalInscattering = pb.mul(\r\n this.$l.directionalInscattering,\r\n pb.max(this.fogFactor, this.fading)\r\n );\r\n\r\n this.$l.fogColor = this.params.parameter1.rgb;\r\n this.$if(pb.greaterThan(this.params.parameter3.y, 0), function () {\r\n this.$l.skyContrib = pb.textureSampleLevel(skyDistantColorLut, pb.vec2(0.5), 0).rgb;\r\n this.fogColor = pb.add(this.fogColor, pb.mul(this.skyContrib, this.params.parameter3.y));\r\n });\r\n this.$l.fogFactor = pb.max(pb.min(this.fogFactor, this.params.parameter3.x), this.fading);\r\n this.$l.fogColor = pb.add(pb.mul(this.fogColor, this.fogFactor), this.directionalInscattering);\r\n this.$return(pb.vec4(this.fogColor, pb.sub(1, this.fogFactor)));\r\n }\r\n );\r\n return scope[funcName](params, cameraPos, worldPos, isSky);\r\n}\r\n"],"names":["MAX_FOG_HEIGHT","getDefaultHeightFogParams","parameter1","Vector4","parameter2","parameter3","parameter4","lightDir","Vector3","lightColor","getHeightFogParamsStruct","pb","defineStruct","vec4","float","vec3","calculateFog","scope","aerialperspective","fogType","atmosphereParams","heightFogParams","uv","isSky","cameraPos","worldPos","additive","apLut","distantLightLut","$builder","funcName","AtmosphereParams","getAtmosphereParamsStruct","HeightFogParams","func","int","bool","vec2","$l","fogging","$if","equal","Fog","FOG_TYPE_HEIGHT","calculateHeightFog","and","notEqual","withAerialPerspective","not","atmosphericFogging","aerialPerspective","FOG_TYPE_NONE","combineAerialPerspectiveFog","$else","a","$return","aerialPerspectiveFog","rgb","add","mul","params","skyDistantColorLut","Params","$choice","cameraPosition","x","min","y","z","ray","sub","worldPosition","d","length","rayNorm","div","origin","term","falloff","clamp","w","fading","smoothStep","factor","greaterThan","abs","exp2","neg","Math","log","worldDistance","dot","lineIntegral","max","directionalInscattering","pow","fogFactor","distanceFactor","fogColor","skyContrib","textureSampleLevel"],"mappings":"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"}
1
+ {"version":3,"file":"fog.js","sources":["../../src/shaders/fog.ts"],"sourcesContent":["import { Vector3, Vector4 } from '@zephyr3d/base';\r\nimport type { PBInsideFunctionScope, PBShaderExp, ProgramBuilder } from '@zephyr3d/device';\r\nimport { aerialPerspective, getAtmosphereParamsStruct } from './atmosphere';\r\nimport { Fog } from '../values';\r\n\r\n/** @internal */\r\nexport const MAX_FOG_HEIGHT = 100;\r\n\r\n/** @internal */\r\nexport type HeightFogParams = {\r\n parameter1: Vector4; // [rgb=fogColor a=heightFalloff]\r\n parameter2: Vector4; // [r=density g=startHeight b=startDistance a=maxHeight]\r\n parameter3: Vector4; // [r=maxOpacity g=atmosphereStrength b=rayOriginTerm a=dirInscatteringExponent]\r\n parameter4: Vector4; // [rgb=directionalInscatteringColor a=UNUSED]\r\n lightDir: Vector3;\r\n lightColor: Vector3;\r\n /**\r\n * Camera pre-exposure applied to the atmosphere-derived LUT samples (distant sky, aerial\r\n * perspective). Those LUTs are baked exposure-independently, unlike the authored fog colors which\r\n * are already pre-exposed on upload. 1 in legacy.\r\n */\r\n preExposure: number;\r\n};\r\n\r\n/** @internal */\r\nexport function getDefaultHeightFogParams() {\r\n return {\r\n parameter1: new Vector4(0, 0, 0, 0.1),\r\n parameter2: new Vector4(0.01, 0, 0, 10000),\r\n parameter3: new Vector4(0.8, 1, 0, 4),\r\n parameter4: new Vector4(0, 0, 0, 0),\r\n lightDir: new Vector3(0, 1, 0),\r\n lightColor: new Vector3(0, 0, 0),\r\n preExposure: 1\r\n } as HeightFogParams;\r\n}\r\n\r\n/** @internal */\r\nexport function getHeightFogParamsStruct(pb: ProgramBuilder) {\r\n return pb.defineStruct([\r\n pb.vec4('parameter1'),\r\n pb.vec4('parameter2'),\r\n pb.vec4('parameter3'),\r\n pb.vec4('parameter4'),\r\n pb.float('dirInscatteringStartDistance'),\r\n pb.vec3('dirInscatteringColor'),\r\n pb.vec3('lightDir'),\r\n pb.vec3('lightColor'),\r\n pb.float('preExposure')\r\n ]);\r\n}\r\n\r\nexport function calculateFog(\r\n scope: PBInsideFunctionScope,\r\n aerialperspective: PBShaderExp,\r\n fogType: PBShaderExp,\r\n atmosphereParams: PBShaderExp,\r\n heightFogParams: PBShaderExp,\r\n uv: PBShaderExp,\r\n isSky: PBShaderExp | boolean,\r\n cameraPos: PBShaderExp,\r\n worldPos: PBShaderExp,\r\n additive: PBShaderExp | number,\r\n apLut: PBShaderExp,\r\n distantLightLut: PBShaderExp\r\n) {\r\n const pb = scope.$builder;\r\n const funcName = 'Z_calculateFog';\r\n const AtmosphereParams = getAtmosphereParamsStruct(pb);\r\n const HeightFogParams = getHeightFogParamsStruct(pb);\r\n pb.func(\r\n funcName,\r\n [\r\n pb.int('withAerialPerspective'),\r\n pb.int('fogType'),\r\n AtmosphereParams('atmosphereParams'),\r\n HeightFogParams('heightFogParams'),\r\n pb.bool('isSky'),\r\n pb.vec2('uv'),\r\n pb.vec3('cameraPos'),\r\n pb.vec3('worldPos'),\r\n pb.int('additive')\r\n ],\r\n function () {\r\n this.$l.fogging = pb.vec4(0, 0, 0, 1);\r\n this.$if(pb.equal(this.fogType, Fog.FOG_TYPE_HEIGHT), function () {\r\n this.fogging = calculateHeightFog(\r\n this,\r\n this.heightFogParams,\r\n this.cameraPos,\r\n this.worldPos,\r\n this.isSky,\r\n distantLightLut\r\n );\r\n });\r\n this.$if(pb.and(pb.notEqual(this.withAerialPerspective, 0), pb.not(this.isSky)), function () {\r\n this.$l.atmosphericFogging = aerialPerspective(\r\n this,\r\n this.uv,\r\n this.atmosphereParams,\r\n this.cameraPos,\r\n this.worldPos,\r\n pb.vec3(32),\r\n apLut\r\n );\r\n // rgb is inscattered radiance from the exposure-independent AP LUT, so it takes the camera\r\n // pre-exposure; alpha is transmittance and must stay unscaled.\r\n this.atmosphericFogging = pb.vec4(\r\n pb.mul(this.atmosphericFogging.rgb, this.heightFogParams.preExposure),\r\n this.atmosphericFogging.a\r\n );\r\n this.$if(pb.notEqual(this.fogType, Fog.FOG_TYPE_NONE), function () {\r\n this.fogging = combineAerialPerspectiveFog(this, this.fogging, this.atmosphericFogging);\r\n }).$else(function () {\r\n this.fogging = this.atmosphericFogging;\r\n });\r\n });\r\n this.$if(pb.notEqual(this.additive, 0), function () {\r\n this.fogging = pb.vec4(pb.vec3(0), this.fogging.a);\r\n });\r\n this.$return(this.fogging);\r\n }\r\n );\r\n return scope[funcName](\r\n aerialperspective,\r\n fogType,\r\n atmosphereParams,\r\n heightFogParams,\r\n isSky,\r\n uv,\r\n cameraPos,\r\n worldPos,\r\n additive\r\n );\r\n}\r\n\r\nexport function combineAerialPerspectiveFog(\r\n scope: PBInsideFunctionScope,\r\n fogging: PBShaderExp,\r\n aerialPerspectiveFog: PBShaderExp\r\n) {\r\n const pb = scope.$builder;\r\n const funcName = 'Z_combineAerialPerspectiveFog';\r\n pb.func(funcName, [pb.vec4('fogging'), pb.vec4('aerialPerspectiveFog')], function () {\r\n this.$l.rgb = pb.add(this.fogging.rgb, pb.mul(this.aerialPerspectiveFog.rgb, this.fogging.a));\r\n this.$l.a = pb.mul(this.fogging.a, this.aerialPerspectiveFog.a);\r\n this.$return(pb.vec4(this.rgb, this.a));\r\n });\r\n return scope[funcName](fogging, aerialPerspectiveFog);\r\n}\r\n\r\nexport function calculateHeightFog(\r\n scope: PBInsideFunctionScope,\r\n params: PBShaderExp,\r\n cameraPos: PBShaderExp,\r\n worldPos: PBShaderExp,\r\n isSky: PBShaderExp | boolean,\r\n skyDistantColorLut: PBShaderExp\r\n) {\r\n const pb = scope.$builder;\r\n const funcName = 'Z_calcHeightFog';\r\n const Params = getHeightFogParamsStruct(pb);\r\n pb.func(\r\n funcName,\r\n [Params('params'), pb.vec3('cameraPosition'), pb.vec3('worldPosition'), pb.bool('isSky')],\r\n function () {\r\n this.$l.cameraPos = this.$choice(\r\n this.isSky,\r\n this.cameraPosition,\r\n pb.vec3(\r\n this.cameraPosition.x,\r\n pb.min(this.cameraPosition.y, pb.add(this.params.parameter2.y, MAX_FOG_HEIGHT)),\r\n this.cameraPosition.z\r\n )\r\n );\r\n this.$l.ray = pb.sub(this.worldPosition, this.cameraPos);\r\n this.$l.d = pb.length(this.ray);\r\n this.$l.rayNorm = pb.div(this.ray, this.d);\r\n this.$l.origin = pb.add(this.cameraPos, pb.mul(this.rayNorm, this.params.parameter2.z));\r\n this.$l.term = this.params.parameter3.z;\r\n this.$l.worldPos = this.$choice(\r\n this.isSky,\r\n pb.add(this.cameraPosition, pb.mul(this.rayNorm, 1e8)),\r\n this.worldPosition\r\n );\r\n this.$l.falloff = pb.clamp(\r\n pb.mul(this.params.parameter1.w, pb.sub(this.worldPos.y, this.origin.y)),\r\n -125,\r\n 126\r\n );\r\n this.$l.fading = this.$choice(this.isSky, pb.smoothStep(5e6, 0, this.worldPos.y), 0);\r\n this.$l.factor = this.$choice(\r\n pb.greaterThan(pb.abs(this.falloff), 0.01),\r\n pb.div(pb.sub(1, pb.exp2(pb.neg(this.falloff))), this.falloff),\r\n pb.sub(Math.log(2), pb.mul(0.5 * Math.log(2) * Math.log(2), this.falloff))\r\n );\r\n this.$l.worldDistance = pb.dot(pb.sub(this.worldPos, this.origin), this.rayNorm);\r\n this.$l.lineIntegral = pb.mul(\r\n this.term,\r\n this.factor,\r\n pb.max(0, this.worldDistance) /*pb.distance(this.origin, this.worldPos)*/\r\n );\r\n\r\n this.$l.directionalInscattering = pb.mul(\r\n pb.add(this.params.parameter4.rgb, pb.mul(this.params.lightColor, this.params.parameter3.y)),\r\n pb.pow(pb.clamp(pb.dot(this.rayNorm, this.params.lightDir), 0, 1), this.params.parameter3.w)\r\n );\r\n this.$l.fogFactor = pb.sub(1, pb.clamp(pb.exp2(pb.neg(this.lineIntegral)), 0, 1));\r\n this.$l.distanceFactor = pb.clamp(pb.div(this.worldDistance, this.params.parameter2.w), 0, 1);\r\n this.fogFactor = pb.mul(this.fogFactor, pb.sub(1, this.distanceFactor));\r\n this.$l.directionalInscattering = pb.mul(\r\n this.$l.directionalInscattering,\r\n pb.max(this.fogFactor, this.fading)\r\n );\r\n\r\n this.$l.fogColor = this.params.parameter1.rgb;\r\n this.$if(pb.greaterThan(this.params.parameter3.y, 0), function () {\r\n // The distant-sky LUT is baked exposure-independently (it feeds the cached IBL), so the\r\n // camera pre-exposure is applied here. The authored fogColor above is already pre-exposed.\r\n this.$l.skyContrib = pb.mul(\r\n pb.textureSampleLevel(skyDistantColorLut, pb.vec2(0.5), 0).rgb,\r\n this.params.preExposure\r\n );\r\n this.fogColor = pb.add(this.fogColor, pb.mul(this.skyContrib, this.params.parameter3.y));\r\n });\r\n this.$l.fogFactor = pb.max(pb.min(this.fogFactor, this.params.parameter3.x), this.fading);\r\n this.$l.fogColor = pb.add(pb.mul(this.fogColor, this.fogFactor), this.directionalInscattering);\r\n this.$return(pb.vec4(this.fogColor, pb.sub(1, this.fogFactor)));\r\n }\r\n );\r\n return scope[funcName](params, cameraPos, worldPos, isSky);\r\n}\r\n"],"names":["MAX_FOG_HEIGHT","getDefaultHeightFogParams","parameter1","Vector4","parameter2","parameter3","parameter4","lightDir","Vector3","lightColor","preExposure","getHeightFogParamsStruct","pb","defineStruct","vec4","float","vec3","calculateFog","scope","aerialperspective","fogType","atmosphereParams","heightFogParams","uv","isSky","cameraPos","worldPos","additive","apLut","distantLightLut","$builder","funcName","AtmosphereParams","getAtmosphereParamsStruct","HeightFogParams","func","int","bool","vec2","$l","fogging","$if","equal","Fog","FOG_TYPE_HEIGHT","calculateHeightFog","and","notEqual","withAerialPerspective","not","atmosphericFogging","aerialPerspective","mul","rgb","a","FOG_TYPE_NONE","combineAerialPerspectiveFog","$else","$return","aerialPerspectiveFog","add","params","skyDistantColorLut","Params","$choice","cameraPosition","x","min","y","z","ray","sub","worldPosition","d","length","rayNorm","div","origin","term","falloff","clamp","w","fading","smoothStep","factor","greaterThan","abs","exp2","neg","Math","log","worldDistance","dot","lineIntegral","max","directionalInscattering","pow","fogFactor","distanceFactor","fogColor","skyContrib","textureSampleLevel"],"mappings":"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"}
@@ -1,10 +1,54 @@
1
1
  import { hasDepthChannel } from '@zephyr3d/device';
2
+ import { REVERSE_Z, DEPTH_FARTHEST } from '@zephyr3d/base';
2
3
  import { LIGHT_TYPE_DIRECTIONAL, LIGHT_TYPE_RECT, LIGHT_TYPE_POINT, LIGHT_TYPE_SPOT } from '../values.js';
3
4
  import { encodeNormalizedFloatToRGBA, decode2HalfFromRGBA, decodeNormalizedFloatFromRGBA } from './misc.js';
4
5
  import { ShaderHelper } from '../material/shader/helper.js';
5
6
  import { smoothNoise3D } from './noise.js';
6
7
  import { getDevice } from '../app/api.js';
7
8
 
9
+ /**
10
+ * Whether the shadow-space depth compared by a filter is the device depth
11
+ * (direction flips under reverse-Z) or a linear distance encoding
12
+ * (direction independent). Directional/rect receivers use the light
13
+ * projection device depth; point uses distance/range and spot a linear
14
+ * view-depth encoding.
15
+ * @internal
16
+ */ function isDeviceDepthShadow(lightType) {
17
+ return lightType !== LIGHT_TYPE_POINT && lightType !== LIGHT_TYPE_SPOT;
18
+ }
19
+ /**
20
+ * Maps the shadow-space NDC position to shadow map coordinates: xy to
21
+ * [0, 1] texture space, depth to the device depth range. Under standard-Z
22
+ * all components map from GL [-1, 1]; under reverse-Z the depth is already
23
+ * zero-to-one and passes through.
24
+ * @internal
25
+ */ function ndcToShadowCoord(scope, ndc) {
26
+ const pb = scope.$builder;
27
+ return REVERSE_Z ? pb.vec4(pb.add(pb.mul(ndc.xy, 0.5), pb.vec2(0.5)), ndc.z, ndc.w) : pb.add(pb.mul(ndc, 0.5), 0.5);
28
+ }
29
+ /**
30
+ * vec3 variant of {@link ndcToShadowCoord}.
31
+ * @internal
32
+ */ function ndcToShadowCoord3(scope, ndc) {
33
+ const pb = scope.$builder;
34
+ return REVERSE_Z ? pb.vec3(pb.add(pb.mul(ndc.xy, 0.5), pb.vec2(0.5)), ndc.z) : pb.add(pb.mul(ndc, 0.5), 0.5);
35
+ }
36
+ /**
37
+ * Whether a shadow map device depth lies within the far bound of the
38
+ * shadow projection ("not beyond the shadow far plane").
39
+ * @internal
40
+ */ function shadowCoordDepthInRange(scope, z) {
41
+ const pb = scope.$builder;
42
+ return REVERSE_Z ? pb.greaterThanEqual(z, 0) : pb.lessThanEqual(z, 1);
43
+ }
44
+ /**
45
+ * Applies a depth bias that moves the receiver towards the light in the
46
+ * encoding of the compared shadow depth.
47
+ * @internal
48
+ */ function applyShadowDepthBias(scope, z, bias, deviceEncoded) {
49
+ const pb = scope.$builder;
50
+ return REVERSE_Z && deviceEncoded ? pb.add(z, bias) : pb.sub(z, bias);
51
+ }
8
52
  /*
9
53
  const PCF_KERNEL_3x3 = [
10
54
  [0.5, 1.0, 0.5],
@@ -303,6 +347,28 @@ import { getDevice } from '../app/api.js';
303
347
  -0.4072
304
348
  ]
305
349
  ];
350
+ /** @internal */ function getProgressivePoissonDiscSample(scope, index) {
351
+ const pb = scope.$builder;
352
+ if (pb.getDevice().type === 'webgl') {
353
+ const funcName = 'lib_getProgressivePoissonDiscSampleWebGL1';
354
+ pb.func(funcName, [
355
+ pb.int('index')
356
+ ], function() {
357
+ for(let i = 0; i < PCF_POISSON_DISC.length; i++){
358
+ const sample = PCF_POISSON_DISC[i * 19 % PCF_POISSON_DISC.length];
359
+ this.$if(pb.equal(this.index, i), function() {
360
+ this.$return(pb.vec2(sample[0], sample[1]));
361
+ });
362
+ }
363
+ this.$return(pb.vec2(PCF_POISSON_DISC[0][0], PCF_POISSON_DISC[0][1]));
364
+ });
365
+ return pb.getGlobalScope()[funcName](index);
366
+ }
367
+ if (!pb.getGlobalScope().PCSSpdSamples) {
368
+ pb.getGlobalScope().PCSSpdSamples = PCF_POISSON_DISC.map((sample)=>pb.vec2(sample[0], sample[1]));
369
+ }
370
+ return pb.getGlobalScope().PCSSpdSamples.at(pb.mod(pb.mul(index, 19), PCF_POISSON_DISC.length));
371
+ }
306
372
  function getPCSSRotationMatrix(scope, sampleCoord, temporalJitter) {
307
373
  const funcName = `lib_getPCSSRotationMatrix_${temporalJitter ? 1 : 0}`;
308
374
  const pb = scope.$builder;
@@ -393,15 +459,17 @@ function sampleShadowMapPCF(scope, shadowMapFormat, pos, offset, depth, cascade)
393
459
  if (shadowMapFormat === 'rgba8unorm') {
394
460
  this.shadowTex.x = decodeNormalizedFloatFromRGBA(this, this.shadowTex);
395
461
  }
396
- this.$return(pb.step(sampleDepth, this.shadowTex.x));
462
+ // Receiver and stored depth are device-encoded here; under reverse-Z
463
+ // "lit" means receiver depth >= stored depth.
464
+ this.$return(REVERSE_Z ? pb.step(this.shadowTex.x, sampleDepth) : pb.step(sampleDepth, this.shadowTex.x));
397
465
  }
398
466
  });
399
467
  return pb.getGlobalScope()[funcName](pos, depth, offset, ...cascade ? [
400
468
  cascade
401
469
  ] : []);
402
470
  }
403
- function sampleShadowDepthPCSS(scope, shadowMapFormat, pos, bounds, cascade) {
404
- const funcName = `lib_sampleShadowDepthPCSS_${shadowMapFormat}_${cascade ? 1 : 0}`;
471
+ function sampleShadowDepthPCSS(scope, shadowMapFormat, deviceEncoded, pos, bounds, cascade) {
472
+ const funcName = `lib_sampleShadowDepthPCSS_${shadowMapFormat}_${cascade ? 1 : 0}${REVERSE_Z && deviceEncoded ? '_rev' : ''}`;
405
473
  const pb = scope.$builder;
406
474
  pb.func(funcName, [
407
475
  pb.vec2('coords'),
@@ -410,7 +478,9 @@ function sampleShadowDepthPCSS(scope, shadowMapFormat, pos, bounds, cascade) {
410
478
  pb.int('cascade')
411
479
  ] : []
412
480
  ], function() {
413
- this.$l.depth = pb.float(1);
481
+ // out-of-bounds samples read as "farthest" (no blocker); farthest is
482
+ // DEPTH_FARTHEST for device-encoded depth, 1 for linear encodings
483
+ this.$l.depth = pb.float(deviceEncoded ? DEPTH_FARTHEST : 1);
414
484
  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)));
415
485
  this.$if(this.sampleInside, function() {
416
486
  this.$l.boundsPadding = pb.mul(pb.sub(this.bounds.zw, this.bounds.xy), getShadowMapTexelSize(this), 0.5);
@@ -435,21 +505,24 @@ function samplePointShadowDepthPCSS(scope, shadowMapFormat, dir) {
435
505
  });
436
506
  return pb.getGlobalScope()[funcName](dir);
437
507
  }
438
- function compareShadowDepthPCSS(scope, sampleDepth, compareDepth, transitionWidth) {
439
- const funcName = 'lib_compareShadowDepthPCSS';
508
+ function compareShadowDepthPCSS(scope, sampleDepth, compareDepth, transitionWidth, deviceEncoded) {
509
+ // Lit when the stored depth is farther than the receiver; farther means a
510
+ // smaller value for device-encoded depth under reverse-Z.
511
+ const flip = REVERSE_Z && deviceEncoded;
512
+ const funcName = flip ? 'lib_compareShadowDepthPCSSRev' : 'lib_compareShadowDepthPCSS';
440
513
  const pb = scope.$builder;
441
514
  pb.func(funcName, [
442
515
  pb.float('sampleDepth'),
443
516
  pb.float('compareDepth'),
444
517
  pb.float('transitionWidth')
445
518
  ], function() {
446
- this.$l.depthDelta = pb.sub(this.sampleDepth, this.compareDepth);
519
+ this.$l.depthDelta = flip ? pb.sub(this.compareDepth, this.sampleDepth) : pb.sub(this.sampleDepth, this.compareDepth);
447
520
  this.$return(pb.smoothStep(pb.neg(this.transitionWidth), this.transitionWidth, this.depthDelta));
448
521
  });
449
522
  return pb.getGlobalScope()[funcName](sampleDepth, compareDepth, transitionWidth);
450
523
  }
451
- function sampleShadowPCFPCSS(scope, shadowMapFormat, pos, bounds, compareDepth, texelSize, receiverPlaneDepthBias, cascade) {
452
- const funcName = `lib_sampleShadowPCFPCSS_${shadowMapFormat}_${receiverPlaneDepthBias ? 1 : 0}_${cascade ? 1 : 0}`;
524
+ function sampleShadowPCFPCSS(scope, shadowMapFormat, deviceEncoded, pos, bounds, compareDepth, texelSize, receiverPlaneDepthBias, cascade) {
525
+ const funcName = `lib_sampleShadowPCFPCSS_${shadowMapFormat}_${receiverPlaneDepthBias ? 1 : 0}_${cascade ? 1 : 0}${REVERSE_Z && deviceEncoded ? '_rev' : ''}`;
453
526
  const pb = scope.$builder;
454
527
  pb.func(funcName, [
455
528
  pb.vec2('coords'),
@@ -490,9 +563,9 @@ function sampleShadowPCFPCSS(scope, shadowMapFormat, pos, bounds, compareDepth,
490
563
  for (const [ox, oy] of offsets){
491
564
  this.offset = pb.mul(pb.vec2(ox, oy), this.texelSize);
492
565
  this.tapCoord = pb.add(this.coords, this.offset);
493
- this.sampleDepth = sampleShadowDepthPCSS(this, shadowMapFormat, this.tapCoord, this.bounds, this.cascade);
566
+ this.sampleDepth = sampleShadowDepthPCSS(this, shadowMapFormat, deviceEncoded, this.tapCoord, this.bounds, this.cascade);
494
567
  this.tapCompareDepth = receiverPlaneDepthBias ? pb.add(this.compareDepth, pb.dot(this.offset, this.receiverPlaneDepthBias.xy)) : this.compareDepth;
495
- this.shadow = pb.add(this.shadow, compareShadowDepthPCSS(this, this.sampleDepth, this.tapCompareDepth, this.transitionWidth));
568
+ this.shadow = pb.add(this.shadow, compareShadowDepthPCSS(this, this.sampleDepth, this.tapCompareDepth, this.transitionWidth, deviceEncoded));
496
569
  }
497
570
  this.$return(pb.mul(this.shadow, 0.25));
498
571
  });
@@ -539,15 +612,16 @@ function samplePointShadowPCFPCSS(scope, shadowMapFormat, dir, compareDepth, tex
539
612
  this.offset = pb.mul(pb.vec2(ox, oy), this.texelSize);
540
613
  this.sampleDir = pb.normalize(pb.add(this.dir, pb.add(pb.mul(this.tangent, this.offset.x), pb.mul(this.bitangent, this.offset.y))));
541
614
  this.sampleDepth = samplePointShadowDepthPCSS(this, shadowMapFormat, this.sampleDir);
542
- this.shadow = pb.add(this.shadow, compareShadowDepthPCSS(this, this.sampleDepth, this.compareDepth, this.transitionWidth));
615
+ this.shadow = pb.add(this.shadow, compareShadowDepthPCSS(this, this.sampleDepth, this.compareDepth, this.transitionWidth, false));
543
616
  }
544
617
  this.$return(pb.mul(this.shadow, 0.25));
545
618
  });
546
619
  return pb.getGlobalScope()[funcName](dir, compareDepth, texelSize, tangent, bitangent);
547
620
  }
548
- function findBlockerPCSS(scope, shadowMapFormat, tapCount, texCoord, bounds, searchRadius, transitionWidth, matrix, cascade) {
549
- const funcName = `lib_findBlockerPCSS_${shadowMapFormat}_${cascade ? 1 : 0}`;
621
+ function findBlockerPCSS(scope, shadowMapFormat, deviceEncoded, tapCount, texCoord, bounds, searchRadius, transitionWidth, matrix, cascade) {
622
+ const funcName = `lib_findBlockerPCSS_${shadowMapFormat}_${cascade ? 1 : 0}${REVERSE_Z && deviceEncoded ? '_rev' : ''}`;
550
623
  const pb = scope.$builder;
624
+ const webgl1 = pb.getDevice().type === 'webgl';
551
625
  pb.func(funcName, [
552
626
  pb.vec4('texCoord'),
553
627
  pb.vec4('bounds'),
@@ -565,11 +639,18 @@ function findBlockerPCSS(scope, shadowMapFormat, tapCount, texCoord, bounds, sea
565
639
  this.$l.sampleCoord = pb.vec2();
566
640
  this.$l.sampleDepth = pb.float();
567
641
  this.$l.blockerWeight = pb.float();
568
- this.$for(pb.float('i'), 0, this.tapCount, function() {
569
- 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);
642
+ this.$for(pb.float('i'), 0, webgl1 ? PCF_POISSON_DISC.length : this.tapCount, function() {
643
+ if (webgl1) {
644
+ this.$if(pb.greaterThanEqual(this.i, this.tapCount), function() {
645
+ this.$break();
646
+ });
647
+ }
648
+ this.duv = pb.mul(pb.mul(this.matrix, getProgressivePoissonDiscSample(this, pb.int(this.i))), this.searchRadius);
570
649
  this.sampleCoord = pb.add(this.texCoord.xy, this.duv);
571
- this.sampleDepth = sampleShadowDepthPCSS(this, shadowMapFormat, this.sampleCoord, this.bounds, this.cascade);
572
- this.blockerWeight = pb.sub(1, pb.smoothStep(pb.neg(this.transitionWidth), this.transitionWidth, pb.sub(this.sampleDepth, this.texCoord.z)));
650
+ this.sampleDepth = sampleShadowDepthPCSS(this, shadowMapFormat, deviceEncoded, this.sampleCoord, this.bounds, this.cascade);
651
+ // Blocker when the sample is closer to the light than the receiver;
652
+ // device-encoded depth mirrors the difference under reverse-Z.
653
+ this.blockerWeight = pb.sub(1, pb.smoothStep(pb.neg(this.transitionWidth), this.transitionWidth, REVERSE_Z && deviceEncoded ? pb.sub(this.texCoord.z, this.sampleDepth) : pb.sub(this.sampleDepth, this.texCoord.z)));
573
654
  this.blockerDepthSum = pb.add(this.blockerDepthSum, pb.mul(this.sampleDepth, this.blockerWeight));
574
655
  this.blockerCount = pb.add(this.blockerCount, this.blockerWeight);
575
656
  });
@@ -582,6 +663,7 @@ function findBlockerPCSS(scope, shadowMapFormat, tapCount, texCoord, bounds, sea
582
663
  function findPointBlockerPCSS(scope, shadowMapFormat, tapCount, dir, compareDepth, searchRadius, transitionWidth, matrix, tangent, bitangent) {
583
664
  const funcName = `lib_findPointBlockerPCSS_${shadowMapFormat}`;
584
665
  const pb = scope.$builder;
666
+ const webgl1 = pb.getDevice().type === 'webgl';
585
667
  pb.func(funcName, [
586
668
  pb.vec3('dir'),
587
669
  pb.float('compareDepth'),
@@ -598,8 +680,13 @@ function findPointBlockerPCSS(scope, shadowMapFormat, tapCount, dir, compareDept
598
680
  this.$l.sampleDir = pb.vec3();
599
681
  this.$l.sampleDepth = pb.float();
600
682
  this.$l.blockerWeight = pb.float();
601
- this.$for(pb.float('i'), 0, this.tapCount, function() {
602
- 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);
683
+ this.$for(pb.float('i'), 0, webgl1 ? PCF_POISSON_DISC.length : this.tapCount, function() {
684
+ if (webgl1) {
685
+ this.$if(pb.greaterThanEqual(this.i, this.tapCount), function() {
686
+ this.$break();
687
+ });
688
+ }
689
+ this.duv = pb.mul(pb.mul(this.matrix, getProgressivePoissonDiscSample(this, pb.int(this.i))), this.searchRadius);
603
690
  this.sampleDir = pb.normalize(pb.add(this.dir, pb.add(pb.mul(this.tangent, this.duv.x), pb.mul(this.bitangent, this.duv.y))));
604
691
  this.sampleDepth = samplePointShadowDepthPCSS(this, shadowMapFormat, this.sampleDir);
605
692
  this.blockerWeight = pb.sub(1, pb.smoothStep(pb.neg(this.transitionWidth), this.transitionWidth, pb.sub(this.sampleDepth, this.compareDepth)));
@@ -610,8 +697,9 @@ function findPointBlockerPCSS(scope, shadowMapFormat, tapCount, dir, compareDept
610
697
  });
611
698
  return pb.getGlobalScope()[funcName](dir, compareDepth, searchRadius, tapCount, transitionWidth, matrix, tangent, bitangent);
612
699
  }
613
- function chebyshevUpperBound(scope, distance, occluder) {
614
- const funcNameChebyshevUpperBound = 'lib_chebyshevUpperBound';
700
+ function chebyshevUpperBound(scope, distance, occluder, deviceEncoded) {
701
+ const flip = REVERSE_Z && deviceEncoded;
702
+ const funcNameChebyshevUpperBound = flip ? 'lib_chebyshevUpperBoundRev' : 'lib_chebyshevUpperBound';
615
703
  const pb = scope.$builder;
616
704
  pb.func(funcNameChebyshevUpperBound, [
617
705
  pb.float('distance'),
@@ -621,7 +709,11 @@ function chebyshevUpperBound(scope, distance, occluder) {
621
709
  this.$l.coverage = this.occluder.z;
622
710
  this.$l.invCoverage = pb.div(1, pb.max(this.coverage, 0.00001));
623
711
  this.$l.moments = pb.mul(this.occluder.xy, this.invCoverage);
624
- this.$l.test = pb.step(this.distance, this.moments.x);
712
+ // The one-sided Chebyshev bound applies when the receiver is farther
713
+ // than the mean occluder depth; variance and squared difference are
714
+ // invariant under the reverse-Z d -> 1-d mirror, only the side test
715
+ // flips.
716
+ this.$l.test = flip ? pb.step(this.moments.x, this.distance) : pb.step(this.distance, this.moments.x);
625
717
  this.$if(pb.notEqual(this.test, 1), function() {
626
718
  this.$l.d = pb.sub(this.distance, this.moments.x);
627
719
  this.$l.variance = pb.max(pb.sub(this.moments.y, pb.mul(this.moments.x, this.moments.x)), 0.000002);
@@ -645,14 +737,14 @@ function chebyshevUpperBound(scope, distance, occluder) {
645
737
  ], function() {
646
738
  if (lightType === LIGHT_TYPE_POINT) {
647
739
  this.$l.shadowTex = pb.textureSampleLevel(ShaderHelper.getShadowMap(this), this.texCoord.xyz, 0);
648
- this.$return(chebyshevUpperBound(this, this.texCoord.w, shadowMapFormat === 'rgba8unorm' ? pb.vec3(decode2HalfFromRGBA(this, this.shadowTex), 1) : this.shadowTex.rgb));
740
+ this.$return(chebyshevUpperBound(this, this.texCoord.w, shadowMapFormat === 'rgba8unorm' ? pb.vec3(decode2HalfFromRGBA(this, this.shadowTex), 1) : this.shadowTex.rgb, false));
649
741
  } else {
650
742
  if (getDevice().type !== 'webgl' && cascade) {
651
743
  this.$l.shadowTex = pb.textureArraySampleLevel(ShaderHelper.getShadowMap(this), this.texCoord.xy, this.cascade, 0);
652
744
  } else {
653
745
  this.$l.shadowTex = pb.textureSampleLevel(ShaderHelper.getShadowMap(this), this.texCoord.xy, 0);
654
746
  }
655
- this.$return(chebyshevUpperBound(this, this.texCoord.z, shadowMapFormat === 'rgba8unorm' ? pb.vec3(decode2HalfFromRGBA(this, this.shadowTex), 1) : this.shadowTex.rgb));
747
+ this.$return(chebyshevUpperBound(this, this.texCoord.z, shadowMapFormat === 'rgba8unorm' ? pb.vec3(decode2HalfFromRGBA(this, this.shadowTex), 1) : this.shadowTex.rgb, isDeviceDepthShadow(lightType)));
656
748
  }
657
749
  });
658
750
  return pb.getGlobalScope()[funcNameFilterShadowVSM](texCoord, ...cascade ? [
@@ -693,11 +785,15 @@ function chebyshevUpperBound(scope, distance, occluder) {
693
785
  this.$l.depth = this.shadowVertex.z;
694
786
  }
695
787
  }
788
+ const deviceEncoded = isDeviceDepthShadow(lightType);
696
789
  if (depthBias) {
697
- this.depth = pb.max(0, pb.sub(this.depth, this.depthBias));
790
+ this.depth = REVERSE_Z && deviceEncoded ? pb.min(1, pb.add(this.depth, this.depthBias)) : pb.max(0, pb.sub(this.depth, this.depthBias));
698
791
  }
699
792
  const depthScale = ShaderHelper.getDepthBiasValues(this).z;
700
- this.$l.shadow = logSpace ? pb.clamp(pb.exp(pb.min(87, pb.sub(this.shadowTex.x, pb.mul(depthScale, this.depth)))), 0, 1) : pb.clamp(pb.exp(pb.min(87, pb.mul(depthScale, pb.sub(this.shadowTex.x, this.depth)))), 0, 1);
793
+ // ESM expects exp(k * (occluder - receiver)) with depth growing away
794
+ // from the light; device-encoded depth grows towards the light under
795
+ // reverse-Z, so the difference is mirrored.
796
+ this.$l.shadow = REVERSE_Z && deviceEncoded ? logSpace ? pb.clamp(pb.exp(pb.min(87, pb.sub(pb.mul(depthScale, this.depth), this.shadowTex.x))), 0, 1) : pb.clamp(pb.exp(pb.min(87, pb.mul(depthScale, pb.sub(this.depth, this.shadowTex.x)))), 0, 1) : logSpace ? pb.clamp(pb.exp(pb.min(87, pb.sub(this.shadowTex.x, pb.mul(depthScale, this.depth)))), 0, 1) : pb.clamp(pb.exp(pb.min(87, pb.mul(depthScale, pb.sub(this.shadowTex.x, this.depth)))), 0, 1);
701
797
  if (shadowMapFormat !== 'rgba8unorm') {
702
798
  this.shadow = pb.mix(1, this.shadow, pb.clamp(this.shadowTex.y, 0, 1));
703
799
  }
@@ -723,7 +819,7 @@ function chebyshevUpperBound(scope, distance, occluder) {
723
819
  ], function() {
724
820
  this.$l.lightDepth = this.texCoord.z;
725
821
  if (receiverPlaneDepthBias) {
726
- this.lightDepth = pb.sub(this.lightDepth, this.receiverPlaneDepthBias.z);
822
+ this.lightDepth = REVERSE_Z ? pb.add(this.lightDepth, this.receiverPlaneDepthBias.z) : pb.sub(this.lightDepth, this.receiverPlaneDepthBias.z);
727
823
  }
728
824
  const shadowMapTexelSize = getShadowMapTexelSize(this);
729
825
  this.$l.uv = pb.add(pb.mul(this.texCoord.xy, pb.vec2(getShadowMapSize(this))), pb.vec2(0));
@@ -793,6 +889,7 @@ function chebyshevUpperBound(scope, distance, occluder) {
793
889
  /** @internal */ function filterShadowPCSS(scope, lightType, shadowMapFormat, texCoord, receiverPlaneDepthBias, cascade, temporalJitter = true, numCascades = 1) {
794
890
  const funcNameFilterShadowPCSS = `lib_filterShadowPCSS_${lightType}_${shadowMapFormat}_${receiverPlaneDepthBias ? 1 : 0}_${cascade ? 1 : 0}_${temporalJitter ? 1 : 0}_${numCascades}`;
795
891
  const pb = scope.$builder;
892
+ const webgl1 = pb.getDevice().type === 'webgl';
796
893
  pb.func(funcNameFilterShadowPCSS, [
797
894
  pb.vec4('texCoord'),
798
895
  ...receiverPlaneDepthBias ? [
@@ -807,9 +904,6 @@ function chebyshevUpperBound(scope, distance, occluder) {
807
904
  this.$l.PCSSlightRadius = ShaderHelper.getShadowImplParams(this).x;
808
905
  this.$l.PCSSmaxFilterRadius = ShaderHelper.getShadowImplParams(this).w;
809
906
  this.$l.PCSSsearchRadius = this.$choice(pb.greaterThan(this.PCSSlightRadius, 0), pb.max(this.PCSSlightRadius, this.PCSSmaxFilterRadius), 0);
810
- if (!pb.getGlobalScope().PCSSpdSamples) {
811
- pb.getGlobalScope().PCSSpdSamples = PCF_POISSON_DISC.map((s)=>pb.vec2(s[0], s[1]));
812
- }
813
907
  if (lightType === LIGHT_TYPE_POINT) {
814
908
  this.$l.lightDepth = this.texCoord.w;
815
909
  this.$l.sampleDir = pb.normalize(this.texCoord.xyz);
@@ -829,8 +923,13 @@ function chebyshevUpperBound(scope, distance, occluder) {
829
923
  this.$l.shadow = pb.float(0);
830
924
  this.$l.duv = pb.vec2();
831
925
  this.$l.samplePointDir = pb.vec3();
832
- this.$for(pb.float('i'), 0, this.PCSSfilterSampleCount, function() {
833
- 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);
926
+ this.$for(pb.float('i'), 0, webgl1 ? PCF_POISSON_DISC.length : this.PCSSfilterSampleCount, function() {
927
+ if (webgl1) {
928
+ this.$if(pb.greaterThanEqual(this.i, this.PCSSfilterSampleCount), function() {
929
+ this.$break();
930
+ });
931
+ }
932
+ this.duv = pb.mul(pb.mul(this.matrix, getProgressivePoissonDiscSample(this, pb.int(this.i))), this.filterRadius);
834
933
  this.samplePointDir = pb.normalize(pb.add(this.sampleDir, pb.add(pb.mul(this.tangent, this.duv.x), pb.mul(this.bitangent, this.duv.y))));
835
934
  this.shadow = pb.add(this.shadow, samplePointShadowPCFPCSS(this, shadowMapFormat, this.samplePointDir, this.lightDepth, this.shadowMapTexelSize, this.tangent, this.bitangent));
836
935
  });
@@ -838,9 +937,12 @@ function chebyshevUpperBound(scope, distance, occluder) {
838
937
  this.$return(this.shadow);
839
938
  return;
840
939
  }
940
+ // Directional/rect compare device depth (flips under reverse-Z);
941
+ // spot receivers and their stored depth use a linear encoding.
942
+ const deviceEncoded = isDeviceDepthShadow(lightType);
841
943
  this.$l.lightDepth = this.texCoord.z;
842
944
  if (receiverPlaneDepthBias) {
843
- this.lightDepth = pb.sub(this.lightDepth, this.receiverPlaneDepthBias.z);
945
+ this.lightDepth = REVERSE_Z && deviceEncoded ? pb.add(this.lightDepth, this.receiverPlaneDepthBias.z) : pb.sub(this.lightDepth, this.receiverPlaneDepthBias.z);
844
946
  }
845
947
  this.$l.sampleBounds = pb.vec4(0, 0, 1, 1);
846
948
  if (cascade && getDevice().type === 'webgl' && numCascades > 1) {
@@ -855,21 +957,28 @@ function chebyshevUpperBound(scope, distance, occluder) {
855
957
  this.$l.matrix = getPCSSRotationMatrix(this, pb.mul(this.texCoord.xy, pb.vec2(getShadowMapSize(this))), temporalJitter);
856
958
  this.$l.searchRadius = pb.mul(pb.clamp(this.PCSSsearchRadius, 0, pb.max(0, this.PCSSmaxFilterRadius)), this.shadowMapTexelSize);
857
959
  this.$l.blockerTransitionWidth = receiverPlaneDepthBias ? pb.max(pb.dot(pb.abs(this.receiverPlaneDepthBias.xy), this.searchRadius), 1 / 65535) : pb.float(1 / 65535);
858
- 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);
960
+ this.$l.blocker = findBlockerPCSS(this, shadowMapFormat, deviceEncoded, this.PCSSblockerSampleCount, pb.vec4(this.texCoord.xy, this.lightDepth, this.texCoord.w), this.sampleBounds, this.searchRadius, this.blockerTransitionWidth, this.matrix, this.cascade);
859
961
  this.$if(pb.lessThanEqual(this.blocker.y, 0), function() {
860
962
  this.$return(pb.float(1));
861
963
  });
862
- this.$l.penumbra = pb.div(pb.max(pb.sub(this.lightDepth, this.blocker.x), 0), pb.max(this.blocker.x, 0.0001));
964
+ // Penumbra estimation (receiver - blocker) / blocker; for device
965
+ // depth under reverse-Z apply the d -> 1-d mirror of the expression.
966
+ this.$l.penumbra = REVERSE_Z && deviceEncoded ? pb.div(pb.max(pb.sub(this.blocker.x, this.lightDepth), 0), pb.max(pb.sub(1, this.blocker.x), 0.0001)) : pb.div(pb.max(pb.sub(this.lightDepth, this.blocker.x), 0), pb.max(this.blocker.x, 0.0001));
863
967
  this.$l.filterRadius = pb.mul(pb.clamp(pb.mul(this.penumbra, this.PCSSlightRadius), 0, pb.max(0, this.PCSSmaxFilterRadius)), this.shadowMapTexelSize);
864
968
  this.$l.shadow = pb.float(0);
865
969
  this.$l.duv = pb.vec2();
866
970
  this.$l.sampleCoord = pb.vec2();
867
971
  this.$l.compareDepth = pb.float();
868
- this.$for(pb.float('i'), 0, this.PCSSfilterSampleCount, function() {
869
- 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);
972
+ this.$for(pb.float('i'), 0, webgl1 ? PCF_POISSON_DISC.length : this.PCSSfilterSampleCount, function() {
973
+ if (webgl1) {
974
+ this.$if(pb.greaterThanEqual(this.i, this.PCSSfilterSampleCount), function() {
975
+ this.$break();
976
+ });
977
+ }
978
+ this.duv = pb.mul(pb.mul(this.matrix, getProgressivePoissonDiscSample(this, pb.int(this.i))), this.filterRadius);
870
979
  this.sampleCoord = pb.add(this.texCoord.xy, this.duv);
871
980
  this.compareDepth = receiverPlaneDepthBias ? pb.add(this.lightDepth, pb.dot(this.duv, this.receiverPlaneDepthBias.xy)) : this.lightDepth;
872
- this.shadow = pb.add(this.shadow, sampleShadowPCFPCSS(this, shadowMapFormat, this.sampleCoord, this.sampleBounds, this.compareDepth, this.shadowMapTexelSize, this.receiverPlaneDepthBias, this.cascade));
981
+ this.shadow = pb.add(this.shadow, sampleShadowPCFPCSS(this, shadowMapFormat, deviceEncoded, this.sampleCoord, this.sampleBounds, this.compareDepth, this.shadowMapTexelSize, this.receiverPlaneDepthBias, this.cascade));
873
982
  });
874
983
  this.shadow = pb.div(this.shadow, this.PCSSfilterSampleCount);
875
984
  this.$return(this.shadow);
@@ -881,5 +990,5 @@ function chebyshevUpperBound(scope, distance, occluder) {
881
990
  ] : []);
882
991
  }
883
992
 
884
- export { computeReceiverPlaneDepthBias, computeShadowMapDepth, filterShadowESM, filterShadowPCF, filterShadowPCSS, filterShadowVSM };
993
+ export { applyShadowDepthBias, computeReceiverPlaneDepthBias, computeShadowMapDepth, filterShadowESM, filterShadowPCF, filterShadowPCSS, filterShadowVSM, getProgressivePoissonDiscSample, isDeviceDepthShadow, ndcToShadowCoord, ndcToShadowCoord3, shadowCoordDepthInRange };
885
994
  //# sourceMappingURL=shadow.js.map