playcanvas
Version:
PlayCanvas WebGL game engine
63 lines (60 loc) • 2.13 kB
JavaScript
import { platform } from '../../core/platform.js';
import { Preprocessor } from '../../core/preprocessor.js';
import { SHADERLANGUAGE_WGSL, SHADERLANGUAGE_GLSL } from './constants.js';
import { ShaderDefinitionUtils } from './shader-definition-utils.js';
let id = 0;
class Shader {
constructor(graphicsDevice, definition){
this.attributes = new Map();
this.id = id++;
this.device = graphicsDevice;
this.definition = definition;
this.name = definition.name || 'Untitled';
this.init();
if (definition.cshader) {
definition.cshader = Preprocessor.run(definition.cshader, definition.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 ??= 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 };