wgsl-renderer 0.3.0 → 0.3.2
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 +36 -73
- package/dist/esm/index.d.ts +13 -13
- package/dist/esm/index.js +36 -74
- package/package.json +1 -1
package/dist/cjs/index.js
CHANGED
|
@@ -10,7 +10,6 @@ var RenderPass = class {
|
|
|
10
10
|
view;
|
|
11
11
|
format;
|
|
12
12
|
renderToCanvas;
|
|
13
|
-
sampleCount = 1;
|
|
14
13
|
passResources = [];
|
|
15
14
|
bindGroups = {};
|
|
16
15
|
activeBindGroupSet = "default";
|
|
@@ -31,7 +30,6 @@ var RenderPass = class {
|
|
|
31
30
|
this.view = descriptor.view;
|
|
32
31
|
this.format = descriptor.format;
|
|
33
32
|
this.renderToCanvas = descriptor.renderToCanvas;
|
|
34
|
-
this.sampleCount = descriptor.sampleCount || 1;
|
|
35
33
|
const actualFormat = descriptor.format || format;
|
|
36
34
|
const module$1 = this.device.createShaderModule({
|
|
37
35
|
code: descriptor.shaderCode,
|
|
@@ -78,8 +76,7 @@ var RenderPass = class {
|
|
|
78
76
|
blend: this.getBlendState()
|
|
79
77
|
}]
|
|
80
78
|
},
|
|
81
|
-
primitive: { topology: "triangle-list" }
|
|
82
|
-
multisample: { count: this.sampleCount }
|
|
79
|
+
primitive: { topology: "triangle-list" }
|
|
83
80
|
});
|
|
84
81
|
this.bindGroup = null;
|
|
85
82
|
}
|
|
@@ -388,6 +385,16 @@ var PassTextureRef = class PassTextureRef {
|
|
|
388
385
|
function isPassTextureRef(obj) {
|
|
389
386
|
return PassTextureRef.is(obj);
|
|
390
387
|
}
|
|
388
|
+
/**
|
|
389
|
+
* Create a texture view suitable for sampling (not for render attachments)
|
|
390
|
+
* This view can include multiple mip levels for shader access
|
|
391
|
+
*/
|
|
392
|
+
function createSamplingView(texture, ref) {
|
|
393
|
+
return texture.createView({
|
|
394
|
+
baseMipLevel: 0,
|
|
395
|
+
mipLevelCount: ref.options?.mipmaps ? texture.mipLevelCount : 1
|
|
396
|
+
});
|
|
397
|
+
}
|
|
391
398
|
|
|
392
399
|
//#endregion
|
|
393
400
|
//#region src/index.ts
|
|
@@ -399,8 +406,6 @@ var WGSLRenderer = class {
|
|
|
399
406
|
textureManager;
|
|
400
407
|
animationFrameId = null;
|
|
401
408
|
isResizing = false;
|
|
402
|
-
supportedSampleCounts = [];
|
|
403
|
-
testedSampleCounts = /* @__PURE__ */ new Set();
|
|
404
409
|
constructor(canvas, options) {
|
|
405
410
|
this.canvas = canvas;
|
|
406
411
|
this.options = options;
|
|
@@ -410,8 +415,6 @@ var WGSLRenderer = class {
|
|
|
410
415
|
async init() {
|
|
411
416
|
this.device = await (await navigator.gpu.requestAdapter()).requestDevice();
|
|
412
417
|
this.format = navigator.gpu.getPreferredCanvasFormat();
|
|
413
|
-
this.supportedSampleCounts = [1];
|
|
414
|
-
this.testedSampleCounts = new Set([1]);
|
|
415
418
|
const config = Object.assign({
|
|
416
419
|
device: this.device,
|
|
417
420
|
format: this.format,
|
|
@@ -445,13 +448,6 @@ var WGSLRenderer = class {
|
|
|
445
448
|
getDevice() {
|
|
446
449
|
return this.device;
|
|
447
450
|
}
|
|
448
|
-
getSupportedSampleCounts() {
|
|
449
|
-
return [...this.supportedSampleCounts];
|
|
450
|
-
}
|
|
451
|
-
isSampleCountSupported(sampleCount) {
|
|
452
|
-
if (this.testedSampleCounts.has(sampleCount)) return this.supportedSampleCounts.includes(sampleCount);
|
|
453
|
-
return this.supportedSampleCounts.includes(sampleCount);
|
|
454
|
-
}
|
|
455
451
|
/**
|
|
456
452
|
* Get texture reference by pass name
|
|
457
453
|
* Returns a PassTextureRef that will resolve to the actual texture at render time
|
|
@@ -462,7 +458,8 @@ var WGSLRenderer = class {
|
|
|
462
458
|
getPassTexture(passName, options) {
|
|
463
459
|
const pass = this.passes.find((pass$1) => pass$1.name === passName);
|
|
464
460
|
if (!pass) throw new Error(`Cannot find pass named '${passName}'. Available passes: [${this.passes.map((p) => p.name).join(", ")}]`);
|
|
465
|
-
|
|
461
|
+
const f = options?.format ?? "rgba8unorm";
|
|
462
|
+
if (pass.format && f !== pass.format) throw new Error(`Format must be set to ${pass.format}, pass name: '${passName}'`);
|
|
466
463
|
return PassTextureRef.create(passName, options);
|
|
467
464
|
}
|
|
468
465
|
/**
|
|
@@ -478,20 +475,18 @@ var WGSLRenderer = class {
|
|
|
478
475
|
const format = ref.options?.format || this.format;
|
|
479
476
|
const usage = ref.options?.usage || GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.RENDER_ATTACHMENT;
|
|
480
477
|
const size = this.textureManager.getPixelSize();
|
|
481
|
-
const requestedSampleCount = ref.options?.sampleCount || 1;
|
|
482
|
-
const actualSampleCount = this.isSampleCountSupported(requestedSampleCount) ? requestedSampleCount : 1;
|
|
483
478
|
texture = this.device.createTexture({
|
|
484
479
|
size: [size.width, size.height],
|
|
485
480
|
format,
|
|
486
481
|
usage,
|
|
487
|
-
sampleCount:
|
|
482
|
+
sampleCount: 1,
|
|
488
483
|
mipLevelCount: ref.options?.mipLevelCount || 1
|
|
489
484
|
});
|
|
490
485
|
this.textureManager.setTexture(textureName, texture);
|
|
491
486
|
}
|
|
492
487
|
return texture.createView({
|
|
493
488
|
baseMipLevel: 0,
|
|
494
|
-
mipLevelCount:
|
|
489
|
+
mipLevelCount: 1
|
|
495
490
|
});
|
|
496
491
|
}
|
|
497
492
|
/**
|
|
@@ -501,6 +496,19 @@ var WGSLRenderer = class {
|
|
|
501
496
|
return this.passes.find((pass) => pass.name === passName);
|
|
502
497
|
}
|
|
503
498
|
/**
|
|
499
|
+
* Get the raw GPUTexture for a pass (useful for creating custom views)
|
|
500
|
+
* Note: The returned texture should not be used directly as a render attachment
|
|
501
|
+
* with mipLevelCount > 1, as that's not allowed by WebGPU.
|
|
502
|
+
*/
|
|
503
|
+
getPassTextureRaw(passName) {
|
|
504
|
+
const targetPass = this.passes.find((pass) => pass.name === passName);
|
|
505
|
+
if (!targetPass) throw new Error(`Cannot find pass named '${passName}'. Available passes: [${this.passes.map((p) => p.name).join(", ")}]`);
|
|
506
|
+
const textureName = `pass_${this.passes.indexOf(targetPass)}_output`;
|
|
507
|
+
const texture = this.textureManager.getTexture(textureName);
|
|
508
|
+
if (texture) return texture;
|
|
509
|
+
return null;
|
|
510
|
+
}
|
|
511
|
+
/**
|
|
504
512
|
* Disable a render pass (it will be skipped during rendering)
|
|
505
513
|
*/
|
|
506
514
|
disablePass(passName) {
|
|
@@ -597,8 +605,7 @@ var WGSLRenderer = class {
|
|
|
597
605
|
bindGroupSets: bindGroupSetsCopy,
|
|
598
606
|
view: descriptor.view,
|
|
599
607
|
format: descriptor.format,
|
|
600
|
-
renderToCanvas: descriptor.renderToCanvas
|
|
601
|
-
sampleCount: descriptor.sampleCount
|
|
608
|
+
renderToCanvas: descriptor.renderToCanvas
|
|
602
609
|
};
|
|
603
610
|
const pipelineFormat = descriptor.format || this.format;
|
|
604
611
|
return new RenderPass(internalDescriptor, this.device, pipelineFormat);
|
|
@@ -607,10 +614,6 @@ var WGSLRenderer = class {
|
|
|
607
614
|
* Add a render pass to the multi-pass pipeline
|
|
608
615
|
*/
|
|
609
616
|
addPass(descriptor) {
|
|
610
|
-
if (descriptor.sampleCount && !this.isSampleCountSupported(descriptor.sampleCount)) {
|
|
611
|
-
console.warn(`Sample count ${descriptor.sampleCount} is not supported. Using sample count 1 instead.`);
|
|
612
|
-
descriptor.sampleCount = 1;
|
|
613
|
-
}
|
|
614
617
|
const pass = this.createPass(descriptor);
|
|
615
618
|
pass.passResources = descriptor.resources ?? [];
|
|
616
619
|
this.passes.push(pass);
|
|
@@ -730,57 +733,16 @@ var WGSLRenderer = class {
|
|
|
730
733
|
let resolveTarget;
|
|
731
734
|
const canvasTexture = this.ctx.getCurrentTexture();
|
|
732
735
|
const isLastPass = i === enabledPasses.length - 1;
|
|
733
|
-
if (pass.renderToCanvas || isLastPass && !pass.view)
|
|
734
|
-
const actualSampleCount = this.isSampleCountSupported(pass.sampleCount) ? pass.sampleCount : 1;
|
|
735
|
-
if (actualSampleCount === 1) renderTarget = canvasTexture.createView();
|
|
736
|
-
else {
|
|
737
|
-
renderTarget = this.device.createTexture({
|
|
738
|
-
size: [canvasTexture.width, canvasTexture.height],
|
|
739
|
-
format: canvasTexture.format,
|
|
740
|
-
usage: GPUTextureUsage.RENDER_ATTACHMENT,
|
|
741
|
-
sampleCount: actualSampleCount
|
|
742
|
-
}).createView();
|
|
743
|
-
resolveTarget = canvasTexture.createView();
|
|
744
|
-
}
|
|
745
|
-
} else renderTarget = canvasTexture.createView();
|
|
736
|
+
if (pass.renderToCanvas || isLastPass && !pass.view) renderTarget = canvasTexture.createView();
|
|
746
737
|
else if (pass.view) renderTarget = pass.view;
|
|
747
738
|
else {
|
|
748
739
|
const textureName = `pass_${i}_output`;
|
|
749
740
|
let texture = this.textureManager.getTexture(textureName);
|
|
750
|
-
if (texture)
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
resolveTarget = resolveTexture.createView();
|
|
756
|
-
} else renderTarget = texture.createView();
|
|
757
|
-
} else if (pass.sampleCount && pass.sampleCount > 1) {
|
|
758
|
-
const actualSampleCount = this.isSampleCountSupported(pass.sampleCount) ? pass.sampleCount : 1;
|
|
759
|
-
if (actualSampleCount > 1) {
|
|
760
|
-
texture = this.device.createTexture({
|
|
761
|
-
size: [this.textureManager.getPixelSize().width, this.textureManager.getPixelSize().height],
|
|
762
|
-
format: pass.format || this.format,
|
|
763
|
-
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,
|
|
764
|
-
sampleCount: actualSampleCount
|
|
765
|
-
});
|
|
766
|
-
const resolveTexture = this.device.createTexture({
|
|
767
|
-
size: [this.textureManager.getPixelSize().width, this.textureManager.getPixelSize().height],
|
|
768
|
-
format: pass.format || this.format,
|
|
769
|
-
usage: GPUTextureUsage.TEXTURE_BINDING,
|
|
770
|
-
sampleCount: 1
|
|
771
|
-
});
|
|
772
|
-
this.textureManager.setTexture(`${textureName}_msaa`, texture);
|
|
773
|
-
this.textureManager.setTexture(`${textureName}_resolve`, resolveTexture);
|
|
774
|
-
renderTarget = texture.createView();
|
|
775
|
-
resolveTarget = resolveTexture.createView();
|
|
776
|
-
} else {
|
|
777
|
-
texture = this.textureManager.createTexture(textureName, pass.format || this.format);
|
|
778
|
-
renderTarget = texture.createView();
|
|
779
|
-
}
|
|
780
|
-
} else {
|
|
781
|
-
texture = this.textureManager.createTexture(textureName, pass.format || this.format);
|
|
782
|
-
renderTarget = texture.createView();
|
|
783
|
-
}
|
|
741
|
+
if (!texture) texture = this.textureManager.createTexture(textureName, pass.format || this.format);
|
|
742
|
+
renderTarget = texture.createView({
|
|
743
|
+
baseMipLevel: 0,
|
|
744
|
+
mipLevelCount: 1
|
|
745
|
+
});
|
|
784
746
|
}
|
|
785
747
|
const renderPass = commandEncoder.beginRenderPass({ colorAttachments: [{
|
|
786
748
|
view: renderTarget,
|
|
@@ -826,4 +788,5 @@ async function createWGSLRenderer(cvs, options) {
|
|
|
826
788
|
//#endregion
|
|
827
789
|
exports.PassTextureRef = PassTextureRef;
|
|
828
790
|
exports.WGSLRenderer = WGSLRenderer;
|
|
791
|
+
exports.createSamplingView = createSamplingView;
|
|
829
792
|
exports.createWGSLRenderer = createWGSLRenderer;
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -6,14 +6,12 @@ declare class PassTextureRef {
|
|
|
6
6
|
readonly options?: {
|
|
7
7
|
format?: GPUTextureFormat;
|
|
8
8
|
mipmaps?: boolean;
|
|
9
|
-
sampleCount?: number;
|
|
10
9
|
usage?: GPUTextureUsageFlags;
|
|
11
10
|
mipLevelCount?: number;
|
|
12
11
|
};
|
|
13
12
|
constructor(passName: string, options?: {
|
|
14
13
|
format?: GPUTextureFormat;
|
|
15
14
|
mipmaps?: boolean;
|
|
16
|
-
sampleCount?: number;
|
|
17
15
|
usage?: GPUTextureUsageFlags;
|
|
18
16
|
mipLevelCount?: number;
|
|
19
17
|
});
|
|
@@ -22,11 +20,15 @@ declare class PassTextureRef {
|
|
|
22
20
|
static create(passName: string, options?: {
|
|
23
21
|
format?: GPUTextureFormat;
|
|
24
22
|
mipmaps?: boolean;
|
|
25
|
-
sampleCount?: number;
|
|
26
23
|
usage?: GPUTextureUsageFlags;
|
|
27
24
|
mipLevelCount?: number;
|
|
28
25
|
}): PassTextureRef;
|
|
29
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* Create a texture view suitable for sampling (not for render attachments)
|
|
29
|
+
* This view can include multiple mip levels for shader access
|
|
30
|
+
*/
|
|
31
|
+
declare function createSamplingView(texture: GPUTexture, ref: PassTextureRef): GPUTextureView;
|
|
30
32
|
//#endregion
|
|
31
33
|
//#region src/RenderPass.d.ts
|
|
32
34
|
type BindingResource = GPUBindingResource | PassTextureRef;
|
|
@@ -56,7 +58,6 @@ interface RenderPassOptions {
|
|
|
56
58
|
view?: GPUTextureView;
|
|
57
59
|
format?: GPUTextureFormat;
|
|
58
60
|
renderToCanvas?: boolean;
|
|
59
|
-
sampleCount?: number;
|
|
60
61
|
}
|
|
61
62
|
interface InternalRenderPassDescriptor {
|
|
62
63
|
name: string;
|
|
@@ -79,7 +80,6 @@ interface InternalRenderPassDescriptor {
|
|
|
79
80
|
view?: GPUTextureView;
|
|
80
81
|
format?: GPUTextureFormat;
|
|
81
82
|
renderToCanvas?: boolean;
|
|
82
|
-
sampleCount?: number;
|
|
83
83
|
}
|
|
84
84
|
declare class RenderPass {
|
|
85
85
|
name: string;
|
|
@@ -96,7 +96,6 @@ declare class RenderPass {
|
|
|
96
96
|
view?: GPUTextureView;
|
|
97
97
|
format?: GPUTextureFormat;
|
|
98
98
|
renderToCanvas?: boolean;
|
|
99
|
-
sampleCount: number;
|
|
100
99
|
passResources: BindingResource[];
|
|
101
100
|
bindGroups: {
|
|
102
101
|
[setName: string]: GPUBindGroup;
|
|
@@ -154,15 +153,11 @@ declare class WGSLRenderer {
|
|
|
154
153
|
private textureManager;
|
|
155
154
|
private animationFrameId;
|
|
156
155
|
private isResizing;
|
|
157
|
-
private supportedSampleCounts;
|
|
158
|
-
private testedSampleCounts;
|
|
159
156
|
constructor(canvas: HTMLCanvasElement, options?: WGSLRendererOptions | undefined);
|
|
160
157
|
init(): Promise<void>;
|
|
161
158
|
resize(width: number, height: number): Promise<void>;
|
|
162
159
|
getContext(): GPUCanvasContext;
|
|
163
160
|
getDevice(): GPUDevice;
|
|
164
|
-
getSupportedSampleCounts(): number[];
|
|
165
|
-
isSampleCountSupported(sampleCount: number): boolean;
|
|
166
161
|
/**
|
|
167
162
|
* Get texture reference by pass name
|
|
168
163
|
* Returns a PassTextureRef that will resolve to the actual texture at render time
|
|
@@ -173,18 +168,23 @@ declare class WGSLRenderer {
|
|
|
173
168
|
getPassTexture(passName: string, options?: {
|
|
174
169
|
format?: GPUTextureFormat;
|
|
175
170
|
mipmaps?: boolean;
|
|
176
|
-
sampleCount?: number;
|
|
177
171
|
usage?: GPUTextureUsageFlags;
|
|
178
172
|
mipLevelCount?: number;
|
|
179
173
|
}): PassTextureRef;
|
|
180
174
|
/**
|
|
181
175
|
* Resolve a PassTextureRef to actual GPUTextureView with validation
|
|
182
176
|
*/
|
|
183
|
-
|
|
177
|
+
resolveTextureRef(ref: PassTextureRef): GPUTextureView;
|
|
184
178
|
/**
|
|
185
179
|
* Get pass by name
|
|
186
180
|
*/
|
|
187
181
|
getPassByName(passName: string): RenderPass | undefined;
|
|
182
|
+
/**
|
|
183
|
+
* Get the raw GPUTexture for a pass (useful for creating custom views)
|
|
184
|
+
* Note: The returned texture should not be used directly as a render attachment
|
|
185
|
+
* with mipLevelCount > 1, as that's not allowed by WebGPU.
|
|
186
|
+
*/
|
|
187
|
+
getPassTextureRaw(passName: string): GPUTexture | null;
|
|
188
188
|
/**
|
|
189
189
|
* Disable a render pass (it will be skipped during rendering)
|
|
190
190
|
*/
|
|
@@ -267,4 +267,4 @@ declare class WGSLRenderer {
|
|
|
267
267
|
}
|
|
268
268
|
declare function createWGSLRenderer(cvs: HTMLCanvasElement, options?: WGSLRendererOptions): Promise<WGSLRenderer>;
|
|
269
269
|
//#endregion
|
|
270
|
-
export { BindingResource, PassTextureRef, RenderPassOptions, WGSLRenderer, createWGSLRenderer };
|
|
270
|
+
export { BindingResource, PassTextureRef, RenderPassOptions, WGSLRenderer, createSamplingView, createWGSLRenderer };
|
package/dist/esm/index.js
CHANGED
|
@@ -9,7 +9,6 @@ var RenderPass = class {
|
|
|
9
9
|
view;
|
|
10
10
|
format;
|
|
11
11
|
renderToCanvas;
|
|
12
|
-
sampleCount = 1;
|
|
13
12
|
passResources = [];
|
|
14
13
|
bindGroups = {};
|
|
15
14
|
activeBindGroupSet = "default";
|
|
@@ -30,7 +29,6 @@ var RenderPass = class {
|
|
|
30
29
|
this.view = descriptor.view;
|
|
31
30
|
this.format = descriptor.format;
|
|
32
31
|
this.renderToCanvas = descriptor.renderToCanvas;
|
|
33
|
-
this.sampleCount = descriptor.sampleCount || 1;
|
|
34
32
|
const actualFormat = descriptor.format || format;
|
|
35
33
|
const module = this.device.createShaderModule({
|
|
36
34
|
code: descriptor.shaderCode,
|
|
@@ -77,8 +75,7 @@ var RenderPass = class {
|
|
|
77
75
|
blend: this.getBlendState()
|
|
78
76
|
}]
|
|
79
77
|
},
|
|
80
|
-
primitive: { topology: "triangle-list" }
|
|
81
|
-
multisample: { count: this.sampleCount }
|
|
78
|
+
primitive: { topology: "triangle-list" }
|
|
82
79
|
});
|
|
83
80
|
this.bindGroup = null;
|
|
84
81
|
}
|
|
@@ -387,6 +384,16 @@ var PassTextureRef = class PassTextureRef {
|
|
|
387
384
|
function isPassTextureRef(obj) {
|
|
388
385
|
return PassTextureRef.is(obj);
|
|
389
386
|
}
|
|
387
|
+
/**
|
|
388
|
+
* Create a texture view suitable for sampling (not for render attachments)
|
|
389
|
+
* This view can include multiple mip levels for shader access
|
|
390
|
+
*/
|
|
391
|
+
function createSamplingView(texture, ref) {
|
|
392
|
+
return texture.createView({
|
|
393
|
+
baseMipLevel: 0,
|
|
394
|
+
mipLevelCount: ref.options?.mipmaps ? texture.mipLevelCount : 1
|
|
395
|
+
});
|
|
396
|
+
}
|
|
390
397
|
|
|
391
398
|
//#endregion
|
|
392
399
|
//#region src/index.ts
|
|
@@ -398,8 +405,6 @@ var WGSLRenderer = class {
|
|
|
398
405
|
textureManager;
|
|
399
406
|
animationFrameId = null;
|
|
400
407
|
isResizing = false;
|
|
401
|
-
supportedSampleCounts = [];
|
|
402
|
-
testedSampleCounts = /* @__PURE__ */ new Set();
|
|
403
408
|
constructor(canvas, options) {
|
|
404
409
|
this.canvas = canvas;
|
|
405
410
|
this.options = options;
|
|
@@ -409,8 +414,6 @@ var WGSLRenderer = class {
|
|
|
409
414
|
async init() {
|
|
410
415
|
this.device = await (await navigator.gpu.requestAdapter()).requestDevice();
|
|
411
416
|
this.format = navigator.gpu.getPreferredCanvasFormat();
|
|
412
|
-
this.supportedSampleCounts = [1];
|
|
413
|
-
this.testedSampleCounts = new Set([1]);
|
|
414
417
|
const config = Object.assign({
|
|
415
418
|
device: this.device,
|
|
416
419
|
format: this.format,
|
|
@@ -444,13 +447,6 @@ var WGSLRenderer = class {
|
|
|
444
447
|
getDevice() {
|
|
445
448
|
return this.device;
|
|
446
449
|
}
|
|
447
|
-
getSupportedSampleCounts() {
|
|
448
|
-
return [...this.supportedSampleCounts];
|
|
449
|
-
}
|
|
450
|
-
isSampleCountSupported(sampleCount) {
|
|
451
|
-
if (this.testedSampleCounts.has(sampleCount)) return this.supportedSampleCounts.includes(sampleCount);
|
|
452
|
-
return this.supportedSampleCounts.includes(sampleCount);
|
|
453
|
-
}
|
|
454
450
|
/**
|
|
455
451
|
* Get texture reference by pass name
|
|
456
452
|
* Returns a PassTextureRef that will resolve to the actual texture at render time
|
|
@@ -461,7 +457,8 @@ var WGSLRenderer = class {
|
|
|
461
457
|
getPassTexture(passName, options) {
|
|
462
458
|
const pass = this.passes.find((pass$1) => pass$1.name === passName);
|
|
463
459
|
if (!pass) throw new Error(`Cannot find pass named '${passName}'. Available passes: [${this.passes.map((p) => p.name).join(", ")}]`);
|
|
464
|
-
|
|
460
|
+
const f = options?.format ?? "rgba8unorm";
|
|
461
|
+
if (pass.format && f !== pass.format) throw new Error(`Format must be set to ${pass.format}, pass name: '${passName}'`);
|
|
465
462
|
return PassTextureRef.create(passName, options);
|
|
466
463
|
}
|
|
467
464
|
/**
|
|
@@ -477,20 +474,18 @@ var WGSLRenderer = class {
|
|
|
477
474
|
const format = ref.options?.format || this.format;
|
|
478
475
|
const usage = ref.options?.usage || GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.RENDER_ATTACHMENT;
|
|
479
476
|
const size = this.textureManager.getPixelSize();
|
|
480
|
-
const requestedSampleCount = ref.options?.sampleCount || 1;
|
|
481
|
-
const actualSampleCount = this.isSampleCountSupported(requestedSampleCount) ? requestedSampleCount : 1;
|
|
482
477
|
texture = this.device.createTexture({
|
|
483
478
|
size: [size.width, size.height],
|
|
484
479
|
format,
|
|
485
480
|
usage,
|
|
486
|
-
sampleCount:
|
|
481
|
+
sampleCount: 1,
|
|
487
482
|
mipLevelCount: ref.options?.mipLevelCount || 1
|
|
488
483
|
});
|
|
489
484
|
this.textureManager.setTexture(textureName, texture);
|
|
490
485
|
}
|
|
491
486
|
return texture.createView({
|
|
492
487
|
baseMipLevel: 0,
|
|
493
|
-
mipLevelCount:
|
|
488
|
+
mipLevelCount: 1
|
|
494
489
|
});
|
|
495
490
|
}
|
|
496
491
|
/**
|
|
@@ -500,6 +495,19 @@ var WGSLRenderer = class {
|
|
|
500
495
|
return this.passes.find((pass) => pass.name === passName);
|
|
501
496
|
}
|
|
502
497
|
/**
|
|
498
|
+
* Get the raw GPUTexture for a pass (useful for creating custom views)
|
|
499
|
+
* Note: The returned texture should not be used directly as a render attachment
|
|
500
|
+
* with mipLevelCount > 1, as that's not allowed by WebGPU.
|
|
501
|
+
*/
|
|
502
|
+
getPassTextureRaw(passName) {
|
|
503
|
+
const targetPass = this.passes.find((pass) => pass.name === passName);
|
|
504
|
+
if (!targetPass) throw new Error(`Cannot find pass named '${passName}'. Available passes: [${this.passes.map((p) => p.name).join(", ")}]`);
|
|
505
|
+
const textureName = `pass_${this.passes.indexOf(targetPass)}_output`;
|
|
506
|
+
const texture = this.textureManager.getTexture(textureName);
|
|
507
|
+
if (texture) return texture;
|
|
508
|
+
return null;
|
|
509
|
+
}
|
|
510
|
+
/**
|
|
503
511
|
* Disable a render pass (it will be skipped during rendering)
|
|
504
512
|
*/
|
|
505
513
|
disablePass(passName) {
|
|
@@ -596,8 +604,7 @@ var WGSLRenderer = class {
|
|
|
596
604
|
bindGroupSets: bindGroupSetsCopy,
|
|
597
605
|
view: descriptor.view,
|
|
598
606
|
format: descriptor.format,
|
|
599
|
-
renderToCanvas: descriptor.renderToCanvas
|
|
600
|
-
sampleCount: descriptor.sampleCount
|
|
607
|
+
renderToCanvas: descriptor.renderToCanvas
|
|
601
608
|
};
|
|
602
609
|
const pipelineFormat = descriptor.format || this.format;
|
|
603
610
|
return new RenderPass(internalDescriptor, this.device, pipelineFormat);
|
|
@@ -606,10 +613,6 @@ var WGSLRenderer = class {
|
|
|
606
613
|
* Add a render pass to the multi-pass pipeline
|
|
607
614
|
*/
|
|
608
615
|
addPass(descriptor) {
|
|
609
|
-
if (descriptor.sampleCount && !this.isSampleCountSupported(descriptor.sampleCount)) {
|
|
610
|
-
console.warn(`Sample count ${descriptor.sampleCount} is not supported. Using sample count 1 instead.`);
|
|
611
|
-
descriptor.sampleCount = 1;
|
|
612
|
-
}
|
|
613
616
|
const pass = this.createPass(descriptor);
|
|
614
617
|
pass.passResources = descriptor.resources ?? [];
|
|
615
618
|
this.passes.push(pass);
|
|
@@ -729,57 +732,16 @@ var WGSLRenderer = class {
|
|
|
729
732
|
let resolveTarget;
|
|
730
733
|
const canvasTexture = this.ctx.getCurrentTexture();
|
|
731
734
|
const isLastPass = i === enabledPasses.length - 1;
|
|
732
|
-
if (pass.renderToCanvas || isLastPass && !pass.view)
|
|
733
|
-
const actualSampleCount = this.isSampleCountSupported(pass.sampleCount) ? pass.sampleCount : 1;
|
|
734
|
-
if (actualSampleCount === 1) renderTarget = canvasTexture.createView();
|
|
735
|
-
else {
|
|
736
|
-
renderTarget = this.device.createTexture({
|
|
737
|
-
size: [canvasTexture.width, canvasTexture.height],
|
|
738
|
-
format: canvasTexture.format,
|
|
739
|
-
usage: GPUTextureUsage.RENDER_ATTACHMENT,
|
|
740
|
-
sampleCount: actualSampleCount
|
|
741
|
-
}).createView();
|
|
742
|
-
resolveTarget = canvasTexture.createView();
|
|
743
|
-
}
|
|
744
|
-
} else renderTarget = canvasTexture.createView();
|
|
735
|
+
if (pass.renderToCanvas || isLastPass && !pass.view) renderTarget = canvasTexture.createView();
|
|
745
736
|
else if (pass.view) renderTarget = pass.view;
|
|
746
737
|
else {
|
|
747
738
|
const textureName = `pass_${i}_output`;
|
|
748
739
|
let texture = this.textureManager.getTexture(textureName);
|
|
749
|
-
if (texture)
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
resolveTarget = resolveTexture.createView();
|
|
755
|
-
} else renderTarget = texture.createView();
|
|
756
|
-
} else if (pass.sampleCount && pass.sampleCount > 1) {
|
|
757
|
-
const actualSampleCount = this.isSampleCountSupported(pass.sampleCount) ? pass.sampleCount : 1;
|
|
758
|
-
if (actualSampleCount > 1) {
|
|
759
|
-
texture = this.device.createTexture({
|
|
760
|
-
size: [this.textureManager.getPixelSize().width, this.textureManager.getPixelSize().height],
|
|
761
|
-
format: pass.format || this.format,
|
|
762
|
-
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,
|
|
763
|
-
sampleCount: actualSampleCount
|
|
764
|
-
});
|
|
765
|
-
const resolveTexture = this.device.createTexture({
|
|
766
|
-
size: [this.textureManager.getPixelSize().width, this.textureManager.getPixelSize().height],
|
|
767
|
-
format: pass.format || this.format,
|
|
768
|
-
usage: GPUTextureUsage.TEXTURE_BINDING,
|
|
769
|
-
sampleCount: 1
|
|
770
|
-
});
|
|
771
|
-
this.textureManager.setTexture(`${textureName}_msaa`, texture);
|
|
772
|
-
this.textureManager.setTexture(`${textureName}_resolve`, resolveTexture);
|
|
773
|
-
renderTarget = texture.createView();
|
|
774
|
-
resolveTarget = resolveTexture.createView();
|
|
775
|
-
} else {
|
|
776
|
-
texture = this.textureManager.createTexture(textureName, pass.format || this.format);
|
|
777
|
-
renderTarget = texture.createView();
|
|
778
|
-
}
|
|
779
|
-
} else {
|
|
780
|
-
texture = this.textureManager.createTexture(textureName, pass.format || this.format);
|
|
781
|
-
renderTarget = texture.createView();
|
|
782
|
-
}
|
|
740
|
+
if (!texture) texture = this.textureManager.createTexture(textureName, pass.format || this.format);
|
|
741
|
+
renderTarget = texture.createView({
|
|
742
|
+
baseMipLevel: 0,
|
|
743
|
+
mipLevelCount: 1
|
|
744
|
+
});
|
|
783
745
|
}
|
|
784
746
|
const renderPass = commandEncoder.beginRenderPass({ colorAttachments: [{
|
|
785
747
|
view: renderTarget,
|
|
@@ -823,4 +785,4 @@ async function createWGSLRenderer(cvs, options) {
|
|
|
823
785
|
}
|
|
824
786
|
|
|
825
787
|
//#endregion
|
|
826
|
-
export { PassTextureRef, WGSLRenderer, createWGSLRenderer };
|
|
788
|
+
export { PassTextureRef, WGSLRenderer, createSamplingView, createWGSLRenderer };
|