playcanvas
Version:
Open-source WebGL/WebGPU 3D engine for the web
74 lines (73 loc) • 2.6 kB
JavaScript
import { TRACEID_SHADER_ALLOC } from "../../core/constants.js";
import { platform } from "../../core/platform.js";
import { Preprocessor } from "../../core/preprocessor.js";
import { SHADERLANGUAGE_GLSL, SHADERLANGUAGE_WGSL } from "./constants.js";
import { ShaderDefinitionUtils } from "./shader-definition-utils.js";
import halfTypes from "./shader-chunks/frag/half-types.js";
let id = 0;
class Shader {
meshUniformBufferFormat;
meshBindGroupFormat;
attributes = /* @__PURE__ */ new Map();
constructor(graphicsDevice, definition) {
this.id = id++;
this.device = graphicsDevice;
this.definition = definition;
this.name = definition.name || "Untitled";
this.init();
if (definition.cshader) {
const enablesCode = ShaderDefinitionUtils.getWGSLEnables(graphicsDevice, "compute");
const definesCode = ShaderDefinitionUtils.getDefinesCode(graphicsDevice, definition.cdefines);
const cshader = enablesCode + definesCode + definition.cshader;
const cincludes = definition.cincludes ?? /* @__PURE__ */ new Map();
if (!cincludes.has("halfTypesCS")) {
cincludes.set("halfTypesCS", halfTypes);
}
definition.cshader = Preprocessor.run(cshader, cincludes, {
sourceName: `compute shader for ${this.label}`,
stripDefines: true
});
} else {
const wgsl = definition.shaderLanguage === SHADERLANGUAGE_WGSL;
definition.vshader = Preprocessor.run(definition.vshader, definition.vincludes, {
sourceName: `vertex shader for ${this.label}`,
stripDefines: wgsl
});
if (definition.shaderLanguage === SHADERLANGUAGE_GLSL) {
definition.attributes ?? (definition.attributes = ShaderDefinitionUtils.collectAttributes(definition.vshader));
}
const stripUnusedColorAttachments = graphicsDevice.isWebGL2 && (platform.name === "osx" || platform.name === "ios");
definition.fshader = Preprocessor.run(definition.fshader, definition.fincludes, {
stripUnusedColorAttachments,
stripDefines: wgsl,
sourceName: `fragment shader for ${this.label}`
});
if (!definition.vshader || !definition.fshader) {
this.failed = true;
return;
}
}
this.impl = graphicsDevice.createShaderImpl(this);
}
init() {
this.ready = false;
this.failed = false;
}
get label() {
return `Shader Id ${this.id} (${this.definition.shaderLanguage === SHADERLANGUAGE_WGSL ? "WGSL" : "GLSL"}) ${this.name}`;
}
destroy() {
this.device.onDestroyShader(this);
this.impl.destroy(this);
}
loseContext() {
this.init();
this.impl.loseContext();
}
restoreContext() {
this.impl.restoreContext(this.device, this);
}
}
export {
Shader
};