typegpu
Version:
A thin layer between JS and WebGPU/WGSL that improves development experience and allows for faster iteration.
50 lines (49 loc) • 1.71 kB
JavaScript
import { getName, setName } from "../shared/meta.js";
import { $internal } from "../shared/symbols.js";
import { schemaCallWrapper } from "./schemaCallWrapper.js";
// ----------
// Public API
// ----------
/**
* Creates a loose struct schema that can be used to construct vertex buffers.
* Describes structs with members of both loose and non-loose types.
*
* The order of members matches the passed in properties object.
* Members are not aligned in respect to their `byteAlignment`,
* unless they are explicitly decorated with the custom align attribute
* via `d.align` function.
*
* @example
* const CircleStruct = d.unstruct({ radius: d.f32, pos: d.vec3f }); // packed struct with no padding
*
* @example
* const CircleStruct = d.unstruct({ radius: d.f32, pos: d.align(16, d.vec3f) });
*
* @param properties Record with `string` keys and `TgpuData` or `TgpuLooseData` values,
* each entry describing one struct member.
*/
export function unstruct(properties) {
// In the schema call, create and return a deep copy
// by wrapping all the values in corresponding schema calls.
const unstructSchema = (instanceProps) => Object.fromEntries(Object.entries(properties).map(([key, schema]) => [
key,
schemaCallWrapper(schema, instanceProps?.[key]),
]));
Object.setPrototypeOf(unstructSchema, UnstructImpl);
unstructSchema.propTypes = properties;
return unstructSchema;
}
// --------------
// Implementation
// --------------
const UnstructImpl = {
[$internal]: true,
type: 'unstruct',
$name(label) {
setName(this, label);
return this;
},
toString() {
return `unstruct:${getName(this) ?? '<unnamed>'}`;
},
};