reze-engine 0.1.13 → 0.1.14
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/engine.d.ts +6 -0
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +77 -74
- package/package.json +1 -1
- package/src/engine.ts +89 -79
package/dist/engine.d.ts
CHANGED
|
@@ -35,6 +35,7 @@ export declare class Engine {
|
|
|
35
35
|
private worldMatrixBuffer?;
|
|
36
36
|
private inverseBindMatrixBuffer?;
|
|
37
37
|
private skinMatrixComputePipeline?;
|
|
38
|
+
private skinMatrixComputeBindGroup?;
|
|
38
39
|
private boneCountBuffer?;
|
|
39
40
|
private multisampleTexture;
|
|
40
41
|
private readonly sampleCount;
|
|
@@ -52,6 +53,10 @@ export declare class Engine {
|
|
|
52
53
|
private bloomIntensityBuffer;
|
|
53
54
|
private bloomThresholdBuffer;
|
|
54
55
|
private linearSampler;
|
|
56
|
+
private bloomExtractBindGroup?;
|
|
57
|
+
private bloomBlurHBindGroup?;
|
|
58
|
+
private bloomBlurVBindGroup?;
|
|
59
|
+
private bloomComposeBindGroup?;
|
|
55
60
|
bloomThreshold: number;
|
|
56
61
|
bloomIntensity: number;
|
|
57
62
|
private rimLightIntensity;
|
|
@@ -78,6 +83,7 @@ export declare class Engine {
|
|
|
78
83
|
private createSkinMatrixComputePipeline;
|
|
79
84
|
private createFullscreenQuad;
|
|
80
85
|
private createBloomPipelines;
|
|
86
|
+
private setupBloom;
|
|
81
87
|
private setupResize;
|
|
82
88
|
private handleResize;
|
|
83
89
|
private setupCamera;
|
package/dist/engine.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACjC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAKnC,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAA;IACX,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,qBAAa,MAAM;IACjB,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,OAAO,CAAmB;IAClC,OAAO,CAAC,kBAAkB,CAAmB;IACtC,MAAM,EAAG,MAAM,CAAA;IACtB,OAAO,CAAC,mBAAmB,CAAY;IACvC,OAAO,CAAC,gBAAgB,CAAuB;IAC/C,OAAO,CAAC,kBAAkB,CAAY;IACtC,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,UAAU,CAAI;IACtB,OAAO,CAAC,YAAY,CAAY;IAChC,OAAO,CAAC,WAAW,CAAC,CAAW;IAC/B,OAAO,CAAC,cAAc,CAA8B;IACpD,OAAO,CAAC,YAAY,CAAa;IACjC,OAAO,CAAC,QAAQ,CAAoB;IACpC,OAAO,CAAC,eAAe,CAAoB;IAC3C,OAAO,CAAC,mBAAmB,CAAoB;IAC/C,OAAO,CAAC,2BAA2B,CAAoB;IACvD,OAAO,CAAC,oBAAoB,CAAoB;IAChD,OAAO,CAAC,kBAAkB,CAAoB;IAC9C,OAAO,CAAC,WAAW,CAAoB;IACvC,OAAO,CAAC,mBAAmB,CAAqB;IAChD,OAAO,CAAC,sBAAsB,CAAqB;IACnD,OAAO,CAAC,YAAY,CAAY;IAChC,OAAO,CAAC,aAAa,CAAY;IACjC,OAAO,CAAC,gBAAgB,CAAC,CAAW;IACpC,OAAO,CAAC,iBAAiB,CAAC,CAAW;IACrC,OAAO,CAAC,uBAAuB,CAAC,CAAW;IAC3C,OAAO,CAAC,yBAAyB,CAAC,CAAoB;IACtD,OAAO,CAAC,eAAe,CAAC,CAAW;IACnC,OAAO,CAAC,kBAAkB,CAAa;IACvC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAI;IAChC,OAAO,CAAC,oBAAoB,CAA0B;IAEtD,OAAO,CAAC,kBAAkB,CAAa;IACvC,OAAO,CAAC,sBAAsB,CAAiB;IAC/C,OAAO,CAAC,mBAAmB,CAAa;IACxC,OAAO,CAAC,iBAAiB,CAAa;IACtC,OAAO,CAAC,iBAAiB,CAAa;IAEtC,OAAO,CAAC,oBAAoB,CAAoB;IAChD,OAAO,CAAC,iBAAiB,CAAoB;IAC7C,OAAO,CAAC,oBAAoB,CAAoB;IAEhD,OAAO,CAAC,oBAAoB,CAAY;IACxC,OAAO,CAAC,mBAAmB,CAAY;IACvC,OAAO,CAAC,oBAAoB,CAAY;IACxC,OAAO,CAAC,oBAAoB,CAAY;IACxC,OAAO,CAAC,aAAa,CAAa;
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"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"}
|
package/dist/engine.js
CHANGED
|
@@ -1072,6 +1072,65 @@ export class Engine {
|
|
|
1072
1072
|
this.bloomThresholdBuffer = bloomThresholdBuffer;
|
|
1073
1073
|
this.linearSampler = linearSampler;
|
|
1074
1074
|
}
|
|
1075
|
+
// Setup bloom textures and bind groups (called when canvas is resized)
|
|
1076
|
+
setupBloom(width, height) {
|
|
1077
|
+
// Create bloom textures (half resolution for performance)
|
|
1078
|
+
const bloomWidth = Math.floor(width / 2);
|
|
1079
|
+
const bloomHeight = Math.floor(height / 2);
|
|
1080
|
+
this.bloomExtractTexture = this.device.createTexture({
|
|
1081
|
+
label: "bloom extract",
|
|
1082
|
+
size: [bloomWidth, bloomHeight],
|
|
1083
|
+
format: this.presentationFormat,
|
|
1084
|
+
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,
|
|
1085
|
+
});
|
|
1086
|
+
this.bloomBlurTexture1 = this.device.createTexture({
|
|
1087
|
+
label: "bloom blur 1",
|
|
1088
|
+
size: [bloomWidth, bloomHeight],
|
|
1089
|
+
format: this.presentationFormat,
|
|
1090
|
+
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,
|
|
1091
|
+
});
|
|
1092
|
+
this.bloomBlurTexture2 = this.device.createTexture({
|
|
1093
|
+
label: "bloom blur 2",
|
|
1094
|
+
size: [bloomWidth, bloomHeight],
|
|
1095
|
+
format: this.presentationFormat,
|
|
1096
|
+
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,
|
|
1097
|
+
});
|
|
1098
|
+
// Create bloom bind groups
|
|
1099
|
+
this.bloomExtractBindGroup = this.device.createBindGroup({
|
|
1100
|
+
layout: this.bloomExtractPipeline.getBindGroupLayout(0),
|
|
1101
|
+
entries: [
|
|
1102
|
+
{ binding: 0, resource: this.sceneRenderTexture.createView() },
|
|
1103
|
+
{ binding: 1, resource: this.linearSampler },
|
|
1104
|
+
{ binding: 2, resource: { buffer: this.bloomThresholdBuffer } },
|
|
1105
|
+
],
|
|
1106
|
+
});
|
|
1107
|
+
this.bloomBlurHBindGroup = this.device.createBindGroup({
|
|
1108
|
+
layout: this.bloomBlurPipeline.getBindGroupLayout(0),
|
|
1109
|
+
entries: [
|
|
1110
|
+
{ binding: 0, resource: this.bloomExtractTexture.createView() },
|
|
1111
|
+
{ binding: 1, resource: this.linearSampler },
|
|
1112
|
+
{ binding: 2, resource: { buffer: this.blurDirectionBuffer } },
|
|
1113
|
+
],
|
|
1114
|
+
});
|
|
1115
|
+
this.bloomBlurVBindGroup = this.device.createBindGroup({
|
|
1116
|
+
layout: this.bloomBlurPipeline.getBindGroupLayout(0),
|
|
1117
|
+
entries: [
|
|
1118
|
+
{ binding: 0, resource: this.bloomBlurTexture1.createView() },
|
|
1119
|
+
{ binding: 1, resource: this.linearSampler },
|
|
1120
|
+
{ binding: 2, resource: { buffer: this.blurDirectionBuffer } },
|
|
1121
|
+
],
|
|
1122
|
+
});
|
|
1123
|
+
this.bloomComposeBindGroup = this.device.createBindGroup({
|
|
1124
|
+
layout: this.bloomComposePipeline.getBindGroupLayout(0),
|
|
1125
|
+
entries: [
|
|
1126
|
+
{ binding: 0, resource: this.sceneRenderTexture.createView() },
|
|
1127
|
+
{ binding: 1, resource: this.linearSampler },
|
|
1128
|
+
{ binding: 2, resource: this.bloomBlurTexture2.createView() },
|
|
1129
|
+
{ binding: 3, resource: this.linearSampler },
|
|
1130
|
+
{ binding: 4, resource: { buffer: this.bloomIntensityBuffer } },
|
|
1131
|
+
],
|
|
1132
|
+
});
|
|
1133
|
+
}
|
|
1075
1134
|
// Step 3: Setup canvas resize handling
|
|
1076
1135
|
setupResize() {
|
|
1077
1136
|
this.resizeObserver = new ResizeObserver(() => this.handleResize());
|
|
@@ -1109,27 +1168,8 @@ export class Engine {
|
|
|
1109
1168
|
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,
|
|
1110
1169
|
});
|
|
1111
1170
|
this.sceneRenderTextureView = this.sceneRenderTexture.createView();
|
|
1112
|
-
//
|
|
1113
|
-
|
|
1114
|
-
const bloomHeight = Math.floor(height / 2);
|
|
1115
|
-
this.bloomExtractTexture = this.device.createTexture({
|
|
1116
|
-
label: "bloom extract",
|
|
1117
|
-
size: [bloomWidth, bloomHeight],
|
|
1118
|
-
format: this.presentationFormat,
|
|
1119
|
-
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,
|
|
1120
|
-
});
|
|
1121
|
-
this.bloomBlurTexture1 = this.device.createTexture({
|
|
1122
|
-
label: "bloom blur 1",
|
|
1123
|
-
size: [bloomWidth, bloomHeight],
|
|
1124
|
-
format: this.presentationFormat,
|
|
1125
|
-
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,
|
|
1126
|
-
});
|
|
1127
|
-
this.bloomBlurTexture2 = this.device.createTexture({
|
|
1128
|
-
label: "bloom blur 2",
|
|
1129
|
-
size: [bloomWidth, bloomHeight],
|
|
1130
|
-
format: this.presentationFormat,
|
|
1131
|
-
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,
|
|
1132
|
-
});
|
|
1171
|
+
// Setup bloom textures and bind groups
|
|
1172
|
+
this.setupBloom(width, height);
|
|
1133
1173
|
const depthTextureView = this.depthTexture.createView();
|
|
1134
1174
|
// Render scene to texture instead of directly to canvas
|
|
1135
1175
|
const colorAttachment = this.sampleCount > 1
|
|
@@ -1302,6 +1342,16 @@ export class Engine {
|
|
|
1302
1342
|
boneCountData[0] = boneCount;
|
|
1303
1343
|
this.device.queue.writeBuffer(this.boneCountBuffer, 0, boneCountData);
|
|
1304
1344
|
this.createSkinMatrixComputePipeline();
|
|
1345
|
+
// Create compute bind group once (reused every frame)
|
|
1346
|
+
this.skinMatrixComputeBindGroup = this.device.createBindGroup({
|
|
1347
|
+
layout: this.skinMatrixComputePipeline.getBindGroupLayout(0),
|
|
1348
|
+
entries: [
|
|
1349
|
+
{ binding: 0, resource: { buffer: this.boneCountBuffer } },
|
|
1350
|
+
{ binding: 1, resource: { buffer: this.worldMatrixBuffer } },
|
|
1351
|
+
{ binding: 2, resource: { buffer: this.inverseBindMatrixBuffer } },
|
|
1352
|
+
{ binding: 3, resource: { buffer: this.skinMatrixBuffer } },
|
|
1353
|
+
],
|
|
1354
|
+
});
|
|
1305
1355
|
const indices = model.getIndices();
|
|
1306
1356
|
if (indices) {
|
|
1307
1357
|
this.indexBuffer = this.device.createBuffer({
|
|
@@ -1751,16 +1801,8 @@ export class Engine {
|
|
|
1751
1801
|
},
|
|
1752
1802
|
],
|
|
1753
1803
|
});
|
|
1754
|
-
const extractBindGroup = this.device.createBindGroup({
|
|
1755
|
-
layout: this.bloomExtractPipeline.getBindGroupLayout(0),
|
|
1756
|
-
entries: [
|
|
1757
|
-
{ binding: 0, resource: this.sceneRenderTexture.createView() },
|
|
1758
|
-
{ binding: 1, resource: this.linearSampler },
|
|
1759
|
-
{ binding: 2, resource: { buffer: this.bloomThresholdBuffer } },
|
|
1760
|
-
],
|
|
1761
|
-
});
|
|
1762
1804
|
extractPass.setPipeline(this.bloomExtractPipeline);
|
|
1763
|
-
extractPass.setBindGroup(0,
|
|
1805
|
+
extractPass.setBindGroup(0, this.bloomExtractBindGroup);
|
|
1764
1806
|
extractPass.draw(6, 1, 0, 0);
|
|
1765
1807
|
extractPass.end();
|
|
1766
1808
|
// Pass 2: Horizontal blur
|
|
@@ -1779,16 +1821,8 @@ export class Engine {
|
|
|
1779
1821
|
},
|
|
1780
1822
|
],
|
|
1781
1823
|
});
|
|
1782
|
-
const blurHBindGroup = this.device.createBindGroup({
|
|
1783
|
-
layout: this.bloomBlurPipeline.getBindGroupLayout(0),
|
|
1784
|
-
entries: [
|
|
1785
|
-
{ binding: 0, resource: this.bloomExtractTexture.createView() },
|
|
1786
|
-
{ binding: 1, resource: this.linearSampler },
|
|
1787
|
-
{ binding: 2, resource: { buffer: this.blurDirectionBuffer } },
|
|
1788
|
-
],
|
|
1789
|
-
});
|
|
1790
1824
|
blurHPass.setPipeline(this.bloomBlurPipeline);
|
|
1791
|
-
blurHPass.setBindGroup(0,
|
|
1825
|
+
blurHPass.setBindGroup(0, this.bloomBlurHBindGroup);
|
|
1792
1826
|
blurHPass.draw(6, 1, 0, 0);
|
|
1793
1827
|
blurHPass.end();
|
|
1794
1828
|
// Pass 3: Vertical blur
|
|
@@ -1807,16 +1841,8 @@ export class Engine {
|
|
|
1807
1841
|
},
|
|
1808
1842
|
],
|
|
1809
1843
|
});
|
|
1810
|
-
const blurVBindGroup = this.device.createBindGroup({
|
|
1811
|
-
layout: this.bloomBlurPipeline.getBindGroupLayout(0),
|
|
1812
|
-
entries: [
|
|
1813
|
-
{ binding: 0, resource: this.bloomBlurTexture1.createView() },
|
|
1814
|
-
{ binding: 1, resource: this.linearSampler },
|
|
1815
|
-
{ binding: 2, resource: { buffer: this.blurDirectionBuffer } },
|
|
1816
|
-
],
|
|
1817
|
-
});
|
|
1818
1844
|
blurVPass.setPipeline(this.bloomBlurPipeline);
|
|
1819
|
-
blurVPass.setBindGroup(0,
|
|
1845
|
+
blurVPass.setBindGroup(0, this.bloomBlurVBindGroup);
|
|
1820
1846
|
blurVPass.draw(6, 1, 0, 0);
|
|
1821
1847
|
blurVPass.end();
|
|
1822
1848
|
// Pass 4: Compose scene + bloom to canvas
|
|
@@ -1831,18 +1857,8 @@ export class Engine {
|
|
|
1831
1857
|
},
|
|
1832
1858
|
],
|
|
1833
1859
|
});
|
|
1834
|
-
const composeBindGroup = this.device.createBindGroup({
|
|
1835
|
-
layout: this.bloomComposePipeline.getBindGroupLayout(0),
|
|
1836
|
-
entries: [
|
|
1837
|
-
{ binding: 0, resource: this.sceneRenderTexture.createView() },
|
|
1838
|
-
{ binding: 1, resource: this.linearSampler },
|
|
1839
|
-
{ binding: 2, resource: this.bloomBlurTexture2.createView() },
|
|
1840
|
-
{ binding: 3, resource: this.linearSampler },
|
|
1841
|
-
{ binding: 4, resource: { buffer: this.bloomIntensityBuffer } },
|
|
1842
|
-
],
|
|
1843
|
-
});
|
|
1844
1860
|
composePass.setPipeline(this.bloomComposePipeline);
|
|
1845
|
-
composePass.setBindGroup(0,
|
|
1861
|
+
composePass.setBindGroup(0, this.bloomComposeBindGroup);
|
|
1846
1862
|
composePass.draw(6, 1, 0, 0);
|
|
1847
1863
|
composePass.end();
|
|
1848
1864
|
this.device.queue.submit([encoder.finish()]);
|
|
@@ -1892,24 +1908,11 @@ export class Engine {
|
|
|
1892
1908
|
const workgroupSize = 64;
|
|
1893
1909
|
// Dispatch exactly enough threads for all bones (no bounds check needed)
|
|
1894
1910
|
const workgroupCount = Math.ceil(boneCount / workgroupSize);
|
|
1895
|
-
//
|
|
1896
|
-
const boneCountData = new Uint32Array(8); // 32 bytes total
|
|
1897
|
-
boneCountData[0] = boneCount;
|
|
1898
|
-
this.device.queue.writeBuffer(this.boneCountBuffer, 0, boneCountData);
|
|
1899
|
-
const bindGroup = this.device.createBindGroup({
|
|
1900
|
-
label: "skin matrix compute bind group",
|
|
1901
|
-
layout: this.skinMatrixComputePipeline.getBindGroupLayout(0),
|
|
1902
|
-
entries: [
|
|
1903
|
-
{ binding: 0, resource: { buffer: this.boneCountBuffer } },
|
|
1904
|
-
{ binding: 1, resource: { buffer: this.worldMatrixBuffer } },
|
|
1905
|
-
{ binding: 2, resource: { buffer: this.inverseBindMatrixBuffer } },
|
|
1906
|
-
{ binding: 3, resource: { buffer: this.skinMatrixBuffer } },
|
|
1907
|
-
],
|
|
1908
|
-
});
|
|
1911
|
+
// Bone count is written once in setupModelBuffers() and never changes
|
|
1909
1912
|
const encoder = this.device.createCommandEncoder();
|
|
1910
1913
|
const pass = encoder.beginComputePass();
|
|
1911
1914
|
pass.setPipeline(this.skinMatrixComputePipeline);
|
|
1912
|
-
pass.setBindGroup(0,
|
|
1915
|
+
pass.setBindGroup(0, this.skinMatrixComputeBindGroup);
|
|
1913
1916
|
pass.dispatchWorkgroups(workgroupCount);
|
|
1914
1917
|
pass.end();
|
|
1915
1918
|
this.device.queue.submit([encoder.finish()]);
|
package/package.json
CHANGED
package/src/engine.ts
CHANGED
|
@@ -40,6 +40,7 @@ export class Engine {
|
|
|
40
40
|
private worldMatrixBuffer?: GPUBuffer
|
|
41
41
|
private inverseBindMatrixBuffer?: GPUBuffer
|
|
42
42
|
private skinMatrixComputePipeline?: GPUComputePipeline
|
|
43
|
+
private skinMatrixComputeBindGroup?: GPUBindGroup
|
|
43
44
|
private boneCountBuffer?: GPUBuffer
|
|
44
45
|
private multisampleTexture!: GPUTexture
|
|
45
46
|
private readonly sampleCount = 4 // MSAA 4x
|
|
@@ -60,6 +61,11 @@ export class Engine {
|
|
|
60
61
|
private bloomIntensityBuffer!: GPUBuffer
|
|
61
62
|
private bloomThresholdBuffer!: GPUBuffer
|
|
62
63
|
private linearSampler!: GPUSampler
|
|
64
|
+
// Bloom bind groups (created once, reused every frame)
|
|
65
|
+
private bloomExtractBindGroup?: GPUBindGroup
|
|
66
|
+
private bloomBlurHBindGroup?: GPUBindGroup
|
|
67
|
+
private bloomBlurVBindGroup?: GPUBindGroup
|
|
68
|
+
private bloomComposeBindGroup?: GPUBindGroup
|
|
63
69
|
// Bloom settings
|
|
64
70
|
public bloomThreshold: number = 0.3
|
|
65
71
|
public bloomIntensity: number = 0.1
|
|
@@ -1156,6 +1162,70 @@ export class Engine {
|
|
|
1156
1162
|
this.linearSampler = linearSampler
|
|
1157
1163
|
}
|
|
1158
1164
|
|
|
1165
|
+
// Setup bloom textures and bind groups (called when canvas is resized)
|
|
1166
|
+
private setupBloom(width: number, height: number) {
|
|
1167
|
+
// Create bloom textures (half resolution for performance)
|
|
1168
|
+
const bloomWidth = Math.floor(width / 2)
|
|
1169
|
+
const bloomHeight = Math.floor(height / 2)
|
|
1170
|
+
this.bloomExtractTexture = this.device.createTexture({
|
|
1171
|
+
label: "bloom extract",
|
|
1172
|
+
size: [bloomWidth, bloomHeight],
|
|
1173
|
+
format: this.presentationFormat,
|
|
1174
|
+
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,
|
|
1175
|
+
})
|
|
1176
|
+
this.bloomBlurTexture1 = this.device.createTexture({
|
|
1177
|
+
label: "bloom blur 1",
|
|
1178
|
+
size: [bloomWidth, bloomHeight],
|
|
1179
|
+
format: this.presentationFormat,
|
|
1180
|
+
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,
|
|
1181
|
+
})
|
|
1182
|
+
this.bloomBlurTexture2 = this.device.createTexture({
|
|
1183
|
+
label: "bloom blur 2",
|
|
1184
|
+
size: [bloomWidth, bloomHeight],
|
|
1185
|
+
format: this.presentationFormat,
|
|
1186
|
+
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,
|
|
1187
|
+
})
|
|
1188
|
+
|
|
1189
|
+
// Create bloom bind groups
|
|
1190
|
+
this.bloomExtractBindGroup = this.device.createBindGroup({
|
|
1191
|
+
layout: this.bloomExtractPipeline.getBindGroupLayout(0),
|
|
1192
|
+
entries: [
|
|
1193
|
+
{ binding: 0, resource: this.sceneRenderTexture.createView() },
|
|
1194
|
+
{ binding: 1, resource: this.linearSampler },
|
|
1195
|
+
{ binding: 2, resource: { buffer: this.bloomThresholdBuffer } },
|
|
1196
|
+
],
|
|
1197
|
+
})
|
|
1198
|
+
|
|
1199
|
+
this.bloomBlurHBindGroup = this.device.createBindGroup({
|
|
1200
|
+
layout: this.bloomBlurPipeline.getBindGroupLayout(0),
|
|
1201
|
+
entries: [
|
|
1202
|
+
{ binding: 0, resource: this.bloomExtractTexture.createView() },
|
|
1203
|
+
{ binding: 1, resource: this.linearSampler },
|
|
1204
|
+
{ binding: 2, resource: { buffer: this.blurDirectionBuffer } },
|
|
1205
|
+
],
|
|
1206
|
+
})
|
|
1207
|
+
|
|
1208
|
+
this.bloomBlurVBindGroup = this.device.createBindGroup({
|
|
1209
|
+
layout: this.bloomBlurPipeline.getBindGroupLayout(0),
|
|
1210
|
+
entries: [
|
|
1211
|
+
{ binding: 0, resource: this.bloomBlurTexture1.createView() },
|
|
1212
|
+
{ binding: 1, resource: this.linearSampler },
|
|
1213
|
+
{ binding: 2, resource: { buffer: this.blurDirectionBuffer } },
|
|
1214
|
+
],
|
|
1215
|
+
})
|
|
1216
|
+
|
|
1217
|
+
this.bloomComposeBindGroup = this.device.createBindGroup({
|
|
1218
|
+
layout: this.bloomComposePipeline.getBindGroupLayout(0),
|
|
1219
|
+
entries: [
|
|
1220
|
+
{ binding: 0, resource: this.sceneRenderTexture.createView() },
|
|
1221
|
+
{ binding: 1, resource: this.linearSampler },
|
|
1222
|
+
{ binding: 2, resource: this.bloomBlurTexture2.createView() },
|
|
1223
|
+
{ binding: 3, resource: this.linearSampler },
|
|
1224
|
+
{ binding: 4, resource: { buffer: this.bloomIntensityBuffer } },
|
|
1225
|
+
],
|
|
1226
|
+
})
|
|
1227
|
+
}
|
|
1228
|
+
|
|
1159
1229
|
// Step 3: Setup canvas resize handling
|
|
1160
1230
|
private setupResize() {
|
|
1161
1231
|
this.resizeObserver = new ResizeObserver(() => this.handleResize())
|
|
@@ -1200,27 +1270,8 @@ export class Engine {
|
|
|
1200
1270
|
})
|
|
1201
1271
|
this.sceneRenderTextureView = this.sceneRenderTexture.createView()
|
|
1202
1272
|
|
|
1203
|
-
//
|
|
1204
|
-
|
|
1205
|
-
const bloomHeight = Math.floor(height / 2)
|
|
1206
|
-
this.bloomExtractTexture = this.device.createTexture({
|
|
1207
|
-
label: "bloom extract",
|
|
1208
|
-
size: [bloomWidth, bloomHeight],
|
|
1209
|
-
format: this.presentationFormat,
|
|
1210
|
-
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,
|
|
1211
|
-
})
|
|
1212
|
-
this.bloomBlurTexture1 = this.device.createTexture({
|
|
1213
|
-
label: "bloom blur 1",
|
|
1214
|
-
size: [bloomWidth, bloomHeight],
|
|
1215
|
-
format: this.presentationFormat,
|
|
1216
|
-
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,
|
|
1217
|
-
})
|
|
1218
|
-
this.bloomBlurTexture2 = this.device.createTexture({
|
|
1219
|
-
label: "bloom blur 2",
|
|
1220
|
-
size: [bloomWidth, bloomHeight],
|
|
1221
|
-
format: this.presentationFormat,
|
|
1222
|
-
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,
|
|
1223
|
-
})
|
|
1273
|
+
// Setup bloom textures and bind groups
|
|
1274
|
+
this.setupBloom(width, height)
|
|
1224
1275
|
|
|
1225
1276
|
const depthTextureView = this.depthTexture.createView()
|
|
1226
1277
|
|
|
@@ -1447,6 +1498,17 @@ export class Engine {
|
|
|
1447
1498
|
|
|
1448
1499
|
this.createSkinMatrixComputePipeline()
|
|
1449
1500
|
|
|
1501
|
+
// Create compute bind group once (reused every frame)
|
|
1502
|
+
this.skinMatrixComputeBindGroup = this.device.createBindGroup({
|
|
1503
|
+
layout: this.skinMatrixComputePipeline!.getBindGroupLayout(0),
|
|
1504
|
+
entries: [
|
|
1505
|
+
{ binding: 0, resource: { buffer: this.boneCountBuffer } },
|
|
1506
|
+
{ binding: 1, resource: { buffer: this.worldMatrixBuffer } },
|
|
1507
|
+
{ binding: 2, resource: { buffer: this.inverseBindMatrixBuffer } },
|
|
1508
|
+
{ binding: 3, resource: { buffer: this.skinMatrixBuffer } },
|
|
1509
|
+
],
|
|
1510
|
+
})
|
|
1511
|
+
|
|
1450
1512
|
const indices = model.getIndices()
|
|
1451
1513
|
if (indices) {
|
|
1452
1514
|
this.indexBuffer = this.device.createBuffer({
|
|
@@ -1987,17 +2049,8 @@ export class Engine {
|
|
|
1987
2049
|
],
|
|
1988
2050
|
})
|
|
1989
2051
|
|
|
1990
|
-
const extractBindGroup = this.device.createBindGroup({
|
|
1991
|
-
layout: this.bloomExtractPipeline.getBindGroupLayout(0),
|
|
1992
|
-
entries: [
|
|
1993
|
-
{ binding: 0, resource: this.sceneRenderTexture.createView() },
|
|
1994
|
-
{ binding: 1, resource: this.linearSampler },
|
|
1995
|
-
{ binding: 2, resource: { buffer: this.bloomThresholdBuffer } },
|
|
1996
|
-
],
|
|
1997
|
-
})
|
|
1998
|
-
|
|
1999
2052
|
extractPass.setPipeline(this.bloomExtractPipeline)
|
|
2000
|
-
extractPass.setBindGroup(0,
|
|
2053
|
+
extractPass.setBindGroup(0, this.bloomExtractBindGroup!)
|
|
2001
2054
|
extractPass.draw(6, 1, 0, 0)
|
|
2002
2055
|
extractPass.end()
|
|
2003
2056
|
|
|
@@ -2018,17 +2071,8 @@ export class Engine {
|
|
|
2018
2071
|
],
|
|
2019
2072
|
})
|
|
2020
2073
|
|
|
2021
|
-
const blurHBindGroup = this.device.createBindGroup({
|
|
2022
|
-
layout: this.bloomBlurPipeline.getBindGroupLayout(0),
|
|
2023
|
-
entries: [
|
|
2024
|
-
{ binding: 0, resource: this.bloomExtractTexture.createView() },
|
|
2025
|
-
{ binding: 1, resource: this.linearSampler },
|
|
2026
|
-
{ binding: 2, resource: { buffer: this.blurDirectionBuffer } },
|
|
2027
|
-
],
|
|
2028
|
-
})
|
|
2029
|
-
|
|
2030
2074
|
blurHPass.setPipeline(this.bloomBlurPipeline)
|
|
2031
|
-
blurHPass.setBindGroup(0,
|
|
2075
|
+
blurHPass.setBindGroup(0, this.bloomBlurHBindGroup!)
|
|
2032
2076
|
blurHPass.draw(6, 1, 0, 0)
|
|
2033
2077
|
blurHPass.end()
|
|
2034
2078
|
|
|
@@ -2049,17 +2093,8 @@ export class Engine {
|
|
|
2049
2093
|
],
|
|
2050
2094
|
})
|
|
2051
2095
|
|
|
2052
|
-
const blurVBindGroup = this.device.createBindGroup({
|
|
2053
|
-
layout: this.bloomBlurPipeline.getBindGroupLayout(0),
|
|
2054
|
-
entries: [
|
|
2055
|
-
{ binding: 0, resource: this.bloomBlurTexture1.createView() },
|
|
2056
|
-
{ binding: 1, resource: this.linearSampler },
|
|
2057
|
-
{ binding: 2, resource: { buffer: this.blurDirectionBuffer } },
|
|
2058
|
-
],
|
|
2059
|
-
})
|
|
2060
|
-
|
|
2061
2096
|
blurVPass.setPipeline(this.bloomBlurPipeline)
|
|
2062
|
-
blurVPass.setBindGroup(0,
|
|
2097
|
+
blurVPass.setBindGroup(0, this.bloomBlurVBindGroup!)
|
|
2063
2098
|
blurVPass.draw(6, 1, 0, 0)
|
|
2064
2099
|
blurVPass.end()
|
|
2065
2100
|
|
|
@@ -2076,19 +2111,8 @@ export class Engine {
|
|
|
2076
2111
|
],
|
|
2077
2112
|
})
|
|
2078
2113
|
|
|
2079
|
-
const composeBindGroup = this.device.createBindGroup({
|
|
2080
|
-
layout: this.bloomComposePipeline.getBindGroupLayout(0),
|
|
2081
|
-
entries: [
|
|
2082
|
-
{ binding: 0, resource: this.sceneRenderTexture.createView() },
|
|
2083
|
-
{ binding: 1, resource: this.linearSampler },
|
|
2084
|
-
{ binding: 2, resource: this.bloomBlurTexture2.createView() },
|
|
2085
|
-
{ binding: 3, resource: this.linearSampler },
|
|
2086
|
-
{ binding: 4, resource: { buffer: this.bloomIntensityBuffer } },
|
|
2087
|
-
],
|
|
2088
|
-
})
|
|
2089
|
-
|
|
2090
2114
|
composePass.setPipeline(this.bloomComposePipeline)
|
|
2091
|
-
composePass.setBindGroup(0,
|
|
2115
|
+
composePass.setBindGroup(0, this.bloomComposeBindGroup!)
|
|
2092
2116
|
composePass.draw(6, 1, 0, 0)
|
|
2093
2117
|
composePass.end()
|
|
2094
2118
|
|
|
@@ -2153,26 +2177,12 @@ export class Engine {
|
|
|
2153
2177
|
// Dispatch exactly enough threads for all bones (no bounds check needed)
|
|
2154
2178
|
const workgroupCount = Math.ceil(boneCount / workgroupSize)
|
|
2155
2179
|
|
|
2156
|
-
//
|
|
2157
|
-
const boneCountData = new Uint32Array(8) // 32 bytes total
|
|
2158
|
-
boneCountData[0] = boneCount
|
|
2159
|
-
this.device.queue.writeBuffer(this.boneCountBuffer!, 0, boneCountData)
|
|
2160
|
-
|
|
2161
|
-
const bindGroup = this.device.createBindGroup({
|
|
2162
|
-
label: "skin matrix compute bind group",
|
|
2163
|
-
layout: this.skinMatrixComputePipeline!.getBindGroupLayout(0),
|
|
2164
|
-
entries: [
|
|
2165
|
-
{ binding: 0, resource: { buffer: this.boneCountBuffer! } },
|
|
2166
|
-
{ binding: 1, resource: { buffer: this.worldMatrixBuffer! } },
|
|
2167
|
-
{ binding: 2, resource: { buffer: this.inverseBindMatrixBuffer! } },
|
|
2168
|
-
{ binding: 3, resource: { buffer: this.skinMatrixBuffer! } },
|
|
2169
|
-
],
|
|
2170
|
-
})
|
|
2180
|
+
// Bone count is written once in setupModelBuffers() and never changes
|
|
2171
2181
|
|
|
2172
2182
|
const encoder = this.device.createCommandEncoder()
|
|
2173
2183
|
const pass = encoder.beginComputePass()
|
|
2174
2184
|
pass.setPipeline(this.skinMatrixComputePipeline!)
|
|
2175
|
-
pass.setBindGroup(0,
|
|
2185
|
+
pass.setBindGroup(0, this.skinMatrixComputeBindGroup!)
|
|
2176
2186
|
pass.dispatchWorkgroups(workgroupCount)
|
|
2177
2187
|
pass.end()
|
|
2178
2188
|
this.device.queue.submit([encoder.finish()])
|