UNPKG

gpu-curtains

Version:

gpu-curtains is a 3D WebGPU rendering engine. It can be used as a standalone 3D engine, but also includes extra classes focused on mapping 3d objects to DOM elements; It allows users to synchronize values such as position, sizing, or scale between them.

349 lines (348 loc) 8.69 kB
import { WebGPUShaderStageConstants } from "../../utils/webgpu-constants.mjs"; //#region src/core/bindings/utils.ts /** * Map {@link MaterialShadersType | shaders types names} with actual {@link https://developer.mozilla.org/en-US/docs/Web/API/GPUDevice/createBindGroupLayout#visibility | GPUShaderStageFlags}. */ const bindingVisibilities = new Map([ ["vertex", WebGPUShaderStageConstants.VERTEX], ["fragment", WebGPUShaderStageConstants.FRAGMENT], ["compute", WebGPUShaderStageConstants.COMPUTE] ]); /** * Get the corresponding {@link https://developer.mozilla.org/en-US/docs/Web/API/GPUDevice/createBindGroupLayout#visibility | GPUShaderStageFlags} based on an array of {@link MaterialShadersType | shaders types names}. * @param visibilities - array of {@link MaterialShadersType | shaders types names}. * @returns - corresponding {@link https://developer.mozilla.org/en-US/docs/Web/API/GPUDevice/createBindGroupLayout#visibility | GPUShaderStageFlags}. */ const getBindingVisibility = (visibilities = []) => { return visibilities.reduce((acc, v) => { return acc | bindingVisibilities.get(v); }, 0); }; /** Object containing all buffer layouts. */ const bufferLayouts = { i32: { numElements: 1, align: 4, size: 4, type: "i32", View: Int32Array }, u32: { numElements: 1, align: 4, size: 4, type: "u32", View: Uint32Array }, f32: { numElements: 1, align: 4, size: 4, type: "f32", View: Float32Array }, f16: { numElements: 1, align: 2, size: 2, type: "u16", View: Uint16Array }, vec2f: { numElements: 2, align: 8, size: 8, type: "f32", View: Float32Array }, vec2i: { numElements: 2, align: 8, size: 8, type: "i32", View: Int32Array }, vec2u: { numElements: 2, align: 8, size: 8, type: "u32", View: Uint32Array }, vec2h: { numElements: 2, align: 4, size: 4, type: "u16", View: Uint16Array }, vec3i: { numElements: 3, align: 16, size: 12, type: "i32", View: Int32Array }, vec3u: { numElements: 3, align: 16, size: 12, type: "u32", View: Uint32Array }, vec3f: { numElements: 3, align: 16, size: 12, type: "f32", View: Float32Array }, vec3h: { numElements: 3, align: 8, size: 6, type: "u16", View: Uint16Array }, vec4i: { numElements: 4, align: 16, size: 16, type: "i32", View: Int32Array }, vec4u: { numElements: 4, align: 16, size: 16, type: "u32", View: Uint32Array }, vec4f: { numElements: 4, align: 16, size: 16, type: "f32", View: Float32Array }, vec4h: { numElements: 4, align: 8, size: 8, type: "u16", View: Uint16Array }, mat2x2f: { numElements: 4, align: 8, size: 16, type: "f32", View: Float32Array }, mat2x2h: { numElements: 4, align: 4, size: 8, type: "u16", View: Uint16Array }, mat3x2f: { numElements: 6, align: 8, size: 24, type: "f32", View: Float32Array }, mat3x2h: { numElements: 6, align: 4, size: 12, type: "u16", View: Uint16Array }, mat4x2f: { numElements: 8, align: 8, size: 32, type: "f32", View: Float32Array }, mat4x2h: { numElements: 8, align: 4, size: 16, type: "u16", View: Uint16Array }, mat2x3f: { numElements: 8, align: 16, size: 32, pad: [3, 1], type: "f32", View: Float32Array }, mat2x3h: { numElements: 8, align: 8, size: 16, pad: [3, 1], type: "u16", View: Uint16Array }, mat3x3f: { numElements: 12, align: 16, size: 48, pad: [3, 1], type: "f32", View: Float32Array }, mat3x3h: { numElements: 12, align: 8, size: 24, pad: [3, 1], type: "u16", View: Uint16Array }, mat4x3f: { numElements: 16, align: 16, size: 64, pad: [3, 1], type: "f32", View: Float32Array }, mat4x3h: { numElements: 16, align: 8, size: 32, pad: [3, 1], type: "u16", View: Uint16Array }, mat2x4f: { numElements: 8, align: 16, size: 32, type: "f32", View: Float32Array }, mat2x4h: { numElements: 8, align: 8, size: 16, type: "u16", View: Uint16Array }, mat3x4f: { numElements: 12, align: 16, size: 48, pad: [3, 1], type: "f32", View: Float32Array }, mat3x4h: { numElements: 12, align: 8, size: 24, pad: [3, 1], type: "u16", View: Uint16Array }, mat4x4f: { numElements: 16, align: 16, size: 64, type: "f32", View: Float32Array }, mat4x4h: { numElements: 16, align: 8, size: 32, type: "u16", View: Uint16Array } }; /** * Get the correct {@link BufferLayout | buffer layout} for given {@link WGSLVariableType | variable type}. * @param bufferType - [{@link WGSLVariableType | variable type} to use. * @returns - the ={@link BufferLayout | buffer layout}. */ const getBufferLayout = (bufferType) => { return bufferLayouts[bufferType]; }; /** * Get the correct WGSL variable declaration code fragment based on the given {@link BufferBinding}. * @param binding - {@link BufferBinding} to use. * @returns - WGSL variable declaration code fragment. */ const getBindingWGSLVarType = (binding) => { switch (binding.bindingType) { case "storage": return `var<${binding.bindingType}, ${binding.options.access}>`; default: return "var<uniform>"; } }; /** * Get the correct WGSL variable declaration code fragment based on the given {@link TextureBinding}. * @param binding - {@link TextureBinding} to use. * @returns - WGSL variable declaration code fragment. */ const getTextureBindingWGSLVarType = (binding) => { if (binding.bindingType === "externalTexture") return `var ${binding.name}: texture_external;`; return binding.bindingType === "storage" ? `var ${binding.name}: texture_storage_${binding.options.viewDimension.replace("-", "_")}<${binding.options.format}, ${binding.options.access}>;` : binding.bindingType === "depth" ? `var ${binding.name}: texture_depth${binding.options.multisampled ? "_multisampled" : ""}_${binding.options.viewDimension.replace("-", "_")};` : `var ${binding.name}: texture${binding.options.multisampled ? "_multisampled" : ""}_${binding.options.viewDimension.replace("-", "_")}<f32>;`; }; /** * Get the correct {@link GPUBindGroupLayout | bind group layout} resource type based on the given {@link core/bindings/Binding.BindingType | binding type}. * @param binding - {@link BufferBinding | buffer binding} to use. * @returns - {@link GPUBindGroupLayout | bind group layout} resource type. */ const getBindGroupLayoutBindingType = (binding) => { if (binding.bindingType === "storage" && binding.options.access === "read_write") return "storage"; else if (binding.bindingType === "storage") return "read-only-storage"; else return "uniform"; }; /** * Get the correct {@link GPUBindGroupLayout} resource type based on the given {@link core/bindings/Binding.BindingType | texture binding type}. * @param binding - {@link TextureBinding | texture binding} to use. * @returns - {@link GPUBindGroupLayout} resource type. */ const getBindGroupLayoutTextureBindingType = (binding) => { switch (binding.bindingType) { case "externalTexture": return { externalTexture: {} }; case "storage": return { storageTexture: { format: binding.options.format, viewDimension: binding.options.viewDimension } }; case "texture": return { texture: { multisampled: binding.options.multisampled, viewDimension: binding.options.viewDimension, sampleType: binding.options.multisampled || binding.options.format.indexOf("depth") !== -1 ? "unfilterable-float" : "float" } }; case "depth": return { texture: { multisampled: binding.options.multisampled, viewDimension: binding.options.viewDimension, sampleType: "depth" } }; default: return null; } }; /** * Get the correct {@link TextureBinding | texture binding} cache key. * @param binding - {@link TextureBinding | texture binding} to use. * @returns - binding cache key. */ const getBindGroupLayoutTextureBindingCacheKey = (binding) => { switch (binding.bindingType) { case "externalTexture": return `externalTexture,${binding.visibility},`; case "storage": return `storageTexture,${binding.options.format},${binding.options.viewDimension},${binding.visibility},`; case "texture": return `texture,${binding.options.multisampled},${binding.options.viewDimension},${binding.options.multisampled ? "unfilterable-float" : "float"},${binding.visibility},`; case "depth": return `depthTexture,${binding.options.format},${binding.options.viewDimension},${binding.visibility},`; default: return `${binding.visibility},`; } }; //#endregion export { getBindGroupLayoutBindingType, getBindGroupLayoutTextureBindingCacheKey, getBindGroupLayoutTextureBindingType, getBindingVisibility, getBindingWGSLVarType, getBufferLayout, getTextureBindingWGSLVarType };