playcanvas
Version:
Open-source WebGL/WebGPU 3D engine for the web
103 lines (102 loc) • 3.58 kB
JavaScript
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
import {
semanticToLocation,
TYPE_INT8,
TYPE_UINT8,
TYPE_INT16,
TYPE_UINT16,
TYPE_INT32,
TYPE_UINT32,
TYPE_FLOAT32,
TYPE_FLOAT16
} from "../constants.js";
const gpuVertexFormats = [];
gpuVertexFormats[TYPE_INT8] = "sint8";
gpuVertexFormats[TYPE_UINT8] = "uint8";
gpuVertexFormats[TYPE_INT16] = "sint16";
gpuVertexFormats[TYPE_UINT16] = "uint16";
gpuVertexFormats[TYPE_INT32] = "sint32";
gpuVertexFormats[TYPE_UINT32] = "uint32";
gpuVertexFormats[TYPE_FLOAT32] = "float32";
gpuVertexFormats[TYPE_FLOAT16] = "float16";
const gpuVertexFormatsNormalized = [];
gpuVertexFormatsNormalized[TYPE_INT8] = "snorm8";
gpuVertexFormatsNormalized[TYPE_UINT8] = "unorm8";
gpuVertexFormatsNormalized[TYPE_INT16] = "snorm16";
gpuVertexFormatsNormalized[TYPE_UINT16] = "unorm16";
gpuVertexFormatsNormalized[TYPE_INT32] = "sint32";
gpuVertexFormatsNormalized[TYPE_UINT32] = "uint32";
gpuVertexFormatsNormalized[TYPE_FLOAT32] = "float32";
gpuVertexFormatsNormalized[TYPE_FLOAT16] = "float16";
class WebgpuVertexBufferLayout {
constructor() {
/**
* @type {Map<string, GPUVertexBufferLayout[]>}
* @private
*/
__publicField(this, "cache", /* @__PURE__ */ new Map());
}
/**
* Obtain a vertex layout of one or two vertex formats.
*
* @param {VertexFormat} vertexFormat0 - The first vertex format.
* @param {VertexFormat} [vertexFormat1] - The second vertex format.
* @returns {any[]} - The vertex layout.
*/
get(vertexFormat0, vertexFormat1 = null) {
const key = this.getKey(vertexFormat0, vertexFormat1);
let layout = this.cache.get(key);
if (!layout) {
layout = this.create(vertexFormat0, vertexFormat1);
this.cache.set(key, layout);
}
return layout;
}
getKey(vertexFormat0, vertexFormat1 = null) {
return `${vertexFormat0?.renderingHashString}-${vertexFormat1?.renderingHashString}`;
}
/**
* @param {VertexFormat} vertexFormat0 - The first vertex format.
* @param {VertexFormat} vertexFormat1 - The second vertex format.
* @returns {any[]} - The vertex buffer layout.
*/
create(vertexFormat0, vertexFormat1) {
const layout = [];
const addFormat = (format) => {
const interleaved = format.interleaved;
const stepMode = format.instancing ? "instance" : "vertex";
let attributes = [];
const elementCount = format.elements.length;
for (let i = 0; i < elementCount; i++) {
const element = format.elements[i];
const location = semanticToLocation[element.name];
const formatTable = element.normalize ? gpuVertexFormatsNormalized : gpuVertexFormats;
attributes.push({
shaderLocation: location,
offset: interleaved ? element.offset : 0,
format: `${formatTable[element.dataType]}${element.numComponents > 1 ? `x${element.numComponents}` : ""}`
});
if (!interleaved || i === elementCount - 1) {
layout.push({
attributes,
arrayStride: element.stride,
stepMode
});
attributes = [];
}
}
};
if (vertexFormat0) {
addFormat(vertexFormat0);
}
if (vertexFormat1) {
addFormat(vertexFormat1);
}
return layout;
}
}
export {
WebgpuVertexBufferLayout
};