186 lines
7.7 KiB
TypeScript
186 lines
7.7 KiB
TypeScript
import EventEmitter from 'eventemitter3';
|
|
import { GlProgram } from '../../gl/shader/GlProgram';
|
|
import { BindGroup } from '../../gpu/shader/BindGroup';
|
|
import { GpuProgram } from '../../gpu/shader/GpuProgram';
|
|
import type { GlProgramOptions } from '../../gl/shader/GlProgram';
|
|
import type { GpuProgramOptions } from '../../gpu/shader/GpuProgram';
|
|
/**
|
|
* A record of {@link BindGroup}'s used by the shader.
|
|
*
|
|
* `Record<number, BindGroup>`
|
|
* @memberof rendering
|
|
*/
|
|
export type ShaderGroups = Record<number, BindGroup>;
|
|
interface ShaderBase {
|
|
/** The WebGL program used by the WebGL renderer. */
|
|
glProgram?: GlProgram;
|
|
/** The WebGPU program used by the WebGPU renderer. */
|
|
gpuProgram?: GpuProgram;
|
|
/**
|
|
* A number that uses two bits on whether the shader is compatible with the WebGL renderer and/or the WebGPU renderer.
|
|
* 0b00 - not compatible with either
|
|
* 0b01 - compatible with WebGL
|
|
* 0b10 - compatible with WebGPU
|
|
* This is automatically set based on if a {@link GlProgram} or {@link GpuProgram} is provided.
|
|
*/
|
|
compatibleRenderers?: number;
|
|
}
|
|
export interface GlShaderWith extends ShaderBase {
|
|
/** The WebGL program used by the WebGL renderer. */
|
|
glProgram: GlProgram;
|
|
}
|
|
export interface GpuShaderWith extends ShaderBase {
|
|
/** The WebGPU program used by the WebGPU renderer. */
|
|
gpuProgram: GpuProgram;
|
|
}
|
|
export interface ShaderWithGroupsDescriptor {
|
|
/** A record of {@link BindGroup}'s used by the shader. */
|
|
groups: ShaderGroups;
|
|
/** an optional map of how to bind the groups. This is automatically generated by reading the WebGPU program */
|
|
groupMap?: Record<string, Record<string, any>>;
|
|
}
|
|
interface ShaderWithResourcesDescriptor {
|
|
/**
|
|
* A key value of uniform resources used by the shader.
|
|
* Under the hood pixi will look at the provided shaders and figure out where
|
|
* the resources are mapped. Its up to you to make sure the resource key
|
|
* matches the uniform name in the webGPU program. WebGL is a little more forgiving!
|
|
*/
|
|
resources?: Record<string, any>;
|
|
}
|
|
/**
|
|
* A descriptor for a shader
|
|
* @memberof rendering
|
|
*/
|
|
export type ShaderWith = GlShaderWith | GpuShaderWith;
|
|
/**
|
|
* A descriptor for a shader with groups.
|
|
* @memberof rendering
|
|
*/
|
|
export type ShaderWithGroups = ShaderWithGroupsDescriptor & ShaderWith;
|
|
export interface IShaderWithGroups extends ShaderWithGroupsDescriptor, ShaderBase {
|
|
}
|
|
/**
|
|
* A descriptor for a shader with resources. This is an easier way to work with uniforms.
|
|
* especially when you are not working with bind groups
|
|
* @memberof rendering
|
|
*/
|
|
export type ShaderWithResources = ShaderWithResourcesDescriptor & ShaderWith;
|
|
export interface IShaderWithResources extends ShaderWithResourcesDescriptor, ShaderBase {
|
|
}
|
|
export type ShaderDescriptor = ShaderWithGroups & ShaderWithResources;
|
|
type GlShaderFromWith = {
|
|
gpu?: GpuProgramOptions;
|
|
gl: GlProgramOptions;
|
|
};
|
|
type GpuShaderFromWith = {
|
|
gpu: GpuProgramOptions;
|
|
gl?: GlProgramOptions;
|
|
};
|
|
export type ShaderFromGroups = (GlShaderFromWith | GpuShaderFromWith) & Omit<ShaderWithGroups, 'glProgram' | 'gpuProgram'>;
|
|
export type ShaderFromResources = (GlShaderFromWith | GpuShaderFromWith) & Omit<ShaderWithResources, 'glProgram' | 'gpuProgram'>;
|
|
/**
|
|
* The Shader class is an integral part of the PixiJS graphics pipeline.
|
|
* Central to rendering in PixiJS are two key elements: A [shader] and a [geometry].
|
|
* The shader incorporates a {@link GlProgram} for WebGL or a {@link GpuProgram} for WebGPU,
|
|
* instructing the respective technology on how to render the geometry.
|
|
*
|
|
* The primary goal of the Shader class is to offer a unified interface compatible with both WebGL and WebGPU.
|
|
* When constructing a shader, you need to provide both a WebGL program and a WebGPU program due to the distinctions
|
|
* between the two rendering engines. If only one is provided, the shader won't function with the omitted renderer.
|
|
*
|
|
* Both WebGL and WebGPU utilize the same resource object when passed into the shader.
|
|
* Post-creation, the shader's interface remains consistent across both WebGL and WebGPU.
|
|
* The sole distinction lies in whether a glProgram or a gpuProgram is employed.
|
|
*
|
|
* Modifying shader uniforms, which can encompass:
|
|
* - TextureSampler {@link TextureStyle}
|
|
* - TextureSource {@link TextureSource}
|
|
* - UniformsGroups {@link UniformGroup}
|
|
* @example
|
|
*
|
|
* const shader = new Shader({
|
|
* glProgram: glProgram,
|
|
* gpuProgram: gpuProgram,
|
|
* resources: {
|
|
* uTexture: texture.source,
|
|
* uSampler: texture.sampler,
|
|
* uColor: [1, 0, 0, 1],
|
|
* },
|
|
* });
|
|
*
|
|
* // update the uniforms
|
|
* shader.resources.uColor[1] = 1;
|
|
* shader.resources.uTexture = texture2.source;
|
|
* @class
|
|
* @memberof rendering
|
|
*/
|
|
export declare class Shader extends EventEmitter<{
|
|
'destroy': Shader;
|
|
}> {
|
|
/** An instance of the GPU program used by the WebGPU renderer */
|
|
gpuProgram: GpuProgram;
|
|
/** An instance of the GL program used by the WebGL renderer */
|
|
glProgram: GlProgram;
|
|
/**
|
|
* A number that uses two bits on whether the shader is compatible with the WebGL renderer and/or the WebGPU renderer.
|
|
* 0b00 - not compatible with either
|
|
* 0b01 - compatible with WebGL
|
|
* 0b10 - compatible with WebGPU
|
|
* This is automatically set based on if a {@link GlProgram} or {@link GpuProgram} is provided.
|
|
*/
|
|
readonly compatibleRenderers: number;
|
|
/** */
|
|
groups: Record<number, BindGroup>;
|
|
/** A record of the resources used by the shader. */
|
|
resources: Record<string, any>;
|
|
/**
|
|
* A record of the uniform groups and resources used by the shader.
|
|
* This is used by WebGL renderer to sync uniform data.
|
|
* @internal
|
|
* @ignore
|
|
*/
|
|
_uniformBindMap: Record<number, Record<number, string>>;
|
|
private readonly _ownedBindGroups;
|
|
/**
|
|
* Fired after rendering finishes.
|
|
* @event rendering.Shader#destroy
|
|
*/
|
|
/**
|
|
* There are two ways to create a shader.
|
|
* one is to pass in resources which is a record of uniform groups and resources.
|
|
* another is to pass in groups which is a record of {@link BindGroup}s.
|
|
* this second method is really to make use of shared {@link BindGroup}s.
|
|
* For most cases you will want to use resources as they are easier to work with.
|
|
* USe Groups if you want to share {@link BindGroup}s between shaders.
|
|
* you cannot mix and match - either use resources or groups.
|
|
* @param {ShaderWithResourcesDescriptor} options - The options for the shader using ShaderWithResourcesDescriptor.
|
|
*/
|
|
constructor(options: ShaderWithResources);
|
|
constructor(options: ShaderWithGroups);
|
|
/**
|
|
* Sometimes a resource group will be provided later (for example global uniforms)
|
|
* In such cases, this method can be used to let the shader know about the group.
|
|
* @param name - the name of the resource group
|
|
* @param groupIndex - the index of the group (should match the webGPU shader group location)
|
|
* @param bindIndex - the index of the bind point (should match the webGPU shader bind point)
|
|
*/
|
|
addResource(name: string, groupIndex: number, bindIndex: number): void;
|
|
private _buildResourceAccessor;
|
|
/**
|
|
* Use to destroy the shader when its not longer needed.
|
|
* It will destroy the resources and remove listeners.
|
|
* @param destroyPrograms - if the programs should be destroyed as well.
|
|
* Make sure its not being used by other shaders!
|
|
*/
|
|
destroy(destroyPrograms?: boolean): void;
|
|
/**
|
|
* A short hand function to create a shader based of a vertex and fragment shader.
|
|
* @param options
|
|
* @returns A shiny new PixiJS shader!
|
|
*/
|
|
static from(options: ShaderFromGroups): Shader;
|
|
static from(options: ShaderFromResources): Shader;
|
|
}
|
|
export {};
|