@wonderlandengine/api
Version:
Wonderland Engine's JavaScript API.
258 lines (257 loc) • 8.03 kB
TypeScript
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;
}