webgl-dsl
Version:
Thin functional WebGL wrapper with strong typed GLSL DSL
327 lines (326 loc) • 15.4 kB
TypeScript
import { Texture } from './texture';
export declare enum Type {
Scalar = "float",
Vector2 = "vec2",
Matrix2 = "mat2",
Vector3 = "vec3",
Matrix3 = "mat3",
Vector4 = "vec4",
Matrix4 = "mat4",
Boolean = "bool",
Sampler = "sampler2D"
}
export declare enum Precision {
High = "highp",
Medium = "mediump",
Low = "lowp"
}
export type TypeSize = 1 | 2 | 3 | 4;
export declare namespace Type {
function size(type: Type.Boolean | Type.Scalar | Type.Sampler): 1;
function size(type: Type.Vector2 | Type.Matrix2): 2;
function size(type: Type.Vector3 | Type.Matrix3): 3;
function size(type: Type.Vector4 | Type.Matrix4): 4;
function size(type: Type): TypeSize;
function vector(size: 2): Type.Vector2;
function vector(size: 3): Type.Vector3;
function vector(size: 4): Type.Vector4;
function vector(size: 2 | 3 | 4): Type.AnyVector;
function numeric(size: 1): Type.Scalar;
function numeric(size: 2): Type.Vector2;
function numeric(size: 3): Type.Vector3;
function numeric(size: 4): Type.Vector4;
function numeric(size: TypeSize): Type.AnyNumeric;
type Numeric<S extends TypeSize> = S extends 1 ? Type.Scalar : S extends 2 ? Type.Vector2 : S extends 3 ? Type.Vector3 : Type.Vector4;
type GetSize<T extends Type.AnyNumeric> = T extends Type.Scalar ? 1 : T extends Type.Vector2 ? 2 : T extends Type.Vector3 ? 3 : 4;
type Indexes<T extends Type.AnyVector> = T extends Type.Vector2 ? 0 | 1 : T extends Type.Vector3 ? 0 | 1 | 2 : 0 | 1 | 2 | 3;
type AnyVector = Type.Vector2 | Type.Vector3 | Type.Vector4;
type AnyMatrix = Type.Matrix2 | Type.Matrix3 | Type.Matrix4;
type AnyNumeric = Type.Scalar | AnyVector;
type JsType<T extends Type> = T extends Type.Scalar ? number : T extends Type.Vector2 ? number[] | {
x: number;
y: number;
} : T extends Type.Vector3 ? number[] | {
x: number;
y: number;
z: number;
} : T extends Type.Vector4 ? number[] : T extends Type.Matrix2 ? number[] : T extends Type.Matrix3 ? number[] : T extends Type.Matrix4 ? number[] : T extends Type.Sampler ? Texture : never;
function isVector(v: Type): v is AnyVector;
function isMatrix(v: Type): v is AnyMatrix;
}
export type Value<T extends Type = Type> = Readonly<{
type: T;
content: string;
}>;
export declare class GlslBuilder {
private readonly cache;
private global;
private local;
constructor(cache?: Map<string, any>);
once<R>(id: string, callback: () => R): R;
getGlobal(): string;
addGlobal(content: string): this;
getLocal(): string;
addLocal(content: string): this;
child(): GlslBuilder;
}
export declare namespace Glsl {
type Boolean = Glsl<Type.Boolean>;
type Scalar = Glsl<Type.Scalar>;
type Vector2 = Glsl<Type.Vector2>;
type Vector3 = Glsl<Type.Vector3>;
type Vector4 = Glsl<Type.Vector4>;
type Matrix2 = Glsl<Type.Matrix2>;
type Matrix3 = Glsl<Type.Matrix3>;
type Matrix4 = Glsl<Type.Matrix4>;
type Sampler = Glsl<Type.Sampler>;
type AnyVector = Glsl<Type.AnyVector>;
type AnyNumeric = Glsl<Type.AnyNumeric>;
type AnyMatrix = Glsl<Type.AnyMatrix>;
}
export declare class Glsl<T extends Type = Type> {
readonly getValue: (builder: GlslBuilder) => Value<T>;
constructor(getValue: (builder: GlslBuilder) => Value<T>);
private static call;
private unary;
sin(this: Glsl<Type.AnyNumeric>): Glsl<T>;
cos(this: Glsl<Type.AnyNumeric>): Glsl<T>;
radians(this: Glsl<Type.AnyNumeric>): Glsl<T>;
degrees(this: Glsl<Type.AnyNumeric>): Glsl<T>;
tan(this: Glsl<Type.AnyNumeric>): Glsl<T>;
asin(this: Glsl<Type.AnyNumeric>): Glsl<T>;
acos(this: Glsl<Type.AnyNumeric>): Glsl<T>;
exp(this: Glsl<Type.AnyNumeric>): Glsl<T>;
log(this: Glsl<Type.AnyNumeric>): Glsl<T>;
exp2(this: Glsl<Type.AnyNumeric>): Glsl<T>;
log2(this: Glsl<Type.AnyNumeric>): Glsl<T>;
sqrt(this: Glsl<Type.AnyNumeric>): Glsl<T>;
inversesqrt(this: Glsl<Type.AnyNumeric>): Glsl<T>;
abs(this: Glsl<Type.AnyNumeric>): Glsl<T>;
sign(this: Glsl<Type.AnyNumeric>): Glsl<T>;
floor(this: Glsl<Type.AnyNumeric>): Glsl<T>;
ceil(this: Glsl<Type.AnyNumeric>): Glsl<T>;
fract(this: Glsl<Type.AnyNumeric>): Glsl<T>;
normalize(this: Glsl<Type.AnyNumeric>): Glsl<T>;
round<T extends Glsl.AnyNumeric>(this: T): T;
not(this: Glsl<Type.Boolean>): Glsl<Type.Boolean>;
atan<T extends Type.AnyNumeric>(this: Glsl<T>): Glsl<T>;
atan<T extends Type.AnyNumeric>(this: Glsl<T>, x: Glsl<T>): Glsl<T>;
atan(this: Glsl.Scalar, x: number): Glsl.Scalar;
pow(this: Glsl.Scalar, p: Glsl.Scalar): Glsl.Scalar;
pow(this: Glsl.Vector2, p: Glsl.Vector2): Glsl.Vector2;
pow(this: Glsl.Vector3, p: Glsl.Vector3): Glsl.Vector3;
pow(this: Glsl.Vector4, p: Glsl.Vector4): Glsl.Vector4;
pow(this: Glsl.Scalar, p: number): Glsl.Scalar;
mod<P extends Type.AnyNumeric>(this: Glsl<P>, p: Glsl<P>): Glsl<P>;
mod(this: Glsl.Scalar, p: number): Glsl.Scalar;
min<P extends Type.AnyNumeric>(this: Glsl<P>, p: Glsl<P>): Glsl<P>;
min(this: Glsl.Scalar, p: number): Glsl.Scalar;
max<P extends Type.AnyNumeric>(this: Glsl<P>, p: Glsl<P>): Glsl<P>;
max(this: Glsl.Scalar, p: number): Glsl.Scalar;
mix<P extends Glsl.AnyNumeric>(this: P, other: P, p: P): P;
mix<P extends Glsl.AnyNumeric>(this: P, other: P, p: number): P;
mix(this: Glsl.Scalar, other: number, p: Glsl.Scalar | number): Glsl.Scalar;
clamp<T extends Glsl.AnyNumeric>(this: T, min: T, max: T): T;
clamp<T extends Glsl.AnyNumeric>(this: T, min: Glsl.Scalar | number, max: Glsl.Scalar | number): T;
smoothstep(this: Glsl.Scalar, edge1: Glsl.Scalar | number, edge2: Glsl.Scalar | number): Glsl.Scalar;
smoothstep<T extends Glsl.AnyNumeric>(this: T, edge1: T, edge2: T): T;
smoothstep<T extends Glsl.AnyNumeric>(this: Glsl.Scalar, edge1: Glsl.Scalar | number, edge2: Glsl.Scalar | number): T;
length(this: Glsl.AnyNumeric): Glsl.Scalar;
distance<T extends Glsl.AnyNumeric>(this: T, other: T): Glsl.Scalar;
distance(this: Glsl.Scalar, other: number): Glsl.Scalar;
dot<T extends Glsl.AnyNumeric>(this: T, other: T): Glsl.Scalar;
dot(this: Glsl.Scalar, other: number): Glsl.Scalar;
reflect<T extends Glsl.AnyNumeric>(this: T, n: T): T;
refract<T extends Glsl.AnyNumeric>(this: T, n: T, eta: Glsl.Scalar | number): T;
/**
* Get texture value at the specified point
*/
texture2D(this: Glsl.Sampler, point: Glsl.Vector2): Glsl.Vector4;
add<T extends Glsl.AnyNumeric | Glsl.AnyMatrix>(this: T, other: T | Glsl.Scalar | number): T;
add<T extends Glsl.AnyNumeric | Glsl.AnyMatrix>(this: Glsl.Scalar, other: T): T;
sub<T extends Glsl.AnyNumeric | Glsl.AnyMatrix>(this: T, other: T | Glsl.Scalar | number): T;
sub<T extends Glsl.AnyNumeric | Glsl.AnyMatrix>(this: Glsl.Scalar, other: T): T;
div<T extends Glsl.AnyNumeric | Glsl.AnyMatrix>(this: T, other: T | Glsl.Scalar | number): T;
div<T extends Glsl.AnyNumeric | Glsl.AnyMatrix>(this: Glsl.Scalar, other: T): T;
mul<T extends Glsl.AnyNumeric | Glsl.AnyMatrix>(this: T, other: T | Glsl.Scalar | number): T;
mul<T extends Glsl.AnyNumeric | Glsl.AnyMatrix>(this: Glsl.Scalar, other: T | Glsl.Scalar | number): T;
mul(this: Glsl.Matrix2, other: Glsl.Vector2): Glsl.Vector2;
mul(this: Glsl.Vector2, other: Glsl.Matrix2): Glsl.Vector2;
mul(this: Glsl.Matrix3, other: Glsl.Vector3): Glsl.Vector3;
mul(this: Glsl.Vector3, other: Glsl.Matrix3): Glsl.Vector3;
mul(this: Glsl.Matrix4, other: Glsl.Vector4): Glsl.Vector4;
mul(this: Glsl.Vector4, other: Glsl.Matrix4): Glsl.Vector4;
private bool;
/** Less */
lt(this: Glsl.Scalar, other: Glsl.Scalar | number): Glsl.Boolean;
/** Greater */
gt(this: Glsl.Scalar, other: Glsl.Scalar | number): Glsl.Boolean;
/** Less or equal */
lte(this: Glsl.Scalar, other: Glsl.Scalar | number): Glsl.Boolean;
/** Greater or equal */
gte(this: Glsl.Scalar, other: Glsl.Scalar | number): Glsl.Boolean;
/** Equal */
eq(this: Glsl.Scalar, other: Glsl.Scalar | number): Glsl.Boolean;
/** Not equal */
neq(this: Glsl.Scalar, other: Glsl.Scalar | number): Glsl.Boolean;
and(this: Glsl.Boolean, other: Glsl.Boolean): Glsl.Boolean;
or(this: Glsl.Boolean, other: Glsl.Boolean): Glsl.Boolean;
/**
* Save some expression into a variable
*/
mem<T extends Glsl>(this: T, precision: Precision): T;
/**
* Save some expression with high quality into a variable
*/
memHQ(): this;
/**
* Save some expression with medium quality into a variable
*/
memMQ(): this;
/**
* Save some expression with low quality into a variable
*/
memLQ(): this;
/**
* Conditional expression
* @param precision Precision of the expression result
* @param whenTrue True brunch of the condition
* @param whenFalse False brunch of the condition
*/
cond<T extends Glsl>(this: Glsl.Boolean, precision: Precision, whenTrue: T, whenFalse: T): T;
condHQ<T extends Glsl>(this: Glsl.Boolean, whenTrue: T, whenFalse: T): T;
condMQ<T extends Glsl>(this: Glsl.Boolean, whenTrue: T, whenFalse: T): T;
condLQ<T extends Glsl>(this: Glsl.Boolean, whenTrue: T, whenFalse: T): T;
take<T extends Type.AnyVector>(this: Glsl<T>, i: Type.Indexes<T>): Glsl.Scalar;
take<T extends Type.AnyVector>(this: Glsl<T>, i1: Type.Indexes<T>, i2: Type.Indexes<T>): Glsl.Vector2;
take<T extends Type.Vector3 | Type.Vector4>(this: Glsl<T>, i1: Type.Indexes<T>, i2: Type.Indexes<T>, i3: Type.Indexes<T>): Glsl.Vector3;
take(this: Glsl.Vector4, i1: Type.Indexes<Type.Vector4>, i2: Type.Indexes<Type.Vector4>, i3: Type.Indexes<Type.Vector4>, i4: Type.Indexes<Type.Vector4>): Glsl.Vector4;
vec2(this: Glsl.Scalar): Glsl.Vector2;
vec3(this: Glsl.Scalar): Glsl.Vector3;
vec4(this: Glsl.Scalar): Glsl.Vector4;
/**
* Get the first component of vector
*/
x(this: Glsl.AnyVector): Glsl.Scalar;
/**
* Get the second component of vector
*/
y(this: Glsl.Vector2 | Glsl.Vector3 | Glsl.Vector4): Glsl.Scalar;
/**
* Get the third component of vector
*/
z(this: Glsl.Vector3 | Glsl.Vector4): Glsl.Scalar;
/**
* Get the fourth component of vector
*/
w(this: Glsl.Vector4): Glsl.Scalar;
/**
* Get the first component of vector
*/
r(this: Glsl.AnyVector): Glsl.Scalar;
/**
* Get the second component of vector
*/
g(this: Glsl.Vector2 | Glsl.Vector3 | Glsl.Vector4): Glsl.Scalar;
/**
* Get the third component of vector
*/
b(this: Glsl.Vector3 | Glsl.Vector4): Glsl.Scalar;
/**
* Get the fourth component of vector
*/
a(this: Glsl.Vector4): Glsl.Scalar;
cat(this: Glsl.Scalar, v: Glsl.Scalar | number): Glsl.Vector2;
cat(this: Glsl.Scalar, v: Glsl.Vector2): Glsl.Vector3;
cat(this: Glsl.Scalar, v: Glsl.Vector3): Glsl.Vector4;
cat(this: Glsl.Vector2, v: Glsl.Scalar | number): Glsl.Vector3;
cat(this: Glsl.Vector2, v: Glsl.Vector2): Glsl.Vector4;
cat(this: Glsl.Vector3, v: Glsl.Scalar | number): Glsl.Vector4;
static val(v: boolean): Glsl<Type.Boolean>;
static val(v: number): Glsl.Scalar;
static val<T extends Glsl>(v: T): T;
static val(v1: Glsl.Scalar | number, v2: Glsl.Scalar | number): Glsl.Vector2;
static val(v1: Glsl.Scalar | number, v2: Glsl.Vector2): Glsl.Vector3;
static val(v1: Glsl.Scalar | number, v2: Glsl.Vector3): Glsl.Vector4;
static val(v1: Glsl.Vector2, v2: Glsl.Scalar | number): Glsl.Vector3;
static val(v1: Glsl.Vector3, v2: Glsl.Scalar | number): Glsl.Vector4;
static val(v1: Glsl.Scalar | number, v2: Glsl.Scalar | number, v3: Glsl.Scalar | number): Glsl.Vector3;
static val(v1: Glsl.Vector2, v2: Glsl.Scalar | number, v3: Glsl.Scalar | number): Glsl.Vector4;
static val(v1: Glsl.Scalar | number, v2: Glsl.Vector2, v3: Glsl.Scalar | number): Glsl.Vector4;
static val(v1: Glsl.Scalar | number, v2: Glsl.Scalar | number, v3: Glsl.Vector2): Glsl.Vector4;
static val(v1: Glsl.Scalar | number, v2: Glsl.Scalar | number, v3: Glsl.Scalar | number, v4: Glsl.Scalar | number): Glsl.Vector4;
static PI: Glsl.Scalar;
}
/**
* Description of attributes/uniforms/varyings
*/
export type TypeMap = {
[key: string]: Type | [Type, Precision];
};
export declare namespace TypeMap {
type GetType<T extends Type | [Type, Precision]> = T extends Type ? T : T[0];
type JsTypeMap<T extends TypeMap> = {
[key in keyof T]: Type.JsType<GetType<T[key]>>;
};
type ToValues<M extends TypeMap> = {
[key in keyof M]: Glsl<GetType<M[key]>>;
};
type WithoutPrecision<M extends TypeMap> = {
[key in keyof M]: GetType<M[key]>;
};
function getType(v: Type | [Type, Precision]): Type;
function getPrecision(v: Type | [Type, Precision]): Precision;
function withoutPrecision<M extends TypeMap>(map: M): WithoutPrecision<M>;
function values(storage: "uniform" | "attribute" | "varying", types: TypeMap): {
[key: string]: Glsl<Type>;
};
function stride(map: TypeMap): number;
interface LayoutItem {
name: string;
size: number;
stride: number;
offset: number;
}
function layout(map: TypeMap): LayoutItem[];
}
/**
* Description of a shader program
*/
export type SourceConfig<Uniforms extends TypeMap, Attributes extends TypeMap, Instances extends TypeMap, Varyings extends TypeMap = {}> = {
uniforms: Uniforms;
attributes: Attributes;
instances?: Instances;
varyings?: Varyings;
vertex: (input: TypeMap.ToValues<Uniforms> & TypeMap.ToValues<Attributes> & TypeMap.ToValues<Instances>) => TypeMap.ToValues<Varyings> & {
gl_Position: Glsl.Vector4;
gl_PointSize?: Glsl.Scalar;
};
fragment: (input: TypeMap.ToValues<Uniforms> & TypeMap.ToValues<Varyings> & {
gl_FragCoord: Glsl.Vector4;
gl_FrontFacing: Glsl.Boolean;
gl_PointCoord: Glsl.Vector2;
}) => {
gl_FragColor: Glsl.Vector4;
};
};
export type ProgramSource<Uniforms extends TypeMap, Attributes extends TypeMap, Instances extends TypeMap> = {
uniforms: Uniforms;
attributes: Attributes;
instances: Instances;
fragment: string;
vertex: string;
};
export declare namespace ProgramSource {
type GetUniforms<T extends ProgramSource<any, any, any>> = T extends ProgramSource<infer R, any, any> ? R : never;
type GetAttributes<T extends ProgramSource<any, any, any>> = T extends ProgramSource<any, infer R, any> ? R : never;
type GetInstances<T extends ProgramSource<any, any, any>> = T extends ProgramSource<any, any, infer R> ? R : never;
}
/**
* Create GLSL program source from argument types and shaders described with the DSL
*/
export declare function source<Uniforms extends TypeMap, Attributes extends TypeMap, Instances extends TypeMap, Varyings extends TypeMap = {}>({ uniforms, attributes, varyings, instances, fragment, vertex, }: SourceConfig<Uniforms, Attributes, Instances, Varyings>): ProgramSource<TypeMap.WithoutPrecision<Uniforms>, TypeMap.WithoutPrecision<Attributes>, TypeMap.WithoutPrecision<Instances>>;
/**
* Wrap a set of values into a single GLSL value
*/
export declare const val: typeof Glsl.val;