@babylonjs/core 8.40.0 → 8.40.1

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 (181) hide show
  1. package/Compute/computeEffect.js +5 -1
  2. package/Compute/computeEffect.js.map +1 -1
  3. package/Compute/computeShader.d.ts +4 -0
  4. package/Compute/computeShader.js +9 -3
  5. package/Compute/computeShader.js.map +1 -1
  6. package/Engines/abstractEngine.js +2 -2
  7. package/Engines/abstractEngine.js.map +1 -1
  8. package/FrameGraph/Passes/renderPass.js +2 -2
  9. package/FrameGraph/Passes/renderPass.js.map +1 -1
  10. package/FrameGraph/Tasks/Layers/baseLayerTask.d.ts +2 -0
  11. package/FrameGraph/Tasks/Layers/baseLayerTask.js +6 -0
  12. package/FrameGraph/Tasks/Layers/baseLayerTask.js.map +1 -1
  13. package/FrameGraph/Tasks/Layers/glowLayerTask.d.ts +1 -0
  14. package/FrameGraph/Tasks/Layers/glowLayerTask.js +3 -0
  15. package/FrameGraph/Tasks/Layers/glowLayerTask.js.map +1 -1
  16. package/FrameGraph/Tasks/Layers/highlightLayerTask.d.ts +1 -0
  17. package/FrameGraph/Tasks/Layers/highlightLayerTask.js +3 -0
  18. package/FrameGraph/Tasks/Layers/highlightLayerTask.js.map +1 -1
  19. package/FrameGraph/Tasks/Misc/computeShaderTask.d.ts +1 -0
  20. package/FrameGraph/Tasks/Misc/computeShaderTask.js +3 -0
  21. package/FrameGraph/Tasks/Misc/computeShaderTask.js.map +1 -1
  22. package/FrameGraph/Tasks/Misc/cullObjectsTask.d.ts +1 -0
  23. package/FrameGraph/Tasks/Misc/cullObjectsTask.js +3 -0
  24. package/FrameGraph/Tasks/Misc/cullObjectsTask.js.map +1 -1
  25. package/FrameGraph/Tasks/Misc/executeTask.d.ts +1 -0
  26. package/FrameGraph/Tasks/Misc/executeTask.js +3 -0
  27. package/FrameGraph/Tasks/Misc/executeTask.js.map +1 -1
  28. package/FrameGraph/Tasks/Misc/lightingVolumeTask.d.ts +1 -0
  29. package/FrameGraph/Tasks/Misc/lightingVolumeTask.js +8 -1
  30. package/FrameGraph/Tasks/Misc/lightingVolumeTask.js.map +1 -1
  31. package/FrameGraph/Tasks/PostProcesses/anaglyphTask.d.ts +1 -0
  32. package/FrameGraph/Tasks/PostProcesses/anaglyphTask.js +3 -0
  33. package/FrameGraph/Tasks/PostProcesses/anaglyphTask.js.map +1 -1
  34. package/FrameGraph/Tasks/PostProcesses/blackAndWhiteTask.d.ts +1 -0
  35. package/FrameGraph/Tasks/PostProcesses/blackAndWhiteTask.js +3 -0
  36. package/FrameGraph/Tasks/PostProcesses/blackAndWhiteTask.js.map +1 -1
  37. package/FrameGraph/Tasks/PostProcesses/bloomMergeTask.d.ts +1 -0
  38. package/FrameGraph/Tasks/PostProcesses/bloomMergeTask.js +3 -0
  39. package/FrameGraph/Tasks/PostProcesses/bloomMergeTask.js.map +1 -1
  40. package/FrameGraph/Tasks/PostProcesses/bloomTask.d.ts +1 -0
  41. package/FrameGraph/Tasks/PostProcesses/bloomTask.js +3 -0
  42. package/FrameGraph/Tasks/PostProcesses/bloomTask.js.map +1 -1
  43. package/FrameGraph/Tasks/PostProcesses/blurTask.d.ts +1 -0
  44. package/FrameGraph/Tasks/PostProcesses/blurTask.js +3 -0
  45. package/FrameGraph/Tasks/PostProcesses/blurTask.js.map +1 -1
  46. package/FrameGraph/Tasks/PostProcesses/chromaticAberrationTask.d.ts +1 -0
  47. package/FrameGraph/Tasks/PostProcesses/chromaticAberrationTask.js +3 -0
  48. package/FrameGraph/Tasks/PostProcesses/chromaticAberrationTask.js.map +1 -1
  49. package/FrameGraph/Tasks/PostProcesses/circleOfConfusionTask.d.ts +1 -0
  50. package/FrameGraph/Tasks/PostProcesses/circleOfConfusionTask.js +3 -0
  51. package/FrameGraph/Tasks/PostProcesses/circleOfConfusionTask.js.map +1 -1
  52. package/FrameGraph/Tasks/PostProcesses/colorCorrectionTask.d.ts +1 -0
  53. package/FrameGraph/Tasks/PostProcesses/colorCorrectionTask.js +3 -0
  54. package/FrameGraph/Tasks/PostProcesses/colorCorrectionTask.js.map +1 -1
  55. package/FrameGraph/Tasks/PostProcesses/convolutionTask.d.ts +1 -0
  56. package/FrameGraph/Tasks/PostProcesses/convolutionTask.js +3 -0
  57. package/FrameGraph/Tasks/PostProcesses/convolutionTask.js.map +1 -1
  58. package/FrameGraph/Tasks/PostProcesses/customPostProcessTask.d.ts +1 -0
  59. package/FrameGraph/Tasks/PostProcesses/customPostProcessTask.js +3 -0
  60. package/FrameGraph/Tasks/PostProcesses/customPostProcessTask.js.map +1 -1
  61. package/FrameGraph/Tasks/PostProcesses/depthOfFieldBlurTask.d.ts +1 -0
  62. package/FrameGraph/Tasks/PostProcesses/depthOfFieldBlurTask.js +3 -0
  63. package/FrameGraph/Tasks/PostProcesses/depthOfFieldBlurTask.js.map +1 -1
  64. package/FrameGraph/Tasks/PostProcesses/depthOfFieldMergeTask.d.ts +1 -0
  65. package/FrameGraph/Tasks/PostProcesses/depthOfFieldMergeTask.js +3 -0
  66. package/FrameGraph/Tasks/PostProcesses/depthOfFieldMergeTask.js.map +1 -1
  67. package/FrameGraph/Tasks/PostProcesses/depthOfFieldTask.d.ts +1 -0
  68. package/FrameGraph/Tasks/PostProcesses/depthOfFieldTask.js +3 -0
  69. package/FrameGraph/Tasks/PostProcesses/depthOfFieldTask.js.map +1 -1
  70. package/FrameGraph/Tasks/PostProcesses/extractHighlightsTask.d.ts +1 -0
  71. package/FrameGraph/Tasks/PostProcesses/extractHighlightsTask.js +3 -0
  72. package/FrameGraph/Tasks/PostProcesses/extractHighlightsTask.js.map +1 -1
  73. package/FrameGraph/Tasks/PostProcesses/filterTask.d.ts +1 -0
  74. package/FrameGraph/Tasks/PostProcesses/filterTask.js +3 -0
  75. package/FrameGraph/Tasks/PostProcesses/filterTask.js.map +1 -1
  76. package/FrameGraph/Tasks/PostProcesses/fxaaTask.d.ts +1 -0
  77. package/FrameGraph/Tasks/PostProcesses/fxaaTask.js +3 -0
  78. package/FrameGraph/Tasks/PostProcesses/fxaaTask.js.map +1 -1
  79. package/FrameGraph/Tasks/PostProcesses/grainTask.d.ts +1 -0
  80. package/FrameGraph/Tasks/PostProcesses/grainTask.js +3 -0
  81. package/FrameGraph/Tasks/PostProcesses/grainTask.js.map +1 -1
  82. package/FrameGraph/Tasks/PostProcesses/imageProcessingTask.d.ts +1 -0
  83. package/FrameGraph/Tasks/PostProcesses/imageProcessingTask.js +3 -0
  84. package/FrameGraph/Tasks/PostProcesses/imageProcessingTask.js.map +1 -1
  85. package/FrameGraph/Tasks/PostProcesses/motionBlurTask.d.ts +1 -0
  86. package/FrameGraph/Tasks/PostProcesses/motionBlurTask.js +3 -0
  87. package/FrameGraph/Tasks/PostProcesses/motionBlurTask.js.map +1 -1
  88. package/FrameGraph/Tasks/PostProcesses/passTask.d.ts +2 -0
  89. package/FrameGraph/Tasks/PostProcesses/passTask.js +6 -0
  90. package/FrameGraph/Tasks/PostProcesses/passTask.js.map +1 -1
  91. package/FrameGraph/Tasks/PostProcesses/postProcessTask.d.ts +1 -0
  92. package/FrameGraph/Tasks/PostProcesses/postProcessTask.js +3 -0
  93. package/FrameGraph/Tasks/PostProcesses/postProcessTask.js.map +1 -1
  94. package/FrameGraph/Tasks/PostProcesses/screenSpaceCurvatureTask.d.ts +1 -0
  95. package/FrameGraph/Tasks/PostProcesses/screenSpaceCurvatureTask.js +3 -0
  96. package/FrameGraph/Tasks/PostProcesses/screenSpaceCurvatureTask.js.map +1 -1
  97. package/FrameGraph/Tasks/PostProcesses/sharpenTask.d.ts +1 -0
  98. package/FrameGraph/Tasks/PostProcesses/sharpenTask.js +3 -0
  99. package/FrameGraph/Tasks/PostProcesses/sharpenTask.js.map +1 -1
  100. package/FrameGraph/Tasks/PostProcesses/ssao2BlurTask.d.ts +1 -0
  101. package/FrameGraph/Tasks/PostProcesses/ssao2BlurTask.js +3 -0
  102. package/FrameGraph/Tasks/PostProcesses/ssao2BlurTask.js.map +1 -1
  103. package/FrameGraph/Tasks/PostProcesses/ssao2RenderingPipelineTask.d.ts +1 -0
  104. package/FrameGraph/Tasks/PostProcesses/ssao2RenderingPipelineTask.js +3 -0
  105. package/FrameGraph/Tasks/PostProcesses/ssao2RenderingPipelineTask.js.map +1 -1
  106. package/FrameGraph/Tasks/PostProcesses/ssao2Task.d.ts +1 -0
  107. package/FrameGraph/Tasks/PostProcesses/ssao2Task.js +3 -0
  108. package/FrameGraph/Tasks/PostProcesses/ssao2Task.js.map +1 -1
  109. package/FrameGraph/Tasks/PostProcesses/ssrBlurTask.d.ts +1 -0
  110. package/FrameGraph/Tasks/PostProcesses/ssrBlurTask.js +3 -0
  111. package/FrameGraph/Tasks/PostProcesses/ssrBlurTask.js.map +1 -1
  112. package/FrameGraph/Tasks/PostProcesses/ssrRenderingPipelineTask.d.ts +1 -0
  113. package/FrameGraph/Tasks/PostProcesses/ssrRenderingPipelineTask.js +3 -0
  114. package/FrameGraph/Tasks/PostProcesses/ssrRenderingPipelineTask.js.map +1 -1
  115. package/FrameGraph/Tasks/PostProcesses/ssrTask.d.ts +1 -0
  116. package/FrameGraph/Tasks/PostProcesses/ssrTask.js +3 -0
  117. package/FrameGraph/Tasks/PostProcesses/ssrTask.js.map +1 -1
  118. package/FrameGraph/Tasks/PostProcesses/taaTask.d.ts +1 -0
  119. package/FrameGraph/Tasks/PostProcesses/taaTask.js +3 -0
  120. package/FrameGraph/Tasks/PostProcesses/taaTask.js.map +1 -1
  121. package/FrameGraph/Tasks/PostProcesses/tonemapTask.d.ts +1 -0
  122. package/FrameGraph/Tasks/PostProcesses/tonemapTask.js +3 -0
  123. package/FrameGraph/Tasks/PostProcesses/tonemapTask.js.map +1 -1
  124. package/FrameGraph/Tasks/PostProcesses/volumetricLightingBlendVolumeTask.d.ts +1 -0
  125. package/FrameGraph/Tasks/PostProcesses/volumetricLightingBlendVolumeTask.js +3 -0
  126. package/FrameGraph/Tasks/PostProcesses/volumetricLightingBlendVolumeTask.js.map +1 -1
  127. package/FrameGraph/Tasks/PostProcesses/volumetricLightingTask.d.ts +3 -1
  128. package/FrameGraph/Tasks/PostProcesses/volumetricLightingTask.js +12 -6
  129. package/FrameGraph/Tasks/PostProcesses/volumetricLightingTask.js.map +1 -1
  130. package/FrameGraph/Tasks/Rendering/csmShadowGeneratorTask.d.ts +1 -0
  131. package/FrameGraph/Tasks/Rendering/csmShadowGeneratorTask.js +3 -0
  132. package/FrameGraph/Tasks/Rendering/csmShadowGeneratorTask.js.map +1 -1
  133. package/FrameGraph/Tasks/Rendering/geometryRendererTask.d.ts +1 -0
  134. package/FrameGraph/Tasks/Rendering/geometryRendererTask.js +3 -0
  135. package/FrameGraph/Tasks/Rendering/geometryRendererTask.js.map +1 -1
  136. package/FrameGraph/Tasks/Rendering/objectRendererTask.d.ts +1 -0
  137. package/FrameGraph/Tasks/Rendering/objectRendererTask.js +3 -0
  138. package/FrameGraph/Tasks/Rendering/objectRendererTask.js.map +1 -1
  139. package/FrameGraph/Tasks/Rendering/shadowGeneratorTask.d.ts +1 -0
  140. package/FrameGraph/Tasks/Rendering/shadowGeneratorTask.js +3 -0
  141. package/FrameGraph/Tasks/Rendering/shadowGeneratorTask.js.map +1 -1
  142. package/FrameGraph/Tasks/Rendering/utilityLayerRendererTask.d.ts +1 -0
  143. package/FrameGraph/Tasks/Rendering/utilityLayerRendererTask.js +3 -0
  144. package/FrameGraph/Tasks/Rendering/utilityLayerRendererTask.js.map +1 -1
  145. package/FrameGraph/Tasks/Texture/clearTextureTask.d.ts +1 -0
  146. package/FrameGraph/Tasks/Texture/clearTextureTask.js +3 -0
  147. package/FrameGraph/Tasks/Texture/clearTextureTask.js.map +1 -1
  148. package/FrameGraph/Tasks/Texture/copyToBackbufferColorTask.d.ts +1 -0
  149. package/FrameGraph/Tasks/Texture/copyToBackbufferColorTask.js +3 -0
  150. package/FrameGraph/Tasks/Texture/copyToBackbufferColorTask.js.map +1 -1
  151. package/FrameGraph/Tasks/Texture/copyToTextureTask.d.ts +1 -0
  152. package/FrameGraph/Tasks/Texture/copyToTextureTask.js +21 -4
  153. package/FrameGraph/Tasks/Texture/copyToTextureTask.js.map +1 -1
  154. package/FrameGraph/Tasks/Texture/generateMipMapsTask.d.ts +1 -0
  155. package/FrameGraph/Tasks/Texture/generateMipMapsTask.js +3 -0
  156. package/FrameGraph/Tasks/Texture/generateMipMapsTask.js.map +1 -1
  157. package/FrameGraph/frameGraphRenderContext.d.ts +1 -0
  158. package/FrameGraph/frameGraphRenderContext.js +14 -5
  159. package/FrameGraph/frameGraphRenderContext.js.map +1 -1
  160. package/FrameGraph/frameGraphTask.d.ts +5 -0
  161. package/FrameGraph/frameGraphTask.js +9 -0
  162. package/FrameGraph/frameGraphTask.js.map +1 -1
  163. package/Lights/lightingVolume.d.ts +10 -1
  164. package/Lights/lightingVolume.js +201 -102
  165. package/Lights/lightingVolume.js.map +1 -1
  166. package/Meshes/geometry.d.ts +2 -1
  167. package/Meshes/geometry.js +6 -2
  168. package/Meshes/geometry.js.map +1 -1
  169. package/Meshes/mesh.d.ts +2 -1
  170. package/Meshes/mesh.js +4 -3
  171. package/Meshes/mesh.js.map +1 -1
  172. package/Shaders/volumetricLightingRenderVolume.fragment.js +2 -2
  173. package/Shaders/volumetricLightingRenderVolume.fragment.js.map +1 -1
  174. package/ShadersWGSL/lightingVolume.compute.js +10 -4
  175. package/ShadersWGSL/lightingVolume.compute.js.map +1 -1
  176. package/ShadersWGSL/volumetricLightingRenderVolume.fragment.js +2 -2
  177. package/ShadersWGSL/volumetricLightingRenderVolume.fragment.js.map +1 -1
  178. package/States/alphaCullingState.d.ts +1 -0
  179. package/States/alphaCullingState.js +3 -0
  180. package/States/alphaCullingState.js.map +1 -1
  181. package/package.json +1 -1
@@ -13,6 +13,7 @@ export declare class LightingVolume {
13
13
  private readonly _buildFullVolume;
14
14
  private _name;
15
15
  private _cs?;
16
+ private _cs2?;
16
17
  private _light?;
17
18
  private _fallbackTexture?;
18
19
  private _storageBuffer?;
@@ -22,6 +23,9 @@ export declare class LightingVolume {
22
23
  private _numFrames;
23
24
  private _firstUpdate;
24
25
  private _currentLightDirection;
26
+ private _positions;
27
+ private _indices;
28
+ private _needFullUpdateUBO;
25
29
  private _shadowGenerator?;
26
30
  /**
27
31
  * The shadow generator used to create the lighting volume.
@@ -56,6 +60,8 @@ export declare class LightingVolume {
56
60
  * If true, the volume has not yet been updated for the first time.
57
61
  */
58
62
  get firstUpdate(): boolean;
63
+ /** @internal */
64
+ _setComputeShaderFastMode(enabled: boolean): void;
59
65
  /**
60
66
  * Creates a new LightingVolume.
61
67
  * @param name The name of the lighting volume.
@@ -78,9 +84,12 @@ export declare class LightingVolume {
78
84
  * Disposes the lighting volume and associated resources.
79
85
  */
80
86
  dispose(): void;
81
- private _recreateGeometry;
87
+ private _needUpdateGeometry;
82
88
  private _createComputeShader;
83
89
  private _createFallbackTextures;
84
90
  private _fallbackReadPixelAsync;
91
+ private _fullUpdateUBO;
85
92
  private _createGeometry;
93
+ private _updateGeometry;
94
+ private _createIndices;
86
95
  }
@@ -1,6 +1,6 @@
1
1
  import { AbortError } from "../Misc/error.js";
2
2
 
3
- import { Matrix, Vector3 } from "../Maths/math.vector.js";
3
+ import { Matrix, Vector3, TmpVectors } from "../Maths/math.vector.js";
4
4
  import { DirectionalLight } from "./directionalLight.js";
5
5
  import { Mesh } from "../Meshes/mesh.js";
6
6
  import { ComputeShader } from "../Compute/computeShader.js";
@@ -10,7 +10,6 @@ import { StorageBuffer } from "../Buffers/storageBuffer.js";
10
10
  import { BaseTexture } from "../Materials/Textures/baseTexture.js";
11
11
  import { VertexBuffer } from "../Buffers/buffer.js";
12
12
  import "../ShadersWGSL/lightingVolume.compute.js";
13
- const InvViewProjMatrix = new Matrix();
14
13
  const TmpVec3 = new Vector3();
15
14
  /**
16
15
  * Class used to create a lighting volume from a directional light's shadow generator.
@@ -29,13 +28,14 @@ export class LightingVolume {
29
28
  }
30
29
  this._shadowGenerator = sg;
31
30
  this._light = light;
32
- this._createGeometry();
31
+ this._updateGeometry();
33
32
  if (!this._engine.isWebGPU) {
34
33
  this._createFallbackTextures();
35
34
  }
36
35
  const depthTexture = this._shadowGenerator.getShadowMap()?.depthStencilTexture;
37
- if (this._cs && depthTexture) {
36
+ if (this._engine.isWebGPU && depthTexture) {
38
37
  this._cs.setInternalTexture("shadowMap", depthTexture);
38
+ this._cs2.setInternalTexture("shadowMap", depthTexture);
39
39
  }
40
40
  }
41
41
  /**
@@ -46,7 +46,7 @@ export class LightingVolume {
46
46
  }
47
47
  set tesselation(n) {
48
48
  this._tesselation = n;
49
- this._createGeometry(true);
49
+ this._createGeometry();
50
50
  }
51
51
  /**
52
52
  * The mesh used as a support for the lighting volume.
@@ -85,6 +85,17 @@ export class LightingVolume {
85
85
  get firstUpdate() {
86
86
  return this._firstUpdate;
87
87
  }
88
+ /** @internal */
89
+ _setComputeShaderFastMode(enabled) {
90
+ if (this._cs) {
91
+ this._cs.fastMode = enabled;
92
+ this._cs.triggerContextRebuild = enabled;
93
+ }
94
+ if (this._cs2) {
95
+ this._cs2.fastMode = enabled;
96
+ this._cs2.triggerContextRebuild = enabled;
97
+ }
98
+ }
88
99
  /**
89
100
  * Creates a new LightingVolume.
90
101
  * @param name The name of the lighting volume.
@@ -99,6 +110,7 @@ export class LightingVolume {
99
110
  this._numFrames = 0;
100
111
  this._firstUpdate = true;
101
112
  this._currentLightDirection = new Vector3();
113
+ this._needFullUpdateUBO = true;
102
114
  this._tesselation = 0;
103
115
  this._frequency = 1;
104
116
  const light = shadowGenerator ? shadowGenerator.getLight() : undefined;
@@ -108,6 +120,7 @@ export class LightingVolume {
108
120
  this._name = name;
109
121
  this._shadowGenerator = shadowGenerator;
110
122
  this._light = light;
123
+ this._indices = [];
111
124
  this._engine = scene.getEngine();
112
125
  this._scene = scene;
113
126
  this._mesh = new Mesh(name, this._scene);
@@ -115,9 +128,12 @@ export class LightingVolume {
115
128
  if (this._engine.isWebGPU) {
116
129
  this._uBuffer = new UniformBuffer(this._engine);
117
130
  this._uBuffer.addUniform("invViewProjMatrix", 16);
131
+ this._uBuffer.addUniform("invViewMatrix", 16);
118
132
  this._uBuffer.addUniform("startVertexIndex", 1);
119
133
  this._uBuffer.addUniform("step", 1);
120
134
  this._uBuffer.addUniform("tesselation", 1);
135
+ this._uBuffer.addUniform("orthoMin", 3);
136
+ this._uBuffer.addUniform("orthoMax", 3);
121
137
  this._uBuffer.update();
122
138
  this._createComputeShader();
123
139
  }
@@ -126,7 +142,7 @@ export class LightingVolume {
126
142
  this._createFallbackTextures();
127
143
  }
128
144
  this._tesselation = tesselation;
129
- this._createGeometry(true);
145
+ this._createGeometry();
130
146
  }
131
147
  /**
132
148
  * Checks if the lighting volume is ready to be updated.
@@ -137,6 +153,9 @@ export class LightingVolume {
137
153
  if (this._cs) {
138
154
  isReady = this._cs.isReady() && isReady;
139
155
  }
156
+ if (this._cs2) {
157
+ isReady = this._cs2.isReady() && isReady;
158
+ }
140
159
  return isReady;
141
160
  }
142
161
  /**
@@ -151,16 +170,24 @@ export class LightingVolume {
151
170
  return;
152
171
  }
153
172
  this._numFrames = 0;
154
- if (this._cs && this._uBuffer) {
155
- this._recreateGeometry();
156
- const dispatchSize = Math.ceil((this._tesselation + 1) / 8);
157
- const viewProjMatrix = this._shadowGenerator.getTransformMatrix();
158
- viewProjMatrix.invertToRef(InvViewProjMatrix);
159
- this._uBuffer.updateMatrix("invViewProjMatrix", InvViewProjMatrix);
160
- this._uBuffer.update();
173
+ if (this._engine.isWebGPU) {
174
+ this._uBuffer.updateMatrix("invViewProjMatrix", this._shadowGenerator.getTransformMatrix().invertToRef(TmpVectors.Matrix[0]));
161
175
  this._engine._debugPushGroup?.(`Update lighting volume (${this._name})`, 1);
176
+ if (this._needUpdateGeometry()) {
177
+ this._fullUpdateUBO(true);
178
+ const dispatchSize = Math.ceil((this._tesselation + 1) / 32);
179
+ this._engine._debugPushGroup?.(`Update vertices of other planes`, 1);
180
+ this._cs2.dispatch(dispatchSize, 1, 1);
181
+ this._engine._debugPopGroup?.(1);
182
+ }
183
+ else {
184
+ this._fullUpdateUBO();
185
+ }
186
+ const dispatchSize = Math.ceil((this._tesselation + 1) / 8);
187
+ this._engine._debugPushGroup?.(`Update vertices of far plane`, 1);
162
188
  this._cs.dispatch(dispatchSize, dispatchSize, 1);
163
189
  this._engine._debugPopGroup?.(1);
190
+ this._engine._debugPopGroup?.(1);
164
191
  this._firstUpdate = false;
165
192
  }
166
193
  else {
@@ -188,32 +215,45 @@ export class LightingVolume {
188
215
  this._uBuffer?.dispose();
189
216
  this._depthCopy?.dispose();
190
217
  }
191
- _recreateGeometry() {
192
- if (this._light && !this._currentLightDirection.equals(this._light.direction)) {
218
+ _needUpdateGeometry() {
219
+ if (this._cs?.triggerContextRebuild || (this._light && !this._currentLightDirection.equals(this._light.direction))) {
193
220
  this._currentLightDirection.copyFrom(this._light.direction);
194
- this._createGeometry();
221
+ return true;
195
222
  }
223
+ return false;
196
224
  }
197
225
  _createComputeShader() {
198
- this._cs = new ComputeShader("createLightVolume", this._engine, "lightingVolume", {
226
+ this._cs = new ComputeShader("updateFarPlaneVertices", this._engine, "lightingVolume", {
199
227
  bindingsMapping: {
200
228
  shadowMap: { group: 0, binding: 0 },
201
229
  params: { group: 0, binding: 1 },
202
230
  positions: { group: 0, binding: 2 },
203
231
  },
204
232
  defines: !this._buildFullVolume ? ["#define KEEP_EDGES", "#define MOVE_FAR_DEPTH_TO_NEAR"] : undefined,
233
+ entryPoint: "updateFarPlaneVertices",
234
+ });
235
+ this._cs2 = new ComputeShader("updatePlaneVertices", this._engine, "lightingVolume", {
236
+ bindingsMapping: {
237
+ shadowMap: { group: 0, binding: 0 },
238
+ params: { group: 0, binding: 1 },
239
+ positions: { group: 0, binding: 2 },
240
+ },
241
+ entryPoint: "updatePlaneVertices",
205
242
  });
206
243
  if (this._shadowGenerator) {
207
244
  const depthTexture = this._shadowGenerator.getShadowMap()?.depthStencilTexture;
208
245
  if (depthTexture) {
209
246
  this._cs.setInternalTexture("shadowMap", depthTexture);
247
+ this._cs2.setInternalTexture("shadowMap", depthTexture);
210
248
  }
211
249
  }
212
250
  if (this._uBuffer) {
213
251
  this._cs.setUniformBuffer("params", this._uBuffer);
252
+ this._cs2.setUniformBuffer("params", this._uBuffer);
214
253
  }
215
254
  if (this._storageBuffer) {
216
255
  this._cs.setStorageBuffer("positions", this._storageBuffer);
256
+ this._cs2.setStorageBuffer("positions", this._storageBuffer);
217
257
  }
218
258
  }
219
259
  _createFallbackTextures() {
@@ -274,7 +314,9 @@ export class LightingVolume {
274
314
  const invViewProjMatrix = shadowGenerator.getTransformMatrix().clone();
275
315
  invViewProjMatrix.invertToRef(invViewProjMatrix);
276
316
  const factor = 4;
277
- this._recreateGeometry();
317
+ if (this._needUpdateGeometry()) {
318
+ this._updateGeometry();
319
+ }
278
320
  let posIndex = startPos;
279
321
  let stepY = 0;
280
322
  for (let y = 0; y < numTesselation + 1; ++y) {
@@ -302,136 +344,193 @@ export class LightingVolume {
302
344
  this._readPixelPromise = null;
303
345
  this._firstUpdate = false;
304
346
  }
305
- _createGeometry(_recreateAll = false) {
306
- if (!this._light) {
347
+ _fullUpdateUBO(force = false) {
348
+ const light = this._light;
349
+ if ((!force && !this._needFullUpdateUBO) || !light || !this._shadowGenerator) {
350
+ this._uBuffer.update();
351
+ return;
352
+ }
353
+ this._needFullUpdateUBO = false;
354
+ const numTesselation = this._tesselation;
355
+ const min = TmpVectors.Vector3[0].set(light.orthoLeft, light.orthoBottom, light.shadowMinZ ?? 0);
356
+ const max = TmpVectors.Vector3[1].set(light.orthoRight, light.orthoTop, light.shadowMaxZ ?? 10000);
357
+ const invViewMatrix = this._shadowGenerator.viewMatrix.invertToRef(TmpVectors.Matrix[1]);
358
+ this._uBuffer.updateUInt("startVertexIndex", this._buildFullVolume ? (numTesselation + 1) * 4 * 3 : 4 * 3);
359
+ this._uBuffer.updateFloat("step", ((this._shadowGenerator?.mapSize ?? 128) - 1) / numTesselation);
360
+ this._uBuffer.updateUInt("tesselation", numTesselation);
361
+ this._uBuffer.updateVector3("orthoMin", min);
362
+ this._uBuffer.updateVector3("orthoMax", max);
363
+ this._uBuffer.updateMatrix("invViewMatrix", invViewMatrix);
364
+ this._uBuffer.update();
365
+ }
366
+ _createGeometry() {
367
+ const light = this._light;
368
+ if (!light) {
307
369
  return;
308
370
  }
309
371
  this._tesselation = Math.max(Math.ceil(this._tesselation) & ~1, 2);
372
+ const numTesselation = this._tesselation;
373
+ const vertexNumber = (numTesselation + 1) * (numTesselation + 1) + (this._buildFullVolume ? (numTesselation + 1) * 4 : 4);
374
+ this._positions = new Float32Array(vertexNumber * 3);
375
+ this._indices.length = 0;
376
+ this._createIndices(light);
377
+ this._mesh.setIndices(this._indices, vertexNumber);
378
+ if (this._engine.isWebGPU) {
379
+ const webGPUEngine = this._engine;
380
+ this._storageBuffer?.dispose();
381
+ this._storageBuffer = new StorageBuffer(webGPUEngine, vertexNumber * 3 * 4, 8 | 3);
382
+ this._mesh.setVerticesBuffer(new VertexBuffer(webGPUEngine, this._storageBuffer.getBuffer(), "position", { takeBufferOwnership: false }), true, vertexNumber);
383
+ this._cs.setStorageBuffer("positions", this._storageBuffer);
384
+ this._cs2.setStorageBuffer("positions", this._storageBuffer);
385
+ this._cs.triggerContextRebuild = true;
386
+ this._cs2.triggerContextRebuild = true;
387
+ this._needFullUpdateUBO = true;
388
+ }
389
+ this._updateGeometry();
390
+ }
391
+ _updateGeometry() {
310
392
  const light = this._light;
311
- const min = new Vector3(light.orthoLeft, light.orthoBottom, light.shadowMinZ ?? 0);
312
- const max = new Vector3(light.orthoRight, light.orthoTop, light.shadowMaxZ ?? 10000);
313
- const invViewMatrix = Matrix.LookAtLH(light.position, light.position.add(light.direction), Vector3.UpReadOnly);
314
- invViewMatrix.invertToRef(invViewMatrix);
315
- const positions = [];
316
- const indices = [];
393
+ if (!light || !this._shadowGenerator) {
394
+ return;
395
+ }
396
+ if (this._indices.length === 0) {
397
+ this._createGeometry();
398
+ return;
399
+ }
400
+ if (this._engine.isWebGPU) {
401
+ return;
402
+ }
317
403
  const numTesselation = this._tesselation;
404
+ const min = TmpVectors.Vector3[0].set(light.orthoLeft, light.orthoBottom, light.shadowMinZ ?? 0);
405
+ const max = TmpVectors.Vector3[1].set(light.orthoRight, light.orthoTop, light.shadowMaxZ ?? 10000);
406
+ const invViewMatrix = this._shadowGenerator.viewMatrix.invertToRef(TmpVectors.Matrix[1]);
318
407
  const stepX = (max.x - min.x) / numTesselation;
319
408
  const stepY = (max.y - min.y) / numTesselation;
320
- const v = new Vector3();
409
+ let vIndex = 0;
410
+ if (this._buildFullVolume) {
411
+ // Right faces of the frustum
412
+ for (let i = 0; i <= numTesselation; ++i) {
413
+ TmpVec3.set(max.x, min.y + i * stepY, min.z);
414
+ Vector3.TransformCoordinatesToRef(TmpVec3, invViewMatrix, TmpVec3);
415
+ this._positions[vIndex++] = TmpVec3.x;
416
+ this._positions[vIndex++] = TmpVec3.y;
417
+ this._positions[vIndex++] = TmpVec3.z;
418
+ }
419
+ // Left faces of the frustum
420
+ for (let i = 0; i <= numTesselation; ++i) {
421
+ TmpVec3.set(min.x, min.y + i * stepY, min.z);
422
+ Vector3.TransformCoordinatesToRef(TmpVec3, invViewMatrix, TmpVec3);
423
+ this._positions[vIndex++] = TmpVec3.x;
424
+ this._positions[vIndex++] = TmpVec3.y;
425
+ this._positions[vIndex++] = TmpVec3.z;
426
+ }
427
+ // Bottom faces of the frustum
428
+ for (let i = 0; i <= numTesselation; ++i) {
429
+ TmpVec3.set(min.x + i * stepX, min.y, min.z);
430
+ Vector3.TransformCoordinatesToRef(TmpVec3, invViewMatrix, TmpVec3);
431
+ this._positions[vIndex++] = TmpVec3.x;
432
+ this._positions[vIndex++] = TmpVec3.y;
433
+ this._positions[vIndex++] = TmpVec3.z;
434
+ }
435
+ // Top faces of the frustum
436
+ for (let i = 0; i <= numTesselation; ++i) {
437
+ TmpVec3.set(min.x + i * stepX, max.y, min.z);
438
+ Vector3.TransformCoordinatesToRef(TmpVec3, invViewMatrix, TmpVec3);
439
+ this._positions[vIndex++] = TmpVec3.x;
440
+ this._positions[vIndex++] = TmpVec3.y;
441
+ this._positions[vIndex++] = TmpVec3.z;
442
+ }
443
+ }
444
+ else {
445
+ // Closes the volume with two near triangles
446
+ TmpVec3.set(max.x, min.y, min.z);
447
+ Vector3.TransformCoordinatesToRef(TmpVec3, invViewMatrix, TmpVec3);
448
+ this._positions[vIndex++] = TmpVec3.x;
449
+ this._positions[vIndex++] = TmpVec3.y;
450
+ this._positions[vIndex++] = TmpVec3.z;
451
+ TmpVec3.set(max.x, max.y, min.z);
452
+ Vector3.TransformCoordinatesToRef(TmpVec3, invViewMatrix, TmpVec3);
453
+ this._positions[vIndex++] = TmpVec3.x;
454
+ this._positions[vIndex++] = TmpVec3.y;
455
+ this._positions[vIndex++] = TmpVec3.z;
456
+ TmpVec3.set(min.x, min.y, min.z);
457
+ Vector3.TransformCoordinatesToRef(TmpVec3, invViewMatrix, TmpVec3);
458
+ this._positions[vIndex++] = TmpVec3.x;
459
+ this._positions[vIndex++] = TmpVec3.y;
460
+ this._positions[vIndex++] = TmpVec3.z;
461
+ TmpVec3.set(min.x, max.y, min.z);
462
+ Vector3.TransformCoordinatesToRef(TmpVec3, invViewMatrix, TmpVec3);
463
+ this._positions[vIndex++] = TmpVec3.x;
464
+ this._positions[vIndex++] = TmpVec3.y;
465
+ this._positions[vIndex++] = TmpVec3.z;
466
+ }
467
+ this._mesh.setVerticesData("position", this._positions);
468
+ }
469
+ _createIndices(light) {
470
+ const invViewMatrix = Matrix.LookAtLH(light.position, light.position.add(light.direction), Vector3.UpReadOnly);
471
+ invViewMatrix.invertToRef(invViewMatrix);
472
+ const numTesselation = this._tesselation;
321
473
  const startFarIndices = this._buildFullVolume ? (numTesselation + 1) * 4 : 4;
322
474
  if (this._buildFullVolume) {
323
- let startIndices = 0;
324
- const rightFaceStartIndex = startIndices;
475
+ const rightFaceStartIndex = 0;
325
476
  // Right faces of the frustum
326
477
  for (let i = 0; i <= numTesselation; ++i) {
327
- v.set(max.x, min.y + i * stepY, min.z);
328
- const p = Vector3.TransformCoordinates(v, invViewMatrix);
329
- positions.push(p.x, p.y, p.z);
330
478
  if (i < numTesselation) {
331
- indices.push(startIndices + i, startFarIndices + numTesselation + (i + 1) * (numTesselation + 1), startFarIndices + numTesselation + i * (numTesselation + 1));
332
- indices.push(startIndices + i, startIndices + i + 1, startFarIndices + numTesselation + (i + 1) * (numTesselation + 1));
479
+ this._indices.push(rightFaceStartIndex + i, startFarIndices + numTesselation + (i + 1) * (numTesselation + 1), startFarIndices + numTesselation + i * (numTesselation + 1));
480
+ this._indices.push(rightFaceStartIndex + i, rightFaceStartIndex + i + 1, startFarIndices + numTesselation + (i + 1) * (numTesselation + 1));
333
481
  }
334
482
  }
335
- startIndices = positions.length / 3;
336
- const leftFaceStartIndex = startIndices;
483
+ const leftFaceStartIndex = rightFaceStartIndex + numTesselation + 1;
337
484
  // Left faces of the frustum
338
485
  for (let i = 0; i <= numTesselation; ++i) {
339
- v.set(min.x, min.y + i * stepY, min.z);
340
- const p = Vector3.TransformCoordinates(v, invViewMatrix);
341
- positions.push(p.x, p.y, p.z);
342
486
  if (i < numTesselation) {
343
- indices.push(startIndices + i, startFarIndices + 0 + i * (numTesselation + 1), startFarIndices + 0 + (i + 1) * (numTesselation + 1));
344
- indices.push(startIndices + i, startFarIndices + 0 + (i + 1) * (numTesselation + 1), startIndices + i + 1);
487
+ this._indices.push(leftFaceStartIndex + i, startFarIndices + 0 + i * (numTesselation + 1), startFarIndices + 0 + (i + 1) * (numTesselation + 1));
488
+ this._indices.push(leftFaceStartIndex + i, startFarIndices + 0 + (i + 1) * (numTesselation + 1), leftFaceStartIndex + i + 1);
345
489
  }
346
490
  }
347
- startIndices = positions.length / 3;
348
- const bottomFaceStartIndex = startIndices;
491
+ const bottomFaceStartIndex = leftFaceStartIndex + numTesselation + 1;
349
492
  // Bottom faces of the frustum
350
493
  for (let i = 0; i <= numTesselation; ++i) {
351
- v.set(min.x + i * stepX, min.y, min.z);
352
- const p = Vector3.TransformCoordinates(v, invViewMatrix);
353
- positions.push(p.x, p.y, p.z);
354
494
  if (i < numTesselation) {
355
- indices.push(startIndices + i, startIndices + i + 1, startFarIndices + i + 0 * (numTesselation + 1));
356
- indices.push(startIndices + i + 1, startFarIndices + i + 1 + 0 * (numTesselation + 1), startFarIndices + i + 0 * (numTesselation + 1));
495
+ this._indices.push(bottomFaceStartIndex + i, bottomFaceStartIndex + i + 1, startFarIndices + i + 0 * (numTesselation + 1));
496
+ this._indices.push(bottomFaceStartIndex + i + 1, startFarIndices + i + 1 + 0 * (numTesselation + 1), startFarIndices + i + 0 * (numTesselation + 1));
357
497
  }
358
498
  }
359
- startIndices = positions.length / 3;
360
- const topFaceStartIndex = startIndices;
499
+ const topFaceStartIndex = bottomFaceStartIndex + numTesselation + 1;
361
500
  // Top faces of the frustum
362
501
  for (let i = 0; i <= numTesselation; ++i) {
363
- v.set(min.x + i * stepX, max.y, min.z);
364
- const p = Vector3.TransformCoordinates(v, invViewMatrix);
365
- positions.push(p.x, p.y, p.z);
366
502
  if (i < numTesselation) {
367
- indices.push(startIndices + i, startFarIndices + i + numTesselation * (numTesselation + 1), startIndices + i + 1);
368
- indices.push(startIndices + i + 1, startFarIndices + i + numTesselation * (numTesselation + 1), startFarIndices + i + 1 + numTesselation * (numTesselation + 1));
503
+ this._indices.push(topFaceStartIndex + i, startFarIndices + i + numTesselation * (numTesselation + 1), topFaceStartIndex + i + 1);
504
+ this._indices.push(topFaceStartIndex + i + 1, startFarIndices + i + numTesselation * (numTesselation + 1), startFarIndices + i + 1 + numTesselation * (numTesselation + 1));
369
505
  }
370
506
  }
371
- startIndices = positions.length / 3;
372
507
  // Near faces of the frustum
373
508
  for (let i = 0; i < numTesselation; ++i) {
374
- indices.push(leftFaceStartIndex + i, leftFaceStartIndex + i + 1, topFaceStartIndex + numTesselation - i);
509
+ this._indices.push(leftFaceStartIndex + i, leftFaceStartIndex + i + 1, topFaceStartIndex + numTesselation - i);
375
510
  if (i < numTesselation - 1) {
376
- indices.push(leftFaceStartIndex + i + 1, topFaceStartIndex + numTesselation - i - 1, topFaceStartIndex + numTesselation - i);
511
+ this._indices.push(leftFaceStartIndex + i + 1, topFaceStartIndex + numTesselation - i - 1, topFaceStartIndex + numTesselation - i);
377
512
  }
378
513
  }
379
514
  for (let i = 0; i < numTesselation; ++i) {
380
- indices.push(bottomFaceStartIndex + i, rightFaceStartIndex + numTesselation - i, rightFaceStartIndex + numTesselation - i - 1);
515
+ this._indices.push(bottomFaceStartIndex + i, rightFaceStartIndex + numTesselation - i, rightFaceStartIndex + numTesselation - i - 1);
381
516
  if (i < numTesselation - 1) {
382
- indices.push(bottomFaceStartIndex + i, rightFaceStartIndex + numTesselation - i - 1, bottomFaceStartIndex + i + 1);
517
+ this._indices.push(bottomFaceStartIndex + i, rightFaceStartIndex + numTesselation - i - 1, bottomFaceStartIndex + i + 1);
383
518
  }
384
519
  }
385
520
  }
386
521
  else {
387
- let p;
388
- v.set(max.x, min.y, min.z);
389
- p = Vector3.TransformCoordinates(v, invViewMatrix);
390
- positions.push(p.x, p.y, p.z);
391
- v.set(max.x, max.y, min.z);
392
- p = Vector3.TransformCoordinates(v, invViewMatrix);
393
- positions.push(p.x, p.y, p.z);
394
- v.set(min.x, min.y, min.z);
395
- p = Vector3.TransformCoordinates(v, invViewMatrix);
396
- positions.push(p.x, p.y, p.z);
397
- v.set(min.x, max.y, min.z);
398
- p = Vector3.TransformCoordinates(v, invViewMatrix);
399
- positions.push(p.x, p.y, p.z);
400
- indices.push(0, 2, 1);
401
- indices.push(2, 3, 1);
402
- }
403
- // Tesselate the near plane
404
- let y = min.y;
522
+ this._indices.push(0, 2, 1);
523
+ this._indices.push(2, 3, 1);
524
+ }
525
+ // Tesselate the far plane
405
526
  for (let iy = 0; iy <= numTesselation; ++iy) {
406
- let x = min.x;
407
527
  for (let ix = 0; ix <= numTesselation; ++ix) {
408
- v.set(x, y, min.z);
409
- const p = Vector3.TransformCoordinates(v, invViewMatrix);
410
- positions.push(p.x, p.y, p.z);
411
528
  if (ix < numTesselation && iy < numTesselation) {
412
- indices.push(startFarIndices + ix + iy * (numTesselation + 1), startFarIndices + ix + 1 + iy * (numTesselation + 1), startFarIndices + ix + 1 + (iy + 1) * (numTesselation + 1));
413
- indices.push(startFarIndices + ix + iy * (numTesselation + 1), startFarIndices + ix + 1 + (iy + 1) * (numTesselation + 1), startFarIndices + ix + (iy + 1) * (numTesselation + 1));
529
+ this._indices.push(startFarIndices + ix + iy * (numTesselation + 1), startFarIndices + ix + 1 + iy * (numTesselation + 1), startFarIndices + ix + 1 + (iy + 1) * (numTesselation + 1));
530
+ this._indices.push(startFarIndices + ix + iy * (numTesselation + 1), startFarIndices + ix + 1 + (iy + 1) * (numTesselation + 1), startFarIndices + ix + (iy + 1) * (numTesselation + 1));
414
531
  }
415
- x += stepX;
416
532
  }
417
- y += stepY;
418
- }
419
- if (this._uBuffer && this._cs) {
420
- const webGPUEngine = this._engine;
421
- this._storageBuffer?.dispose();
422
- this._storageBuffer = new StorageBuffer(webGPUEngine, positions.length * 4, 8 | 3);
423
- this._storageBuffer.update(positions);
424
- const vertexBuffer = new VertexBuffer(webGPUEngine, this._storageBuffer.getBuffer(), "position", { takeBufferOwnership: false });
425
- this._mesh.setVerticesBuffer(vertexBuffer);
426
- this._cs.setStorageBuffer("positions", this._storageBuffer);
427
- this._uBuffer.updateUInt("startVertexIndex", this._buildFullVolume ? (numTesselation + 1) * 4 * 3 : 4 * 3);
428
- this._uBuffer.updateFloat("step", ((this._shadowGenerator?.mapSize ?? 128) - 1) / numTesselation);
429
- this._uBuffer.updateUInt("tesselation", numTesselation);
430
- }
431
- else {
432
- this._mesh.setVerticesData("position", positions);
433
533
  }
434
- this._mesh.setIndices(indices, positions.length / 3);
435
534
  }
436
535
  }
437
536
  //# sourceMappingURL=lightingVolume.js.map