UNPKG

playcanvas

Version:

Open-source WebGL/WebGPU 3D engine for the web

129 lines (128 loc) 4.46 kB
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 { Debug } from "../core/debug.js"; import { DeviceCache } from "../platform/graphics/device-cache.js"; import { SHADER_FORWARD, SHADER_PICK, SHADER_SHADOW, SHADER_PREPASS, SHADER_DEPTH_PICK } from "./constants.js"; const shaderPassDeviceCache = new DeviceCache(); class ShaderPassInfo { /** * @param {string} name - The name, for example 'depth'. Must contain only letters, numbers, * and underscores, and start with a letter. * @param {number} index - Index from ShaderPass#nextIndex. * @param {object} [options] - Options for additional configuration of the shader pass. * @param {boolean} [options.isForward] - Whether the pass is forward. * @param {boolean} [options.isShadow] - Whether the pass is shadow. * @param {boolean} [options.lightType] - Type of light, for example `pc.LIGHTTYPE_DIRECTIONAL`. * @param {boolean} [options.shadowType] - Type of shadow, for example `pc.SHADOW_PCF3_32F`. */ constructor(name, index, options = {}) { /** @type {number} */ __publicField(this, "index"); /** @type {string} */ __publicField(this, "name"); /** @type {Map<string, string>} */ __publicField(this, "defines", /* @__PURE__ */ new Map()); Debug.assert(/^[a-z]\w*$/i.test(name), `ShaderPass name can only contain letters, numbers and underscores and start with a letter: ${name}`); this.name = name; this.index = index; Object.assign(this, options); this.buildShaderDefines(); } buildShaderDefines() { let keyword; if (this.isShadow) { keyword = "SHADOW"; } else if (this.isForward) { keyword = "FORWARD"; } else if (this.index === SHADER_PICK) { keyword = "PICK"; } else if (this.index === SHADER_DEPTH_PICK) { keyword = "PICK"; this.defines.set("DEPTH_PICK_PASS", ""); } this.defines.set(`${keyword}_PASS`, ""); this.defines.set(`${this.name.toUpperCase()}_PASS`, ""); } } class ShaderPass { constructor() { /** * Allocated shader passes, map of a shader pass name to info. * * @type {Map<string, ShaderPassInfo>} */ __publicField(this, "passesNamed", /* @__PURE__ */ new Map()); /** * Allocated shader passes, indexed by their index. * * @type {Array<ShaderPassInfo>} */ __publicField(this, "passesIndexed", []); /** Next available index */ __publicField(this, "nextIndex", 0); const add = (name, index, options) => { const info = this.allocate(name, options); Debug.assert(info.index === index); }; add("forward", SHADER_FORWARD, { isForward: true }); add("prepass", SHADER_PREPASS); add("shadow", SHADER_SHADOW); add("pick", SHADER_PICK); add("depth_pick", SHADER_DEPTH_PICK); } /** * Get access to the shader pass instance for the specified device. * * @param {GraphicsDevice} device - The graphics device. * @returns { ShaderPass } The shader pass instance for the specified device. */ static get(device) { Debug.assert(device); return shaderPassDeviceCache.get(device, () => { return new ShaderPass(); }); } /** * Allocates a shader pass with the specified name and options. * * @param {string} name - A name of the shader pass. * @param {object} [options] - Options for the shader pass, which are added as properties to the * shader pass info. * @returns {ShaderPassInfo} The allocated shader pass info. */ allocate(name, options) { let info = this.passesNamed.get(name); if (info === void 0) { info = new ShaderPassInfo(name, this.nextIndex, options); this.passesNamed.set(info.name, info); this.passesIndexed[info.index] = info; this.nextIndex++; } return info; } /** * Return the shader pass info for the specified index. * * @param {number} index - The shader pass index. * @returns {ShaderPassInfo} - The shader pass info. */ getByIndex(index) { const info = this.passesIndexed[index]; Debug.assert(info); return info; } getByName(name) { return this.passesNamed.get(name); } } export { ShaderPass, ShaderPassInfo };