@babylonjs/core 8.15.0 → 8.16.0

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 (173) hide show
  1. package/Animations/animatable.core.d.ts +6 -0
  2. package/Animations/animatable.core.js +7 -1
  3. package/Animations/animatable.core.js.map +1 -1
  4. package/Animations/animationGroup.d.ts +3 -1
  5. package/Animations/animationGroup.js +3 -2
  6. package/Animations/animationGroup.js.map +1 -1
  7. package/AudioV2/webAudio/components/webAudioParameterComponent.d.ts +8 -0
  8. package/AudioV2/webAudio/components/webAudioParameterComponent.js +36 -3
  9. package/AudioV2/webAudio/components/webAudioParameterComponent.js.map +1 -1
  10. package/AudioV2/webAudio/subNodes/spatialWebAudioSubNode.js +10 -0
  11. package/AudioV2/webAudio/subNodes/spatialWebAudioSubNode.js.map +1 -1
  12. package/AudioV2/webAudio/subProperties/spatialWebAudioListener.js +11 -0
  13. package/AudioV2/webAudio/subProperties/spatialWebAudioListener.js.map +1 -1
  14. package/AudioV2/webAudio/webAudioEngine.d.ts +7 -0
  15. package/AudioV2/webAudio/webAudioEngine.js +45 -0
  16. package/AudioV2/webAudio/webAudioEngine.js.map +1 -1
  17. package/AudioV2/webAudio/webAudioStaticSound.d.ts +1 -0
  18. package/AudioV2/webAudio/webAudioStaticSound.js +4 -1
  19. package/AudioV2/webAudio/webAudioStaticSound.js.map +1 -1
  20. package/Behaviors/Cameras/framingBehavior.js +3 -3
  21. package/Behaviors/Cameras/framingBehavior.js.map +1 -1
  22. package/Debug/directionalLightFrustumViewer.d.ts +6 -0
  23. package/Debug/directionalLightFrustumViewer.js +39 -1
  24. package/Debug/directionalLightFrustumViewer.js.map +1 -1
  25. package/Engines/AbstractEngine/abstractEngine.alpha.d.ts +2 -1
  26. package/Engines/AbstractEngine/abstractEngine.alpha.js +9 -9
  27. package/Engines/AbstractEngine/abstractEngine.alpha.js.map +1 -1
  28. package/Engines/AbstractEngine/abstractEngine.states.d.ts +4 -104
  29. package/Engines/AbstractEngine/abstractEngine.states.js +4 -70
  30. package/Engines/AbstractEngine/abstractEngine.states.js.map +1 -1
  31. package/Engines/AbstractEngine/abstractEngine.stencil.d.ts +147 -0
  32. package/Engines/AbstractEngine/abstractEngine.stencil.js +93 -0
  33. package/Engines/AbstractEngine/abstractEngine.stencil.js.map +1 -0
  34. package/Engines/AbstractEngine/index.d.ts +1 -0
  35. package/Engines/AbstractEngine/index.js +1 -0
  36. package/Engines/AbstractEngine/index.js.map +1 -1
  37. package/Engines/Extensions/engine.alpha.d.ts +2 -1
  38. package/Engines/Extensions/engine.alpha.js +7 -78
  39. package/Engines/Extensions/engine.alpha.js.map +1 -1
  40. package/Engines/WebGL/webGL2ShaderProcessors.js +8 -1
  41. package/Engines/WebGL/webGL2ShaderProcessors.js.map +1 -1
  42. package/Engines/WebGPU/Extensions/engine.alpha.d.ts +2 -1
  43. package/Engines/WebGPU/Extensions/engine.alpha.js +12 -82
  44. package/Engines/WebGPU/Extensions/engine.alpha.js.map +1 -1
  45. package/Engines/WebGPU/webgpuCacheRenderPipeline.d.ts +12 -5
  46. package/Engines/WebGPU/webgpuCacheRenderPipeline.js +139 -72
  47. package/Engines/WebGPU/webgpuCacheRenderPipeline.js.map +1 -1
  48. package/Engines/WebGPU/webgpuShaderProcessorsWGSL.js +13 -1
  49. package/Engines/WebGPU/webgpuShaderProcessorsWGSL.js.map +1 -1
  50. package/Engines/WebGPU/webgpuStencilStateComposer.d.ts +8 -0
  51. package/Engines/WebGPU/webgpuStencilStateComposer.js +40 -0
  52. package/Engines/WebGPU/webgpuStencilStateComposer.js.map +1 -1
  53. package/Engines/abstractEngine.d.ts +7 -3
  54. package/Engines/abstractEngine.js +12 -5
  55. package/Engines/abstractEngine.js.map +1 -1
  56. package/Engines/constants.d.ts +30 -28
  57. package/Engines/constants.js +30 -28
  58. package/Engines/constants.js.map +1 -1
  59. package/Engines/engine.d.ts +10 -0
  60. package/Engines/engine.js +1 -0
  61. package/Engines/engine.js.map +1 -1
  62. package/Engines/engineCapabilities.d.ts +4 -0
  63. package/Engines/engineCapabilities.js.map +1 -1
  64. package/Engines/nativeEngine.d.ts +2 -1
  65. package/Engines/nativeEngine.js +6 -3
  66. package/Engines/nativeEngine.js.map +1 -1
  67. package/Engines/nullEngine.d.ts +2 -1
  68. package/Engines/nullEngine.js +7 -4
  69. package/Engines/nullEngine.js.map +1 -1
  70. package/Engines/thinEngine.js +16 -3
  71. package/Engines/thinEngine.js.map +1 -1
  72. package/Engines/webgpuEngine.d.ts +1 -0
  73. package/Engines/webgpuEngine.js +6 -4
  74. package/Engines/webgpuEngine.js.map +1 -1
  75. package/FrameGraph/Tasks/PostProcesses/passTask.d.ts +1 -1
  76. package/FrameGraph/Tasks/PostProcesses/passTask.js.map +1 -1
  77. package/FrameGraph/Tasks/Rendering/objectRendererTask.d.ts +8 -1
  78. package/FrameGraph/Tasks/Rendering/objectRendererTask.js +14 -6
  79. package/FrameGraph/Tasks/Rendering/objectRendererTask.js.map +1 -1
  80. package/FrameGraph/Tasks/Rendering/shadowGeneratorTask.js +3 -0
  81. package/FrameGraph/Tasks/Rendering/shadowGeneratorTask.js.map +1 -1
  82. package/FrameGraph/Tasks/Rendering/taaObjectRendererTask.js +6 -5
  83. package/FrameGraph/Tasks/Rendering/taaObjectRendererTask.js.map +1 -1
  84. package/FrameGraph/Tasks/Texture/clearTextureTask.d.ts +1 -1
  85. package/FrameGraph/Tasks/Texture/clearTextureTask.js +7 -5
  86. package/FrameGraph/Tasks/Texture/clearTextureTask.js.map +1 -1
  87. package/FrameGraph/frameGraph.d.ts +6 -0
  88. package/FrameGraph/frameGraph.js +8 -0
  89. package/FrameGraph/frameGraph.js.map +1 -1
  90. package/FrameGraph/frameGraphContext.d.ts +16 -0
  91. package/FrameGraph/frameGraphContext.js +23 -0
  92. package/FrameGraph/frameGraphContext.js.map +1 -1
  93. package/FrameGraph/frameGraphRenderContext.d.ts +9 -16
  94. package/FrameGraph/frameGraphRenderContext.js +15 -23
  95. package/FrameGraph/frameGraphRenderContext.js.map +1 -1
  96. package/FrameGraph/frameGraphUtils.d.ts +52 -0
  97. package/FrameGraph/frameGraphUtils.js +99 -0
  98. package/FrameGraph/frameGraphUtils.js.map +1 -0
  99. package/FrameGraph/index.d.ts +1 -0
  100. package/FrameGraph/index.js +1 -0
  101. package/FrameGraph/index.js.map +1 -1
  102. package/Gizmos/boundingBoxGizmo.js +2 -0
  103. package/Gizmos/boundingBoxGizmo.js.map +1 -1
  104. package/Loading/Plugins/babylonFileLoader.js +35 -2
  105. package/Loading/Plugins/babylonFileLoader.js.map +1 -1
  106. package/Materials/material.d.ts +32 -12
  107. package/Materials/material.js +49 -17
  108. package/Materials/material.js.map +1 -1
  109. package/Materials/materialStencilState.d.ts +24 -0
  110. package/Materials/materialStencilState.js +53 -1
  111. package/Materials/materialStencilState.js.map +1 -1
  112. package/Meshes/GaussianSplatting/gaussianSplattingMesh.js +4 -4
  113. package/Meshes/GaussianSplatting/gaussianSplattingMesh.js.map +1 -1
  114. package/Meshes/geometry.js +1 -1
  115. package/Meshes/geometry.js.map +1 -1
  116. package/Meshes/instancedMesh.d.ts +5 -0
  117. package/Meshes/instancedMesh.js +3 -3
  118. package/Meshes/instancedMesh.js.map +1 -1
  119. package/Meshes/mesh.d.ts +28 -5
  120. package/Meshes/mesh.js +127 -57
  121. package/Meshes/mesh.js.map +1 -1
  122. package/Meshes/thinInstanceMesh.js +4 -0
  123. package/Meshes/thinInstanceMesh.js.map +1 -1
  124. package/Misc/snapshotRenderingHelper.js +2 -1
  125. package/Misc/snapshotRenderingHelper.js.map +1 -1
  126. package/PostProcesses/RenderPipeline/Pipelines/taaMaterialManager.d.ts +71 -0
  127. package/PostProcesses/RenderPipeline/Pipelines/taaMaterialManager.js +156 -0
  128. package/PostProcesses/RenderPipeline/Pipelines/taaMaterialManager.js.map +1 -0
  129. package/PostProcesses/RenderPipeline/Pipelines/taaRenderingPipeline.d.ts +13 -0
  130. package/PostProcesses/RenderPipeline/Pipelines/taaRenderingPipeline.js +79 -3
  131. package/PostProcesses/RenderPipeline/Pipelines/taaRenderingPipeline.js.map +1 -1
  132. package/PostProcesses/RenderPipeline/postProcessRenderPipeline.d.ts +4 -0
  133. package/PostProcesses/RenderPipeline/postProcessRenderPipeline.js +5 -0
  134. package/PostProcesses/RenderPipeline/postProcessRenderPipeline.js.map +1 -1
  135. package/PostProcesses/RenderPipeline/postProcessRenderPipelineManager.d.ts +12 -3
  136. package/PostProcesses/RenderPipeline/postProcessRenderPipelineManager.js +22 -1
  137. package/PostProcesses/RenderPipeline/postProcessRenderPipelineManager.js.map +1 -1
  138. package/PostProcesses/thinPassPostProcess.js +7 -3
  139. package/PostProcesses/thinPassPostProcess.js.map +1 -1
  140. package/PostProcesses/thinTAAPostProcess.d.ts +17 -0
  141. package/PostProcesses/thinTAAPostProcess.js +51 -0
  142. package/PostProcesses/thinTAAPostProcess.js.map +1 -1
  143. package/Rendering/edgesRenderer.js +3 -2
  144. package/Rendering/edgesRenderer.js.map +1 -1
  145. package/Rendering/geometryBufferRenderer.js +1 -1
  146. package/Rendering/geometryBufferRenderer.js.map +1 -1
  147. package/Rendering/outlineRenderer.js +1 -1
  148. package/Rendering/outlineRenderer.js.map +1 -1
  149. package/Shaders/lod.fragment.js +2 -3
  150. package/Shaders/lod.fragment.js.map +1 -1
  151. package/Shaders/taa.fragment.js +15 -1
  152. package/Shaders/taa.fragment.js.map +1 -1
  153. package/ShadersWGSL/lod.fragment.js +2 -2
  154. package/ShadersWGSL/lod.fragment.js.map +1 -1
  155. package/ShadersWGSL/taa.fragment.js +16 -2
  156. package/ShadersWGSL/taa.fragment.js.map +1 -1
  157. package/States/IStencilState.d.ts +6 -2
  158. package/States/IStencilState.js.map +1 -1
  159. package/States/alphaCullingState.d.ts +7 -5
  160. package/States/alphaCullingState.js +144 -33
  161. package/States/alphaCullingState.js.map +1 -1
  162. package/States/stencilState.d.ts +12 -0
  163. package/States/stencilState.js +29 -1
  164. package/States/stencilState.js.map +1 -1
  165. package/States/stencilStateComposer.d.ts +12 -0
  166. package/States/stencilStateComposer.js +48 -2
  167. package/States/stencilStateComposer.js.map +1 -1
  168. package/assetContainer.js +29 -8
  169. package/assetContainer.js.map +1 -1
  170. package/package.json +1 -1
  171. package/scene.d.ts +2 -1
  172. package/scene.js +1 -0
  173. package/scene.js.map +1 -1
@@ -15,14 +15,16 @@ var StatePosition;
15
15
  StatePosition[StatePosition["DepthBias"] = 2] = "DepthBias";
16
16
  StatePosition[StatePosition["DepthBiasSlopeScale"] = 3] = "DepthBiasSlopeScale";
17
17
  StatePosition[StatePosition["DepthStencilState"] = 4] = "DepthStencilState";
18
- StatePosition[StatePosition["MRTAttachments1"] = 5] = "MRTAttachments1";
19
- StatePosition[StatePosition["MRTAttachments2"] = 6] = "MRTAttachments2";
20
- StatePosition[StatePosition["RasterizationState"] = 7] = "RasterizationState";
21
- StatePosition[StatePosition["ColorStates"] = 8] = "ColorStates";
22
- StatePosition[StatePosition["ShaderStage"] = 9] = "ShaderStage";
23
- StatePosition[StatePosition["TextureStage"] = 10] = "TextureStage";
24
- StatePosition[StatePosition["VertexState"] = 11] = "VertexState";
25
- StatePosition[StatePosition["NumStates"] = 12] = "NumStates";
18
+ StatePosition[StatePosition["MRTAttachments"] = 5] = "MRTAttachments";
19
+ StatePosition[StatePosition["RasterizationState"] = 6] = "RasterizationState";
20
+ StatePosition[StatePosition["ColorStates1"] = 7] = "ColorStates1";
21
+ StatePosition[StatePosition["ColorStates2"] = 8] = "ColorStates2";
22
+ StatePosition[StatePosition["ColorStates3"] = 9] = "ColorStates3";
23
+ StatePosition[StatePosition["ColorStates4"] = 10] = "ColorStates4";
24
+ StatePosition[StatePosition["ShaderStage"] = 11] = "ShaderStage";
25
+ StatePosition[StatePosition["TextureStage"] = 12] = "TextureStage";
26
+ StatePosition[StatePosition["VertexState"] = 13] = "VertexState";
27
+ StatePosition[StatePosition["NumStates"] = 14] = "NumStates";
26
28
  })(StatePosition || (StatePosition = {}));
27
29
  const alphaBlendFactorToIndex = {
28
30
  0: 1, // Zero
@@ -38,8 +40,19 @@ const alphaBlendFactorToIndex = {
38
40
  0x0308: 11, // SrcAlphaSaturated
39
41
  0x8001: 12, // BlendColor
40
42
  0x8002: 13, // OneMinusBlendColor
41
- 0x8003: 12, // BlendColor (alpha)
42
- 0x8004: 13, // OneMinusBlendColor (alpha)
43
+ 0x8003: 14, // BlendColor (alpha)
44
+ 0x8004: 15, // OneMinusBlendColor (alpha)
45
+ 0x88f9: 16, // Src1Color
46
+ 0x88fa: 17, // OneMinusSrc1Color
47
+ 0x8589: 18, // Src1Alpha
48
+ 0x88fb: 19, // OneMinusSrc1Alpha
49
+ };
50
+ const alphaBlendEquationToIndex = {
51
+ 0x8006: 0, // Add
52
+ 0x8007: 1, // Min
53
+ 0x8008: 2, // Max
54
+ 0x800a: 3, // Subtract
55
+ 0x800b: 4, // ReverseSubtract
43
56
  };
44
57
  const stencilOpToIndex = {
45
58
  0x0000: 0, // ZERO
@@ -51,6 +64,7 @@ const stencilOpToIndex = {
51
64
  0x8507: 6, // INCR_WRAP
52
65
  0x8508: 7, // DECR_WRAP
53
66
  };
67
+ const colorStates = [0, 0, 0, 0];
54
68
  /** @internal */
55
69
  export class WebGPUCacheRenderPipeline {
56
70
  constructor(device, emptyVertexBuffer) {
@@ -79,7 +93,7 @@ export class WebGPUCacheRenderPipeline {
79
93
  this._webgpuColorFormat = ["bgra8unorm" /* WebGPUConstants.TextureFormat.BGRA8Unorm */];
80
94
  this.setColorFormat("bgra8unorm" /* WebGPUConstants.TextureFormat.BGRA8Unorm */);
81
95
  this.setMRT([]);
82
- this.setAlphaBlendEnabled(false);
96
+ this.setAlphaBlendEnabled([false], 1);
83
97
  this.setAlphaBlendFactors([null, null, null, null], [null, null]);
84
98
  this.setWriteMask(0xf);
85
99
  this.setDepthStencilFormat("depth24plus-stencil8" /* WebGPUConstants.TextureFormat.Depth24PlusStencil8 */);
@@ -89,7 +103,7 @@ export class WebGPUCacheRenderPipeline {
89
103
  this._setTextureState(0);
90
104
  }
91
105
  get colorFormats() {
92
- return this._mrtAttachments1 > 0 ? this._mrtFormats : this._webgpuColorFormat;
106
+ return this._mrtAttachments > 0 ? this._mrtFormats : this._webgpuColorFormat;
93
107
  }
94
108
  getRenderPipeline(fillMode, effect, sampleCount, textureState = 0) {
95
109
  sampleCount = WebGPUTextureHelper.GetSample(sampleCount);
@@ -187,6 +201,7 @@ export class WebGPUCacheRenderPipeline {
187
201
  this._webgpuColorFormat[0] = format;
188
202
  this._colorFormat = renderableTextureFormatToIndex[format ?? ""];
189
203
  }
204
+ // Must be called after setMRT!
190
205
  setMRTAttachments(attachments) {
191
206
  this.mrtAttachments = attachments;
192
207
  let mask = 0;
@@ -198,47 +213,40 @@ export class WebGPUCacheRenderPipeline {
198
213
  if (this._mrtEnabledMask !== mask) {
199
214
  this._mrtEnabledMask = mask;
200
215
  this._isDirty = true;
201
- this._stateDirtyLowestIndex = Math.min(this._stateDirtyLowestIndex, StatePosition.MRTAttachments1);
216
+ this._stateDirtyLowestIndex = Math.min(this._stateDirtyLowestIndex, StatePosition.MRTAttachments);
202
217
  }
203
218
  }
204
219
  setMRT(textureArray, textureCount) {
205
220
  textureCount = textureCount ?? textureArray.length;
206
- if (textureCount > 10) {
207
- // If we want more than 10 attachments we need to change this method (and the StatePosition enum) but 10 seems plenty: note that WebGPU only supports 8 at the time (2021/12/13)!
208
- // As we need ~39 different values we are using 6 bits to encode a texture format, meaning we can encode 5 texture formats in 32 bits
209
- // We are using 2x32 bit values to handle 10 textures
210
- // eslint-disable-next-line no-throw-literal
211
- throw "Can't handle more than 10 attachments for a MRT in cache render pipeline!";
221
+ if (textureCount > 8) {
222
+ // We only support 8 MRTs in WebGPU, so we throw an error if we try to set more than that.
223
+ throw new Error("Can't handle more than 8 attachments for a MRT in cache render pipeline!");
212
224
  }
213
225
  this.mrtTextureArray = textureArray;
214
226
  this.mrtTextureCount = textureCount;
227
+ // Since we need approximately 45 different values per texture format (see WebGPUTextureManager.renderableTextureFormatToIndex), we use 6 bits to encode a texture format,
228
+ // which means we can encode 8 texture formats in 48 bits (a double can represent integers exactly up until 2^53, so 48 bits is ok).
215
229
  this._mrtEnabledMask = 0xffff; // all textures are enabled at start (meaning we can write to them). Calls to setMRTAttachments may disable some
216
- const bits = [0, 0];
217
- let indexBits = 0, mask = 0, numRT = 0;
230
+ let mrtAttachments = 0;
231
+ let mask = 0;
218
232
  for (let i = 0; i < textureCount; ++i) {
219
233
  const texture = textureArray[i];
220
234
  const gpuWrapper = texture?._hardwareTexture;
221
- this._mrtFormats[numRT] = gpuWrapper?.format ?? this._webgpuColorFormat[0];
222
- bits[indexBits] += renderableTextureFormatToIndex[this._mrtFormats[numRT] ?? ""] << mask;
235
+ this._mrtFormats[i] = gpuWrapper?.format ?? this._webgpuColorFormat[0];
236
+ mrtAttachments += renderableTextureFormatToIndex[this._mrtFormats[i] ?? ""] * 2 ** mask;
223
237
  mask += 6;
224
- numRT++;
225
- if (mask >= 32) {
226
- mask = 0;
227
- indexBits++;
228
- }
229
238
  }
230
- this._mrtFormats.length = numRT;
231
- if (this._mrtAttachments1 !== bits[0] || this._mrtAttachments2 !== bits[1]) {
232
- this._mrtAttachments1 = bits[0];
233
- this._mrtAttachments2 = bits[1];
234
- this._states[StatePosition.MRTAttachments1] = bits[0];
235
- this._states[StatePosition.MRTAttachments2] = bits[1];
239
+ this._mrtFormats.length = textureCount;
240
+ if (this._mrtAttachments !== mrtAttachments) {
241
+ this._mrtAttachments = mrtAttachments;
242
+ this._states[StatePosition.MRTAttachments] = mrtAttachments;
236
243
  this._isDirty = true;
237
- this._stateDirtyLowestIndex = Math.min(this._stateDirtyLowestIndex, StatePosition.MRTAttachments1);
244
+ this._stateDirtyLowestIndex = Math.min(this._stateDirtyLowestIndex, StatePosition.MRTAttachments);
238
245
  }
239
246
  }
240
- setAlphaBlendEnabled(enabled) {
247
+ setAlphaBlendEnabled(enabled, numAlphaBlendTargetsEnabled) {
241
248
  this._alphaBlendEnabled = enabled;
249
+ this._numAlphaBlendTargetsEnabled = numAlphaBlendTargetsEnabled;
242
250
  }
243
251
  setAlphaBlendFactors(factors, operations) {
244
252
  this._alphaBlendFuncParams = factors;
@@ -275,6 +283,18 @@ export class WebGPUCacheRenderPipeline {
275
283
  setStencilFailOp(op) {
276
284
  this._stencilFrontFailOp = op === null ? 1 /* KEEP */ : stencilOpToIndex[op];
277
285
  }
286
+ setStencilBackCompare(func) {
287
+ this._stencilBackCompare = (func ?? 519) - 0x0200;
288
+ }
289
+ setStencilBackDepthFailOp(op) {
290
+ this._stencilBackDepthFailOp = op === null ? 1 /* KEEP */ : stencilOpToIndex[op];
291
+ }
292
+ setStencilBackPassOp(op) {
293
+ this._stencilBackPassOp = op === null ? 2 /* REPLACE */ : stencilOpToIndex[op];
294
+ }
295
+ setStencilBackFailOp(op) {
296
+ this._stencilBackFailOp = op === null ? 1 /* KEEP */ : stencilOpToIndex[op];
297
+ }
278
298
  setStencilReadMask(mask) {
279
299
  if (this._stencilReadMask !== mask) {
280
300
  this._stencilReadMask = mask;
@@ -294,12 +314,16 @@ export class WebGPUCacheRenderPipeline {
294
314
  resetStencilState() {
295
315
  this.setStencilState(false, 519, 7680, 7681, 7680, 0xff, 0xff);
296
316
  }
297
- setStencilState(stencilEnabled, compare, depthFailOp, passOp, failOp, readMask, writeMask) {
317
+ setStencilState(stencilEnabled, compare, depthFailOp, passOp, failOp, readMask, writeMask, backCompare = null, backDepthFailOp = null, backPassOp = null, backFailOp = null) {
298
318
  this._stencilEnabled = stencilEnabled;
299
319
  this._stencilFrontCompare = (compare ?? 519) - 0x0200;
300
320
  this._stencilFrontDepthFailOp = depthFailOp === null ? 1 /* KEEP */ : stencilOpToIndex[depthFailOp];
301
321
  this._stencilFrontPassOp = passOp === null ? 2 /* REPLACE */ : stencilOpToIndex[passOp];
302
322
  this._stencilFrontFailOp = failOp === null ? 1 /* KEEP */ : stencilOpToIndex[failOp];
323
+ this._stencilBackCompare = (backCompare ?? 519) - 0x0200;
324
+ this._stencilBackDepthFailOp = backDepthFailOp === null ? 1 /* KEEP */ : stencilOpToIndex[backDepthFailOp];
325
+ this._stencilBackPassOp = backPassOp === null ? 2 /* REPLACE */ : stencilOpToIndex[backPassOp];
326
+ this._stencilBackFailOp = backFailOp === null ? 1 /* KEEP */ : stencilOpToIndex[backFailOp];
303
327
  this.setStencilReadMask(readMask);
304
328
  this.setStencilWriteMask(writeMask);
305
329
  }
@@ -381,11 +405,9 @@ export class WebGPUCacheRenderPipeline {
381
405
  case 776:
382
406
  return "src-alpha-saturated" /* WebGPUConstants.BlendFactor.SrcAlphaSaturated */;
383
407
  case 32769:
384
- return "constant" /* WebGPUConstants.BlendFactor.Constant */;
385
- case 32770:
386
- return "one-minus-constant" /* WebGPUConstants.BlendFactor.OneMinusConstant */;
387
408
  case 32771:
388
409
  return "constant" /* WebGPUConstants.BlendFactor.Constant */;
410
+ case 32770:
389
411
  case 32772:
390
412
  return "one-minus-constant" /* WebGPUConstants.BlendFactor.OneMinusConstant */;
391
413
  case 35065:
@@ -526,24 +548,24 @@ export class WebGPUCacheRenderPipeline {
526
548
  }
527
549
  throw new Error(`Invalid Format '${vertexBuffer.getKind()}' - type=${type}, normalized=${normalized}, size=${size}`);
528
550
  }
529
- _getAphaBlendState() {
530
- if (!this._alphaBlendEnabled) {
551
+ _getAphaBlendState(targetIndex) {
552
+ if (!this._alphaBlendEnabled[targetIndex]) {
531
553
  return null;
532
554
  }
533
555
  return {
534
- srcFactor: WebGPUCacheRenderPipeline._GetAphaBlendFactor(this._alphaBlendFuncParams[2]),
535
- dstFactor: WebGPUCacheRenderPipeline._GetAphaBlendFactor(this._alphaBlendFuncParams[3]),
536
- operation: WebGPUCacheRenderPipeline._GetAphaBlendOperation(this._alphaBlendEqParams[1]),
556
+ srcFactor: WebGPUCacheRenderPipeline._GetAphaBlendFactor(this._alphaBlendFuncParams[targetIndex * 4 + 2]),
557
+ dstFactor: WebGPUCacheRenderPipeline._GetAphaBlendFactor(this._alphaBlendFuncParams[targetIndex * 4 + 3]),
558
+ operation: WebGPUCacheRenderPipeline._GetAphaBlendOperation(this._alphaBlendEqParams[targetIndex * 2 + 1]),
537
559
  };
538
560
  }
539
- _getColorBlendState() {
561
+ _getColorBlendState(targetIndex) {
540
562
  if (!this._alphaBlendEnabled) {
541
563
  return null;
542
564
  }
543
565
  return {
544
- srcFactor: WebGPUCacheRenderPipeline._GetAphaBlendFactor(this._alphaBlendFuncParams[0]),
545
- dstFactor: WebGPUCacheRenderPipeline._GetAphaBlendFactor(this._alphaBlendFuncParams[1]),
546
- operation: WebGPUCacheRenderPipeline._GetAphaBlendOperation(this._alphaBlendEqParams[0]),
566
+ srcFactor: WebGPUCacheRenderPipeline._GetAphaBlendFactor(this._alphaBlendFuncParams[targetIndex * 4 + 0]),
567
+ dstFactor: WebGPUCacheRenderPipeline._GetAphaBlendFactor(this._alphaBlendFuncParams[targetIndex * 4 + 1]),
568
+ operation: WebGPUCacheRenderPipeline._GetAphaBlendOperation(this._alphaBlendEqParams[targetIndex * 2 + 0]),
547
569
  };
548
570
  }
549
571
  _setShaderStage(id) {
@@ -568,28 +590,65 @@ export class WebGPUCacheRenderPipeline {
568
590
  }
569
591
  }
570
592
  _setColorStates() {
571
- let colorStates = ((this._writeMask ? 1 : 0) << 22) + (this._colorFormat << 23) + ((this._depthWriteEnabled ? 1 : 0) << 29); // this state has been moved from depthStencilState here because alpha and depth are related (generally when alpha is on, depth write is off and the other way around)
572
- if (this._alphaBlendEnabled) {
573
- colorStates +=
574
- ((this._alphaBlendFuncParams[0] === null ? 2 : alphaBlendFactorToIndex[this._alphaBlendFuncParams[0]]) << 0) +
575
- ((this._alphaBlendFuncParams[1] === null ? 2 : alphaBlendFactorToIndex[this._alphaBlendFuncParams[1]]) << 4) +
576
- ((this._alphaBlendFuncParams[2] === null ? 2 : alphaBlendFactorToIndex[this._alphaBlendFuncParams[2]]) << 8) +
577
- ((this._alphaBlendFuncParams[3] === null ? 2 : alphaBlendFactorToIndex[this._alphaBlendFuncParams[3]]) << 12) +
578
- ((this._alphaBlendEqParams[0] === null ? 1 : this._alphaBlendEqParams[0] - 0x8005) << 16) +
579
- ((this._alphaBlendEqParams[1] === null ? 1 : this._alphaBlendEqParams[1] - 0x8005) << 19);
580
- }
581
- if (colorStates !== this._colorStates) {
582
- this._colorStates = colorStates;
583
- this._states[StatePosition.ColorStates] = this._colorStates;
593
+ // Note that _depthWriteEnabled state has been moved from depthStencilState here because alpha and depth are related (generally when alpha is on, depth write is off and the other way around)
594
+ // We need 4 color states because we will be grouping 2 blend targets in each state (and WebGPU supports up to 8 targets).
595
+ // Integers can only be represented exactly in 53 bits with a double, so we can only use 53 bits for each state.
596
+ // We use 25 bits for each blend target (5 bits for the 2 (color/alpha) equations and 4*5 bits for the 4 factors (src/dst color and src/dst alpha)).
597
+ // This means that we need 25*2=50 bits to pack 2 blend targets, and we can use the remaining 3 bits for other states (write mask, depth write, color format).
598
+ // The color format is encoded on 6 bits, so we dispatch it over 3 bits to the last two color states.
599
+ colorStates[0] = (this._writeMask ? 1 : 0) * 2 ** 53;
600
+ colorStates[1] = (this._depthWriteEnabled ? 1 : 0) * 2 ** 53;
601
+ colorStates[2] = (this._colorFormat & 0x07) * 2 ** 50;
602
+ colorStates[3] = (this._colorFormat & 0x38) * 2 ** 47;
603
+ let colorStateIndex = 0;
604
+ let isDirty = false;
605
+ for (let i = 0; i < 8; i++) {
606
+ if (this._alphaBlendEnabled[i]) {
607
+ const index0 = i * 4 + 0;
608
+ const index1 = i * 4 + 1;
609
+ const index2 = i * 4 + 2;
610
+ const index3 = i * 4 + 3;
611
+ const indexEq0 = i * 2 + 0;
612
+ const indexEq1 = i * 2 + 1;
613
+ const eq0 = this._alphaBlendEqParams[indexEq0] === null ? 0 : alphaBlendEquationToIndex[this._alphaBlendEqParams[indexEq0]];
614
+ const eq1 = this._alphaBlendEqParams[indexEq1] === null ? 0 : alphaBlendEquationToIndex[this._alphaBlendEqParams[indexEq1]];
615
+ colorStates[colorStateIndex] +=
616
+ ((this._alphaBlendFuncParams[index0] === null ? 1 : alphaBlendFactorToIndex[this._alphaBlendFuncParams[index0]]) << 0) +
617
+ ((this._alphaBlendFuncParams[index1] === null ? 1 : alphaBlendFactorToIndex[this._alphaBlendFuncParams[index1]]) << 5) +
618
+ ((this._alphaBlendFuncParams[index2] === null ? 1 : alphaBlendFactorToIndex[this._alphaBlendFuncParams[index2]]) << 10) +
619
+ ((this._alphaBlendFuncParams[index3] === null ? 1 : alphaBlendFactorToIndex[this._alphaBlendFuncParams[index3]]) << 15) +
620
+ (eq0 + eq1 * 5) * (1 << 20);
621
+ }
622
+ if (i & 1) {
623
+ isDirty = isDirty || this._states[StatePosition.ColorStates1 + colorStateIndex] !== colorStates[colorStateIndex];
624
+ this._states[StatePosition.ColorStates1 + colorStateIndex] = colorStates[colorStateIndex];
625
+ colorStateIndex++;
626
+ }
627
+ }
628
+ if (isDirty) {
584
629
  this._isDirty = true;
585
- this._stateDirtyLowestIndex = Math.min(this._stateDirtyLowestIndex, StatePosition.ColorStates);
630
+ this._stateDirtyLowestIndex = Math.min(this._stateDirtyLowestIndex, StatePosition.ColorStates1);
586
631
  }
587
632
  }
588
633
  _setDepthStencilState() {
589
634
  const stencilState = !this._stencilEnabled
590
- ? 7 /* ALWAYS */ + (1 /* KEEP */ << 3) + (1 /* KEEP */ << 6) + (1 /* KEEP */ << 9)
591
- : this._stencilFrontCompare + (this._stencilFrontDepthFailOp << 3) + (this._stencilFrontPassOp << 6) + (this._stencilFrontFailOp << 9);
592
- const depthStencilState = this._depthStencilFormat + ((this._depthTestEnabled ? this._depthCompare : 7) /* ALWAYS */ << 6) + (stencilState << 10); // stencil front - stencil back is the same
635
+ ? 7 /* ALWAYS */ +
636
+ (1 /* KEEP */ << 3) +
637
+ (1 /* KEEP */ << 6) +
638
+ (1 /* KEEP */ << 9) + // front
639
+ (7 /* ALWAYS */ << 12) +
640
+ (1 /* KEEP */ << 15) +
641
+ (1 /* KEEP */ << 18) +
642
+ (1 /* KEEP */ << 21) // back
643
+ : this._stencilFrontCompare +
644
+ (this._stencilFrontDepthFailOp << 3) +
645
+ (this._stencilFrontPassOp << 6) +
646
+ (this._stencilFrontFailOp << 9) + // front
647
+ (this._stencilBackCompare << 12) +
648
+ (this._stencilBackDepthFailOp << 15) +
649
+ (this._stencilBackPassOp << 18) +
650
+ (this._stencilBackFailOp << 21); // back
651
+ const depthStencilState = this._depthStencilFormat + ((this._depthTestEnabled ? this._depthCompare : 7) /* ALWAYS */ << 6) + stencilState * (1 << 10); // stencil front + back
593
652
  if (this._depthStencilState !== depthStencilState) {
594
653
  this._depthStencilState = depthStencilState;
595
654
  this._states[StatePosition.DepthStencilState] = this._depthStencilState;
@@ -752,12 +811,10 @@ export class WebGPUCacheRenderPipeline {
752
811
  const inputStateDescriptor = this._getVertexInputDescriptor(effect);
753
812
  const pipelineLayout = this._createPipelineLayout(webgpuPipelineContext);
754
813
  const colorStates = [];
755
- const alphaBlend = this._getAphaBlendState();
756
- const colorBlend = this._getColorBlendState();
757
814
  if (this._vertexBuffers) {
758
815
  checkNonFloatVertexBuffers(this._vertexBuffers, effect);
759
816
  }
760
- if (this._mrtAttachments1 > 0) {
817
+ if (this._mrtAttachments > 0) {
761
818
  for (let i = 0; i < this._mrtFormats.length; ++i) {
762
819
  const format = this._mrtFormats[i];
763
820
  if (format) {
@@ -765,6 +822,8 @@ export class WebGPUCacheRenderPipeline {
765
822
  format,
766
823
  writeMask: (this._mrtEnabledMask & (1 << i)) !== 0 ? this._writeMask : 0,
767
824
  };
825
+ const alphaBlend = this._getAphaBlendState(i < this._numAlphaBlendTargetsEnabled ? i : 0);
826
+ const colorBlend = this._getColorBlendState(i < this._numAlphaBlendTargetsEnabled ? i : 0);
768
827
  if (alphaBlend && colorBlend) {
769
828
  descr.blend = {
770
829
  alpha: alphaBlend,
@@ -784,6 +843,8 @@ export class WebGPUCacheRenderPipeline {
784
843
  format: this._webgpuColorFormat[0],
785
844
  writeMask: this._writeMask,
786
845
  };
846
+ const alphaBlend = this._getAphaBlendState(0);
847
+ const colorBlend = this._getColorBlendState(0);
787
848
  if (alphaBlend && colorBlend) {
788
849
  descr.blend = {
789
850
  alpha: alphaBlend,
@@ -796,12 +857,18 @@ export class WebGPUCacheRenderPipeline {
796
857
  colorStates.push(null);
797
858
  }
798
859
  }
799
- const stencilFrontBack = {
860
+ const stencilFront = {
800
861
  compare: WebGPUCacheRenderPipeline._GetCompareFunction(this._stencilEnabled ? this._stencilFrontCompare : 7 /* ALWAYS */),
801
862
  depthFailOp: WebGPUCacheRenderPipeline._GetStencilOpFunction(this._stencilEnabled ? this._stencilFrontDepthFailOp : 1 /* KEEP */),
802
863
  failOp: WebGPUCacheRenderPipeline._GetStencilOpFunction(this._stencilEnabled ? this._stencilFrontFailOp : 1 /* KEEP */),
803
864
  passOp: WebGPUCacheRenderPipeline._GetStencilOpFunction(this._stencilEnabled ? this._stencilFrontPassOp : 1 /* KEEP */),
804
865
  };
866
+ const stencilBack = {
867
+ compare: WebGPUCacheRenderPipeline._GetCompareFunction(this._stencilEnabled ? this._stencilBackCompare : 7 /* ALWAYS */),
868
+ depthFailOp: WebGPUCacheRenderPipeline._GetStencilOpFunction(this._stencilEnabled ? this._stencilBackDepthFailOp : 1 /* KEEP */),
869
+ failOp: WebGPUCacheRenderPipeline._GetStencilOpFunction(this._stencilEnabled ? this._stencilBackFailOp : 1 /* KEEP */),
870
+ passOp: WebGPUCacheRenderPipeline._GetStencilOpFunction(this._stencilEnabled ? this._stencilBackPassOp : 1 /* KEEP */),
871
+ };
805
872
  const topologyIsTriangle = topology === "triangle-list" /* WebGPUConstants.PrimitiveTopology.TriangleList */ || topology === "triangle-strip" /* WebGPUConstants.PrimitiveTopology.TriangleStrip */;
806
873
  let stripIndexFormat = undefined;
807
874
  if (topology === "line-strip" /* WebGPUConstants.PrimitiveTopology.LineStrip */ || topology === "triangle-strip" /* WebGPUConstants.PrimitiveTopology.TriangleStrip */) {
@@ -840,8 +907,8 @@ export class WebGPUCacheRenderPipeline {
840
907
  depthWriteEnabled: this._depthWriteEnabled,
841
908
  depthCompare: this._depthTestEnabled ? WebGPUCacheRenderPipeline._GetCompareFunction(this._depthCompare) : "always" /* WebGPUConstants.CompareFunction.Always */,
842
909
  format: this._webgpuDepthStencilFormat,
843
- stencilFront: this._stencilEnabled && depthStencilFormatHasStencil ? stencilFrontBack : undefined,
844
- stencilBack: this._stencilEnabled && depthStencilFormatHasStencil ? stencilFrontBack : undefined,
910
+ stencilFront: this._stencilEnabled && depthStencilFormatHasStencil ? stencilFront : undefined,
911
+ stencilBack: this._stencilEnabled && depthStencilFormatHasStencil ? stencilBack : undefined,
845
912
  stencilReadMask: this._stencilEnabled && depthStencilFormatHasStencil ? this._stencilReadMask : undefined,
846
913
  stencilWriteMask: this._stencilEnabled && depthStencilFormatHasStencil ? this._stencilWriteMask : undefined,
847
914
  depthBias: this._depthBias,