(device: GPUDevice, options?: PieRendererOptions)
| 148 | ]); |
| 149 | |
| 150 | export function createPieRenderer(device: GPUDevice, options?: PieRendererOptions): PieRenderer { |
| 151 | let disposed = false; |
| 152 | const targetFormat = options?.targetFormat ?? DEFAULT_TARGET_FORMAT; |
| 153 | |
| 154 | const bindGroupLayout = device.createBindGroupLayout({ |
| 155 | entries: [{ binding: 0, visibility: GPUShaderStage.VERTEX, buffer: { type: 'uniform' } }], |
| 156 | }); |
| 157 | |
| 158 | // VSUniforms in `pie.wgsl`: mat4x4 (64) + viewportPx vec2 (8) + pad vec2 (8) = 80 bytes. |
| 159 | const vsUniformBuffer = createUniformBuffer(device, 80, { label: 'pieRenderer/vsUniforms' }); |
| 160 | |
| 161 | // Reused CPU-side staging for uniform writes (avoid per-frame allocations). |
| 162 | const vsUniformScratchBuffer = new ArrayBuffer(80); |
| 163 | const vsUniformScratchF32 = new Float32Array(vsUniformScratchBuffer); |
| 164 | |
| 165 | const bindGroup = device.createBindGroup({ |
| 166 | layout: bindGroupLayout, |
| 167 | entries: [{ binding: 0, resource: { buffer: vsUniformBuffer } }], |
| 168 | }); |
| 169 | |
| 170 | const pipeline = createRenderPipeline(device, { |
| 171 | label: 'pieRenderer/pipeline', |
| 172 | bindGroupLayouts: [bindGroupLayout], |
| 173 | vertex: { |
| 174 | code: pieWgsl, |
| 175 | label: 'pie.wgsl', |
| 176 | buffers: [ |
| 177 | { |
| 178 | arrayStride: INSTANCE_STRIDE_BYTES, |
| 179 | stepMode: 'instance', |
| 180 | attributes: [ |
| 181 | { shaderLocation: 0, format: 'float32x2', offset: 0 }, // center |
| 182 | { shaderLocation: 1, format: 'float32', offset: 8 }, // startAngleRad |
| 183 | { shaderLocation: 2, format: 'float32', offset: 12 }, // endAngleRad |
| 184 | { shaderLocation: 3, format: 'float32x2', offset: 16 }, // radiiPx |
| 185 | { shaderLocation: 4, format: 'float32x4', offset: 24 }, // color |
| 186 | ], |
| 187 | }, |
| 188 | ], |
| 189 | }, |
| 190 | fragment: { |
| 191 | code: pieWgsl, |
| 192 | label: 'pie.wgsl', |
| 193 | formats: targetFormat, |
| 194 | // Standard alpha blending for AA edges and translucent slice colors. |
| 195 | blend: { |
| 196 | color: { operation: 'add', srcFactor: 'src-alpha', dstFactor: 'one-minus-src-alpha' }, |
| 197 | alpha: { operation: 'add', srcFactor: 'one', dstFactor: 'one-minus-src-alpha' }, |
| 198 | }, |
| 199 | }, |
| 200 | primitive: { topology: 'triangle-list', cullMode: 'none' }, |
| 201 | multisample: { count: 1 }, |
| 202 | }); |
| 203 | |
| 204 | let instanceBuffer: GPUBuffer | null = null; |
| 205 | let instanceCount = 0; |
| 206 | let cpuInstanceStagingBuffer = new ArrayBuffer(0); |
| 207 | let cpuInstanceStagingF32 = new Float32Array(cpuInstanceStagingBuffer); |
no test coverage detected