wgsl-renderer 0.6.0 → 0.7.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.
package/dist/cjs/index.js CHANGED
@@ -542,7 +542,7 @@ var WGSLRenderer = class {
542
542
  animationFrameId = null;
543
543
  isResizing = false;
544
544
  renderMode = "normal";
545
- readBuffer = null;
545
+ readedBuffer = null;
546
546
  hasClearedCanvasThisFrame = false;
547
547
  getPassOutputTextureName(passName) {
548
548
  return `pass_${passName}_output`;
@@ -1033,8 +1033,8 @@ var WGSLRenderer = class {
1033
1033
  this.stopLoop();
1034
1034
  this.passes = [];
1035
1035
  this.textureManager.destroy();
1036
- this.readBuffer?.destroy();
1037
- this.readBuffer = null;
1036
+ this.readedBuffer?.destroy();
1037
+ this.readedBuffer = null;
1038
1038
  }
1039
1039
  /**
1040
1040
  * 快速捕获当前帧的像素数据
@@ -1048,22 +1048,22 @@ var WGSLRenderer = class {
1048
1048
  const height = outputTexture.height;
1049
1049
  const bytesPerRow = Math.ceil(width * 4 / 256) * 256;
1050
1050
  const bufferSize = bytesPerRow * height;
1051
- if (!this.readBuffer || this.readBuffer.size !== bufferSize) {
1052
- this.readBuffer?.destroy();
1053
- this.readBuffer = this.device.createBuffer({
1051
+ if (!this.readedBuffer || this.readedBuffer.size !== bufferSize) {
1052
+ this.readedBuffer?.destroy();
1053
+ this.readedBuffer = this.device.createBuffer({
1054
1054
  size: bufferSize,
1055
1055
  usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
1056
1056
  });
1057
1057
  }
1058
1058
  const commandEncoder = this.device.createCommandEncoder();
1059
1059
  commandEncoder.copyTextureToBuffer({ texture: outputTexture }, {
1060
- buffer: this.readBuffer,
1060
+ buffer: this.readedBuffer,
1061
1061
  bytesPerRow
1062
1062
  }, [width, height]);
1063
1063
  this.device.queue.submit([commandEncoder.finish()]);
1064
- await this.readBuffer.mapAsync(GPUMapMode.READ);
1065
- const mappedBuffer = new Uint8Array(this.readBuffer.getMappedRange().slice(0));
1066
- this.readBuffer.unmap();
1064
+ await this.readedBuffer.mapAsync(GPUMapMode.READ);
1065
+ const mappedBuffer = new Uint8Array(this.readedBuffer.getMappedRange().slice(0));
1066
+ this.readedBuffer.unmap();
1067
1067
  const pixelData = new Uint8Array(width * height * 4);
1068
1068
  for (let row = 0; row < height; row++) {
1069
1069
  const srcOffset = row * bytesPerRow;
@@ -1073,6 +1073,44 @@ var WGSLRenderer = class {
1073
1073
  return pixelData;
1074
1074
  }
1075
1075
  /**
1076
+ * Create a storage buffer for compute shader read/write
1077
+ */
1078
+ createStorageBuffer(size, label) {
1079
+ return this.device.createBuffer({
1080
+ label,
1081
+ size,
1082
+ usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST
1083
+ });
1084
+ }
1085
+ /**
1086
+ * Create an indirect buffer for GPU-driven draw/dispatch
1087
+ */
1088
+ createIndirectBuffer(size, label) {
1089
+ return this.device.createBuffer({
1090
+ label,
1091
+ size,
1092
+ usage: GPUBufferUsage.INDIRECT | GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST
1093
+ });
1094
+ }
1095
+ /**
1096
+ * Read back data from a GPU buffer
1097
+ * Buffer must have COPY_SRC usage
1098
+ */
1099
+ async readBuffer(buffer) {
1100
+ const stagingBuffer = this.device.createBuffer({
1101
+ size: buffer.size,
1102
+ usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
1103
+ });
1104
+ const commandEncoder = this.device.createCommandEncoder();
1105
+ commandEncoder.copyBufferToBuffer(buffer, 0, stagingBuffer, 0, buffer.size);
1106
+ this.device.queue.submit([commandEncoder.finish()]);
1107
+ await stagingBuffer.mapAsync(GPUMapMode.READ);
1108
+ const data = stagingBuffer.getMappedRange().slice(0);
1109
+ stagingBuffer.unmap();
1110
+ stagingBuffer.destroy();
1111
+ return data;
1112
+ }
1113
+ /**
1076
1114
  * Create a storage-capable texture (useful for compute passes)
1077
1115
  */
1078
1116
  createStorageTexture(options) {
@@ -235,7 +235,7 @@ declare class WGSLRenderer {
235
235
  private animationFrameId;
236
236
  private isResizing;
237
237
  private renderMode;
238
- private readBuffer;
238
+ private readedBuffer;
239
239
  private hasClearedCanvasThisFrame;
240
240
  private getPassOutputTextureName;
241
241
  constructor(canvas: HTMLCanvasElement, options?: WGSLRendererOptions | undefined);
@@ -367,6 +367,19 @@ declare class WGSLRenderer {
367
367
  * @returns Uint8Array格式的RGBA像素数据
368
368
  */
369
369
  captureFrameFast(): Promise<Uint8Array>;
370
+ /**
371
+ * Create a storage buffer for compute shader read/write
372
+ */
373
+ createStorageBuffer(size: number, label?: string): GPUBuffer;
374
+ /**
375
+ * Create an indirect buffer for GPU-driven draw/dispatch
376
+ */
377
+ createIndirectBuffer(size: number, label?: string): GPUBuffer;
378
+ /**
379
+ * Read back data from a GPU buffer
380
+ * Buffer must have COPY_SRC usage
381
+ */
382
+ readBuffer(buffer: GPUBuffer): Promise<ArrayBuffer>;
370
383
  /**
371
384
  * Create a storage-capable texture (useful for compute passes)
372
385
  */
package/dist/esm/index.js CHANGED
@@ -541,7 +541,7 @@ var WGSLRenderer = class {
541
541
  animationFrameId = null;
542
542
  isResizing = false;
543
543
  renderMode = "normal";
544
- readBuffer = null;
544
+ readedBuffer = null;
545
545
  hasClearedCanvasThisFrame = false;
546
546
  getPassOutputTextureName(passName) {
547
547
  return `pass_${passName}_output`;
@@ -1032,8 +1032,8 @@ var WGSLRenderer = class {
1032
1032
  this.stopLoop();
1033
1033
  this.passes = [];
1034
1034
  this.textureManager.destroy();
1035
- this.readBuffer?.destroy();
1036
- this.readBuffer = null;
1035
+ this.readedBuffer?.destroy();
1036
+ this.readedBuffer = null;
1037
1037
  }
1038
1038
  /**
1039
1039
  * 快速捕获当前帧的像素数据
@@ -1047,22 +1047,22 @@ var WGSLRenderer = class {
1047
1047
  const height = outputTexture.height;
1048
1048
  const bytesPerRow = Math.ceil(width * 4 / 256) * 256;
1049
1049
  const bufferSize = bytesPerRow * height;
1050
- if (!this.readBuffer || this.readBuffer.size !== bufferSize) {
1051
- this.readBuffer?.destroy();
1052
- this.readBuffer = this.device.createBuffer({
1050
+ if (!this.readedBuffer || this.readedBuffer.size !== bufferSize) {
1051
+ this.readedBuffer?.destroy();
1052
+ this.readedBuffer = this.device.createBuffer({
1053
1053
  size: bufferSize,
1054
1054
  usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
1055
1055
  });
1056
1056
  }
1057
1057
  const commandEncoder = this.device.createCommandEncoder();
1058
1058
  commandEncoder.copyTextureToBuffer({ texture: outputTexture }, {
1059
- buffer: this.readBuffer,
1059
+ buffer: this.readedBuffer,
1060
1060
  bytesPerRow
1061
1061
  }, [width, height]);
1062
1062
  this.device.queue.submit([commandEncoder.finish()]);
1063
- await this.readBuffer.mapAsync(GPUMapMode.READ);
1064
- const mappedBuffer = new Uint8Array(this.readBuffer.getMappedRange().slice(0));
1065
- this.readBuffer.unmap();
1063
+ await this.readedBuffer.mapAsync(GPUMapMode.READ);
1064
+ const mappedBuffer = new Uint8Array(this.readedBuffer.getMappedRange().slice(0));
1065
+ this.readedBuffer.unmap();
1066
1066
  const pixelData = new Uint8Array(width * height * 4);
1067
1067
  for (let row = 0; row < height; row++) {
1068
1068
  const srcOffset = row * bytesPerRow;
@@ -1072,6 +1072,44 @@ var WGSLRenderer = class {
1072
1072
  return pixelData;
1073
1073
  }
1074
1074
  /**
1075
+ * Create a storage buffer for compute shader read/write
1076
+ */
1077
+ createStorageBuffer(size, label) {
1078
+ return this.device.createBuffer({
1079
+ label,
1080
+ size,
1081
+ usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST
1082
+ });
1083
+ }
1084
+ /**
1085
+ * Create an indirect buffer for GPU-driven draw/dispatch
1086
+ */
1087
+ createIndirectBuffer(size, label) {
1088
+ return this.device.createBuffer({
1089
+ label,
1090
+ size,
1091
+ usage: GPUBufferUsage.INDIRECT | GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST
1092
+ });
1093
+ }
1094
+ /**
1095
+ * Read back data from a GPU buffer
1096
+ * Buffer must have COPY_SRC usage
1097
+ */
1098
+ async readBuffer(buffer) {
1099
+ const stagingBuffer = this.device.createBuffer({
1100
+ size: buffer.size,
1101
+ usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
1102
+ });
1103
+ const commandEncoder = this.device.createCommandEncoder();
1104
+ commandEncoder.copyBufferToBuffer(buffer, 0, stagingBuffer, 0, buffer.size);
1105
+ this.device.queue.submit([commandEncoder.finish()]);
1106
+ await stagingBuffer.mapAsync(GPUMapMode.READ);
1107
+ const data = stagingBuffer.getMappedRange().slice(0);
1108
+ stagingBuffer.unmap();
1109
+ stagingBuffer.destroy();
1110
+ return data;
1111
+ }
1112
+ /**
1075
1113
  * Create a storage-capable texture (useful for compute passes)
1076
1114
  */
1077
1115
  createStorageTexture(options) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wgsl-renderer",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "A multi-pass renderer based on WebGPU and WGSL.",
5
5
  "type": "module",
6
6
  "main": "./dist/cjs/index.js",