mirror of
https://github.com/allaunthefox/Research-Stack.git
synced 2026-07-31 03:05:21 +00:00
125 lines
3.3 KiB
TypeScript
125 lines
3.3 KiB
TypeScript
export type AsciiDofQuadBuffer = {
|
|
buffers: GPUBuffer[];
|
|
cellCount: number;
|
|
byteLength: number;
|
|
currentWrite(frameCounter: number): GPUBuffer;
|
|
currentRead(frameCounter: number): GPUBuffer;
|
|
queued(frameCounter: number): [GPUBuffer, GPUBuffer];
|
|
};
|
|
|
|
declare const GPUBufferUsage: {
|
|
COPY_SRC: GPUBufferUsageFlags;
|
|
COPY_DST: GPUBufferUsageFlags;
|
|
STORAGE: GPUBufferUsageFlags;
|
|
UNIFORM: GPUBufferUsageFlags;
|
|
};
|
|
|
|
export type AsciiDofParams = {
|
|
sourceWidth: number;
|
|
sourceHeight: number;
|
|
gridWidth: number;
|
|
gridHeight: number;
|
|
cellWidth: number;
|
|
cellHeight: number;
|
|
focus: number;
|
|
aperture: number;
|
|
cocScale: number;
|
|
flags?: number;
|
|
};
|
|
|
|
export const ASCII_DOF_PACKED_CELL_BYTES = 4;
|
|
export const ASCII_DOF_PARAM_BYTES = 48;
|
|
const Q16_SCALE = 65536;
|
|
|
|
export function toQ16Unit(value: number): number {
|
|
const clamped = Math.min(1, Math.max(0, value));
|
|
return Math.min(0x00010000, Math.round(clamped * Q16_SCALE)) >>> 0;
|
|
}
|
|
|
|
export function createAsciiDofQuadBuffer(
|
|
device: GPUDevice,
|
|
gridWidth: number,
|
|
gridHeight: number,
|
|
label = "ascii-dof",
|
|
): AsciiDofQuadBuffer {
|
|
const cellCount = gridWidth * gridHeight;
|
|
const byteLength = cellCount * ASCII_DOF_PACKED_CELL_BYTES;
|
|
const buffers = Array.from({ length: 4 }, (_, i) =>
|
|
device.createBuffer({
|
|
label: `${label}-${i}`,
|
|
size: byteLength,
|
|
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC,
|
|
}),
|
|
);
|
|
|
|
return {
|
|
buffers,
|
|
cellCount,
|
|
byteLength,
|
|
currentWrite(frameCounter: number) {
|
|
return buffers[frameCounter & 3];
|
|
},
|
|
currentRead(frameCounter: number) {
|
|
return buffers[(frameCounter + 3) & 3];
|
|
},
|
|
queued(frameCounter: number) {
|
|
return [buffers[(frameCounter + 2) & 3], buffers[(frameCounter + 1) & 3]];
|
|
},
|
|
};
|
|
}
|
|
|
|
export function createAsciiDofParamBuffer(device: GPUDevice, label = "ascii-dof-params"): GPUBuffer {
|
|
return device.createBuffer({
|
|
label,
|
|
size: ASCII_DOF_PARAM_BYTES,
|
|
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
|
|
});
|
|
}
|
|
|
|
export function writeAsciiDofParams(
|
|
device: GPUDevice,
|
|
buffer: GPUBuffer,
|
|
params: AsciiDofParams,
|
|
): void {
|
|
const words = new Uint32Array(12);
|
|
words[0] = params.sourceWidth >>> 0;
|
|
words[1] = params.sourceHeight >>> 0;
|
|
words[2] = params.gridWidth >>> 0;
|
|
words[3] = params.gridHeight >>> 0;
|
|
words[4] = params.cellWidth >>> 0;
|
|
words[5] = params.cellHeight >>> 0;
|
|
words[6] = toQ16Unit(params.focus);
|
|
words[7] = toQ16Unit(params.aperture);
|
|
words[8] = toQ16Unit(params.cocScale);
|
|
words[9] = (params.flags ?? 0) & 0xf;
|
|
device.queue.writeBuffer(buffer, 0, words);
|
|
}
|
|
|
|
export function createAsciiDofBindGroup(
|
|
device: GPUDevice,
|
|
layout: GPUBindGroupLayout,
|
|
asciiBuffer: GPUBuffer,
|
|
depthView: GPUTextureView,
|
|
colorView: GPUTextureView,
|
|
paramBuffer: GPUBuffer,
|
|
): GPUBindGroup {
|
|
return device.createBindGroup({
|
|
layout,
|
|
entries: [
|
|
{ binding: 0, resource: { buffer: asciiBuffer } },
|
|
{ binding: 1, resource: depthView },
|
|
{ binding: 2, resource: colorView },
|
|
{ binding: 3, resource: { buffer: paramBuffer } },
|
|
],
|
|
});
|
|
}
|
|
|
|
export function decodePackedAsciiCell(packed: number) {
|
|
return {
|
|
depth13: (packed >>> 19) & 0x1fff,
|
|
luma7: (packed >>> 12) & 0x7f,
|
|
char6: (packed >>> 6) & 0x3f,
|
|
flags4: (packed >>> 2) & 0xf,
|
|
reserved2: packed & 0x3,
|
|
};
|
|
}
|