@types/three
Version:
TypeScript definitions for three
267 lines (256 loc) • 8.41 kB
TypeScript
import { GLSLVersion } from "../constants.js";
import { JSONMeta } from "../core/Object3D.js";
import { UniformsGroup } from "../core/UniformsGroup.js";
import { Matrix3Tuple } from "../math/Matrix3.js";
import { Matrix4Tuple } from "../math/Matrix4.js";
import { Vector2Tuple } from "../math/Vector2.js";
import { Vector3Tuple } from "../math/Vector3.js";
import { Vector4Tuple } from "../math/Vector4.js";
import { IUniform } from "../renderers/shaders/UniformsLib.js";
import { MapColorPropertiesToColorRepresentations, Material, MaterialJSON, MaterialProperties } from "./Material.js";
export interface ShaderMaterialProperties extends MaterialProperties {
/**
* Defines custom constants using `#define` directives within the GLSL code
* for both the vertex shader and the fragment shader; each key/value pair
* yields another directive.
* ```js
* defines: {
* FOO: 15,
* BAR: true
* }
* ```
* Yields the lines:
* ```
* #define FOO 15
* #define BAR true
* ```
*/
defines: Record<string, unknown>;
/**
* An object of the form:
* ```js
* {
* "uniform1": { value: 1.0 },
* "uniform2": { value: 2 }
* }
* ```
* specifying the uniforms to be passed to the shader code; keys are uniform
* names, values are definitions of the form
* ```
* {
* value: 1.0
* }
* ```
* where `value` is the value of the uniform. Names must match the name of
* the uniform, as defined in the GLSL code. Note that uniforms are refreshed
* on every frame, so updating the value of the uniform will immediately
* update the value available to the GLSL code.
*/
uniforms: { [uniform: string]: IUniform };
/**
* An array holding uniforms groups for configuring UBOs.
*/
uniformsGroups: Array<UniformsGroup>;
/**
* Vertex shader GLSL code. This is the actual code for the shader.
*/
vertexShader: string;
/**
* Fragment shader GLSL code. This is the actual code for the shader.
*/
fragmentShader: string;
/**
* Controls line thickness or lines.
*
* WebGL and WebGPU ignore this setting and always render line primitives with a
* width of one pixel.
*
* @default 1
*/
linewidth: number;
/**
* Renders the geometry as a wireframe.
*
* @default false
*/
wireframe: boolean;
/**
* Controls the thickness of the wireframe.
*
* WebGL and WebGPU ignore this property and always render
* 1 pixel wide lines.
*
* @default 1
*/
wireframeLinewidth: number;
/**
* Defines whether the material color is affected by global fog settings; `true`
* to pass fog uniforms to the shader.
*
* Setting this property to `true` requires the definition of fog uniforms. It is
* recommended to use `UniformsUtils.merge()` to combine the custom shader uniforms
* with predefined fog uniforms.
*
* ```js
* const material = new ShaderMaterial( {
* uniforms: UniformsUtils.merge( [ UniformsLib[ 'fog' ], shaderUniforms ] );
* vertexShader: vertexShader,
* fragmentShader: fragmentShader,
* fog: true
* } );
* ```
*
* @default false
*/
fog: boolean;
/**
* Defines whether this material uses lighting; `true` to pass uniform data
* related to lighting to this shader.
*
* @default false
*/
lights: boolean;
/**
* Defines whether this material supports clipping; `true` to let the renderer
* pass the clippingPlanes uniform.
*
* @default false
*/
clipping: boolean;
/**
* This object allows to enable certain WebGL 2 extensions.
*
* - clipCullDistance: set to `true` to use vertex shader clipping
* - multiDraw: set to `true` to use vertex shader multi_draw / enable gl_DrawID
*/
extensions: {
clipCullDistance: boolean;
multiDraw: boolean;
};
/**
* When the rendered geometry doesn't include these attributes but the
* material does, these default values will be passed to the shaders. This
* avoids errors when buffer data is missing.
*
* - color: [ 1, 1, 1 ]
* - uv: [ 0, 0 ]
* - uv1: [ 0, 0 ]
*/
defaultAttributeValues: {
color: [number, number, number];
uv: [number, number];
uv1: [number, number];
};
/**
* If set, this calls [gl.bindAttribLocation](https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bindAttribLocation)
* to bind a generic vertex index to an attribute variable.
*
* @default undefined
*/
index0AttributeName: string | undefined;
/**
* Can be used to force a uniform update while changing uniforms in
* {@link Object3D#onBeforeRender}.
*
* @default false
*/
uniformsNeedUpdate: boolean;
/**
* Defines the GLSL version of custom shader code.
*
* @default null
*/
glslVersion: GLSLVersion | null;
}
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface ShaderMaterialParameters
extends Partial<MapColorPropertiesToColorRepresentations<ShaderMaterialProperties>>
{}
export type ShaderMaterialUniformJSON = {
type: "t";
value: string;
} | {
type: "c";
value: number;
} | {
type: "v2";
value: Vector2Tuple;
} | {
type: "v3";
value: Vector3Tuple;
} | {
type: "v4";
value: Vector4Tuple;
} | {
type: "m3";
value: Matrix3Tuple;
} | {
type: "m4";
value: Matrix4Tuple;
} | {
value: unknown;
};
export interface ShaderMaterialJSON extends MaterialJSON {
glslVersion: number | null;
uniforms: Record<string, ShaderMaterialUniformJSON>;
defines?: Record<string, unknown>;
vertexShader: string;
fragmentShader: string;
lights: boolean;
clipping: boolean;
extensions?: Record<string, boolean>;
}
/**
* A material rendered with custom shaders. A shader is a small program written in GLSL.
* that runs on the GPU. You may want to use a custom shader if you need to implement an
* effect not included with any of the built-in materials.
*
* There are the following notes to bear in mind when using a `ShaderMaterial`:
*
* - `ShaderMaterial` can only be used with {@link WebGLRenderer}.
* - Built in attributes and uniforms are passed to the shaders along with your code. If
* you don't want that, use {@link RawShaderMaterial} instead.
* - You can use the directive `#pragma unroll_loop_start` and `#pragma unroll_loop_end`
* in order to unroll a `for` loop in GLSL by the shader preprocessor. The directive has
* to be placed right above the loop. The loop formatting has to correspond to a defined standard.
* - The loop has to be [normalized](https://en.wikipedia.org/wiki/Normalized_loop).
* - The loop variable has to be *i*.
* - The value `UNROLLED_LOOP_INDEX` will be replaced with the explicitly
* value of *i* for the given iteration and can be used in preprocessor
* statements.
*
* ```js
* const material = new THREE.ShaderMaterial( {
* uniforms: {
* time: { value: 1.0 },
* resolution: { value: new THREE.Vector2() }
* },
* vertexShader: document.getElementById( 'vertexShader' ).textContent,
* fragmentShader: document.getElementById( 'fragmentShader' ).textContent
* } );
* ```
*/
export class ShaderMaterial extends Material {
/**
* Constructs a new shader material.
*
* @param {Object} [parameters] - An object with one or more properties
* defining the material's appearance. Any property of the material
* (including any property from inherited materials) can be passed
* in here. Color values can be passed any type of value accepted
* by {@link Color#set}.
*/
constructor(parameters?: ShaderMaterialParameters);
/**
* This flag can be used for type testing.
*
* @default true
*/
readonly isShaderMaterial: boolean;
setValues(values?: ShaderMaterialParameters): void;
toJSON(meta?: JSONMeta): ShaderMaterialJSON;
}
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface ShaderMaterial extends ShaderMaterialProperties {
defines: Record<string, unknown>;
}