playcanvas
Version:
PlayCanvas WebGL game engine
129 lines (126 loc) • 5.41 kB
JavaScript
import { Debug } from '../../core/debug.js';
import { ShaderProcessorOptions } from '../../platform/graphics/shader-processor-options.js';
import { SHADERDEF_MORPH_TEXTURE_BASED_INT, SHADERDEF_MORPH_NORMAL, SHADERDEF_MORPH_POSITION, SHADERDEF_INSTANCING, SHADERDEF_SKIN } from '../constants.js';
import { getProgramLibrary } from '../shader-lib/get-program-library.js';
import { shaderGeneratorShader } from '../shader-lib/programs/shader-generator-shader.js';
import { getCoreDefines } from '../shader-lib/utils.js';
import { Material } from './material.js';
function _extends() {
_extends = Object.assign || function(target) {
for(var i = 1; i < arguments.length; i++){
var source = arguments[i];
for(var key in source){
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
return _extends.apply(this, arguments);
}
/**
* @typedef {object} ShaderDesc - The description of the shader used by the {@link ShaderMaterial}.
* @property {string} uniqueName - Unique name for the shader. If a shader with this name already
* exists, it will be returned instead of a new shader instance.
* @property {string} [shaderLanguage] - The language used by the shader source. Can be:
*
* - {@link SHADERLANGUAGE_GLSL}
* - {@link SHADERLANGUAGE_WGSL}
*
* Defaults to {@link SHADERLANGUAGE_GLSL}.
* @property {string} [vertexCode] - The vertex shader code.
* @property {string} [fragmentCode] - The fragment shader code.
* @property {Object<string, string>} [attributes] - Object detailing the mapping of vertex shader
* attribute names to semantics SEMANTIC_*. This enables the engine to match vertex buffer data as
* inputs to the shader. Defaults to undefined, which generates the default attributes.
* @param {string | string[]} [fragmentOutputTypes] - Fragment shader output types, which default to
* vec4. Passing a string will set the output type for all color attachments. Passing an array will
* set the output type for each color attachment. @see ShaderUtils.createDefinition
*/ /**
* A ShaderMaterial is a type of material that utilizes a specified shader for rendering purposes.
*
* A simple example which creates a material with custom vertex and fragment shaders:
*
* ```javascript
* const material = new pc.ShaderMaterial({
* uniqueName: 'MyShader',
* attributes: { aPosition: pc.SEMANTIC_POSITION },
* vertexCode: `
* attribute vec3 aPosition;
* uniform mat4 matrix_viewProjection;
* void main(void)
* {
* gl_Position = matrix_viewProjection * pos;
* }`,
* fragmentCode: `
* void main(void) {
* gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
* }`
* });
* ```
*
* @category Graphics
*/ class ShaderMaterial extends Material {
/**
* Sets the shader description.
*
* @type {ShaderDesc|undefined}
*/ set shaderDesc(value) {
if (value) {
Debug.assert(value.vertexCode, 'ShaderMaterial: shaderDesc must contain vertexCode');
Debug.assert(value.fragmentCode, 'ShaderMaterial: shaderDesc must contain fragmentCode');
}
// shallow clone the object
this._shaderDesc = value ? _extends({}, value) : undefined;
this.clearVariants();
}
/**
* Gets the shader description.
*
* @type {ShaderDesc|undefined}
*/ get shaderDesc() {
return this._shaderDesc;
}
/**
* Copy a `ShaderMaterial`.
*
* @param {ShaderMaterial} source - The material to copy from.
* @returns {ShaderMaterial} The destination material.
*/ copy(source) {
super.copy(source);
this.shaderDesc = source.shaderDesc;
return this;
}
getShaderVariant(params) {
var { objDefs } = params;
var _this_chunks;
var options = {
defines: getCoreDefines(this, params),
skin: (objDefs & SHADERDEF_SKIN) !== 0,
useInstancing: (objDefs & SHADERDEF_INSTANCING) !== 0,
useMorphPosition: (objDefs & SHADERDEF_MORPH_POSITION) !== 0,
useMorphNormal: (objDefs & SHADERDEF_MORPH_NORMAL) !== 0,
useMorphTextureBasedInt: (objDefs & SHADERDEF_MORPH_TEXTURE_BASED_INT) !== 0,
pass: params.pass,
gamma: params.cameraShaderParams.shaderOutputGamma,
toneMapping: params.cameraShaderParams.toneMapping,
fog: params.cameraShaderParams.fog,
shaderDesc: this.shaderDesc,
chunks: (_this_chunks = this.chunks) != null ? _this_chunks : {} // override chunks from the material
};
var processingOptions = new ShaderProcessorOptions(params.viewUniformFormat, params.viewBindGroupFormat, params.vertexFormat);
var library = getProgramLibrary(params.device);
library.register('shader-material', shaderGeneratorShader);
return library.getProgram('shader-material', options, processingOptions, this.userId);
}
/**
* Create a new ShaderMaterial instance.
*
* @param {ShaderDesc} [shaderDesc] - The description of the shader to be used by the material.
*/ constructor(shaderDesc){
super();
this.shaderDesc = shaderDesc;
}
}
export { ShaderMaterial };