UNPKG

@wonderlandengine/api

Version:

Wonderland Engine's JavaScript API.

258 lines (257 loc) 8.03 kB
import { WonderlandEngine } from '../engine.js'; import { Resource, ResourceManager, ResourceType } from './resource.js'; /** * Material parameter type. */ export declare enum MaterialParamType { /** Unsigned integer parameter type. */ UnsignedInt = 0, /** Integer parameter type. */ Int = 1, /** 16-bit float parameter type. */ HalfFloat = 2, /** Float parameter type. */ Float = 3, /** Sampler resource parameter type, i.e., a {@link Texture}. */ Sampler = 4, /** * Font resource parameter type. * * **Note**: Changing font isn't exposed yet and will raise an error. */ Font = 5 } /** * Constructor parameters object for a {@link Material} instance. * * @deprecated Use {@link MaterialManager#getTemplate} instead: * * ```js * const PhongMaterial = engine.materials.getTemplate('Phong Opaque'); * const material = new PhongMaterial(); * material.setDiffuseColor([1, 0, 0]); * ``` */ export interface MaterialParameters { /** The name of the pipeline. */ pipeline: string; } /** * Material constructor. * * Material classes are automatically generated by the runtime based on the * loaded scene shaders. */ export interface MaterialConstructor<T extends Material = Material> { /** * Set of the dynamic parameters that exist on the definition. * * For instance, the set would contain elements such as `ambientColor`, `diffuseColor` * for a Phong material. */ readonly Parameters: Set<string>; /** * Create a new Material. * * The material is created from the pipeline associated to the material class. * * @note Creating material is expensive. Please use {@link Material#clone} to clone a material. * @note Do not use this constructor directly with an index, this is reserved for internal purposes. */ new (index?: number): T; } /** * Wrapper around a native material. * * For more information about how to create materials, have a look at the * {@link MaterialManager} class. * * #### Properties * * The material properties are automatically converted into getters/setters: * * ```js * const material = new PhongMaterial(); * * // Set the `diffuseColor` property * material.setDiffuseColor([1.0, 0.0, 0.0, 1.0]); * console.log(material.getDiffuseColor()); * ``` * * Getters for non-scalar types have an optional argument to skip an array * allocation: * * ```js * const material = new PhongMaterial(); * const diffuse = [0, 0, 0, 0]; * material.getDiffuseColor(diffuse); * console.log(diffuse) // Prints '[1.0, 1.0, 1.0, 1.0]' * ``` * * @note Materials are **per-engine**, they can thus be shared by multiple scenes. * * #### TypeScript * * The Wonderland Editor can automatically generate material definitions (.d.ts) * from the project pipelines. * * To enable the generation, go to the `Project Settings > JavaScript` panel and * set `materialDefinitions` to a path, e.g., `materials.d.ts`. * * It's then possible to cast the material type using: * * ```ts * // Note the `.js` instead of `.d.ts` * import {PhongOpaque} from './materials.js'; * * const mesh = object.getComponent('mesh'); * const material = mesh.material as PhongOpaque; * material.setDiffuseColor([1, 0, 0, 1]); // Set a red diffuse * ``` * * @since 1.2.0 */ export declare class Material extends Resource { /** @hidden */ static getResourceType(): ResourceType; /** * @deprecated Use {@link MaterialManager#getTemplate} via {@link WonderlandEngine.materials} * to create a new material with a given pipeline: * * ```js * const PhongMaterial = engine.materials.getTemplate('Phong Opaque'); * const material = new PhongMaterial(); * material.setDiffuseColor([1, 0, 0]); * ``` */ constructor(engine: WonderlandEngine, params: number | MaterialParameters); /** * Check whether a parameter exists on this material. * * @param name The name to check. * @returns `true` if the parameter with name `name` exists on this material, * `false` otherwise. */ hasParameter(name: string): boolean; /** @deprecated Use {@link pipeline} instead. */ get shader(): string; /** Name of the pipeline used by this material. */ get pipeline(): string; /** * Create a copy of the underlying native material. * * @returns Material clone. */ clone(): Material | null; toString(): string; /** * Wrap a native material index. * * @param engine Engine instance. * @param index The index. * @returns Material instance or `null` if index <= 0. * * @deprecated Use the {@link WonderlandEngine.materials} instead. */ static wrap(engine: WonderlandEngine, index: number): Material | null; } /** * Manage materials. * * #### Creation * * To create a material, first retrieve the class associated to * the pipeline using {@link MaterialManager.getTemplate}: * * ```js * const PhongMaterial = engine.materials.getTemplate('Phong Opaque'); * ``` * * Creating a material is then done using the constructor: * * ```js * const material = new PhongMaterial(); * material.setDiffuseColor([1.0, 0.0, 0.0, 1.0]); * ``` */ export declare class MaterialManager extends ResourceManager<Material> { /** Material classes. @hidden. */ private readonly _materialTemplates; /** @hidden */ constructor(engine: WonderlandEngine); /** @override */ wrap(index: number): Material | null; /** * Get the material class with the given pipeline name. * * #### Usage * * ```js * const PhongMaterial = engine.materials.getTemplate('Phong Opaque'); * const material = new PhongMaterial(); * material.setDiffuseColor([1.0, 0.0, 0.0, 1.0]); * ``` * * #### TypeScript * * This method provide a simple way to cast the constructor returned by `getTemplate`: * * ```ts * interface Phong { * getAmbientColor(out?: Float32Array): Float32Array; * setAmbientColor(value: NumberArray): void; * } * const PhongMaterial = engine.materials.getTemplate<Phong>('Phong Opaque'); * const mat = new PhongMaterial(); // `mat` is of type `Phong` * ``` * * However, this means manually writing types for each pipeline. * * Fortunately, The Wonderland Editor can automatically generate material definitions (.d.ts) * from the project pipelines. * * To enable the generation, go to the `Project Settings > JavaScript` panel and * set `materialDefinitions` to a path, e.g., `materials.d.ts`. * * Material constructors will then be typed automatically when using a string literal pipeline name: * * ```ts * // Note the `.js` instead of `.d.ts` * import {PhongOpaque} from './materials.js'; * * const PhongMaterial = engine.materials.getTemplate('Phong Opaque'); * const mat = new PhongMaterial(); // `mat` is of type `PhongOpaque` * ``` * * @param pipeline The pipeline name to search for. * @returns The material class. * * @throws `Error` if the material class doesn't exist. */ getTemplate<T extends Material = Material>(pipeline: string): MaterialConstructor<T>; /** * Wrap a material instance. * * @todo: Remove at 2.0.0. * * @note Wrapping should only be called once per instance. * * @param instance The material instance. * @returns The new material, wrapped in a proxy. */ _wrapInstance(instance: Material): Material; /** * Cache all pipeline definitions. * * @hidden */ private _cacheDefinitions; /** * Create a material class from a definition index. * * @param wasm The WASM instance. * @param definitionIndex The definition index to wrap. * @returns The material class. */ private _createMaterialTemplate; }