UNPKG

playcanvas

Version:

PlayCanvas WebGL game engine

481 lines (480 loc) 16.7 kB
/** * - The description of the parameters used by the * Material#getShaderVariant function. */ export type ShaderVariantParams = { /** * - The graphics device. */ device: GraphicsDevice; /** * - The scene. */ scene: Scene; /** * - The object definitions. */ objDefs: number; /** * - The camera shader parameters. */ cameraShaderParams: CameraShaderParams; /** * - The shader pass. */ pass: number; /** * - The sorted lights. */ sortedLights: Light[][]; /** * - The view uniform format. */ viewUniformFormat: UniformBufferFormat | undefined; /** * - The view bind group format. */ viewBindGroupFormat: BindGroupFormat | undefined; /** * - The vertex format. */ vertexFormat: VertexFormat; }; /** * @typedef {object} ShaderVariantParams - The description of the parameters used by the * Material#getShaderVariant function. * @property {GraphicsDevice} device - The graphics device. * @property {Scene} scene - The scene. * @property {number} objDefs - The object definitions. * @property {CameraShaderParams} cameraShaderParams - The camera shader parameters. * @property {number} pass - The shader pass. * @property {Light[][]} sortedLights - The sorted lights. * @property {UniformBufferFormat|undefined} viewUniformFormat - The view uniform format. * @property {BindGroupFormat|undefined} viewBindGroupFormat - The view bind group format. * @property {VertexFormat} vertexFormat - The vertex format. * @ignore */ /** * A material determines how a particular mesh instance is rendered. It specifies the shader and * render state that is set before the mesh instance is submitted to the graphics device. * * @category Graphics */ export class Material { /** * The mesh instances referencing this material * * @type {MeshInstance[]} * @private */ private meshInstances; /** * The name of the material. * * @type {string} */ name: string; /** * A unique id the user can assign to the material. The engine internally does not use this for * anything, and the user can assign a value to this id for any purpose they like. Defaults to * an empty string. * * @type {string} */ userId: string; id: number; /** * The cache of shader variants generated for this material. The key represents the unique * variant, the value is the shader. * * @type {Map<number, Shader>} * @ignore */ variants: Map<number, Shader>; /** * The set of defines used to generate the shader variants. * * @type {Map<string, string>} * @ignore */ defines: Map<string, string>; _definesDirty: boolean; parameters: {}; /** * The alpha test reference value to control which fragments are written to the currently * active render target based on alpha value. All fragments with an alpha value of less than * the alphaTest reference value will be discarded. alphaTest defaults to 0 (all fragments * pass). * * @type {number} */ alphaTest: number; /** * Enables or disables alpha to coverage (WebGL2 only). When enabled, and if hardware * anti-aliasing is on, limited order-independent transparency can be achieved. Quality depends * on the number of MSAA samples of the current render target. It can nicely soften edges of * otherwise sharp alpha cutouts, but isn't recommended for large area semi-transparent * surfaces. Note, that you don't need to enable blending to make alpha to coverage work. It * will work without it, just like alphaTest. * * @type {boolean} */ alphaToCoverage: boolean; /** @ignore */ _blendState: BlendState; /** @ignore */ _depthState: DepthState; /** * Controls how triangles are culled based on their face direction with respect to the * viewpoint. Can be: * * - {@link CULLFACE_NONE}: Do not cull triangles based on face direction. * - {@link CULLFACE_BACK}: Cull the back faces of triangles (do not render triangles facing * away from the view point). * - {@link CULLFACE_FRONT}: Cull the front faces of triangles (do not render triangles facing * towards the view point). * * Defaults to {@link CULLFACE_BACK}. * * @type {number} */ cull: number; /** * Stencil parameters for front faces (default is null). * * @type {StencilParameters|null} */ stencilFront: StencilParameters | null; /** * Stencil parameters for back faces (default is null). * * @type {StencilParameters|null} */ stencilBack: StencilParameters | null; /** * @type {Object<string, string>} * @private */ private _chunks; _dirtyShader: boolean; /** * Sets the object containing custom shader chunks that will replace default ones. * * @type {Object<string, string>} */ set chunks(value: { [x: string]: string; }); /** * Gets the object containing custom shader chunks. * * @type {Object<string, string>} */ get chunks(): { [x: string]: string; }; /** * Sets the offset for the output depth buffer value. Useful for decals to prevent z-fighting. * Typically a small negative value (-0.1) is used to render the mesh slightly closer to the * camera. * * @type {number} */ set depthBias(value: number); /** * Gets the offset for the output depth buffer value. * * @type {number} */ get depthBias(): number; /** * Sets the offset for the output depth buffer value based on the slope of the triangle * relative to the camera. * * @type {number} */ set slopeDepthBias(value: number); /** * Gets the offset for the output depth buffer value based on the slope of the triangle * relative to the camera. * * @type {number} */ get slopeDepthBias(): number; _shaderVersion: number; _scene: any; dirty: boolean; /** * Sets whether the red channel is written to the color buffer. If true, the red component of * fragments generated by the shader of this material is written to the color buffer of the * currently active render target. If false, the red component will not be written. Defaults to * true. * * @type {boolean} */ set redWrite(value: boolean); /** * Gets whether the red channel is written to the color buffer. * * @type {boolean} */ get redWrite(): boolean; /** * Sets whether the green channel is written to the color buffer. If true, the red component of * fragments generated by the shader of this material is written to the color buffer of the * currently active render target. If false, the green component will not be written. Defaults * to true. * * @type {boolean} */ set greenWrite(value: boolean); /** * Gets whether the green channel is written to the color buffer. * * @type {boolean} */ get greenWrite(): boolean; /** * Sets whether the blue channel is written to the color buffer. If true, the red component of * fragments generated by the shader of this material is written to the color buffer of the * currently active render target. If false, the blue component will not be written. Defaults * to true. * * @type {boolean} */ set blueWrite(value: boolean); /** * Gets whether the blue channel is written to the color buffer. * * @type {boolean} */ get blueWrite(): boolean; /** * Sets whether the alpha channel is written to the color buffer. If true, the red component of * fragments generated by the shader of this material is written to the color buffer of the * currently active render target. If false, the alpha component will not be written. Defaults * to true. * * @type {boolean} */ set alphaWrite(value: boolean); /** * Gets whether the alpha channel is written to the color buffer. * * @type {boolean} */ get alphaWrite(): boolean; get transparent(): boolean; _updateTransparency(): void; /** * Sets the blend state for this material. Controls how fragment shader outputs are blended * when being written to the currently active render target. This overwrites blending type set * using {@link Material#blendType}, and offers more control over blending. * * @type {BlendState} */ set blendState(value: BlendState); /** * Gets the blend state for this material. * * @type {BlendState} */ get blendState(): BlendState; /** * Sets the blend mode for this material. Controls how fragment shader outputs are blended when * being written to the currently active render target. Can be: * * - {@link BLEND_SUBTRACTIVE}: Subtract the color of the source fragment from the destination * fragment and write the result to the frame buffer. * - {@link BLEND_ADDITIVE}: Add the color of the source fragment to the destination fragment * and write the result to the frame buffer. * - {@link BLEND_NORMAL}: Enable simple translucency for materials such as glass. This is * equivalent to enabling a source blend mode of {@link BLENDMODE_SRC_ALPHA} and a destination * blend mode of {@link BLENDMODE_ONE_MINUS_SRC_ALPHA}. * - {@link BLEND_NONE}: Disable blending. * - {@link BLEND_PREMULTIPLIED}: Similar to {@link BLEND_NORMAL} expect the source fragment is * assumed to have already been multiplied by the source alpha value. * - {@link BLEND_MULTIPLICATIVE}: Multiply the color of the source fragment by the color of the * destination fragment and write the result to the frame buffer. * - {@link BLEND_ADDITIVEALPHA}: Same as {@link BLEND_ADDITIVE} except the source RGB is * multiplied by the source alpha. * - {@link BLEND_MULTIPLICATIVE2X}: Multiplies colors and doubles the result. * - {@link BLEND_SCREEN}: Softer version of additive. * - {@link BLEND_MIN}: Minimum color. * - {@link BLEND_MAX}: Maximum color. * * Defaults to {@link BLEND_NONE}. * * @type {number} */ set blendType(type: number); /** * Gets the blend mode for this material. * * @type {number} */ get blendType(): number; /** * Sets the depth state. Note that this can also be done by using {@link Material#depthTest}, * {@link Material#depthFunc} and {@link Material#depthWrite}. * * @type {DepthState} */ set depthState(value: DepthState); /** * Gets the depth state. * * @type {DepthState} */ get depthState(): DepthState; /** * Sets whether depth testing is enabled. If true, fragments generated by the shader of this * material are only written to the current render target if they pass the depth test. If * false, fragments generated by the shader of this material are written to the current render * target regardless of what is in the depth buffer. Defaults to true. * * @type {boolean} */ set depthTest(value: boolean); /** * Gets whether depth testing is enabled. * * @type {boolean} */ get depthTest(): boolean; /** * Sets the depth test function. Controls how the depth of new fragments is compared against * the current depth contained in the depth buffer. Can be: * * - {@link FUNC_NEVER}: don't draw * - {@link FUNC_LESS}: draw if new depth < depth buffer * - {@link FUNC_EQUAL}: draw if new depth == depth buffer * - {@link FUNC_LESSEQUAL}: draw if new depth <= depth buffer * - {@link FUNC_GREATER}: draw if new depth > depth buffer * - {@link FUNC_NOTEQUAL}: draw if new depth != depth buffer * - {@link FUNC_GREATEREQUAL}: draw if new depth >= depth buffer * - {@link FUNC_ALWAYS}: always draw * * Defaults to {@link FUNC_LESSEQUAL}. * * @type {number} */ set depthFunc(value: number); /** * Gets the depth test function. * * @type {number} */ get depthFunc(): number; /** * Sets whether depth writing is enabled. If true, fragments generated by the shader of this * material write a depth value to the depth buffer of the currently active render target. If * false, no depth value is written. Defaults to true. * * @type {boolean} */ set depthWrite(value: boolean); /** * Gets whether depth writing is enabled. * * @type {boolean} */ get depthWrite(): boolean; /** * Copy a material. * * @param {Material} source - The material to copy. * @returns {Material} The destination material. */ copy(source: Material): Material; /** * Clone a material. * * @returns {this} A newly cloned material. */ clone(): this; _updateMeshInstanceKeys(): void; updateUniforms(device: any, scene: any): void; /** * @param {ShaderVariantParams} params - The parameters used to generate the shader variant. * @ignore */ getShaderVariant(params: ShaderVariantParams): void; /** * Applies any changes made to the material's properties. */ update(): void; clearParameters(): void; getParameters(): {}; clearVariants(): void; /** * Retrieves the specified shader parameter from a material. * * @param {string} name - The name of the parameter to query. * @returns {object} The named parameter. */ getParameter(name: string): object; _setParameterSimple(name: any, data: any): void; /** * Sets a shader parameter on a material. * * @param {string} name - The name of the parameter to set. * @param {number|number[]|Float32Array|Texture} data - The value for the specified parameter. */ setParameter(name: string, data: number | number[] | Float32Array | Texture): void; /** * Deletes a shader parameter on a material. * * @param {string} name - The name of the parameter to delete. */ deleteParameter(name: string): void; setParameters(device: any, names: any): void; /** * Adds or removes a define on the material. Defines can be used to enable or disable various * parts of the shader code. * * @param {string} name - The name of the define to set. * @param {string|undefined|false} value - The value of the define. If undefined or false, the * define is removed. */ setDefine(name: string, value: string | undefined | false): void; /** * Returns true if a define is enabled on the material, otherwise false. * * @param {string} name - The name of the define to check. * @returns {boolean} The value of the define. */ getDefine(name: string): boolean; /** * Removes this material from the scene and possibly frees up memory from its shaders (if there * are no other materials using it). */ destroy(): void; /** * Registers mesh instance as referencing the material. * * @param {MeshInstance} meshInstance - The mesh instance to register. * @ignore */ addMeshInstanceRef(meshInstance: MeshInstance): void; /** * De-registers mesh instance as referencing the material. * * @param {MeshInstance} meshInstance - The mesh instance to de-register. * @ignore */ removeMeshInstanceRef(meshInstance: MeshInstance): void; } import type { GraphicsDevice } from '../../platform/graphics/graphics-device.js'; import type { Scene } from '../scene.js'; import type { CameraShaderParams } from '../camera-shader-params.js'; import type { Light } from '../light.js'; import type { UniformBufferFormat } from '../../platform/graphics/uniform-buffer-format.js'; import type { BindGroupFormat } from '../../platform/graphics/bind-group-format.js'; import type { VertexFormat } from '../../platform/graphics/vertex-format.js'; import type { Shader } from '../../platform/graphics/shader.js'; import { BlendState } from '../../platform/graphics/blend-state.js'; import { DepthState } from '../../platform/graphics/depth-state.js'; import type { StencilParameters } from '../../platform/graphics/stencil-parameters.js'; import type { Texture } from '../../platform/graphics/texture.js'; import type { MeshInstance } from '../mesh-instance.js';