From 2113c924fd57a07ba759982f7ee455deed9577cd Mon Sep 17 00:00:00 2001 From: cmhhelgeson <62450112+cmhhelgeson@users.noreply.github.com> Date: Wed, 25 Oct 2023 17:21:15 -0700 Subject: [PATCH] Removed extraneous utils --- src/sample/normalMap/main.ts | 651 +++++++++++++++++----------------- src/sample/normalMap/utils.ts | 109 ------ 2 files changed, 327 insertions(+), 433 deletions(-) diff --git a/src/sample/normalMap/main.ts b/src/sample/normalMap/main.ts index f54af4b6..6927aa32 100644 --- a/src/sample/normalMap/main.ts +++ b/src/sample/normalMap/main.ts @@ -4,13 +4,10 @@ import normalMapWGSL from './normalMap.wgsl'; import { createMeshRenderable } from '../../meshes/mesh'; import { createBoxMeshWithTangents } from '../../meshes/box'; import { - SampleInitFactoryWebGPU, PBRDescriptor, createPBRDescriptor, createBindGroupDescriptor, create3DRenderPipeline, - write32ToBuffer, - writeMat4ToBuffer, } from './utils'; const MAT4X4_BYTES = 64; @@ -20,350 +17,356 @@ enum TextureAtlas { BrickWall, } -let init: SampleInit; -SampleInitFactoryWebGPU( - async ({ canvas, pageState, gui, device, context, presentationFormat }) => { - interface GUISettings { - 'Bump Mode': - | 'Diffuse Texture' - | 'Normal Texture' - | 'Depth Texture' - | 'Normal Map' - | 'Parallax Scale' - | 'Steep Parallax'; - cameraPosX: number; - cameraPosY: number; - cameraPosZ: number; - lightPosX: number; - lightPosY: number; - lightPosZ: number; - lightIntensity: number; - depthScale: number; - depthLayers: number; - Texture: string; - 'Reset Light': () => void; - } +const init: SampleInit = async ({ canvas, pageState, gui }) => { + const adapter = await navigator.gpu.requestAdapter(); + const device = await adapter.requestDevice(); + if (!pageState.active) return; + const context = canvas.getContext('webgpu') as GPUCanvasContext; + const devicePixelRatio = window.devicePixelRatio || 1; + canvas.width = canvas.clientWidth * devicePixelRatio; + canvas.height = canvas.clientHeight * devicePixelRatio; + const presentationFormat = navigator.gpu.getPreferredCanvasFormat(); + context.configure({ + device, + format: presentationFormat, + alphaMode: 'premultiplied', + }); - const settings: GUISettings = { - 'Bump Mode': 'Normal Map', - cameraPosX: 0.0, - cameraPosY: 0.0, - cameraPosZ: -2.4, - lightPosX: 1.7, - lightPosY: -0.7, - lightPosZ: 1.9, - lightIntensity: 0.02, - depthScale: 0.05, - depthLayers: 16, - Texture: 'Spiral', - 'Reset Light': () => { - return; - }, - }; - - // Create normal mapping resources and pipeline - const depthTexture = device.createTexture({ - size: [canvas.width, canvas.height], - format: 'depth24plus', - usage: GPUTextureUsage.RENDER_ATTACHMENT, - }); - - const uniformBuffer = device.createBuffer({ - // Buffer holding projection, view, and model matrices plus padding bytes - size: MAT4X4_BYTES * 4, - usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST, - }); - - const mapMethodBuffer = device.createBuffer({ - // Buffer holding mapping type, light uniforms, and depth uniforms - size: Float32Array.BYTES_PER_ELEMENT * 7, - usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST, - }); - - // Create PBR info (diffuse, normal, and depth/height textures) - let spiralPBR: Required; - { - const response = await createPBRDescriptor(device, [ - 'wood_diffuse.png', - 'spiral_normal.png', - 'spiral_height.png', - ]); - spiralPBR = response as Required; - } + interface GUISettings { + 'Bump Mode': + | 'Diffuse Texture' + | 'Normal Texture' + | 'Depth Texture' + | 'Normal Map' + | 'Parallax Scale' + | 'Steep Parallax'; + cameraPosX: number; + cameraPosY: number; + cameraPosZ: number; + lightPosX: number; + lightPosY: number; + lightPosZ: number; + lightIntensity: number; + depthScale: number; + depthLayers: number; + Texture: string; + 'Reset Light': () => void; + } - let toyboxPBR: Required; - { - const response = await createPBRDescriptor(device, [ - 'wood_diffuse.png', - 'toybox_normal.png', - 'toybox_height.png', - ]); - toyboxPBR = response as Required; - } + const settings: GUISettings = { + 'Bump Mode': 'Normal Map', + cameraPosX: 0.0, + cameraPosY: 0.0, + cameraPosZ: -2.4, + lightPosX: 1.7, + lightPosY: -0.7, + lightPosZ: 1.9, + lightIntensity: 0.02, + depthScale: 0.05, + depthLayers: 16, + Texture: 'Spiral', + 'Reset Light': () => { + return; + }, + }; + + // Create normal mapping resources and pipeline + const depthTexture = device.createTexture({ + size: [canvas.width, canvas.height], + format: 'depth24plus', + usage: GPUTextureUsage.RENDER_ATTACHMENT, + }); - let brickWallPBR: Required; - { - const response = await createPBRDescriptor(device, [ - 'brickwall_diffuse.png', - 'brickwall_normal.png', - 'brickwall_height.png', - ]); - brickWallPBR = response as Required; - } + const uniformBuffer = device.createBuffer({ + // Buffer holding projection, view, and model matrices plus padding bytes + size: MAT4X4_BYTES * 4, + usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST, + }); - // Create a sampler with linear filtering for smooth interpolation. - const sampler = device.createSampler({ - magFilter: 'linear', - minFilter: 'linear', - }); - - const renderPassDescriptor: GPURenderPassDescriptor = { - colorAttachments: [ - { - view: undefined, // Assigned later - - clearValue: { r: 0.0, g: 0.0, b: 0.0, a: 1.0 }, - loadOp: 'clear', - storeOp: 'store', - }, - ], - depthStencilAttachment: { - view: depthTexture.createView(), + const mapMethodBuffer = device.createBuffer({ + // Buffer holding mapping type, light uniforms, and depth uniforms + size: Float32Array.BYTES_PER_ELEMENT * 7, + usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST, + }); - depthClearValue: 1.0, - depthLoadOp: 'clear', - depthStoreOp: 'store', - }, - }; + // Create PBR info (diffuse, normal, and depth/height textures) + let spiralPBR: Required; + { + const response = await createPBRDescriptor(device, [ + 'wood_diffuse.png', + 'spiral_normal.png', + 'spiral_height.png', + ]); + spiralPBR = response as Required; + } - const box = createMeshRenderable( - device, - createBoxMeshWithTangents(1.0, 1.0, 1.0) - ); + let toyboxPBR: Required; + { + const response = await createPBRDescriptor(device, [ + 'wood_diffuse.png', + 'toybox_normal.png', + 'toybox_height.png', + ]); + toyboxPBR = response as Required; + } + + let brickWallPBR: Required; + { + const response = await createPBRDescriptor(device, [ + 'brickwall_diffuse.png', + 'brickwall_normal.png', + 'brickwall_height.png', + ]); + brickWallPBR = response as Required; + } - // Uniform bindGroups and bindGroupLayout - const frameBGDescriptor = createBindGroupDescriptor( - [0, 1], + // Create a sampler with linear filtering for smooth interpolation. + const sampler = device.createSampler({ + magFilter: 'linear', + minFilter: 'linear', + }); + + const renderPassDescriptor: GPURenderPassDescriptor = { + colorAttachments: [ + { + view: undefined, // Assigned later + + clearValue: { r: 0.0, g: 0.0, b: 0.0, a: 1.0 }, + loadOp: 'clear', + storeOp: 'store', + }, + ], + depthStencilAttachment: { + view: depthTexture.createView(), + + depthClearValue: 1.0, + depthLoadOp: 'clear', + depthStoreOp: 'store', + }, + }; + + const box = createMeshRenderable( + device, + createBoxMeshWithTangents(1.0, 1.0, 1.0) + ); + + // Uniform bindGroups and bindGroupLayout + const frameBGDescriptor = createBindGroupDescriptor( + [0, 1], + [ + GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT, + GPUShaderStage.FRAGMENT | GPUShaderStage.VERTEX, + ], + ['buffer', 'buffer'], + [{ type: 'uniform' }, { type: 'uniform' }], + [[{ buffer: uniformBuffer }, { buffer: mapMethodBuffer }]], + 'Frame', + device + ); + + // Texture bindGroups and bindGroupLayout + const surfaceBGDescriptor = createBindGroupDescriptor( + [0, 1, 2, 3], + [GPUShaderStage.FRAGMENT], + ['sampler', 'texture', 'texture', 'texture'], + [ + { type: 'filtering' }, + { sampleType: 'float' }, + { sampleType: 'float' }, + { sampleType: 'float' }, + ], + // Multiple bindgroups that accord to the layout defined above + [ [ - GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT, - GPUShaderStage.FRAGMENT | GPUShaderStage.VERTEX, + sampler, + spiralPBR.diffuse.createView(), + spiralPBR.normal.createView(), + spiralPBR.height.createView(), ], - ['buffer', 'buffer'], - [{ type: 'uniform' }, { type: 'uniform' }], - [[{ buffer: uniformBuffer }, { buffer: mapMethodBuffer }]], - 'Frame', - device - ); - - // Texture bindGroups and bindGroupLayout - const surfaceBGDescriptor = createBindGroupDescriptor( - [0, 1, 2, 3], - [GPUShaderStage.FRAGMENT], - ['sampler', 'texture', 'texture', 'texture'], [ - { type: 'filtering' }, - { sampleType: 'float' }, - { sampleType: 'float' }, - { sampleType: 'float' }, + sampler, + toyboxPBR.diffuse.createView(), + toyboxPBR.normal.createView(), + toyboxPBR.height.createView(), ], - // Multiple bindgroups that accord to the layout defined above [ - [ - sampler, - spiralPBR.diffuse.createView(), - spiralPBR.normal.createView(), - spiralPBR.height.createView(), - ], - [ - sampler, - toyboxPBR.diffuse.createView(), - toyboxPBR.normal.createView(), - toyboxPBR.height.createView(), - ], - [ - sampler, - brickWallPBR.diffuse.createView(), - brickWallPBR.normal.createView(), - brickWallPBR.height.createView(), - ], + sampler, + brickWallPBR.diffuse.createView(), + brickWallPBR.normal.createView(), + brickWallPBR.height.createView(), ], - 'Surface', - device + ], + 'Surface', + device + ); + + const aspect = canvas.width / canvas.height; + const projectionMatrix = mat4.perspective( + (2 * Math.PI) / 5, + aspect, + 1, + 100.0 + ) as Float32Array; + + function getViewMatrix() { + const viewMatrix = mat4.identity(); + mat4.translate( + viewMatrix, + vec3.fromValues( + settings.cameraPosX, + settings.cameraPosY, + settings.cameraPosZ + ), + viewMatrix ); + return viewMatrix; + } - const aspect = canvas.width / canvas.height; - const projectionMatrix = mat4.perspective( - (2 * Math.PI) / 5, - aspect, - 1, - 100.0 - ) as Float32Array; - - function getViewMatrix() { - const viewMatrix = mat4.identity(); - mat4.translate( - viewMatrix, - vec3.fromValues( - settings.cameraPosX, - settings.cameraPosY, - settings.cameraPosZ - ), - viewMatrix - ); - return viewMatrix; - } + function getModelMatrix() { + const modelMatrix = mat4.create(); + mat4.identity(modelMatrix); + mat4.rotateX(modelMatrix, 10, modelMatrix); + const now = Date.now() / 1000; + mat4.rotateY(modelMatrix, now * -0.5, modelMatrix); + return modelMatrix; + } - function getModelMatrix() { - const modelMatrix = mat4.create(); - mat4.identity(modelMatrix); - mat4.rotateX(modelMatrix, 10, modelMatrix); - const now = Date.now() / 1000; - mat4.rotateY(modelMatrix, now * -0.5, modelMatrix); - return modelMatrix; + // Change the model mapping type + const getMappingType = (): number => { + switch (settings['Bump Mode']) { + case 'Diffuse Texture': + return 0; + case 'Normal Texture': + return 1; + case 'Depth Texture': + return 2; + case 'Normal Map': + return 3; + case 'Parallax Scale': + return 4; + case 'Steep Parallax': + return 5; } + }; + + const texturedCubePipeline = create3DRenderPipeline( + device, + 'NormalMappingRender', + [frameBGDescriptor.bindGroupLayout, surfaceBGDescriptor.bindGroupLayout], + normalMapWGSL, + // Position, normal uv tangent bitangent + ['float32x3', 'float32x3', 'float32x2', 'float32x3', 'float32x3'], + normalMapWGSL, + presentationFormat, + true + ); + + let currentSurfaceBindGroup = 0; + const onChangeTexture = () => { + currentSurfaceBindGroup = TextureAtlas[settings.Texture]; + }; + + gui.add(settings, 'Bump Mode', [ + 'Diffuse Texture', + 'Normal Texture', + 'Depth Texture', + 'Normal Map', + 'Parallax Scale', + 'Steep Parallax', + ]); + gui + .add(settings, 'Texture', ['Spiral', 'Toybox', 'BrickWall']) + .onChange(onChangeTexture); + const lightFolder = gui.addFolder('Light'); + const depthFolder = gui.addFolder('Depth'); + lightFolder.add(settings, 'Reset Light').onChange(() => { + lightPosXCell.setValue(1.7); + lightPosYCell.setValue(-0.7); + lightPosZCell.setValue(1.9); + lightIntensityCell.setValue(0.02); + }); + const lightPosXCell = lightFolder.add(settings, 'lightPosX', -5, 5).step(0.1); + const lightPosYCell = lightFolder.add(settings, 'lightPosY', -5, 5).step(0.1); + const lightPosZCell = lightFolder.add(settings, 'lightPosZ', -5, 5).step(0.1); + const lightIntensityCell = lightFolder + .add(settings, 'lightIntensity', 0.0, 0.1) + .step(0.002); + depthFolder.add(settings, 'depthScale', 0.0, 0.1).step(0.01); + depthFolder.add(settings, 'depthLayers', 1, 32).step(1); + + const liFunctionElements = document.getElementsByClassName('cr function'); + for (let i = 0; i < liFunctionElements.length; i++) { + (liFunctionElements[i].children[0] as HTMLElement).style.display = 'flex'; + (liFunctionElements[i].children[0] as HTMLElement).style.justifyContent = + 'center'; + ( + liFunctionElements[i].children[0].children[1] as HTMLElement + ).style.position = 'absolute'; + } - // Change the model mapping type - const getMappingType = (arr: Uint32Array) => { - switch (settings['Bump Mode']) { - case 'Diffuse Texture': - arr[0] = 0; - break; - case 'Normal Texture': - arr[0] = 1; - break; - case 'Depth Texture': - arr[0] = 2; - break; - case 'Normal Map': - arr[0] = 3; - break; - case 'Parallax Scale': - arr[0] = 4; - break; - case 'Steep Parallax': - arr[0] = 5; - break; - } - }; - const mappingType: Uint32Array = new Uint32Array([0]); - - const texturedCubePipeline = create3DRenderPipeline( - device, - 'NormalMappingRender', - [frameBGDescriptor.bindGroupLayout, surfaceBGDescriptor.bindGroupLayout], - normalMapWGSL, - // Position, normal uv tangent bitangent - ['float32x3', 'float32x3', 'float32x2', 'float32x3', 'float32x3'], - normalMapWGSL, - presentationFormat, - true - ); + function frame() { + if (!pageState.active) return; + + // Write to normal map shader + const viewMatrixTemp = getViewMatrix(); + const viewMatrix = viewMatrixTemp as Float32Array; - let currentSurfaceBindGroup = 0; - const onChangeTexture = () => { - currentSurfaceBindGroup = TextureAtlas[settings.Texture]; - }; - - gui.add(settings, 'Bump Mode', [ - 'Diffuse Texture', - 'Normal Texture', - 'Depth Texture', - 'Normal Map', - 'Parallax Scale', - 'Steep Parallax', + const modelMatrixTemp = getModelMatrix(); + const modelMatrix = modelMatrixTemp as Float32Array; + + const matrices = new Float32Array([ + ...projectionMatrix, + ...viewMatrix, + ...modelMatrix, ]); - gui - .add(settings, 'Texture', ['Spiral', 'Toybox', 'BrickWall']) - .onChange(onChangeTexture); - const lightFolder = gui.addFolder('Light'); - const depthFolder = gui.addFolder('Depth'); - lightFolder.add(settings, 'Reset Light').onChange(() => { - lightPosXCell.setValue(1.7); - lightPosYCell.setValue(-0.7); - lightPosZCell.setValue(1.9); - lightIntensityCell.setValue(0.02); - }); - const lightPosXCell = lightFolder - .add(settings, 'lightPosX', -5, 5) - .step(0.1); - const lightPosYCell = lightFolder - .add(settings, 'lightPosY', -5, 5) - .step(0.1); - const lightPosZCell = lightFolder - .add(settings, 'lightPosZ', -5, 5) - .step(0.1); - const lightIntensityCell = lightFolder - .add(settings, 'lightIntensity', 0.0, 0.1) - .step(0.002); - depthFolder.add(settings, 'depthScale', 0.0, 0.1).step(0.01); - depthFolder.add(settings, 'depthLayers', 1, 32).step(1); - - const liFunctionElements = document.getElementsByClassName('cr function'); - for (let i = 0; i < liFunctionElements.length; i++) { - (liFunctionElements[i].children[0] as HTMLElement).style.display = 'flex'; - (liFunctionElements[i].children[0] as HTMLElement).style.justifyContent = - 'center'; - ( - liFunctionElements[i].children[0].children[1] as HTMLElement - ).style.position = 'absolute'; - } - function frame() { - if (!pageState.active) return; - - // Write to normal map shader - const viewMatrixTemp = getViewMatrix(); - const viewMatrix = viewMatrixTemp as Float32Array; - - const modelMatrixTemp = getModelMatrix(); - const modelMatrix = modelMatrixTemp as Float32Array; - - writeMat4ToBuffer(device, uniformBuffer, [ - projectionMatrix, - viewMatrix, - modelMatrix, - ]); - - getMappingType(mappingType); - - write32ToBuffer(device, mapMethodBuffer, [mappingType]); - device.queue.writeBuffer( - mapMethodBuffer, - 4, - new Float32Array([ - settings.lightPosX, - settings.lightPosY, - settings.lightPosZ, - settings.lightIntensity, - settings.depthScale, - settings.depthLayers, - ]) - ); - - renderPassDescriptor.colorAttachments[0].view = context - .getCurrentTexture() - .createView(); - - const commandEncoder = device.createCommandEncoder(); - const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor); - // Draw textured Cube - passEncoder.setPipeline(texturedCubePipeline); - passEncoder.setBindGroup(0, frameBGDescriptor.bindGroups[0]); - passEncoder.setBindGroup( - 1, - surfaceBGDescriptor.bindGroups[currentSurfaceBindGroup] - ); - passEncoder.setVertexBuffer(0, box.vertexBuffer); - passEncoder.setIndexBuffer(box.indexBuffer, 'uint16'); - passEncoder.drawIndexed(box.indexCount); - passEncoder.end(); - device.queue.submit([commandEncoder.finish()]); - - requestAnimationFrame(frame); - } + const mappingType = getMappingType(); + + device.queue.writeBuffer( + uniformBuffer, + 0, + matrices.buffer, + matrices.byteOffset, + matrices.byteLength + ); + + device.queue.writeBuffer( + mapMethodBuffer, + 0, + new Float32Array([ + mappingType, + settings.lightPosX, + settings.lightPosY, + settings.lightPosZ, + settings.lightIntensity, + settings.depthScale, + settings.depthLayers, + ]) + ); + + renderPassDescriptor.colorAttachments[0].view = context + .getCurrentTexture() + .createView(); + + const commandEncoder = device.createCommandEncoder(); + const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor); + // Draw textured Cube + passEncoder.setPipeline(texturedCubePipeline); + passEncoder.setBindGroup(0, frameBGDescriptor.bindGroups[0]); + passEncoder.setBindGroup( + 1, + surfaceBGDescriptor.bindGroups[currentSurfaceBindGroup] + ); + passEncoder.setVertexBuffer(0, box.vertexBuffer); + passEncoder.setIndexBuffer(box.indexBuffer, 'uint16'); + passEncoder.drawIndexed(box.indexCount); + passEncoder.end(); + device.queue.submit([commandEncoder.finish()]); + requestAnimationFrame(frame); } -).then((resultInit) => (init = resultInit)); + requestAnimationFrame(frame); +}; const NormalMapping: () => JSX.Element = () => makeSample({ diff --git a/src/sample/normalMap/utils.ts b/src/sample/normalMap/utils.ts index fc543716..107cc0f6 100644 --- a/src/sample/normalMap/utils.ts +++ b/src/sample/normalMap/utils.ts @@ -1,6 +1,3 @@ -import { SampleInit } from '../../components/SampleLayout'; -import type { GUI } from 'dat.gui'; - type BindGroupBindingLayout = | GPUBufferBindingLayout | GPUTextureBindingLayout @@ -50,10 +47,6 @@ export const createBindGroupDescriptor = ( }); const bindGroups: GPUBindGroup[] = []; - // i represent the bindGroup index, j represents the binding index of the resource within the bindgroup - // i=0, j=0 bindGroup: 0, binding: 0 - // i=1, j=1, bindGroup: 0, binding: 1 - // NOTE: not the same as @group(0) @binding(1) group index within the fragment shader is set within a pipeline for (let i = 0; i < resources.length; i++) { const groupEntries: GPUBindGroupEntry[] = []; for (let j = 0; j < resources[0].length; j++) { @@ -80,60 +73,6 @@ export type ShaderKeyInterface = { [K in T[number]]: number; }; -export type SampleInitParams = { - canvas: HTMLCanvasElement; - pageState: { active: boolean }; - gui?: GUI; - stats?: Stats; -}; - -interface DeviceInitParms { - device: GPUDevice; -} - -interface DeviceInit3DParams extends DeviceInitParms { - context: GPUCanvasContext; - presentationFormat: GPUTextureFormat; -} - -type CallbackSync3D = (params: SampleInitParams & DeviceInit3DParams) => void; -type CallbackAsync3D = ( - params: SampleInitParams & DeviceInit3DParams -) => Promise; - -type SampleInitCallback3D = CallbackSync3D | CallbackAsync3D; - -export const SampleInitFactoryWebGPU = async ( - callback: SampleInitCallback3D -): Promise => { - const init: SampleInit = async ({ canvas, pageState, gui, stats }) => { - const adapter = await navigator.gpu.requestAdapter(); - const device = await adapter.requestDevice(); - if (!pageState.active) return; - const context = canvas.getContext('webgpu') as GPUCanvasContext; - const devicePixelRatio = window.devicePixelRatio || 1; - canvas.width = canvas.clientWidth * devicePixelRatio; - canvas.height = canvas.clientHeight * devicePixelRatio; - const presentationFormat = navigator.gpu.getPreferredCanvasFormat(); - context.configure({ - device, - format: presentationFormat, - alphaMode: 'premultiplied', - }); - - callback({ - canvas, - pageState, - gui, - device, - context, - presentationFormat, - stats, - }); - }; - return init; -}; - interface AttribAcc { attributes: GPUVertexAttribute[]; arrayStride: number; @@ -323,51 +262,3 @@ export const createPBRDescriptor = async ( } return pbr; }; - -/** - * @param {GPUDevice} device - The GPU performing each buffer write. - * @param {GPUBuffer} buffer- The buffer we are filling with data. - * @param {Float32Array[]} mat4Arr - An array of multiple 4x4 matrices. - * @returns {string} An offset designating the end of the region that was written to within the buffer. - */ -export const writeMat4ToBuffer = ( - device: GPUDevice, - buffer: GPUBuffer, - mat4Arr: Float32Array[], - offset = 0 -): number => { - for (let i = 0; i < mat4Arr.length; i++) { - device.queue.writeBuffer( - buffer, - offset + 64 * i, - mat4Arr[i].buffer, - mat4Arr[i].byteOffset, - mat4Arr[i].byteLength - ); - } - return 64 * mat4Arr.length; -}; - -/** - * @param {GPUDevice} device - The GPU performing each buffer write. - * @param {GPUBuffer} buffer- The buffer we are filling with data. - * @param {Float32Array[]} mat4Arr - An array of f32 values. - * @returns {string} An offset designating the end of the region that was written to within the buffer. - */ -export const write32ToBuffer = ( - device: GPUDevice, - buffer: GPUBuffer, - arr: (Float32Array | Uint32Array)[], - offset = 0 -) => { - for (let i = 0; i < arr.length; i++) { - device.queue.writeBuffer( - buffer, - offset + 4 * i, - arr[i].buffer, - arr[i].byteOffset, - arr[i].byteLength - ); - } - return 4 * arr.length; -};