UNPKG

playcanvas

Version:

PlayCanvas WebGL game engine

99 lines (96 loc) 4.5 kB
import { semanticToLocation, TYPE_INT8, TYPE_UINT8, TYPE_INT16, TYPE_UINT16, TYPE_INT32, TYPE_UINT32, TYPE_FLOAT32, TYPE_FLOAT16 } from '../constants.js'; /** * @import { VertexFormat } from '../vertex-format.js' */ // map of TYPE_*** to GPUVertexFormat var 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'; var gpuVertexFormatsNormalized = []; gpuVertexFormatsNormalized[TYPE_INT8] = 'snorm8'; gpuVertexFormatsNormalized[TYPE_UINT8] = 'unorm8'; gpuVertexFormatsNormalized[TYPE_INT16] = 'snorm16'; gpuVertexFormatsNormalized[TYPE_UINT16] = 'unorm16'; gpuVertexFormatsNormalized[TYPE_INT32] = 'sint32'; // there is no 32bit normalized signed int gpuVertexFormatsNormalized[TYPE_UINT32] = 'uint32'; // there is no 32bit normalized unsigned int gpuVertexFormatsNormalized[TYPE_FLOAT32] = 'float32'; // there is no 32bit normalized float gpuVertexFormatsNormalized[TYPE_FLOAT16] = 'float16'; // there is no 16bit normalized half-float class WebgpuVertexBufferLayout { /** * 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) { if (vertexFormat1 === void 0) vertexFormat1 = null; var key = this.getKey(vertexFormat0, vertexFormat1); var layout = this.cache.get(key); if (!layout) { layout = this.create(vertexFormat0, vertexFormat1); this.cache.set(key, layout); } return layout; } getKey(vertexFormat0, vertexFormat1) { if (vertexFormat1 === void 0) vertexFormat1 = null; return (vertexFormat0 == null ? void 0 : vertexFormat0.renderingHashString) + "-" + (vertexFormat1 == null ? void 0 : 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) { // type {GPUVertexBufferLayout[]} var layout = []; // Note: If the VertexFormat is interleaved, we use a single vertex buffer with multiple // attributes. This uses a smaller number of vertex buffers (1), which has performance // benefits when setting it up on the device. // If the VertexFormat is not interleaved, we use multiple vertex buffers, one per // attribute. This is less efficient, but is required as there is a pretty small // limit on the attribute offsets in the vertex buffer layout. var addFormat = (format)=>{ var interleaved = format.interleaved; var stepMode = format.instancing ? 'instance' : 'vertex'; var attributes = []; var elementCount = format.elements.length; for(var i = 0; i < elementCount; i++){ var element = format.elements[i]; var location = semanticToLocation[element.name]; var 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: attributes, arrayStride: element.stride, stepMode: stepMode }); attributes = []; } } }; if (vertexFormat0) { addFormat(vertexFormat0); } if (vertexFormat1) { addFormat(vertexFormat1); } return layout; } constructor(){ /** * @type {Map<string, GPUVertexBufferLayout[]>} * @private */ this.cache = new Map(); } } export { WebgpuVertexBufferLayout };