@footgun/cobalt 0.8.0 → 0.8.1

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.
@@ -1,57 +1,27 @@
1
- /// <reference types="@webgpu/types"/>
2
-
3
- import * as wgpuMatrix from "wgpu-matrix";
4
- import { LightsBuffer } from "./lights-buffer";
5
- import { LightsTexture, type LightsTextureProperties } from "./texture/lights-texture";
6
- import { type LightObstacleSegment } from "./texture/lights-texture-mask";
7
-
8
- type TextureSamplable = {
9
- readonly view: GPUTextureView;
10
- readonly sampler: GPUSampler;
11
- };
12
-
13
- type TextureRenderable = {
14
- readonly format: GPUTextureFormat;
15
- };
16
-
17
- type Parameters = {
18
- readonly device: GPUDevice;
19
- readonly albedo: TextureSamplable;
20
- readonly targetTexture: TextureRenderable;
21
- readonly lightsBuffer: LightsBuffer;
22
- readonly lightsTextureProperties: LightsTextureProperties;
23
- };
1
+ import { LightsBuffer } from "./lights-buffer.js";
2
+ import { LightsTexture } from "./texture/lights-texture.js";
24
3
 
25
4
  class LightsRenderer {
26
- private readonly device: GPUDevice;
27
-
28
- private ambientLight: [number, number, number] = [0.2, 0.2, 0.2];
29
-
30
- private readonly targetTexture: TextureRenderable;
31
-
32
- private readonly renderPipeline: GPURenderPipeline;
33
- private readonly uniformsBufferGpu: GPUBuffer;
34
- private readonly bindgroup0: GPUBindGroup;
35
- private bindgroup1: GPUBindGroup;
36
- private renderBundle: GPURenderBundle;
37
-
38
- private readonly lightsBuffer: LightsBuffer;
39
- private readonly lightsTexture: LightsTexture;
40
-
41
- public constructor(params: Parameters) {
5
+ device;
6
+ ambientLight = [0.2, 0.2, 0.2];
7
+ targetTexture;
8
+ renderPipeline;
9
+ uniformsBufferGpu;
10
+ bindgroup0;
11
+ bindgroup1;
12
+ renderBundle;
13
+ lightsBuffer;
14
+ lightsTexture;
15
+ constructor(params) {
42
16
  this.device = params.device;
43
-
44
17
  this.targetTexture = params.targetTexture;
45
18
  this.lightsBuffer = params.lightsBuffer;
46
-
47
19
  this.lightsTexture = new LightsTexture(params.device, params.lightsBuffer, params.lightsTextureProperties);
48
-
49
20
  this.uniformsBufferGpu = params.device.createBuffer({
50
21
  label: "LightsRenderer uniforms buffer",
51
22
  size: 80,
52
23
  usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
53
24
  });
54
-
55
25
  const shaderModule = params.device.createShaderModule({
56
26
  label: "LightsRenderer shader module",
57
27
  code: `
@@ -154,7 +124,6 @@ fn main_fragment(in: VertexOut) -> FragmentOut {
154
124
  }
155
125
  `,
156
126
  });
157
-
158
127
  this.renderPipeline = params.device.createRenderPipeline({
159
128
  label: "LightsRenderer renderpipeline",
160
129
  layout: "auto",
@@ -166,17 +135,15 @@ fn main_fragment(in: VertexOut) -> FragmentOut {
166
135
  module: shaderModule,
167
136
  entryPoint: "main_fragment",
168
137
  targets: [{
169
- format: this.targetTexture.format,
170
- }],
138
+ format: this.targetTexture.format,
139
+ }],
171
140
  },
172
141
  primitive: {
173
142
  cullMode: "none",
174
143
  topology: "triangle-strip",
175
144
  },
176
145
  });
177
-
178
146
  const bindgroupLayout = this.renderPipeline.getBindGroupLayout(0);
179
-
180
147
  this.bindgroup0 = params.device.createBindGroup({
181
148
  label: "LightsRenderer bindgroup 0",
182
149
  layout: bindgroupLayout,
@@ -205,44 +172,34 @@ fn main_fragment(in: VertexOut) -> FragmentOut {
205
172
  },
206
173
  ]
207
174
  });
208
-
209
175
  this.bindgroup1 = this.buildBindgroup1(params.albedo);
210
176
  this.renderBundle = this.buildRenderBundle();
211
177
  }
212
-
213
- public computeLightsTexture(commandEncoder: GPUCommandEncoder): void {
178
+ computeLightsTexture(commandEncoder) {
214
179
  this.lightsTexture.update(commandEncoder);
215
180
  }
216
-
217
- public render(renderpassEncoder: GPURenderPassEncoder, invertVpMatrix: wgpuMatrix.Mat4Arg): void {
181
+ render(renderpassEncoder, invertVpMatrix) {
218
182
  const uniformsBufferCpu = new ArrayBuffer(80);
219
183
  new Float32Array(uniformsBufferCpu, 0, 16).set(invertVpMatrix);
220
184
  new Float32Array(uniformsBufferCpu, 64, 3).set(this.ambientLight);
221
185
  this.device.queue.writeBuffer(this.uniformsBufferGpu, 0, uniformsBufferCpu);
222
-
223
186
  renderpassEncoder.executeBundles([this.renderBundle]);
224
187
  }
225
-
226
- public setAlbedo(albedo: TextureSamplable): void {
188
+ setAlbedo(albedo) {
227
189
  this.bindgroup1 = this.buildBindgroup1(albedo);
228
190
  this.renderBundle = this.buildRenderBundle();
229
191
  }
230
-
231
- public setAmbientLight(color: [number, number, number]): void {
192
+ setAmbientLight(color) {
232
193
  this.ambientLight = [...color];
233
194
  }
234
-
235
- public setObstacles(segments: ReadonlyArray<LightObstacleSegment>): void {
195
+ setObstacles(segments) {
236
196
  this.lightsTexture.setObstacles(segments);
237
197
  }
238
-
239
- public destroy(): void {
198
+ destroy() {
240
199
  this.uniformsBufferGpu.destroy();
241
-
242
200
  this.lightsTexture.destroy();
243
201
  }
244
-
245
- private buildBindgroup1(albedo: TextureSamplable): GPUBindGroup {
202
+ buildBindgroup1(albedo) {
246
203
  return this.device.createBindGroup({
247
204
  label: "LightsRenderer bindgroup 1",
248
205
  layout: this.renderPipeline.getBindGroupLayout(1),
@@ -258,8 +215,7 @@ fn main_fragment(in: VertexOut) -> FragmentOut {
258
215
  ]
259
216
  });
260
217
  }
261
-
262
- private buildRenderBundle(): GPURenderBundle {
218
+ buildRenderBundle() {
263
219
  const renderBundleEncoder = this.device.createRenderBundleEncoder({
264
220
  label: "LightsRenderer renderbundle encoder",
265
221
  colorFormats: [this.targetTexture.format],
@@ -271,8 +227,4 @@ fn main_fragment(in: VertexOut) -> FragmentOut {
271
227
  return renderBundleEncoder.finish({ label: "LightsRenderer renderbundle" });
272
228
  }
273
229
  }
274
-
275
- export {
276
- LightsRenderer
277
- };
278
-
230
+ export { LightsRenderer };
@@ -1,19 +1,12 @@
1
- /// <reference types="@webgpu/types"/>
2
-
3
- import { LightsBuffer } from "../lights-buffer";
4
- import { type ILightsTexture } from "./lights-texture";
1
+ import { LightsBuffer } from "../lights-buffer.js";
5
2
 
6
3
  class LightsTextureInitializer {
7
- private readonly lightsBuffer: LightsBuffer;
8
-
9
- private readonly renderPipeline: GPURenderPipeline;
10
- private readonly bindgroup: GPUBindGroup;
11
-
12
- private readonly renderBundle: GPURenderBundle;
13
-
14
- public constructor(device: GPUDevice, lightsBuffer: LightsBuffer, lightsTexture: ILightsTexture, maxLightSize: number) {
4
+ lightsBuffer;
5
+ renderPipeline;
6
+ bindgroup;
7
+ renderBundle;
8
+ constructor(device, lightsBuffer, lightsTexture, maxLightSize) {
15
9
  this.lightsBuffer = lightsBuffer;
16
-
17
10
  const shaderModule = device.createShaderModule({
18
11
  label: "LightsTextureInitializer shader module",
19
12
  code: `
@@ -130,7 +123,6 @@ fn main_fragment(in: VertexOut) -> FragmentOut {
130
123
  }
131
124
  `,
132
125
  });
133
-
134
126
  this.renderPipeline = device.createRenderPipeline({
135
127
  label: "LightsTextureInitializer renderpipeline",
136
128
  layout: "auto",
@@ -142,8 +134,8 @@ fn main_fragment(in: VertexOut) -> FragmentOut {
142
134
  module: shaderModule,
143
135
  entryPoint: "main_fragment",
144
136
  targets: [{
145
- format: lightsTexture.format,
146
- }],
137
+ format: lightsTexture.format,
138
+ }],
147
139
  },
148
140
  primitive: {
149
141
  cullMode: "none",
@@ -153,7 +145,6 @@ fn main_fragment(in: VertexOut) -> FragmentOut {
153
145
  count: lightsTexture.sampleCount,
154
146
  },
155
147
  });
156
-
157
148
  this.bindgroup = device.createBindGroup({
158
149
  label: "LightsTextureInitializer bindgroup 0",
159
150
  layout: this.renderPipeline.getBindGroupLayout(0),
@@ -164,7 +155,6 @@ fn main_fragment(in: VertexOut) -> FragmentOut {
164
155
  },
165
156
  ]
166
157
  });
167
-
168
158
  const renderBundleEncoder = device.createRenderBundleEncoder({
169
159
  label: "LightsTextureInitializer renderbundle encoder",
170
160
  colorFormats: [lightsTexture.format],
@@ -175,17 +165,11 @@ fn main_fragment(in: VertexOut) -> FragmentOut {
175
165
  renderBundleEncoder.draw(4);
176
166
  this.renderBundle = renderBundleEncoder.finish({ label: "LightsTextureInitializer renderbundle" });
177
167
  }
178
-
179
- public getRenderBundle(): GPURenderBundle {
168
+ getRenderBundle() {
180
169
  return this.renderBundle;
181
170
  }
182
-
183
- public destroy(): void {
171
+ destroy() {
184
172
  // nothing to do
185
173
  }
186
174
  }
187
-
188
- export {
189
- LightsTextureInitializer
190
- };
191
-
175
+ export { LightsTextureInitializer };
@@ -1,37 +1,17 @@
1
- /// <reference types="@webgpu/types"/>
2
-
3
- import { LightsBuffer } from "../lights-buffer";
4
- import { type Point } from "../types";
5
- import { type ILightsTexture } from "./lights-texture";
6
-
7
- type LightObstacleSegment = [Point, Point];
1
+ import { LightsBuffer } from "../lights-buffer.js";
8
2
 
9
3
  class LightsTextureMask {
10
- private readonly device: GPUDevice;
11
-
12
- private readonly renderPipeline: GPURenderPipeline;
13
-
14
- private readonly renderBundleEncoderDescriptor: GPURenderBundleEncoderDescriptor;
15
- private renderBundle: GPURenderBundle;
16
-
17
- private readonly lightsBuffer: LightsBuffer;
18
-
19
- private readonly indirectDrawing: {
20
- readonly bufferCpu: ArrayBuffer;
21
- readonly bufferGpu: GPUBuffer;
22
- };
23
-
24
- private obstacles: {
25
- readonly positionsBufferGpu: GPUBuffer;
26
- readonly indexBufferGpu: GPUBuffer;
27
- } | null = null;
28
-
29
- public constructor(device: GPUDevice, lightsBuffer: LightsBuffer, lightsTexture: ILightsTexture, uniformLightSize: number) {
4
+ device;
5
+ renderPipeline;
6
+ renderBundleEncoderDescriptor;
7
+ renderBundle;
8
+ lightsBuffer;
9
+ indirectDrawing;
10
+ obstacles = null;
11
+ constructor(device, lightsBuffer, lightsTexture, uniformLightSize) {
30
12
  this.device = device;
31
13
  this.lightsBuffer = lightsBuffer;
32
-
33
- const obstaclesAreTwoWay = true as boolean;
34
-
14
+ const obstaclesAreTwoWay = true;
35
15
  const shaderModule = device.createShaderModule({
36
16
  label: "LightsTextureMask shader module",
37
17
  code: `
@@ -94,7 +74,6 @@ fn main_fragment(in: VertexOut) -> FragmentOut {
94
74
  }
95
75
  `,
96
76
  });
97
-
98
77
  this.renderPipeline = device.createRenderPipeline({
99
78
  label: "LightsTextureMask renderpipeline",
100
79
  layout: "auto",
@@ -135,20 +114,20 @@ fn main_fragment(in: VertexOut) -> FragmentOut {
135
114
  module: shaderModule,
136
115
  entryPoint: "main_fragment",
137
116
  targets: [{
138
- format: lightsTexture.format,
139
- blend: {
140
- color: {
141
- operation: "min",
142
- srcFactor: "one",
143
- dstFactor: "one",
144
- },
145
- alpha: {
146
- operation: "min",
147
- srcFactor: "one",
148
- dstFactor: "one",
117
+ format: lightsTexture.format,
118
+ blend: {
119
+ color: {
120
+ operation: "min",
121
+ srcFactor: "one",
122
+ dstFactor: "one",
123
+ },
124
+ alpha: {
125
+ operation: "min",
126
+ srcFactor: "one",
127
+ dstFactor: "one",
128
+ },
149
129
  },
150
- },
151
- }],
130
+ }],
152
131
  },
153
132
  primitive: {
154
133
  cullMode: obstaclesAreTwoWay ? "none" : "back",
@@ -158,7 +137,6 @@ fn main_fragment(in: VertexOut) -> FragmentOut {
158
137
  count: lightsTexture.sampleCount,
159
138
  },
160
139
  });
161
-
162
140
  this.indirectDrawing = {
163
141
  bufferCpu: new ArrayBuffer(20),
164
142
  bufferGpu: device.createBuffer({
@@ -168,7 +146,6 @@ fn main_fragment(in: VertexOut) -> FragmentOut {
168
146
  }),
169
147
  };
170
148
  this.uploadIndirectDrawingBuffer();
171
-
172
149
  this.renderBundleEncoderDescriptor = {
173
150
  label: "LightsTextureMask renderbundle encoder",
174
151
  colorFormats: [lightsTexture.format],
@@ -176,32 +153,18 @@ fn main_fragment(in: VertexOut) -> FragmentOut {
176
153
  };
177
154
  this.renderBundle = this.buildRenderBundle();
178
155
  }
179
-
180
- public getRenderBundle(): GPURenderBundle {
156
+ getRenderBundle() {
181
157
  return this.renderBundle;
182
158
  }
183
-
184
- public setObstacles(segments: ReadonlyArray<LightObstacleSegment>): void {
185
- const positions: number[] = [];
186
- const indices: number[] = [];
159
+ setObstacles(segments) {
160
+ const positions = [];
161
+ const indices = [];
187
162
  for (const segment of segments) {
188
163
  const firstQuadIndex = positions.length / 3;
189
-
190
- positions.push(
191
- ...segment[0], 0,
192
- ...segment[1], 0,
193
- ...segment[0], 1,
194
- ...segment[1], 1,
195
- );
196
-
197
- indices.push(
198
- firstQuadIndex + 0, firstQuadIndex + 1, firstQuadIndex + 3,
199
- firstQuadIndex + 0, firstQuadIndex + 3, firstQuadIndex + 2,
200
- );
164
+ positions.push(...segment[0], 0, ...segment[1], 0, ...segment[0], 1, ...segment[1], 1);
165
+ indices.push(firstQuadIndex + 0, firstQuadIndex + 1, firstQuadIndex + 3, firstQuadIndex + 0, firstQuadIndex + 3, firstQuadIndex + 2);
201
166
  }
202
-
203
167
  let gpuBuffersChanged = false;
204
-
205
168
  const positionsArray = new Float32Array(positions);
206
169
  let positionsBufferGpu = this.obstacles?.positionsBufferGpu;
207
170
  if (!positionsBufferGpu || positionsBufferGpu.size < positionsArray.byteLength) {
@@ -214,7 +177,6 @@ fn main_fragment(in: VertexOut) -> FragmentOut {
214
177
  gpuBuffersChanged = true;
215
178
  }
216
179
  this.device.queue.writeBuffer(positionsBufferGpu, 0, positionsArray);
217
-
218
180
  const indicesArray = new Uint16Array(indices);
219
181
  let indexBufferGpu = this.obstacles?.indexBufferGpu;
220
182
  if (!indexBufferGpu || indexBufferGpu.size < indicesArray.byteLength) {
@@ -227,43 +189,35 @@ fn main_fragment(in: VertexOut) -> FragmentOut {
227
189
  gpuBuffersChanged = true;
228
190
  }
229
191
  this.device.queue.writeBuffer(indexBufferGpu, 0, indicesArray);
230
-
231
192
  this.obstacles = { positionsBufferGpu, indexBufferGpu };
232
-
233
193
  this.setIndirectIndexCount(indices.length);
234
-
235
194
  if (gpuBuffersChanged) {
236
195
  this.renderBundle = this.buildRenderBundle();
237
196
  }
238
197
  }
239
-
240
- public setLightsCount(count: number): void {
198
+ setLightsCount(count) {
241
199
  this.setIndirectInstanceCount(count);
242
200
  }
243
-
244
- public destroy(): void {
201
+ destroy() {
245
202
  this.indirectDrawing.bufferGpu.destroy();
246
203
  this.obstacles?.positionsBufferGpu.destroy();
247
204
  this.obstacles?.indexBufferGpu.destroy();
248
205
  }
249
-
250
- private setIndirectIndexCount(indexCount: number): void {
206
+ setIndirectIndexCount(indexCount) {
251
207
  const drawIndexedIndirectParameters = new Uint32Array(this.indirectDrawing.bufferCpu);
252
208
  if (drawIndexedIndirectParameters[0] !== indexCount) {
253
209
  drawIndexedIndirectParameters[0] = indexCount;
254
210
  this.uploadIndirectDrawingBuffer();
255
211
  }
256
212
  }
257
-
258
- private setIndirectInstanceCount(instanceCount: number): void {
213
+ setIndirectInstanceCount(instanceCount) {
259
214
  const drawIndexedIndirectParameters = new Uint32Array(this.indirectDrawing.bufferCpu);
260
215
  if (drawIndexedIndirectParameters[1] !== instanceCount) {
261
216
  drawIndexedIndirectParameters[1] = instanceCount;
262
217
  this.uploadIndirectDrawingBuffer();
263
218
  }
264
219
  }
265
-
266
- private buildRenderBundle(): GPURenderBundle {
220
+ buildRenderBundle() {
267
221
  const renderBundleEncoder = this.device.createRenderBundleEncoder(this.renderBundleEncoderDescriptor);
268
222
  if (this.obstacles) {
269
223
  renderBundleEncoder.setPipeline(this.renderPipeline);
@@ -274,13 +228,8 @@ fn main_fragment(in: VertexOut) -> FragmentOut {
274
228
  }
275
229
  return renderBundleEncoder.finish({ label: "LightsTextureMask renderbundle" });
276
230
  }
277
-
278
- private uploadIndirectDrawingBuffer(): void {
231
+ uploadIndirectDrawingBuffer() {
279
232
  this.device.queue.writeBuffer(this.indirectDrawing.bufferGpu, 0, this.indirectDrawing.bufferCpu);
280
233
  }
281
234
  }
282
-
283
- export {
284
- LightsTextureMask, type LightObstacleSegment
285
- };
286
-
235
+ export { LightsTextureMask };
@@ -1,37 +1,16 @@
1
- /// <reference types="@webgpu/types"/>
2
-
3
- import { type LightsBuffer } from "../lights-buffer";
4
- import { LightsTextureInitializer } from "./lights-texture-initializer";
5
- import { type LightObstacleSegment, LightsTextureMask } from "./lights-texture-mask";
6
-
7
- type ILightsTexture = {
8
- readonly gridSize: { readonly x: number, readonly y: number };
9
- readonly format: GPUTextureFormat;
10
- readonly sampleCount: number;
11
- };
12
-
13
- type LightsTextureProperties = {
14
- readonly resolutionPerLight: number;
15
- readonly maxLightSize: number;
16
- readonly antialiased: boolean;
17
- readonly filtering: GPUFilterMode;
18
- };
1
+ import { LightsTextureInitializer } from "./lights-texture-initializer.js";
2
+ import { LightsTextureMask } from "./lights-texture-mask.js";
19
3
 
20
4
  class LightsTexture {
21
- private readonly lightsBuffer: LightsBuffer;
22
-
23
- public readonly texture: GPUTexture;
24
- public readonly gridSize: { readonly x: number, readonly y: number };
25
-
26
- private readonly textureMultisampled: GPUTexture | null = null;
27
- private readonly textureRenderpassDescriptor: GPURenderPassDescriptor;
28
-
29
- private readonly textureInitializer: LightsTextureInitializer;
30
- private readonly textureMask: LightsTextureMask;
31
-
32
- public constructor(device: GPUDevice, lightsBuffer: LightsBuffer, lightsTextureProperties: LightsTextureProperties) {
5
+ lightsBuffer;
6
+ texture;
7
+ gridSize;
8
+ textureMultisampled = null;
9
+ textureRenderpassDescriptor;
10
+ textureInitializer;
11
+ textureMask;
12
+ constructor(device, lightsBuffer, lightsTextureProperties) {
33
13
  this.lightsBuffer = lightsBuffer;
34
-
35
14
  const cellsCount = this.lightsBuffer.maxLightsCount / 4;
36
15
  const gridSize = {
37
16
  x: Math.ceil(Math.sqrt(cellsCount)),
@@ -39,12 +18,10 @@ class LightsTexture {
39
18
  };
40
19
  gridSize.y = Math.ceil(cellsCount / gridSize.x);
41
20
  this.gridSize = gridSize;
42
-
43
21
  const lightTextureSize = {
44
22
  width: gridSize.x * lightsTextureProperties.resolutionPerLight,
45
23
  height: gridSize.y * lightsTextureProperties.resolutionPerLight,
46
24
  };
47
-
48
25
  const format = lightsTextureProperties.textureFormat;
49
26
  this.texture = device.createTexture({
50
27
  label: "LightsTextureMask texture",
@@ -52,7 +29,6 @@ class LightsTexture {
52
29
  format,
53
30
  usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.RENDER_ATTACHMENT,
54
31
  });
55
-
56
32
  if (lightsTextureProperties.antialiased) {
57
33
  this.textureMultisampled = device.createTexture({
58
34
  label: "LightsTextureMask texture multisampled",
@@ -62,10 +38,8 @@ class LightsTexture {
62
38
  sampleCount: 4,
63
39
  });
64
40
  }
65
-
66
41
  const textureToRenderTo = this.textureMultisampled ?? this.texture;
67
-
68
- const textureRenderpassColorAttachment: GPURenderPassColorAttachment = {
42
+ const textureRenderpassColorAttachment = {
69
43
  view: textureToRenderTo.createView(),
70
44
  clearValue: [0, 0, 0, 1],
71
45
  loadOp: "load",
@@ -78,8 +52,7 @@ class LightsTexture {
78
52
  label: "lights-renderer render to texture renderpass",
79
53
  colorAttachments: [textureRenderpassColorAttachment],
80
54
  };
81
-
82
- const lightsTexture: ILightsTexture = {
55
+ const lightsTexture = {
83
56
  gridSize,
84
57
  format,
85
58
  sampleCount: this.textureMultisampled?.sampleCount ?? 1,
@@ -87,10 +60,8 @@ class LightsTexture {
87
60
  this.textureInitializer = new LightsTextureInitializer(device, lightsBuffer, lightsTexture, lightsTextureProperties.maxLightSize);
88
61
  this.textureMask = new LightsTextureMask(device, lightsBuffer, lightsTexture, lightsTextureProperties.maxLightSize);
89
62
  }
90
-
91
- public update(commandEncoder: GPUCommandEncoder): void {
63
+ update(commandEncoder) {
92
64
  this.textureMask.setLightsCount(this.lightsBuffer.lightsCount);
93
-
94
65
  const renderpassEncoder = commandEncoder.beginRenderPass(this.textureRenderpassDescriptor);
95
66
  const [textureWidth, textureHeight] = [this.texture.width, this.texture.height];
96
67
  renderpassEncoder.setViewport(0, 0, textureWidth, textureHeight, 0, 1);
@@ -101,21 +72,14 @@ class LightsTexture {
101
72
  ]);
102
73
  renderpassEncoder.end();
103
74
  }
104
-
105
- public setObstacles(segments: ReadonlyArray<LightObstacleSegment>): void {
75
+ setObstacles(segments) {
106
76
  this.textureMask.setObstacles(segments);
107
77
  }
108
-
109
- public destroy(): void {
78
+ destroy() {
110
79
  this.texture.destroy();
111
80
  this.textureMultisampled?.destroy();
112
-
113
81
  this.textureInitializer.destroy();
114
82
  this.textureMask.destroy();
115
83
  }
116
84
  }
117
-
118
- export {
119
- LightsTexture, type ILightsTexture, type LightsTextureProperties
120
- };
121
-
85
+ export { LightsTexture };
@@ -1,54 +1,35 @@
1
1
  import * as wgpuMatrix from "wgpu-matrix";
2
- import { type Point } from "./types";
3
-
4
- type Parameters = {
5
- readonly viewportSize: {
6
- width: number;
7
- height: number;
8
- };
9
- readonly center?: Point;
10
- readonly zoom?: number;
11
- };
12
2
 
13
3
  class Viewport {
14
- private readonly invViewProjectionMatrix: wgpuMatrix.Mat4Arg = wgpuMatrix.mat4.identity();
15
-
16
- private readonly viewportSize = { width: 1, height: 1 };
17
- private readonly topLeft: Point = [0, 0];
18
- private zoom: number = 1;
19
-
20
- public constructor(params: Parameters) {
4
+ invViewProjectionMatrix = wgpuMatrix.mat4.identity();
5
+ viewportSize = { width: 1, height: 1 };
6
+ topLeft = [0, 0];
7
+ zoom = 1;
8
+ constructor(params) {
21
9
  this.setViewportSize(params.viewportSize.width, params.viewportSize.height);
22
-
23
10
  const initialTopLeft = params.center ?? this.topLeft;
24
11
  this.setTopLeft(...initialTopLeft);
25
-
26
12
  const initialZoom = params.zoom ?? 1;
27
13
  this.setZoom(initialZoom);
28
14
  }
29
-
30
- public get invertViewProjectionMatrix(): wgpuMatrix.Mat4Arg {
15
+ get invertViewProjectionMatrix() {
31
16
  return this.invViewProjectionMatrix;
32
17
  }
33
-
34
- public setViewportSize(width: number, height: number): void {
18
+ setViewportSize(width, height) {
35
19
  this.viewportSize.width = width;
36
20
  this.viewportSize.height = height;
37
21
  this.updateMatrices();
38
22
  }
39
-
40
- public setTopLeft(x: number, y: number): void {
23
+ setTopLeft(x, y) {
41
24
  this.topLeft[0] = x;
42
25
  this.topLeft[1] = y;
43
26
  this.updateMatrices();
44
27
  }
45
-
46
- public setZoom(zoom: number): void {
28
+ setZoom(zoom) {
47
29
  this.zoom = zoom;
48
30
  this.updateMatrices();
49
31
  }
50
-
51
- private updateMatrices(): void {
32
+ updateMatrices() {
52
33
  wgpuMatrix.mat4.identity(this.invViewProjectionMatrix);
53
34
  wgpuMatrix.mat4.multiply(wgpuMatrix.mat4.scaling([1, -1, 0]), this.invViewProjectionMatrix, this.invViewProjectionMatrix);
54
35
  wgpuMatrix.mat4.multiply(wgpuMatrix.mat4.translation([1, 1, 0]), this.invViewProjectionMatrix, this.invViewProjectionMatrix);
@@ -56,8 +37,4 @@ class Viewport {
56
37
  wgpuMatrix.mat4.multiply(wgpuMatrix.mat4.translation([this.topLeft[0], this.topLeft[1], 0]), this.invViewProjectionMatrix, this.invViewProjectionMatrix);
57
38
  }
58
39
  }
59
-
60
- export {
61
- Viewport
62
- };
63
-
40
+ export { Viewport };