@onerjs/core 8.27.3 → 8.27.4

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 (88) hide show
  1. package/Cameras/arcRotateCamera.js +7 -5
  2. package/Cameras/arcRotateCamera.js.map +1 -1
  3. package/Cameras/targetCamera.d.ts +12 -0
  4. package/Cameras/targetCamera.js +19 -5
  5. package/Cameras/targetCamera.js.map +1 -1
  6. package/Engines/abstractEngine.js +2 -2
  7. package/Engines/abstractEngine.js.map +1 -1
  8. package/FrameGraph/Node/Blocks/inputBlock.js +1 -1
  9. package/FrameGraph/Node/Blocks/inputBlock.js.map +1 -1
  10. package/FrameGraph/Node/nodeRenderGraph.d.ts +2 -1
  11. package/FrameGraph/Node/nodeRenderGraph.js +8 -8
  12. package/FrameGraph/Node/nodeRenderGraph.js.map +1 -1
  13. package/FrameGraph/Passes/renderPass.js +3 -3
  14. package/FrameGraph/Passes/renderPass.js.map +1 -1
  15. package/FrameGraph/Tasks/Rendering/taaObjectRendererTask.js +7 -7
  16. package/FrameGraph/Tasks/Rendering/taaObjectRendererTask.js.map +1 -1
  17. package/FrameGraph/Tasks/Texture/clearTextureTask.js +1 -1
  18. package/FrameGraph/Tasks/Texture/clearTextureTask.js.map +1 -1
  19. package/FrameGraph/frameGraph.d.ts +4 -0
  20. package/FrameGraph/frameGraph.js +8 -0
  21. package/FrameGraph/frameGraph.js.map +1 -1
  22. package/FrameGraph/frameGraphRenderContext.d.ts +2 -1
  23. package/FrameGraph/frameGraphRenderContext.js +10 -3
  24. package/FrameGraph/frameGraphRenderContext.js.map +1 -1
  25. package/FrameGraph/frameGraphTextureManager.d.ts +32 -6
  26. package/FrameGraph/frameGraphTextureManager.js +138 -14
  27. package/FrameGraph/frameGraphTextureManager.js.map +1 -1
  28. package/Materials/Background/backgroundMaterial.js +1 -1
  29. package/Materials/Background/backgroundMaterial.js.map +1 -1
  30. package/Materials/PBR/openPbrMaterial.js +1 -1
  31. package/Materials/PBR/openPbrMaterial.js.map +1 -1
  32. package/Materials/PBR/pbrBaseMaterial.js +1 -1
  33. package/Materials/PBR/pbrBaseMaterial.js.map +1 -1
  34. package/Materials/Textures/texture.js +13 -3
  35. package/Materials/Textures/texture.js.map +1 -1
  36. package/Materials/floatingOriginMatrixOverrides.js +11 -6
  37. package/Materials/floatingOriginMatrixOverrides.js.map +1 -1
  38. package/Materials/materialHelper.functions.d.ts +3 -3
  39. package/Materials/materialHelper.functions.js +2 -3
  40. package/Materials/materialHelper.functions.js.map +1 -1
  41. package/Materials/standardMaterial.js +1 -1
  42. package/Materials/standardMaterial.js.map +1 -1
  43. package/Maths/math.vector.functions.d.ts +17 -0
  44. package/Maths/math.vector.functions.js +27 -0
  45. package/Maths/math.vector.functions.js.map +1 -1
  46. package/Meshes/mesh.js +1 -1
  47. package/Meshes/mesh.js.map +1 -1
  48. package/Misc/screenshotTools.d.ts +63 -1
  49. package/Misc/screenshotTools.js +207 -4
  50. package/Misc/screenshotTools.js.map +1 -1
  51. package/Misc/textureTools.d.ts +6 -0
  52. package/Misc/textureTools.js +6 -1
  53. package/Misc/textureTools.js.map +1 -1
  54. package/Particles/Node/Blocks/Emitters/boxShapeBlock.js +1 -0
  55. package/Particles/Node/Blocks/Emitters/boxShapeBlock.js.map +1 -1
  56. package/Particles/Node/Blocks/Emitters/customShapeBlock.js +1 -0
  57. package/Particles/Node/Blocks/Emitters/customShapeBlock.js.map +1 -1
  58. package/Particles/Node/Blocks/Emitters/cylinderShapeBlock.js +1 -0
  59. package/Particles/Node/Blocks/Emitters/cylinderShapeBlock.js.map +1 -1
  60. package/Particles/Node/Blocks/Emitters/meshShapeBlock.js +1 -0
  61. package/Particles/Node/Blocks/Emitters/meshShapeBlock.js.map +1 -1
  62. package/Particles/Node/Blocks/Emitters/pointShapeBlock.js +1 -0
  63. package/Particles/Node/Blocks/Emitters/pointShapeBlock.js.map +1 -1
  64. package/Particles/Node/Blocks/Emitters/sphereShapeBlock.js +1 -0
  65. package/Particles/Node/Blocks/Emitters/sphereShapeBlock.js.map +1 -1
  66. package/Particles/Node/Blocks/index.d.ts +1 -0
  67. package/Particles/Node/Blocks/index.js +1 -0
  68. package/Particles/Node/Blocks/index.js.map +1 -1
  69. package/Particles/Node/Blocks/particleFresnelBlock.d.ts +34 -0
  70. package/Particles/Node/Blocks/particleFresnelBlock.js +74 -0
  71. package/Particles/Node/Blocks/particleFresnelBlock.js.map +1 -0
  72. package/Particles/Node/Blocks/particleInputBlock.js +2 -0
  73. package/Particles/Node/Blocks/particleInputBlock.js.map +1 -1
  74. package/Particles/Node/Blocks/particleLerpBlock.d.ts +1 -1
  75. package/Particles/Node/Blocks/particleLerpBlock.js +1 -1
  76. package/Particles/Node/Blocks/particleLerpBlock.js.map +1 -1
  77. package/Particles/Node/Enums/nodeParticleContextualSources.d.ts +3 -1
  78. package/Particles/Node/Enums/nodeParticleContextualSources.js +2 -0
  79. package/Particles/Node/Enums/nodeParticleContextualSources.js.map +1 -1
  80. package/Particles/Node/Enums/nodeParticleSystemSources.d.ts +3 -1
  81. package/Particles/Node/Enums/nodeParticleSystemSources.js +2 -0
  82. package/Particles/Node/Enums/nodeParticleSystemSources.js.map +1 -1
  83. package/Particles/Node/nodeParticleBuildState.d.ts +1 -1
  84. package/Particles/Node/nodeParticleBuildState.js +4 -0
  85. package/Particles/Node/nodeParticleBuildState.js.map +1 -1
  86. package/node.js +4 -1
  87. package/node.js.map +1 -1
  88. package/package.json +1 -1
@@ -2,6 +2,7 @@ import type { Camera } from "../Cameras/camera.js";
2
2
  import { RenderTargetTexture } from "../Materials/Textures/renderTargetTexture.js";
3
3
  import type { IScreenshotSize } from "./interfaces/screenshotSize.js";
4
4
  import type { AbstractEngine } from "../Engines/abstractEngine.js";
5
+ import type { FrameGraph } from "../FrameGraph/frameGraph.js";
5
6
  /**
6
7
  * Captures a screenshot of the current rendering
7
8
  * Please note that simultaneous screenshots are not supported: you must wait until one screenshot is complete before taking another.
@@ -40,10 +41,11 @@ export declare function CreateScreenshot(engine: AbstractEngine, camera: Camera,
40
41
  * @param quality The quality of the image if lossy mimeType is used (e.g. image/jpeg, image/webp). See {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob | HTMLCanvasElement.toBlob()}'s `quality` parameter.
41
42
  * @param useFill fill the screenshot dimensions with the render canvas and clip any overflow. If false, fit the canvas within the screenshot, as in letterboxing.
42
43
  * @param clearWithSceneColor If true, the screenshot canvas will be cleared with the scene clear color before copying the render.
44
+ * @param forceDownload force the system to download the image
43
45
  * @returns screenshot as a string of base64-encoded characters. This string can be assigned
44
46
  * to the src parameter of an <img> to display it
45
47
  */
46
- export declare function CreateScreenshotAsync(engine: AbstractEngine, camera: Camera, size: IScreenshotSize | number, mimeType?: string, quality?: number, useFill?: boolean, clearWithSceneColor?: boolean): Promise<string>;
48
+ export declare function CreateScreenshotAsync(engine: AbstractEngine, camera: Camera, size: IScreenshotSize | number, mimeType?: string, quality?: number, useFill?: boolean, clearWithSceneColor?: boolean, forceDownload?: boolean): Promise<string>;
47
49
  /**
48
50
  * Captures and automatically downloads a screenshot of the current rendering for a specific size. This will render the entire canvas but will generate a blink (due to canvas resize)
49
51
  * If screenshot image data is needed, use {@link CreateScreenshotAsync} instead.
@@ -113,12 +115,41 @@ export declare function CreateScreenshotUsingRenderTarget(engine: AbstractEngine
113
115
  * to the src parameter of an <img> to display it
114
116
  */
115
117
  export declare function CreateScreenshotUsingRenderTargetAsync(engine: AbstractEngine, camera: Camera, size: IScreenshotSize | number, mimeType?: string, samples?: number, antialiasing?: boolean, fileName?: string, renderSprites?: boolean, enableStencilBuffer?: boolean, useLayerMask?: boolean, quality?: number, customizeTexture?: (texture: RenderTargetTexture) => void, customDumpData?: (width: number, height: number, data: ArrayBufferView, successCallback?: (data: string | ArrayBuffer) => void, mimeType?: string, fileName?: string, invertY?: boolean, toArrayBuffer?: boolean, quality?: number) => void): Promise<string>;
118
+ /**
119
+ * Generates an image screenshot from the specified frame graph and camera
120
+ * Please note:
121
+ * - that the frame graph must write to the back buffer color for this to work! This is because the back buffer color is replaced by the texture of the screenshot during the operation.
122
+ * - the camera is set as the camera for the main object renderer of the frame graph during the operation, and restored afterwards.
123
+ * This will only work if the frame graph has a main object renderer (isMainObjectRenderer is true for one of its object renderers)
124
+ * - that simultaneous screenshots are not supported: you must wait until one screenshot is complete before taking another.
125
+ * @param frameGraph The frame graph to use for rendering
126
+ * @param camera The camera to use for rendering
127
+ * @param size This parameter can be set to a single number or to an object with the
128
+ * following (optional) properties: precision, width, height. If a single number is passed,
129
+ * it will be used for both width and height. If an object is passed, the screenshot size
130
+ * will be derived from the parameters. The precision property is a multiplier allowing
131
+ * rendering at a higher or lower resolution
132
+ * @param mimeType The MIME type of the screenshot image (default: image/png).
133
+ * Check your browser for supported MIME types
134
+ * @param samples Texture samples (default: 1)
135
+ * @param antialiasing Whether antialiasing should be turned on or not (default: false)
136
+ * @param fileName A name for for the downloaded file.
137
+ * @param quality The quality of the image if lossy mimeType is used (e.g. image/jpeg, image/webp). See {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob | HTMLCanvasElement.toBlob()}'s `quality` parameter.
138
+ * @param customDumpData The function to use to dump the data. If not provided, the default DumpData function will be used.
139
+ * @param automaticDownload If true, the screenshot will be automatically downloaded as a file instead of being returned as a string: in this case, null is returned.
140
+ * @param numberOfFramesToRender If provided, the number of frames to render before taking the screenshot.
141
+ * If not provided, the screenshot will be taken after the next frame, or after 32 frames if the frame graph has at least one history texture.
142
+ * @returns screenshot as a string of base64-encoded characters. This string can be assigned
143
+ * to the src parameter of an <img> to display it. If automaticDownload is true, null is returned instead
144
+ */
145
+ export declare function CreateScreenshotForFrameGraphAsync(frameGraph: FrameGraph, camera: Camera, size: IScreenshotSize | number, mimeType?: string, samples?: number, antialiasing?: boolean, fileName?: string, quality?: number, customDumpData?: (width: number, height: number, data: ArrayBufferView, successCallback?: (data: string | ArrayBuffer) => void, mimeType?: string, fileName?: string, invertY?: boolean, toArrayBuffer?: boolean, quality?: number) => void, automaticDownload?: boolean, numberOfFramesToRender?: number): Promise<string | ArrayBuffer | null>;
116
146
  /**
117
147
  * Class containing a set of static utilities functions for screenshots
118
148
  */
119
149
  export declare const ScreenshotTools: {
120
150
  /**
121
151
  * Captures a screenshot of the current rendering
152
+ * Please note that simultaneous screenshots are not supported: you must wait until one screenshot is complete before taking another.
122
153
  * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/renderToPNG
123
154
  * @param engine defines the rendering engine
124
155
  * @param camera defines the source camera. If the camera is not the scene's active camera, {@link CreateScreenshotUsingRenderTarget} will be used instead, and `useFill` will be ignored
@@ -139,6 +170,7 @@ export declare const ScreenshotTools: {
139
170
  CreateScreenshot: typeof CreateScreenshot;
140
171
  /**
141
172
  * Captures a screenshot of the current rendering
173
+ * Please note that simultaneous screenshots are not supported: you must wait until one screenshot is complete before taking another.
142
174
  * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/renderToPNG
143
175
  * @param engine defines the rendering engine
144
176
  * @param camera defines the source camera. If the camera is not the scene's active camera, {@link CreateScreenshotUsingRenderTarget} will be used instead, and `useFill` will be ignored
@@ -151,6 +183,7 @@ export declare const ScreenshotTools: {
151
183
  * Check your browser for supported MIME types
152
184
  * @param quality The quality of the image if lossy mimeType is used (e.g. image/jpeg, image/webp). See {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob | HTMLCanvasElement.toBlob()}'s `quality` parameter.
153
185
  * @param useFill fill the screenshot dimensions with the render canvas and clip any overflow. If false, fit the canvas within the screenshot, as in letterboxing.
186
+ * @param forceDownload force the system to download the image
154
187
  * @returns screenshot as a string of base64-encoded characters. This string can be assigned
155
188
  * to the src parameter of an <img> to display it
156
189
  */
@@ -158,6 +191,7 @@ export declare const ScreenshotTools: {
158
191
  /**
159
192
  * Captures and automatically downloads a screenshot of the current rendering for a specific size. This will render the entire canvas but will generate a blink (due to canvas resize)
160
193
  * If screenshot image data is needed, use {@link CreateScreenshotAsync} instead.
194
+ * Please note that simultaneous screenshots are not supported: you must wait until one screenshot is complete before taking another.
161
195
  * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/renderToPNG
162
196
  * @param engine defines the rendering engine
163
197
  * @param camera defines the source camera. If the camera is not the scene's active camera, {@link CreateScreenshotUsingRenderTarget} will be used instead, and `useFill` will be ignored
@@ -172,6 +206,7 @@ export declare const ScreenshotTools: {
172
206
  CreateScreenshotWithResizeAsync: typeof CreateScreenshotWithResizeAsync;
173
207
  /**
174
208
  * Generates an image screenshot from the specified camera.
209
+ * Please note that simultaneous screenshots are not supported: you must wait until one screenshot is complete before taking another.
175
210
  * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/renderToPNG
176
211
  * @param engine The engine to use for rendering
177
212
  * @param camera The camera to use for rendering
@@ -195,6 +230,7 @@ export declare const ScreenshotTools: {
195
230
  CreateScreenshotUsingRenderTarget: typeof CreateScreenshotUsingRenderTarget;
196
231
  /**
197
232
  * Generates an image screenshot from the specified camera.
233
+ * Please note that simultaneous screenshots are not supported: you must wait until one screenshot is complete before taking another.
198
234
  * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/renderToPNG
199
235
  * @param engine The engine to use for rendering
200
236
  * @param camera The camera to use for rendering
@@ -214,4 +250,30 @@ export declare const ScreenshotTools: {
214
250
  * to the src parameter of an <img> to display it
215
251
  */
216
252
  CreateScreenshotUsingRenderTargetAsync: typeof CreateScreenshotUsingRenderTargetAsync;
253
+ /**
254
+ * Generates an image screenshot from the specified frame graph and camera
255
+ * Please note:
256
+ * - that the frame graph must write to the back buffer color for this to work! This is because the back buffer color is replaced by the texture of the screenshot during the operation.
257
+ * - the camera is set as the camera for the main object renderer of the frame graph during the operation, and restored afterwards.
258
+ * This will only work if the frame graph has a main object renderer (isMainObjectRenderer is true for one of its object renderers)
259
+ * - that simultaneous screenshots are not supported: you must wait until one screenshot is complete before taking another.
260
+ * @param frameGraph The frame graph to use for rendering
261
+ * @param camera The camera to use for rendering
262
+ * @param size This parameter can be set to a single number or to an object with the
263
+ * following (optional) properties: precision, width, height. If a single number is passed,
264
+ * it will be used for both width and height. If an object is passed, the screenshot size
265
+ * will be derived from the parameters. The precision property is a multiplier allowing
266
+ * rendering at a higher or lower resolution
267
+ * @param mimeType The MIME type of the screenshot image (default: image/png).
268
+ * Check your browser for supported MIME types
269
+ * @param samples Texture samples (default: 1)
270
+ * @param antialiasing Whether antialiasing should be turned on or not (default: false)
271
+ * @param fileName A name for for the downloaded file.
272
+ * @param quality The quality of the image if lossy mimeType is used (e.g. image/jpeg, image/webp). See {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob | HTMLCanvasElement.toBlob()}'s `quality` parameter.
273
+ * @param customDumpData The function to use to dump the data. If not provided, the default DumpData function will be used.
274
+ * @param automaticDownload If true, the screenshot will be automatically downloaded as a file instead of being returned as a string: in this case, null is returned.
275
+ * @returns screenshot as a string of base64-encoded characters. This string can be assigned
276
+ * to the src parameter of an <img> to display it. If automaticDownload is true, null is returned instead
277
+ */
278
+ CreateScreenshotForFrameGraphAsync: typeof CreateScreenshotForFrameGraphAsync;
217
279
  };
@@ -7,6 +7,10 @@ import { Tools } from "./tools.js";
7
7
  import { DumpData } from "./dumpTools.js";
8
8
  import { ApplyPostProcess } from "./textureTools.js";
9
9
  import { _RetryWithInterval } from "./timingTools.js";
10
+ import { backbufferColorTextureHandle } from "../FrameGraph/frameGraphTypes.js";
11
+ import { FrameGraphFXAATask } from "../FrameGraph/Tasks/PostProcesses/fxaaTask.js";
12
+ import { FrameGraphPassTask } from "../FrameGraph/Tasks/PostProcesses/passTask.js";
13
+ import { FrameGraphUtils } from "../FrameGraph/frameGraphUtils.js";
10
14
  let screenshotCanvas = null;
11
15
  /**
12
16
  * Captures a screenshot of the current rendering
@@ -36,7 +40,14 @@ export function CreateScreenshot(engine, camera, size, successCallback, mimeType
36
40
  return;
37
41
  }
38
42
  const scene = camera.getScene();
39
- if (scene.activeCamera !== camera && !scene.frameGraph) {
43
+ let useRenderTarget = scene.activeCamera !== camera;
44
+ if (scene.frameGraph) {
45
+ const mainObjectRendererTask = FrameGraphUtils.FindMainObjectRenderer(scene.frameGraph);
46
+ if (mainObjectRendererTask) {
47
+ useRenderTarget = mainObjectRendererTask.camera !== camera;
48
+ }
49
+ }
50
+ if (useRenderTarget) {
40
51
  CreateScreenshotUsingRenderTarget(engine, camera, size, (data) => {
41
52
  if (forceDownload) {
42
53
  const blob = new Blob([data]);
@@ -109,10 +120,11 @@ export function CreateScreenshot(engine, camera, size, successCallback, mimeType
109
120
  * @param quality The quality of the image if lossy mimeType is used (e.g. image/jpeg, image/webp). See {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob | HTMLCanvasElement.toBlob()}'s `quality` parameter.
110
121
  * @param useFill fill the screenshot dimensions with the render canvas and clip any overflow. If false, fit the canvas within the screenshot, as in letterboxing.
111
122
  * @param clearWithSceneColor If true, the screenshot canvas will be cleared with the scene clear color before copying the render.
123
+ * @param forceDownload force the system to download the image
112
124
  * @returns screenshot as a string of base64-encoded characters. This string can be assigned
113
125
  * to the src parameter of an <img> to display it
114
126
  */
115
- export async function CreateScreenshotAsync(engine, camera, size, mimeType = "image/png", quality, useFill = false, clearWithSceneColor = false) {
127
+ export async function CreateScreenshotAsync(engine, camera, size, mimeType = "image/png", quality, useFill = false, clearWithSceneColor = false, forceDownload = false) {
116
128
  return await new Promise((resolve, reject) => {
117
129
  CreateScreenshot(engine, camera, size, (data) => {
118
130
  if (typeof data !== "undefined") {
@@ -121,7 +133,7 @@ export async function CreateScreenshotAsync(engine, camera, size, mimeType = "im
121
133
  else {
122
134
  reject(new Error("Data is undefined"));
123
135
  }
124
- }, mimeType, undefined, quality, useFill, clearWithSceneColor);
136
+ }, mimeType, forceDownload, quality, useFill, clearWithSceneColor);
125
137
  });
126
138
  }
127
139
  /**
@@ -173,6 +185,16 @@ export async function CreateScreenshotWithResizeAsync(engine, camera, width, hei
173
185
  * @param customDumpData The function to use to dump the data. If not provided, the default DumpData function will be used.
174
186
  */
175
187
  export function CreateScreenshotUsingRenderTarget(engine, camera, size, successCallback, mimeType = "image/png", samples = 1, antialiasing = false, fileName, renderSprites = false, enableStencilBuffer = false, useLayerMask = true, quality, customizeTexture, customDumpData) {
188
+ const scene = camera.getScene();
189
+ if (scene.frameGraph) {
190
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then
191
+ CreateScreenshotForFrameGraphAsync(scene.frameGraph, camera, size, mimeType, samples, antialiasing, fileName, quality, customDumpData, !successCallback).then((data) => {
192
+ if (successCallback) {
193
+ successCallback(data);
194
+ }
195
+ });
196
+ return;
197
+ }
176
198
  const { height, width, finalWidth, finalHeight } = GetScreenshotSize(engine, camera, size);
177
199
  const targetTextureSize = { width, height };
178
200
  if (!(height && width)) {
@@ -203,7 +225,6 @@ export function CreateScreenshotUsingRenderTarget(engine, camera, size, successC
203
225
  if (engine.onResizeObservable.hasObservers()) {
204
226
  engine.onResizeObservable.notifyObservers(engine);
205
227
  }
206
- const scene = camera.getScene();
207
228
  // At this point size can be a number, or an object (according to engine.prototype.createRenderTargetTexture method)
208
229
  const texture = new RenderTargetTexture("screenShot", targetTextureSize, scene, false, false, 0, false, Texture.BILINEAR_SAMPLINGMODE, undefined, enableStencilBuffer, undefined, undefined, undefined, samples);
209
230
  texture.renderList = scene.meshes.slice();
@@ -344,6 +365,156 @@ export async function CreateScreenshotUsingRenderTargetAsync(engine, camera, siz
344
365
  }, mimeType, samples, antialiasing, fileName, renderSprites, enableStencilBuffer, useLayerMask, quality, customizeTexture, customDumpData);
345
366
  });
346
367
  }
368
+ /**
369
+ * Generates an image screenshot from the specified frame graph and camera
370
+ * Please note:
371
+ * - that the frame graph must write to the back buffer color for this to work! This is because the back buffer color is replaced by the texture of the screenshot during the operation.
372
+ * - the camera is set as the camera for the main object renderer of the frame graph during the operation, and restored afterwards.
373
+ * This will only work if the frame graph has a main object renderer (isMainObjectRenderer is true for one of its object renderers)
374
+ * - that simultaneous screenshots are not supported: you must wait until one screenshot is complete before taking another.
375
+ * @param frameGraph The frame graph to use for rendering
376
+ * @param camera The camera to use for rendering
377
+ * @param size This parameter can be set to a single number or to an object with the
378
+ * following (optional) properties: precision, width, height. If a single number is passed,
379
+ * it will be used for both width and height. If an object is passed, the screenshot size
380
+ * will be derived from the parameters. The precision property is a multiplier allowing
381
+ * rendering at a higher or lower resolution
382
+ * @param mimeType The MIME type of the screenshot image (default: image/png).
383
+ * Check your browser for supported MIME types
384
+ * @param samples Texture samples (default: 1)
385
+ * @param antialiasing Whether antialiasing should be turned on or not (default: false)
386
+ * @param fileName A name for for the downloaded file.
387
+ * @param quality The quality of the image if lossy mimeType is used (e.g. image/jpeg, image/webp). See {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob | HTMLCanvasElement.toBlob()}'s `quality` parameter.
388
+ * @param customDumpData The function to use to dump the data. If not provided, the default DumpData function will be used.
389
+ * @param automaticDownload If true, the screenshot will be automatically downloaded as a file instead of being returned as a string: in this case, null is returned.
390
+ * @param numberOfFramesToRender If provided, the number of frames to render before taking the screenshot.
391
+ * If not provided, the screenshot will be taken after the next frame, or after 32 frames if the frame graph has at least one history texture.
392
+ * @returns screenshot as a string of base64-encoded characters. This string can be assigned
393
+ * to the src parameter of an <img> to display it. If automaticDownload is true, null is returned instead
394
+ */
395
+ export async function CreateScreenshotForFrameGraphAsync(frameGraph, camera, size, mimeType = "image/png", samples = 1, antialiasing = false, fileName, quality, customDumpData, automaticDownload = false, numberOfFramesToRender) {
396
+ const engine = frameGraph.engine;
397
+ const textureManager = frameGraph.textureManager;
398
+ const { height, width, finalWidth, finalHeight } = GetScreenshotSize(engine, camera, size);
399
+ const targetTextureSize = { width, height };
400
+ const dumpDataFunc = customDumpData || DumpData;
401
+ const tasks = frameGraph.tasks;
402
+ const currentTaskListLength = tasks.length;
403
+ const pausedExecution = frameGraph.pausedExecution;
404
+ const currentParallelShaderCompile = engine.getCaps().parallelShaderCompile;
405
+ textureManager.setBackBufferTextures(0, 0, {
406
+ size: targetTextureSize,
407
+ options: {
408
+ createMipMaps: false,
409
+ samples,
410
+ types: [0],
411
+ formats: [5],
412
+ useSRGBBuffers: [false],
413
+ creationFlags: [0],
414
+ labels: ["screenshot color"],
415
+ },
416
+ sizeIsPercentage: false,
417
+ }, {
418
+ size: targetTextureSize,
419
+ options: {
420
+ createMipMaps: false,
421
+ samples,
422
+ types: [0],
423
+ formats: [engine.isStencilEnable ? 13 : 14],
424
+ useSRGBBuffers: [false],
425
+ creationFlags: [0],
426
+ labels: ["screenshot depth"],
427
+ },
428
+ sizeIsPercentage: false,
429
+ });
430
+ let outputTextureHandle = backbufferColorTextureHandle;
431
+ if (antialiasing) {
432
+ const task = new FrameGraphFXAATask("fxaa", frameGraph);
433
+ task.sourceTexture = outputTextureHandle;
434
+ outputTextureHandle = task.outputTexture;
435
+ frameGraph.addTask(task);
436
+ }
437
+ if (finalWidth !== width || finalHeight !== height) {
438
+ const task = new FrameGraphPassTask("pass", frameGraph);
439
+ task.sourceTexture = outputTextureHandle;
440
+ task.targetTexture = frameGraph.textureManager.createRenderTargetTexture("pass_output", {
441
+ size: { width: finalWidth, height: finalHeight },
442
+ options: {
443
+ createMipMaps: false,
444
+ types: [0],
445
+ formats: [5],
446
+ samples: 1,
447
+ labels: ["screenshot_final_texture"],
448
+ useSRGBBuffers: [false],
449
+ },
450
+ sizeIsPercentage: false,
451
+ });
452
+ outputTextureHandle = task.outputTexture;
453
+ frameGraph.addTask(task);
454
+ }
455
+ const mainObjectRendererTask = FrameGraphUtils.FindMainObjectRenderer(frameGraph);
456
+ let currentCamera = null;
457
+ if (mainObjectRendererTask) {
458
+ currentCamera = mainObjectRendererTask.camera;
459
+ mainObjectRendererTask.camera = camera;
460
+ }
461
+ /**
462
+ * We need to disable parallel shader compile before running frameGraph.whenReadyAsync because of WebGL.
463
+ * In some cases, when whenReadyAsync is not ready the first time readiness is checked, the execute call will
464
+ * not render correctly. Disabling parallel shader compile fixes the problem. This does not happen with WebGPU.
465
+ *
466
+ * That's what happens in this PG: http://playground.babylonjs.com/#GAGVQO#16
467
+ *
468
+ * The FXAA task is injected in the frame graph (because antialiasing==true), and whenReadyAsync checks the readiness
469
+ * of the FXAA task for the first time, it returns false because the shader is not yet imported/compiled.
470
+ * If you uncomment line 2 in the PG, the FXAA shader will be preloaded/compiled before the screenshot is taken and
471
+ * whenReadyAsync won't have to check readiness twice. In that case, disabling parallel shader compile won't be necessary to have a correct screenshot.
472
+ *
473
+ * Same problem in: http://playground.babylonjs.com/#Z6C5EF#3
474
+ *
475
+ * TODO: find a better solution for this problem?
476
+ */
477
+ engine.getCaps().parallelShaderCompile = undefined;
478
+ frameGraph.build();
479
+ // We don't want the frame graph to render while waiting for whenReadyAsync to complete
480
+ frameGraph.pausedExecution = true;
481
+ await frameGraph.whenReadyAsync();
482
+ // eslint-disable-next-line require-atomic-updates
483
+ frameGraph.pausedExecution = false;
484
+ const numberOfFrames = numberOfFramesToRender ?? (textureManager.hasHistoryTextures ? 32 : 1);
485
+ for (let i = 0; i < numberOfFrames; ++i) {
486
+ frameGraph.execute();
487
+ }
488
+ // eslint-disable-next-line require-atomic-updates
489
+ frameGraph.pausedExecution = true;
490
+ engine.getCaps().parallelShaderCompile = currentParallelShaderCompile;
491
+ for (let i = currentTaskListLength; i < tasks.length; ++i) {
492
+ frameGraph.tasks[i].dispose();
493
+ }
494
+ // eslint-disable-next-line require-atomic-updates
495
+ frameGraph.tasks.length = currentTaskListLength;
496
+ if (mainObjectRendererTask && currentCamera) {
497
+ mainObjectRendererTask.camera = currentCamera;
498
+ }
499
+ const texture = frameGraph.textureManager.getTextureFromHandle(outputTextureHandle);
500
+ texture.incrementReferences();
501
+ textureManager.resetBackBufferTextures();
502
+ frameGraph.build();
503
+ await frameGraph.whenReadyAsync();
504
+ // eslint-disable-next-line require-atomic-updates
505
+ frameGraph.pausedExecution = pausedExecution;
506
+ // eslint-disable-next-line @typescript-eslint/return-await
507
+ return new Promise((resolve) => {
508
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then
509
+ engine._readTexturePixels(texture, finalWidth, finalHeight, -1, 0, null, true, false, 0, 0).then(async (data) => {
510
+ texture.dispose();
511
+ dumpDataFunc(finalWidth, finalHeight, data, automaticDownload ? undefined : (data) => resolve(data), mimeType, fileName, true, undefined, quality);
512
+ if (automaticDownload) {
513
+ resolve(null);
514
+ }
515
+ });
516
+ });
517
+ }
347
518
  /**
348
519
  * Gets height and width for screenshot size
349
520
  * @param engine The engine to use for rendering
@@ -431,6 +602,7 @@ function GetScreenshotSize(engine, camera, size) {
431
602
  export const ScreenshotTools = {
432
603
  /**
433
604
  * Captures a screenshot of the current rendering
605
+ * Please note that simultaneous screenshots are not supported: you must wait until one screenshot is complete before taking another.
434
606
  * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/renderToPNG
435
607
  * @param engine defines the rendering engine
436
608
  * @param camera defines the source camera. If the camera is not the scene's active camera, {@link CreateScreenshotUsingRenderTarget} will be used instead, and `useFill` will be ignored
@@ -451,6 +623,7 @@ export const ScreenshotTools = {
451
623
  CreateScreenshot,
452
624
  /**
453
625
  * Captures a screenshot of the current rendering
626
+ * Please note that simultaneous screenshots are not supported: you must wait until one screenshot is complete before taking another.
454
627
  * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/renderToPNG
455
628
  * @param engine defines the rendering engine
456
629
  * @param camera defines the source camera. If the camera is not the scene's active camera, {@link CreateScreenshotUsingRenderTarget} will be used instead, and `useFill` will be ignored
@@ -463,6 +636,7 @@ export const ScreenshotTools = {
463
636
  * Check your browser for supported MIME types
464
637
  * @param quality The quality of the image if lossy mimeType is used (e.g. image/jpeg, image/webp). See {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob | HTMLCanvasElement.toBlob()}'s `quality` parameter.
465
638
  * @param useFill fill the screenshot dimensions with the render canvas and clip any overflow. If false, fit the canvas within the screenshot, as in letterboxing.
639
+ * @param forceDownload force the system to download the image
466
640
  * @returns screenshot as a string of base64-encoded characters. This string can be assigned
467
641
  * to the src parameter of an <img> to display it
468
642
  */
@@ -470,6 +644,7 @@ export const ScreenshotTools = {
470
644
  /**
471
645
  * Captures and automatically downloads a screenshot of the current rendering for a specific size. This will render the entire canvas but will generate a blink (due to canvas resize)
472
646
  * If screenshot image data is needed, use {@link CreateScreenshotAsync} instead.
647
+ * Please note that simultaneous screenshots are not supported: you must wait until one screenshot is complete before taking another.
473
648
  * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/renderToPNG
474
649
  * @param engine defines the rendering engine
475
650
  * @param camera defines the source camera. If the camera is not the scene's active camera, {@link CreateScreenshotUsingRenderTarget} will be used instead, and `useFill` will be ignored
@@ -484,6 +659,7 @@ export const ScreenshotTools = {
484
659
  CreateScreenshotWithResizeAsync,
485
660
  /**
486
661
  * Generates an image screenshot from the specified camera.
662
+ * Please note that simultaneous screenshots are not supported: you must wait until one screenshot is complete before taking another.
487
663
  * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/renderToPNG
488
664
  * @param engine The engine to use for rendering
489
665
  * @param camera The camera to use for rendering
@@ -507,6 +683,7 @@ export const ScreenshotTools = {
507
683
  CreateScreenshotUsingRenderTarget,
508
684
  /**
509
685
  * Generates an image screenshot from the specified camera.
686
+ * Please note that simultaneous screenshots are not supported: you must wait until one screenshot is complete before taking another.
510
687
  * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/renderToPNG
511
688
  * @param engine The engine to use for rendering
512
689
  * @param camera The camera to use for rendering
@@ -526,6 +703,32 @@ export const ScreenshotTools = {
526
703
  * to the src parameter of an <img> to display it
527
704
  */
528
705
  CreateScreenshotUsingRenderTargetAsync,
706
+ /**
707
+ * Generates an image screenshot from the specified frame graph and camera
708
+ * Please note:
709
+ * - that the frame graph must write to the back buffer color for this to work! This is because the back buffer color is replaced by the texture of the screenshot during the operation.
710
+ * - the camera is set as the camera for the main object renderer of the frame graph during the operation, and restored afterwards.
711
+ * This will only work if the frame graph has a main object renderer (isMainObjectRenderer is true for one of its object renderers)
712
+ * - that simultaneous screenshots are not supported: you must wait until one screenshot is complete before taking another.
713
+ * @param frameGraph The frame graph to use for rendering
714
+ * @param camera The camera to use for rendering
715
+ * @param size This parameter can be set to a single number or to an object with the
716
+ * following (optional) properties: precision, width, height. If a single number is passed,
717
+ * it will be used for both width and height. If an object is passed, the screenshot size
718
+ * will be derived from the parameters. The precision property is a multiplier allowing
719
+ * rendering at a higher or lower resolution
720
+ * @param mimeType The MIME type of the screenshot image (default: image/png).
721
+ * Check your browser for supported MIME types
722
+ * @param samples Texture samples (default: 1)
723
+ * @param antialiasing Whether antialiasing should be turned on or not (default: false)
724
+ * @param fileName A name for for the downloaded file.
725
+ * @param quality The quality of the image if lossy mimeType is used (e.g. image/jpeg, image/webp). See {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob | HTMLCanvasElement.toBlob()}'s `quality` parameter.
726
+ * @param customDumpData The function to use to dump the data. If not provided, the default DumpData function will be used.
727
+ * @param automaticDownload If true, the screenshot will be automatically downloaded as a file instead of being returned as a string: in this case, null is returned.
728
+ * @returns screenshot as a string of base64-encoded characters. This string can be assigned
729
+ * to the src parameter of an <img> to display it. If automaticDownload is true, null is returned instead
730
+ */
731
+ CreateScreenshotForFrameGraphAsync,
529
732
  };
530
733
  /**
531
734
  * This will be executed automatically for UMD and es5.