@zephyr3d/scene 0.9.21 → 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 (238) 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 +9100 -8712
  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 +51 -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 +1196 -0
  83. package/dist/posteffect/ssgi.js.map +1 -0
  84. package/dist/posteffect/ssr.js +83 -45
  85. package/dist/posteffect/ssr.js.map +1 -1
  86. package/dist/posteffect/sss.js +137 -49
  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 +41 -0
  121. package/dist/render/rendergraph/frame_graph_context.js.map +1 -0
  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 +10 -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.js +63 -0
  179. package/dist/shaders/ssgi.js.map +1 -0
  180. package/dist/shaders/ssgi_reprojection.js +118 -0
  181. package/dist/shaders/ssgi_reprojection.js.map +1 -0
  182. package/dist/shaders/ssr.js +322 -154
  183. package/dist/shaders/ssr.js.map +1 -1
  184. package/dist/shadow/esm.js +13 -8
  185. package/dist/shadow/esm.js.map +1 -1
  186. package/dist/shadow/pcf_opt.js +15 -12
  187. package/dist/shadow/pcf_opt.js.map +1 -1
  188. package/dist/shadow/pcf_pd.js +15 -12
  189. package/dist/shadow/pcf_pd.js.map +1 -1
  190. package/dist/shadow/pcss.js +17 -11
  191. package/dist/shadow/pcss.js.map +1 -1
  192. package/dist/shadow/shadow_impl.js +20 -2
  193. package/dist/shadow/shadow_impl.js.map +1 -1
  194. package/dist/shadow/shadowmapper.js +10 -3
  195. package/dist/shadow/shadowmapper.js.map +1 -1
  196. package/dist/shadow/ssm.js +16 -13
  197. package/dist/shadow/ssm.js.map +1 -1
  198. package/dist/shadow/vsm.js +10 -8
  199. package/dist/shadow/vsm.js.map +1 -1
  200. package/dist/utility/physical.js +74 -0
  201. package/dist/utility/physical.js.map +1 -0
  202. package/dist/utility/rendermipmap.js +2 -2
  203. package/dist/utility/rendermipmap.js.map +1 -1
  204. package/dist/utility/serialization/manager.js +3 -1
  205. package/dist/utility/serialization/manager.js.map +1 -1
  206. package/dist/utility/serialization/scene/animation.js +3 -1
  207. package/dist/utility/serialization/scene/animation.js.map +1 -1
  208. package/dist/utility/serialization/scene/batch.js +3 -1
  209. package/dist/utility/serialization/scene/batch.js.map +1 -1
  210. package/dist/utility/serialization/scene/camera.js +598 -2
  211. package/dist/utility/serialization/scene/camera.js.map +1 -1
  212. package/dist/utility/serialization/scene/light.js +180 -9
  213. package/dist/utility/serialization/scene/light.js.map +1 -1
  214. package/dist/utility/serialization/scene/material.js +43 -3
  215. package/dist/utility/serialization/scene/material.js.map +1 -1
  216. package/dist/utility/serialization/scene/mesh.js +3 -1
  217. package/dist/utility/serialization/scene/mesh.js.map +1 -1
  218. package/dist/utility/serialization/scene/node.js +3 -1
  219. package/dist/utility/serialization/scene/node.js.map +1 -1
  220. package/dist/utility/serialization/scene/particle.js +3 -1
  221. package/dist/utility/serialization/scene/particle.js.map +1 -1
  222. package/dist/utility/serialization/scene/primitive.js +2 -0
  223. package/dist/utility/serialization/scene/primitive.js.map +1 -1
  224. package/dist/utility/serialization/scene/scene.js +70 -0
  225. package/dist/utility/serialization/scene/scene.js.map +1 -1
  226. package/dist/utility/serialization/scene/sprite.js +3 -1
  227. package/dist/utility/serialization/scene/sprite.js.map +1 -1
  228. package/dist/utility/serialization/scene/terrain.js +3 -1
  229. package/dist/utility/serialization/scene/terrain.js.map +1 -1
  230. package/dist/utility/serialization/scene/text.js +3 -0
  231. package/dist/utility/serialization/scene/text.js.map +1 -1
  232. package/dist/utility/serialization/scene/water.js +3 -1
  233. package/dist/utility/serialization/scene/water.js.map +1 -1
  234. package/dist/values.js +2 -3
  235. package/dist/values.js.map +1 -1
  236. package/package.json +3 -3
  237. package/dist/animation/joint_dynamics/convex_collider.js +0 -320
  238. package/dist/animation/joint_dynamics/convex_collider.js.map +0 -1
@@ -1,8 +1,8 @@
1
1
  import { AbstractPostEffect, PostEffectLayer } from './posteffect.js';
2
2
  import { linearToGamma } from '../shaders/misc.js';
3
- import { SSR_calcJitter, screenSpaceRayTracing_HiZ, screenSpaceRayTracing_Linear2D } from '../shaders/ssr.js';
3
+ import { SSR_calcJitter, SSR_interleavedGradientNoise, screenSpaceRayTracing_HiZ, screenSpaceRayTracing_Linear2D } from '../shaders/ssr.js';
4
4
  import { temporalResolve } from '../shaders/temporal.js';
5
- import { Vector2, Matrix4x4, Vector4 } from '@zephyr3d/base';
5
+ import { DEPTH_COMPARE_FARTHER, Vector2, Matrix4x4, Vector4, DEPTH_FARTHEST } from '@zephyr3d/base';
6
6
  import { copyTexture, fetchSampler } from '../utility/misc.js';
7
7
  import { getGGXLUT } from '../utility/textures/ggxlut.js';
8
8
  import { BilateralBlurBlitter } from '../blitter/bilateralblur.js';
@@ -28,6 +28,7 @@ import '../utility/blueprint/material/texture.js';
28
28
  import { RGHistoryResources } from '../render/rendergraph/history_resources.js';
29
29
  import { FrameResources } from '../render/rendergraph/blackboard.js';
30
30
 
31
+ const DEBUG_HIZ_INTERSECT = false;
31
32
  /**
32
33
  * SSR post effect
33
34
  *
@@ -65,6 +66,15 @@ import { FrameResources } from '../render/rendergraph/blackboard.js';
65
66
  /** {@inheritDoc AbstractPostEffect.requireMotionVectorTexture} */ requireMotionVectorTexture(ctx) {
66
67
  return !!ctx.camera.ssrTemporal;
67
68
  }
69
+ /** {@inheritDoc AbstractPostEffect.requireHiZTexture} */ requireHiZTexture(ctx) {
70
+ return !!ctx.camera.HiZ;
71
+ }
72
+ /** {@inheritDoc AbstractPostEffect.requireSceneNormalTexture} */ requireSceneNormalTexture() {
73
+ return true;
74
+ }
75
+ /** {@inheritDoc AbstractPostEffect.requireSceneRoughnessTexture} */ requireSceneRoughnessTexture() {
76
+ return true;
77
+ }
68
78
  /**
69
79
  * Declares SSR's internal steps (intersect, resolve, optional bilateral
70
80
  * blur, optional temporal resolve, combine) as individual render graph
@@ -72,6 +82,11 @@ import { FrameResources } from '../render/rendergraph/blackboard.js';
72
82
  */ setup(s) {
73
83
  const { graph, ctx, history } = s;
74
84
  const linearDepthHandle = s.blackboard.get(FrameResources.LinearDepth);
85
+ // Reflected geometry must contribute its own radiance, not the fog the camera
86
+ // ray picked up on the way to it, which would otherwise be applied twice:
87
+ // once inside the reflection and again over the final image. Only published
88
+ // when the scene has fog; without it SceneColor is already fog free.
89
+ const noFogHandle = s.blackboard.get(FrameResources.SceneColorNoFog);
75
90
  const texDesc = {
76
91
  format: 'rgba16f',
77
92
  sizeMode: 'absolute',
@@ -120,6 +135,9 @@ import { FrameResources } from '../render/rendergraph/blackboard.js';
120
135
  // 2. Resolve reflection color from the intersect result.
121
136
  const resolveHandle = graph.addPass('SSR:Resolve', (builder)=>{
122
137
  builder.read(s.input);
138
+ if (noFogHandle) {
139
+ builder.read(noFogHandle);
140
+ }
123
141
  builder.read(intersectHandle);
124
142
  readCommon(builder);
125
143
  const out = builder.createTexture({
@@ -140,7 +158,7 @@ import { FrameResources } from '../render/rendergraph/blackboard.js';
140
158
  try {
141
159
  device.setFramebuffer(rg.getFramebuffer(fb));
142
160
  const inputTex = rg.getTexture(s.input);
143
- this.resolve(ctx, ctx.sceneColorTexture ?? inputTex, getLinearDepth(rg), rg.getTexture(intersectHandle));
161
+ this.resolve(ctx, noFogHandle ? rg.getTexture(noFogHandle) : ctx.sceneColorTexture ?? inputTex, getLinearDepth(rg), rg.getTexture(intersectHandle));
144
162
  } finally{
145
163
  device.popDeviceStates();
146
164
  }
@@ -189,10 +207,10 @@ import { FrameResources } from '../render/rendergraph/blackboard.js';
189
207
  const stdDev = ctx.camera.ssrBlurStdDev;
190
208
  const depthCutoff = ctx.camera.ssrBlurDepthCutoff;
191
209
  const blitterH = SSR._blurBlitterH = SSR._blurBlitterH ?? new BilateralBlurBlitter(false);
192
- blitterH.renderStates = AbstractPostEffect.getDefaultRenderState(ctx, 'gt');
210
+ blitterH.renderStates = AbstractPostEffect.getDefaultRenderState(ctx, DEPTH_COMPARE_FARTHER);
193
211
  this.blurPass(ctx, blitterH, intersectTex, 2, blurSizeScale, kernelRadius, stdDev, depthCutoff, rg.getTexture(resolveHandle), rg.getFramebuffer(middleFB));
194
212
  const blitterV = SSR._blurBlitterV = SSR._blurBlitterV ?? new BilateralBlurBlitter(true);
195
- blitterV.renderStates = AbstractPostEffect.getDefaultRenderState(ctx, 'gt');
213
+ blitterV.renderStates = AbstractPostEffect.getDefaultRenderState(ctx, DEPTH_COMPARE_FARTHER);
196
214
  this.blurPass(ctx, blitterV, intersectTex, 2, blurSizeScale, kernelRadius, stdDev, depthCutoff, rg.getTexture(middle), rg.getFramebuffer(outFB));
197
215
  } finally{
198
216
  device.popDeviceStates();
@@ -314,7 +332,7 @@ import { FrameResources } from '../render/rendergraph/blackboard.js';
314
332
  program = this._createCombineProgrm(ctx);
315
333
  SSR._combineProgram = program;
316
334
  }
317
- const roughnessTexture = ctx.SSRRoughnessTexture;
335
+ const roughnessTexture = ctx.SceneRoughnessTexture;
318
336
  if (!this._combineBindGroup) {
319
337
  this._combineBindGroup = device.createBindGroup(program.bindGroupLayouts[0]);
320
338
  }
@@ -325,7 +343,7 @@ import { FrameResources } from '../render/rendergraph/blackboard.js';
325
343
  this._combineBindGroup.setTexture('roughnessTex', roughnessTexture, linearSampler);
326
344
  this._combineBindGroup.setTexture('albedoTex', inputColorTexture, linearSampler);
327
345
  this._combineBindGroup.setTexture('extraTex', inputColorTexture, nearestSampler);
328
- this._combineBindGroup.setTexture('normalTex', ctx.SSRNormalTexture, nearestSampler);
346
+ this._combineBindGroup.setTexture('normalTex', ctx.SceneNormalTexture, nearestSampler);
329
347
  this._combineBindGroup.setTexture('depthTex', ctx.linearDepthTexture, nearestSampler);
330
348
  this._combineBindGroup.setTexture('zGGXLut', getGGXLUT(1024), fetchSampler('clamp_nearest_nomip'));
331
349
  this._combineBindGroup.setValue('ssrMaxRoughness', ctx.camera.ssrMaxRoughness);
@@ -338,7 +356,7 @@ import { FrameResources } from '../render/rendergraph/blackboard.js';
338
356
  this._combineBindGroup.setValue('srgbOut', srgbOut ? 1 : 0);
339
357
  device.setProgram(program);
340
358
  device.setBindGroup(0, this._combineBindGroup);
341
- this.drawFullscreenQuad(AbstractPostEffect.getDefaultRenderState(ctx, 'gt'));
359
+ this.drawFullscreenQuad(AbstractPostEffect.getDefaultRenderState(ctx, DEPTH_COMPARE_FARTHER));
342
360
  }
343
361
  /** @internal */ resolve(ctx, inputColorTexture, sceneDepthTexture, intersectTexture) {
344
362
  const device = ctx.device;
@@ -356,8 +374,8 @@ import { FrameResources } from '../render/rendergraph/blackboard.js';
356
374
  }
357
375
  const nearestSampler = fetchSampler('clamp_nearest');
358
376
  const linearSampler = fetchSampler('clamp_linear');
359
- const roughnessTexture = ctx.SSRRoughnessTexture;
360
- const normalTexture = ctx.SSRNormalTexture;
377
+ const roughnessTexture = ctx.SceneRoughnessTexture;
378
+ const normalTexture = ctx.SceneNormalTexture;
361
379
  bindGroup.setTexture('colorTex', inputColorTexture, linearSampler);
362
380
  bindGroup.setTexture('intersectTex', intersectTexture, nearestSampler);
363
381
  bindGroup.setTexture('roughnessTex', roughnessTexture, nearestSampler);
@@ -374,14 +392,14 @@ import { FrameResources } from '../render/rendergraph/blackboard.js';
374
392
  bindGroup.setValue('viewMatrix', ctx.camera.viewMatrix);
375
393
  bindGroup.setValue('invViewMatrix', ctx.camera.worldMatrix);
376
394
  if (hasEnvRadiance) {
377
- bindGroup.setValue('envLightStrength', ctx.env.light.strength);
395
+ bindGroup.setValue('envLightStrength', ShaderHelper.getEnvLightLuminance(ctx));
378
396
  bindGroup.setValue('envLightSpecularStrength', ctx.env.light.specularStrength ?? 1);
379
397
  ctx.env.light.envLight.updateBindGroup(bindGroup);
380
398
  }
381
399
  bindGroup.setValue('flip', this.needFlip(device) ? 1 : 0);
382
400
  device.setProgram(program);
383
401
  device.setBindGroup(0, bindGroup);
384
- this.drawFullscreenQuad(AbstractPostEffect.getDefaultRenderState(ctx, 'gt'));
402
+ this.drawFullscreenQuad(AbstractPostEffect.getDefaultRenderState(ctx, DEPTH_COMPARE_FARTHER));
385
403
  }
386
404
  /** @internal */ intersect(ctx, inputColorTexture, sceneDepthTexture, blur, srgbOut) {
387
405
  const device = ctx.device;
@@ -403,12 +421,12 @@ import { FrameResources } from '../render/rendergraph/blackboard.js';
403
421
  }
404
422
  const nearestSampler = fetchSampler('clamp_nearest');
405
423
  const linearSampler = fetchSampler('clamp_linear');
406
- const roughnessTexture = ctx.SSRRoughnessTexture;
407
- const normalTexture = ctx.SSRNormalTexture;
424
+ const roughnessTexture = ctx.SceneRoughnessTexture;
425
+ const normalTexture = ctx.SceneNormalTexture;
408
426
  if (!blur) {
409
427
  bindGroup.setTexture('colorTex', inputColorTexture, linearSampler);
410
428
  if (hasEnvRadiance) {
411
- bindGroup.setValue('envLightStrength', ctx.env.light.strength);
429
+ bindGroup.setValue('envLightStrength', ShaderHelper.getEnvLightLuminance(ctx));
412
430
  bindGroup.setValue('envLightSpecularStrength', ctx.env.light.specularStrength ?? 1);
413
431
  ctx.env.light.envLight.updateBindGroup(bindGroup);
414
432
  }
@@ -431,6 +449,9 @@ import { FrameResources } from '../render/rendergraph/blackboard.js';
431
449
  if (ctx.HiZTexture) {
432
450
  bindGroup.setTexture('hizTex', ctx.HiZTexture, nearestSampler);
433
451
  bindGroup.setValue('depthMipLevels', ctx.HiZTexture.mipLevelCount);
452
+ // Temporal jitter phase for the UE5-style fixed-step HZB march
453
+ // (UE View.StateFrameIndexMod8).
454
+ bindGroup.setValue('ssrFrameIndex', device.frameInfo.frameCounter % 8);
434
455
  bindGroup.setValue('targetSize', new Vector4(sceneDepthTexture.width, sceneDepthTexture.height, ctx.HiZTexture.width, ctx.HiZTexture.height));
435
456
  } else {
436
457
  bindGroup.setValue('ssrStride', ctx.camera.ssrStride);
@@ -440,7 +461,7 @@ import { FrameResources } from '../render/rendergraph/blackboard.js';
440
461
  bindGroup.setValue('srgbOut', srgbOut ? 1 : 0);
441
462
  device.setProgram(program);
442
463
  device.setBindGroup(0, bindGroup);
443
- this.drawFullscreenQuad(AbstractPostEffect.getDefaultRenderState(ctx, 'gt'));
464
+ this.drawFullscreenQuad(AbstractPostEffect.getDefaultRenderState(ctx, DEPTH_COMPARE_FARTHER));
444
465
  }
445
466
  /** @internal */ temporal(ctx, currentReflectTex, sceneDepthTexture, prevReflectTex, prevMotionVectorTex, outFramebuffer) {
446
467
  const device = ctx.device;
@@ -463,7 +484,7 @@ import { FrameResources } from '../render/rendergraph/blackboard.js';
463
484
  device.setFramebuffer(outFramebuffer);
464
485
  device.setProgram(program);
465
486
  device.setBindGroup(0, this._temporalBindGroup);
466
- this.drawFullscreenQuad(AbstractPostEffect.getDefaultRenderState(ctx, 'gt'));
487
+ this.drawFullscreenQuad(AbstractPostEffect.getDefaultRenderState(ctx, DEPTH_COMPARE_FARTHER));
467
488
  }
468
489
  /** {@inheritDoc AbstractPostEffect.apply} */ apply(ctx, inputColorTexture, sceneDepthTexture, srgbOutput) {
469
490
  const device = ctx.device;
@@ -486,10 +507,10 @@ import { FrameResources } from '../render/rendergraph/blackboard.js';
486
507
  const stdDev = ctx.camera.ssrBlurStdDev;
487
508
  const depthCutoff = ctx.camera.ssrBlurDepthCutoff;
488
509
  const blitterH = SSR._blurBlitterH = SSR._blurBlitterH ?? new BilateralBlurBlitter(false);
489
- blitterH.renderStates = AbstractPostEffect.getDefaultRenderState(ctx, 'gt');
510
+ blitterH.renderStates = AbstractPostEffect.getDefaultRenderState(ctx, DEPTH_COMPARE_FARTHER);
490
511
  this.blurPass(ctx, blitterH, intersectTex, 2, blurSizeScale, kernelRadius, stdDev, depthCutoff, pingpongFramebuffer[0].getColorAttachments()[0], pingpongFramebuffer[1]);
491
512
  const blitterV = SSR._blurBlitterV = SSR._blurBlitterV ?? new BilateralBlurBlitter(true);
492
- blitterV.renderStates = AbstractPostEffect.getDefaultRenderState(ctx, 'gt');
513
+ blitterV.renderStates = AbstractPostEffect.getDefaultRenderState(ctx, DEPTH_COMPARE_FARTHER);
493
514
  this.blurPass(ctx, blitterV, intersectTex, 2, blurSizeScale, kernelRadius, stdDev, depthCutoff, pingpongFramebuffer[1].getColorAttachments()[0], pingpongFramebuffer[0]);
494
515
  }
495
516
  const historyManager = ctx.camera.getHistoryResourceManager();
@@ -538,7 +559,7 @@ import { FrameResources } from '../render/rendergraph/blackboard.js';
538
559
  this.$inputs.pos = pb.vec2().attrib('position');
539
560
  this.$outputs.uv = pb.vec2();
540
561
  pb.main(function() {
541
- this.$builtins.position = pb.vec4(this.$inputs.pos, 1, 1);
562
+ this.$builtins.position = pb.vec4(this.$inputs.pos, DEPTH_FARTHEST, 1);
542
563
  this.$outputs.uv = pb.add(pb.mul(this.$inputs.pos.xy, 0.5), pb.vec2(0.5));
543
564
  this.$if(pb.notEqual(this.flip, 0), function() {
544
565
  this.$builtins.position.y = pb.neg(this.$builtins.position.y);
@@ -552,7 +573,10 @@ import { FrameResources } from '../render/rendergraph/blackboard.js';
552
573
  this.albedoTex = pb.tex2D().uniform(0);
553
574
  this.extraTex = pb.tex2D().uniform(0);
554
575
  this.normalTex = pb.tex2D().uniform(0);
555
- this.depthTex = pb.tex2D().uniform(0);
576
+ // Linear depth is r32f/rg32f and is only sampled with nearest
577
+ // filtering, so it must use the non-filtering float sample type on
578
+ // adapters without float32-filterable.
579
+ this.depthTex = pb.tex2D().sampleType('unfilterable-float').uniform(0);
556
580
  this.zGGXLut = pb.tex2D().uniform(0);
557
581
  this.targetSize = pb.vec4().uniform(0);
558
582
  this.cameraNearFar = pb.vec2().uniform(0);
@@ -566,8 +590,8 @@ import { FrameResources } from '../render/rendergraph/blackboard.js';
566
590
  pb.vec2('uv')
567
591
  ], function() {
568
592
  this.$l.linearDepth = ShaderHelper.sampleLinearDepth(this, this.depthTex, this.uv, 0);
569
- this.$l.nonLinearDepth = pb.div(pb.sub(pb.div(this.cameraNearFar.x, this.linearDepth), this.cameraNearFar.y), pb.sub(this.cameraNearFar.x, this.cameraNearFar.y));
570
- this.$l.clipSpacePos = pb.vec4(pb.sub(pb.mul(this.uv, 2), pb.vec2(1)), pb.sub(pb.mul(pb.clamp(this.nonLinearDepth, 0, 1), 2), 1), 1);
593
+ this.$l.nonLinearDepth = ShaderHelper.linearNormalizedToNonLinearDepth(this, this.linearDepth, this.cameraNearFar);
594
+ this.$l.clipSpacePos = pb.vec4(pb.sub(pb.mul(this.uv, 2), pb.vec2(1)), ShaderHelper.deviceDepthToClipZ(this, pb.clamp(this.nonLinearDepth, 0, 1)), 1);
571
595
  this.$l.viewPos4 = pb.mul(this.invProjMatrix, this.clipSpacePos);
572
596
  this.$return(pb.vec4(pb.div(this.viewPos4.xyz, this.viewPos4.w), this.linearDepth));
573
597
  });
@@ -660,7 +684,7 @@ import { FrameResources } from '../render/rendergraph/blackboard.js';
660
684
  ctx.env.light.envLight.initShaderBindings(pb);
661
685
  }
662
686
  pb.main(function() {
663
- this.$builtins.position = pb.vec4(this.$inputs.pos, 1, 1);
687
+ this.$builtins.position = pb.vec4(this.$inputs.pos, DEPTH_FARTHEST, 1);
664
688
  this.$outputs.uv = pb.add(pb.mul(this.$inputs.pos.xy, 0.5), pb.vec2(0.5));
665
689
  this.$if(pb.notEqual(this.flip, 0), function() {
666
690
  this.$builtins.position.y = pb.neg(this.$builtins.position.y);
@@ -674,7 +698,7 @@ import { FrameResources } from '../render/rendergraph/blackboard.js';
674
698
  this.normalTex = pb.tex2D().uniform(0);
675
699
  this.albedoTex = pb.tex2D().uniform(0);
676
700
  this.extraTex = pb.tex2D().uniform(0);
677
- this.depthTex = pb.tex2D().uniform(0);
701
+ this.depthTex = pb.tex2D().sampleType('unfilterable-float').uniform(0);
678
702
  this.zGGXLut = pb.tex2D().uniform(0);
679
703
  this.cameraNearFar = pb.vec2().uniform(0);
680
704
  this.targetSize = pb.vec4().uniform(0);
@@ -694,8 +718,8 @@ import { FrameResources } from '../render/rendergraph/blackboard.js';
694
718
  pb.mat4('mat')
695
719
  ], function() {
696
720
  this.$l.linearDepth = ShaderHelper.sampleLinearDepth(this, this.depthTex, this.uv, 0);
697
- this.$l.nonLinearDepth = pb.div(pb.sub(pb.div(this.cameraNearFar.x, this.linearDepth), this.cameraNearFar.y), pb.sub(this.cameraNearFar.x, this.cameraNearFar.y));
698
- this.$l.clipSpacePos = pb.vec4(pb.sub(pb.mul(this.uv, 2), pb.vec2(1)), pb.sub(pb.mul(pb.clamp(this.nonLinearDepth, 0, 1), 2), 1), 1);
721
+ this.$l.nonLinearDepth = ShaderHelper.linearNormalizedToNonLinearDepth(this, this.linearDepth, this.cameraNearFar);
722
+ this.$l.clipSpacePos = pb.vec4(pb.sub(pb.mul(this.uv, 2), pb.vec2(1)), ShaderHelper.deviceDepthToClipZ(this, pb.clamp(this.nonLinearDepth, 0, 1)), 1);
699
723
  this.$l.wPos = pb.mul(this.mat, this.clipSpacePos);
700
724
  this.$return(pb.vec4(pb.div(this.wPos.xyz, this.wPos.w), this.linearDepth));
701
725
  });
@@ -828,7 +852,7 @@ import { FrameResources } from '../render/rendergraph/blackboard.js';
828
852
  this.$inputs.pos = pb.vec2().attrib('position');
829
853
  this.$outputs.uv = pb.vec2();
830
854
  pb.main(function() {
831
- this.$builtins.position = pb.vec4(this.$inputs.pos, 1, 1);
855
+ this.$builtins.position = pb.vec4(this.$inputs.pos, DEPTH_FARTHEST, 1);
832
856
  this.$outputs.uv = pb.add(pb.mul(this.$inputs.pos.xy, 0.5), pb.vec2(0.5));
833
857
  this.$if(pb.notEqual(this.flip, 0), function() {
834
858
  this.$builtins.position.y = pb.neg(this.$builtins.position.y);
@@ -866,7 +890,7 @@ import { FrameResources } from '../render/rendergraph/blackboard.js';
866
890
  ctx.env.light.envLight.initShaderBindings(pb);
867
891
  }
868
892
  pb.main(function() {
869
- this.$builtins.position = pb.vec4(this.$inputs.pos, 1, 1);
893
+ this.$builtins.position = pb.vec4(this.$inputs.pos, DEPTH_FARTHEST, 1);
870
894
  this.$outputs.uv = pb.add(pb.mul(this.$inputs.pos.xy, 0.5), pb.vec2(0.5));
871
895
  this.$if(pb.notEqual(this.flip, 0), function() {
872
896
  this.$builtins.position.y = pb.neg(this.$builtins.position.y);
@@ -886,7 +910,7 @@ import { FrameResources } from '../render/rendergraph/blackboard.js';
886
910
  this.roughnessTex = pb.tex2D().uniform(0);
887
911
  this.normalTex = pb.tex2D().uniform(0);
888
912
  this.extraTex = pb.tex2D().uniform(0);
889
- this.depthTex = pb.tex2D().uniform(0);
913
+ this.depthTex = pb.tex2D().sampleType('unfilterable-float').uniform(0);
890
914
  this.zGGXLut = pb.tex2D().uniform(0);
891
915
  this.cameraNearFar = pb.vec2().uniform(0);
892
916
  this.cameraPos = pb.vec3().uniform(0);
@@ -899,8 +923,11 @@ import { FrameResources } from '../render/rendergraph/blackboard.js';
899
923
  this.ssrStrengthMode = pb.int().uniform(0);
900
924
  this.targetSize = pb.vec4().uniform(0);
901
925
  if (ctx.HiZTexture) {
902
- this.hizTex = pb.tex2D().uniform(0);
926
+ // Hi-Z is r32f and is sampled with a nearest sampler. Do not
927
+ // require the optional float32-filterable feature just to bind it.
928
+ this.hizTex = pb.tex2D().sampleType('unfilterable-float').uniform(0);
903
929
  this.depthMipLevels = pb.int().uniform(0);
930
+ this.ssrFrameIndex = pb.float().uniform(0);
904
931
  } else {
905
932
  this.ssrStride = pb.float().uniform(0);
906
933
  }
@@ -911,8 +938,8 @@ import { FrameResources } from '../render/rendergraph/blackboard.js';
911
938
  pb.mat4('mat')
912
939
  ], function() {
913
940
  this.$l.linearDepth = ShaderHelper.sampleLinearDepth(this, this.depthTex, this.uv, 0);
914
- this.$l.nonLinearDepth = pb.div(pb.sub(pb.div(this.cameraNearFar.x, this.linearDepth), this.cameraNearFar.y), pb.sub(this.cameraNearFar.x, this.cameraNearFar.y));
915
- this.$l.clipSpacePos = pb.vec4(pb.sub(pb.mul(this.uv, 2), pb.vec2(1)), pb.sub(pb.mul(pb.clamp(this.nonLinearDepth, 0, 1), 2), 1), 1);
941
+ this.$l.nonLinearDepth = ShaderHelper.linearNormalizedToNonLinearDepth(this, this.linearDepth, this.cameraNearFar);
942
+ this.$l.clipSpacePos = pb.vec4(pb.sub(pb.mul(this.uv, 2), pb.vec2(1)), ShaderHelper.deviceDepthToClipZ(this, pb.clamp(this.nonLinearDepth, 0, 1)), 1);
916
943
  this.$l.wPos = pb.mul(this.mat, this.clipSpacePos);
917
944
  this.$return(pb.vec4(pb.div(this.wPos.xyz, this.wPos.w), this.linearDepth));
918
945
  });
@@ -969,24 +996,35 @@ import { FrameResources } from '../render/rendergraph/blackboard.js';
969
996
  this.$l.reflectVec = pb.add(pb.reflect(this.viewVec, this.viewNormal), SSR_calcJitter(this, this.viewPos, this.roughness));
970
997
  this.$l.hitInfo = pb.vec4(0);
971
998
  if (ctx.HiZTexture) {
972
- this.hitInfo = screenSpaceRayTracing_HiZ(this, this.viewPos, this.reflectVec, this.viewMatrix, this.projMatrix, this.invProjMatrix, this.cameraNearFar, this.depthMipLevels, this.ssrParams.y, this.ssrParams.x, this.ssrParams.z, this.targetSize, this.hizTex, this.normalTex);
999
+ // UE5-style temporal jitter of the fixed-step march; the
1000
+ // temporal resolve pass converges the resulting noise.
1001
+ this.$l.ssrStepOffset = pb.sub(SSR_interleavedGradientNoise(this, this.$builtins.fragCoord.xy, this.ssrFrameIndex), 0.5);
1002
+ // Nudge the ray origin off the surface along the normal so the
1003
+ // grazing-angle march does not self-intersect the reflector's
1004
+ // quantized depth staircase (regular stripe artifacts). Scales
1005
+ // with view distance to track depth precision; same idea as the
1006
+ // SSGI ray-origin bias.
1007
+ this.$l.ssrRayOrigin = pb.add(this.viewPos, pb.mul(pb.normalize(this.viewNormal), pb.max(0.01, pb.mul(pb.neg(this.viewPos.z), 0.002))));
1008
+ this.hitInfo = screenSpaceRayTracing_HiZ(this, this.ssrRayOrigin, this.reflectVec, this.viewMatrix, this.projMatrix, this.invProjMatrix, this.cameraNearFar, this.depthMipLevels, this.ssrParams.y, this.ssrParams.x, this.ssrParams.z, this.targetSize, this.hizTex, this.normalTex, undefined, this.roughness, this.ssrStepOffset);
973
1009
  } else {
974
1010
  this.hitInfo = screenSpaceRayTracing_Linear2D(this, this.viewPos, this.reflectVec, this.viewMatrix, this.projMatrix, this.invProjMatrix, this.cameraNearFar, this.ssrParams.x, this.ssrParams.y, this.ssrParams.z, this.ssrStride, this.targetSize, this.depthTex, this.normalTex, !!ctx.camera.ssrCalcThickness);
975
1011
  }
976
1012
  this.$l.hitAlpha = pb.clamp(this.hitInfo.w, 0, 1);
977
1013
  this.$l.hitUV = pb.clamp(this.hitInfo.xy, pb.vec2(0), pb.vec2(1));
978
1014
  if (blur) {
979
- this.blurRadius = pb.float(0);
980
- this.$if(pb.greaterThan(this.roughness, 0.001), function() {
981
- this.$l.coneAngle = pb.mul(pb.min(this.roughness, 0.999), Math.PI * 0.5);
982
- this.$l.coneLen = this.$choice(pb.greaterThan(this.hitAlpha, 0), this.hitInfo.z, pb.min(this.targetSize.z, this.targetSize.w));
983
- this.$l.opLen = pb.mul(pb.tan(this.coneAngle), this.coneLen, 2);
984
- this.$l.a2 = pb.mul(this.opLen, this.opLen);
985
- this.$l.fh2 = pb.mul(this.coneLen, this.coneLen, 4);
986
- this.blurRadius = pb.div(pb.mul(this.opLen, pb.sub(pb.sqrt(pb.add(this.a2, this.fh2)), this.opLen)), pb.mul(this.coneLen, 4));
987
- });
988
- this.a = this.hitAlpha;
989
- this.color = pb.vec3(this.hitUV, pb.clamp(pb.div(this.blurRadius, 255), 0, 1));
1015
+ if (ctx.HiZTexture && DEBUG_HIZ_INTERSECT) ; else {
1016
+ this.blurRadius = pb.float(0);
1017
+ this.$if(pb.greaterThan(this.roughness, 0.001), function() {
1018
+ this.$l.coneAngle = pb.mul(pb.min(this.roughness, 0.999), Math.PI * 0.5);
1019
+ this.$l.coneLen = this.$choice(pb.greaterThan(this.hitAlpha, 0), this.hitInfo.z, pb.min(this.targetSize.x, this.targetSize.y));
1020
+ this.$l.opLen = pb.mul(pb.tan(this.coneAngle), this.coneLen, 2);
1021
+ this.$l.a2 = pb.mul(this.opLen, this.opLen);
1022
+ this.$l.fh2 = pb.mul(this.coneLen, this.coneLen, 4);
1023
+ this.blurRadius = pb.div(pb.mul(this.opLen, pb.sub(pb.sqrt(pb.add(this.a2, this.fh2)), this.opLen)), pb.mul(this.coneLen, 4));
1024
+ });
1025
+ this.a = this.hitAlpha;
1026
+ this.color = pb.vec3(this.hitUV, pb.clamp(pb.div(this.blurRadius, 255), 0, 1));
1027
+ }
990
1028
  } else {
991
1029
  if (ctx.env.light.envLight?.hasRadiance()) {
992
1030
  this.$l.reflectVecW = pb.mul(this.invViewMatrix, pb.vec4(this.reflectVec, 0)).xyz;