@zephyr3d/scene 0.9.22 → 0.9.23

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 -8734
  30. package/dist/index.js +9 -1
  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 +186 -11
  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 +12 -6
  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 +197 -35
  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 +96 -29
  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 +15 -11
  189. package/dist/shadow/pcss.js.map +1 -1
  190. package/dist/shadow/shadow_impl.js +20 -2
  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 +2 -3
  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],
@@ -393,15 +437,17 @@ function sampleShadowMapPCF(scope, shadowMapFormat, pos, offset, depth, cascade)
393
437
  if (shadowMapFormat === 'rgba8unorm') {
394
438
  this.shadowTex.x = decodeNormalizedFloatFromRGBA(this, this.shadowTex);
395
439
  }
396
- this.$return(pb.step(sampleDepth, this.shadowTex.x));
440
+ // Receiver and stored depth are device-encoded here; under reverse-Z
441
+ // "lit" means receiver depth >= stored depth.
442
+ this.$return(REVERSE_Z ? pb.step(this.shadowTex.x, sampleDepth) : pb.step(sampleDepth, this.shadowTex.x));
397
443
  }
398
444
  });
399
445
  return pb.getGlobalScope()[funcName](pos, depth, offset, ...cascade ? [
400
446
  cascade
401
447
  ] : []);
402
448
  }
403
- function sampleShadowDepthPCSS(scope, shadowMapFormat, pos, bounds, cascade) {
404
- const funcName = `lib_sampleShadowDepthPCSS_${shadowMapFormat}_${cascade ? 1 : 0}`;
449
+ function sampleShadowDepthPCSS(scope, shadowMapFormat, deviceEncoded, pos, bounds, cascade) {
450
+ const funcName = `lib_sampleShadowDepthPCSS_${shadowMapFormat}_${cascade ? 1 : 0}${REVERSE_Z && deviceEncoded ? '_rev' : ''}`;
405
451
  const pb = scope.$builder;
406
452
  pb.func(funcName, [
407
453
  pb.vec2('coords'),
@@ -410,7 +456,9 @@ function sampleShadowDepthPCSS(scope, shadowMapFormat, pos, bounds, cascade) {
410
456
  pb.int('cascade')
411
457
  ] : []
412
458
  ], function() {
413
- this.$l.depth = pb.float(1);
459
+ // out-of-bounds samples read as "farthest" (no blocker); farthest is
460
+ // DEPTH_FARTHEST for device-encoded depth, 1 for linear encodings
461
+ this.$l.depth = pb.float(deviceEncoded ? DEPTH_FARTHEST : 1);
414
462
  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
463
  this.$if(this.sampleInside, function() {
416
464
  this.$l.boundsPadding = pb.mul(pb.sub(this.bounds.zw, this.bounds.xy), getShadowMapTexelSize(this), 0.5);
@@ -435,21 +483,24 @@ function samplePointShadowDepthPCSS(scope, shadowMapFormat, dir) {
435
483
  });
436
484
  return pb.getGlobalScope()[funcName](dir);
437
485
  }
438
- function compareShadowDepthPCSS(scope, sampleDepth, compareDepth, transitionWidth) {
439
- const funcName = 'lib_compareShadowDepthPCSS';
486
+ function compareShadowDepthPCSS(scope, sampleDepth, compareDepth, transitionWidth, deviceEncoded) {
487
+ // Lit when the stored depth is farther than the receiver; farther means a
488
+ // smaller value for device-encoded depth under reverse-Z.
489
+ const flip = REVERSE_Z && deviceEncoded;
490
+ const funcName = flip ? 'lib_compareShadowDepthPCSSRev' : 'lib_compareShadowDepthPCSS';
440
491
  const pb = scope.$builder;
441
492
  pb.func(funcName, [
442
493
  pb.float('sampleDepth'),
443
494
  pb.float('compareDepth'),
444
495
  pb.float('transitionWidth')
445
496
  ], function() {
446
- this.$l.depthDelta = pb.sub(this.sampleDepth, this.compareDepth);
497
+ this.$l.depthDelta = flip ? pb.sub(this.compareDepth, this.sampleDepth) : pb.sub(this.sampleDepth, this.compareDepth);
447
498
  this.$return(pb.smoothStep(pb.neg(this.transitionWidth), this.transitionWidth, this.depthDelta));
448
499
  });
449
500
  return pb.getGlobalScope()[funcName](sampleDepth, compareDepth, transitionWidth);
450
501
  }
451
- function sampleShadowPCFPCSS(scope, shadowMapFormat, pos, bounds, compareDepth, texelSize, receiverPlaneDepthBias, cascade) {
452
- const funcName = `lib_sampleShadowPCFPCSS_${shadowMapFormat}_${receiverPlaneDepthBias ? 1 : 0}_${cascade ? 1 : 0}`;
502
+ function sampleShadowPCFPCSS(scope, shadowMapFormat, deviceEncoded, pos, bounds, compareDepth, texelSize, receiverPlaneDepthBias, cascade) {
503
+ const funcName = `lib_sampleShadowPCFPCSS_${shadowMapFormat}_${receiverPlaneDepthBias ? 1 : 0}_${cascade ? 1 : 0}${REVERSE_Z && deviceEncoded ? '_rev' : ''}`;
453
504
  const pb = scope.$builder;
454
505
  pb.func(funcName, [
455
506
  pb.vec2('coords'),
@@ -490,9 +541,9 @@ function sampleShadowPCFPCSS(scope, shadowMapFormat, pos, bounds, compareDepth,
490
541
  for (const [ox, oy] of offsets){
491
542
  this.offset = pb.mul(pb.vec2(ox, oy), this.texelSize);
492
543
  this.tapCoord = pb.add(this.coords, this.offset);
493
- this.sampleDepth = sampleShadowDepthPCSS(this, shadowMapFormat, this.tapCoord, this.bounds, this.cascade);
544
+ this.sampleDepth = sampleShadowDepthPCSS(this, shadowMapFormat, deviceEncoded, this.tapCoord, this.bounds, this.cascade);
494
545
  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));
546
+ this.shadow = pb.add(this.shadow, compareShadowDepthPCSS(this, this.sampleDepth, this.tapCompareDepth, this.transitionWidth, deviceEncoded));
496
547
  }
497
548
  this.$return(pb.mul(this.shadow, 0.25));
498
549
  });
@@ -539,14 +590,14 @@ function samplePointShadowPCFPCSS(scope, shadowMapFormat, dir, compareDepth, tex
539
590
  this.offset = pb.mul(pb.vec2(ox, oy), this.texelSize);
540
591
  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
592
  this.sampleDepth = samplePointShadowDepthPCSS(this, shadowMapFormat, this.sampleDir);
542
- this.shadow = pb.add(this.shadow, compareShadowDepthPCSS(this, this.sampleDepth, this.compareDepth, this.transitionWidth));
593
+ this.shadow = pb.add(this.shadow, compareShadowDepthPCSS(this, this.sampleDepth, this.compareDepth, this.transitionWidth, false));
543
594
  }
544
595
  this.$return(pb.mul(this.shadow, 0.25));
545
596
  });
546
597
  return pb.getGlobalScope()[funcName](dir, compareDepth, texelSize, tangent, bitangent);
547
598
  }
548
- function findBlockerPCSS(scope, shadowMapFormat, tapCount, texCoord, bounds, searchRadius, transitionWidth, matrix, cascade) {
549
- const funcName = `lib_findBlockerPCSS_${shadowMapFormat}_${cascade ? 1 : 0}`;
599
+ function findBlockerPCSS(scope, shadowMapFormat, deviceEncoded, tapCount, texCoord, bounds, searchRadius, transitionWidth, matrix, cascade) {
600
+ const funcName = `lib_findBlockerPCSS_${shadowMapFormat}_${cascade ? 1 : 0}${REVERSE_Z && deviceEncoded ? '_rev' : ''}`;
550
601
  const pb = scope.$builder;
551
602
  pb.func(funcName, [
552
603
  pb.vec4('texCoord'),
@@ -568,8 +619,10 @@ function findBlockerPCSS(scope, shadowMapFormat, tapCount, texCoord, bounds, sea
568
619
  this.$for(pb.float('i'), 0, this.tapCount, function() {
569
620
  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);
570
621
  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)));
622
+ this.sampleDepth = sampleShadowDepthPCSS(this, shadowMapFormat, deviceEncoded, this.sampleCoord, this.bounds, this.cascade);
623
+ // Blocker when the sample is closer to the light than the receiver;
624
+ // device-encoded depth mirrors the difference under reverse-Z.
625
+ 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
626
  this.blockerDepthSum = pb.add(this.blockerDepthSum, pb.mul(this.sampleDepth, this.blockerWeight));
574
627
  this.blockerCount = pb.add(this.blockerCount, this.blockerWeight);
575
628
  });
@@ -610,8 +663,9 @@ function findPointBlockerPCSS(scope, shadowMapFormat, tapCount, dir, compareDept
610
663
  });
611
664
  return pb.getGlobalScope()[funcName](dir, compareDepth, searchRadius, tapCount, transitionWidth, matrix, tangent, bitangent);
612
665
  }
613
- function chebyshevUpperBound(scope, distance, occluder) {
614
- const funcNameChebyshevUpperBound = 'lib_chebyshevUpperBound';
666
+ function chebyshevUpperBound(scope, distance, occluder, deviceEncoded) {
667
+ const flip = REVERSE_Z && deviceEncoded;
668
+ const funcNameChebyshevUpperBound = flip ? 'lib_chebyshevUpperBoundRev' : 'lib_chebyshevUpperBound';
615
669
  const pb = scope.$builder;
616
670
  pb.func(funcNameChebyshevUpperBound, [
617
671
  pb.float('distance'),
@@ -621,7 +675,11 @@ function chebyshevUpperBound(scope, distance, occluder) {
621
675
  this.$l.coverage = this.occluder.z;
622
676
  this.$l.invCoverage = pb.div(1, pb.max(this.coverage, 0.00001));
623
677
  this.$l.moments = pb.mul(this.occluder.xy, this.invCoverage);
624
- this.$l.test = pb.step(this.distance, this.moments.x);
678
+ // The one-sided Chebyshev bound applies when the receiver is farther
679
+ // than the mean occluder depth; variance and squared difference are
680
+ // invariant under the reverse-Z d -> 1-d mirror, only the side test
681
+ // flips.
682
+ this.$l.test = flip ? pb.step(this.moments.x, this.distance) : pb.step(this.distance, this.moments.x);
625
683
  this.$if(pb.notEqual(this.test, 1), function() {
626
684
  this.$l.d = pb.sub(this.distance, this.moments.x);
627
685
  this.$l.variance = pb.max(pb.sub(this.moments.y, pb.mul(this.moments.x, this.moments.x)), 0.000002);
@@ -645,14 +703,14 @@ function chebyshevUpperBound(scope, distance, occluder) {
645
703
  ], function() {
646
704
  if (lightType === LIGHT_TYPE_POINT) {
647
705
  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));
706
+ this.$return(chebyshevUpperBound(this, this.texCoord.w, shadowMapFormat === 'rgba8unorm' ? pb.vec3(decode2HalfFromRGBA(this, this.shadowTex), 1) : this.shadowTex.rgb, false));
649
707
  } else {
650
708
  if (getDevice().type !== 'webgl' && cascade) {
651
709
  this.$l.shadowTex = pb.textureArraySampleLevel(ShaderHelper.getShadowMap(this), this.texCoord.xy, this.cascade, 0);
652
710
  } else {
653
711
  this.$l.shadowTex = pb.textureSampleLevel(ShaderHelper.getShadowMap(this), this.texCoord.xy, 0);
654
712
  }
655
- this.$return(chebyshevUpperBound(this, this.texCoord.z, shadowMapFormat === 'rgba8unorm' ? pb.vec3(decode2HalfFromRGBA(this, this.shadowTex), 1) : this.shadowTex.rgb));
713
+ this.$return(chebyshevUpperBound(this, this.texCoord.z, shadowMapFormat === 'rgba8unorm' ? pb.vec3(decode2HalfFromRGBA(this, this.shadowTex), 1) : this.shadowTex.rgb, isDeviceDepthShadow(lightType)));
656
714
  }
657
715
  });
658
716
  return pb.getGlobalScope()[funcNameFilterShadowVSM](texCoord, ...cascade ? [
@@ -693,11 +751,15 @@ function chebyshevUpperBound(scope, distance, occluder) {
693
751
  this.$l.depth = this.shadowVertex.z;
694
752
  }
695
753
  }
754
+ const deviceEncoded = isDeviceDepthShadow(lightType);
696
755
  if (depthBias) {
697
- this.depth = pb.max(0, pb.sub(this.depth, this.depthBias));
756
+ this.depth = REVERSE_Z && deviceEncoded ? pb.min(1, pb.add(this.depth, this.depthBias)) : pb.max(0, pb.sub(this.depth, this.depthBias));
698
757
  }
699
758
  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);
759
+ // ESM expects exp(k * (occluder - receiver)) with depth growing away
760
+ // from the light; device-encoded depth grows towards the light under
761
+ // reverse-Z, so the difference is mirrored.
762
+ 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
763
  if (shadowMapFormat !== 'rgba8unorm') {
702
764
  this.shadow = pb.mix(1, this.shadow, pb.clamp(this.shadowTex.y, 0, 1));
703
765
  }
@@ -723,7 +785,7 @@ function chebyshevUpperBound(scope, distance, occluder) {
723
785
  ], function() {
724
786
  this.$l.lightDepth = this.texCoord.z;
725
787
  if (receiverPlaneDepthBias) {
726
- this.lightDepth = pb.sub(this.lightDepth, this.receiverPlaneDepthBias.z);
788
+ this.lightDepth = REVERSE_Z ? pb.add(this.lightDepth, this.receiverPlaneDepthBias.z) : pb.sub(this.lightDepth, this.receiverPlaneDepthBias.z);
727
789
  }
728
790
  const shadowMapTexelSize = getShadowMapTexelSize(this);
729
791
  this.$l.uv = pb.add(pb.mul(this.texCoord.xy, pb.vec2(getShadowMapSize(this))), pb.vec2(0));
@@ -838,9 +900,12 @@ function chebyshevUpperBound(scope, distance, occluder) {
838
900
  this.$return(this.shadow);
839
901
  return;
840
902
  }
903
+ // Directional/rect compare device depth (flips under reverse-Z);
904
+ // spot receivers and their stored depth use a linear encoding.
905
+ const deviceEncoded = isDeviceDepthShadow(lightType);
841
906
  this.$l.lightDepth = this.texCoord.z;
842
907
  if (receiverPlaneDepthBias) {
843
- this.lightDepth = pb.sub(this.lightDepth, this.receiverPlaneDepthBias.z);
908
+ this.lightDepth = REVERSE_Z && deviceEncoded ? pb.add(this.lightDepth, this.receiverPlaneDepthBias.z) : pb.sub(this.lightDepth, this.receiverPlaneDepthBias.z);
844
909
  }
845
910
  this.$l.sampleBounds = pb.vec4(0, 0, 1, 1);
846
911
  if (cascade && getDevice().type === 'webgl' && numCascades > 1) {
@@ -855,11 +920,13 @@ function chebyshevUpperBound(scope, distance, occluder) {
855
920
  this.$l.matrix = getPCSSRotationMatrix(this, pb.mul(this.texCoord.xy, pb.vec2(getShadowMapSize(this))), temporalJitter);
856
921
  this.$l.searchRadius = pb.mul(pb.clamp(this.PCSSsearchRadius, 0, pb.max(0, this.PCSSmaxFilterRadius)), this.shadowMapTexelSize);
857
922
  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);
923
+ 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
924
  this.$if(pb.lessThanEqual(this.blocker.y, 0), function() {
860
925
  this.$return(pb.float(1));
861
926
  });
862
- this.$l.penumbra = pb.div(pb.max(pb.sub(this.lightDepth, this.blocker.x), 0), pb.max(this.blocker.x, 0.0001));
927
+ // Penumbra estimation (receiver - blocker) / blocker; for device
928
+ // depth under reverse-Z apply the d -> 1-d mirror of the expression.
929
+ 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
930
  this.$l.filterRadius = pb.mul(pb.clamp(pb.mul(this.penumbra, this.PCSSlightRadius), 0, pb.max(0, this.PCSSmaxFilterRadius)), this.shadowMapTexelSize);
864
931
  this.$l.shadow = pb.float(0);
865
932
  this.$l.duv = pb.vec2();
@@ -869,7 +936,7 @@ function chebyshevUpperBound(scope, distance, occluder) {
869
936
  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);
870
937
  this.sampleCoord = pb.add(this.texCoord.xy, this.duv);
871
938
  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));
939
+ this.shadow = pb.add(this.shadow, sampleShadowPCFPCSS(this, shadowMapFormat, deviceEncoded, this.sampleCoord, this.sampleBounds, this.compareDepth, this.shadowMapTexelSize, this.receiverPlaneDepthBias, this.cascade));
873
940
  });
874
941
  this.shadow = pb.div(this.shadow, this.PCSSfilterSampleCount);
875
942
  this.$return(this.shadow);
@@ -881,5 +948,5 @@ function chebyshevUpperBound(scope, distance, occluder) {
881
948
  ] : []);
882
949
  }
883
950
 
884
- export { computeReceiverPlaneDepthBias, computeShadowMapDepth, filterShadowESM, filterShadowPCF, filterShadowPCSS, filterShadowVSM };
951
+ export { applyShadowDepthBias, computeReceiverPlaneDepthBias, computeShadowMapDepth, filterShadowESM, filterShadowPCF, filterShadowPCSS, filterShadowVSM, isDeviceDepthShadow, ndcToShadowCoord, ndcToShadowCoord3, shadowCoordDepthInRange };
885
952
  //# sourceMappingURL=shadow.js.map