Blending of Three.js materials

Blending of Three.js materials

// blending modes
export type Blending =
    | type of NoBlending
    | type of NormalBlending
    | type of AdditiveBlending
    | type of SubtractiveBlending
    | typeof MultiplyBlending
    | typeof CustomBlending;

// custom blending destination factors
export type BlendingDstFactor =
    | type of ZeroFactor
    |typeofOneFactor
    | typeof SrcColorFactor
    | typeof OneMinusSrcColorFactor
    | typeof SrcAlphaFactor
    | typeof OneMinusSrcAlphaFactor
    | typeof DstAlphaFactor
    | typeof OneMinusDstAlphaFactor
    | typeof DstColorFactor
    | typeof OneMinusDstColorFactor;

// custom blending equations
export type BlendingEquation =
    | typeof AddEquation
    | typeof SubtractEquation
    | typeof ReverseSubtractEquation
    | typeof MinEquation
    | typeof MaxEquation;

// custom blending src factors
export const SrcAlphaSaturateFactor: 210;
export type BlendingSrcFactor = typeof SrcAlphaSaturateFactor;

// custom blending destination factors
export type BlendingDstFactor =
    | type of ZeroFactor
    |typeofOneFactor
    | typeof SrcColorFactor
    | typeof OneMinusSrcColorFactor
    | typeof SrcAlphaFactor
    | typeof OneMinusSrcAlphaFactor
    | typeof DstAlphaFactor
    | typeof OneMinusDstAlphaFactor
    | typeof DstColorFactor
    | typeof OneMinusDstColorFactor;

class Material {<!-- -->
  blending: Blending;

  blendEquation: BlendingEquation;
  blendEquationAlpha: BlendingEquation;

  blendDst: BlendingDstFactor;
  blendDstAlpha: BlendingDstFactor;

  blendSrc: BlendingSrcFactor | BlendingDstFactor;
  blendSrcAlpha: BlendingSrcFactor | BlendingDstFactor;
}
1. blending

The blending mode of the material.

id = gl.BLEND

//NoBlending
gl.disable(id);

//NormalBlending
// AdditiveBlending
// SubtractiveBlending
// MultiplyBlending
// CustomBlending
gl.enable(id);
2. blendEquation

The blending formula determines how new pixels are combined with pixels already in the WebGLFramebuffer.

API for mixed equations:
gl.blendEquationSeparate: used to set the RGB blending equation and alpha blending equation separately
gl.blendEquation: RGB blend equation and alpha blend equation set to a single equation.

// blending:
//NormalBlending
// AdditiveBlending
// SubtractiveBlending
// MultiplyBlending
gl.blendEquation( gl.FUNC_ADD );

// blending:
// CustomBlending
gl.blendEquationSeparate(
    equationToGL[ blendEquation ],
    equationToGL[ blendEquationAlpha ]
);

Values of the mixed equation:

const equationToGL = {<!-- -->
    [ AddEquation ]: gl.FUNC_ADD,
    [ SubtractEquation ]: gl.FUNC_SUBTRACT,
    [ ReverseSubtractEquation ]: gl.FUNC_REVERSE_SUBTRACT
    [ MinEquation ]: gl.MIN
    [ MaxEquation ]: gl.MAX
};

source: the color to be painted next
destination: the color already drawn in the framebuffer

AddEquation: source + destination
SubtractEquation: source - destination
ReverseSubtractEquation: destination - source
MinEquation: Math.min(source, destination)
MaxEquation: Math.max(source, destination)
3. blendFunc

Function used for blending pixel algorithms.

Mixed function API:
gl.blendFunc: RGB and alpha set to a single blend function.
gl.blendFuncSepar: Blend function that mixes RGB and alpha components separately.

// Function of mixed pixel algorithm
// sfactor: source mixing factor
// dfactor: destination mixing factor
gl.blendFunc(sfactor, dfactor)

// sourceColor: vec4;
// color(RGBA) = (sourceColor * sfactor) + (destinationColor * dfactor)
// srcRGB: source RGB mixing factor
// dstRGB: destination RGB mixing factor
// dstRGB: source A mixing factor
// dstRGB: dstAlpha RGB mixing factor
blendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha)

// sourceColor: vec3;
// sourceAlpha: float;
// color(RGB) = (sourceColor * srcRGB) + (destinationColor * dstRGB)
// color(A) = (sourceAlpha * srcAlpha) + (destinationAlpha * dstAlpha)
// blending = NormalBlending
gl.blendFuncSeparate(
    gl.SRC_ALPHA,
    gl.ONE_MINUS_SRC_ALPHA,
    gl.ONE,
    gl.ONE_MINUS_SRC_ALPHA
);

// blending = AdditiveBlending
gl.blendFunc( gl.SRC_ALPHA, gl.ONE );

// blending = SubtractiveBlending
gl.blendFuncSeparate(
    gl.ZERO,
    gl.ONE_MINUS_SRC_COLOR,
    gl.ZERO,
    gl.ONE
);

// blending = MultiplyBlending
gl.blendFunc( gl.ZERO, gl.SRC_COLOR );

// blending = CustomBlending
gl.blendFuncSeparate(
    factorToGL[ blendSrc ],
    factorToGL[ blendDst ],
    factorToGL[ blendSrcAlpha ],
    factorToGL[ blendDstAlpha ]
);

Mixing factor values:

const factorToGL = {<!-- -->
    [ ZeroFactor ]: gl.ZERO,
    [OneFactor]: gl.ONE,

    [ SrcColorFactor ]: gl.SRC_COLOR,
    [ SrcAlphaFactor ]: gl.SRC_ALPHA,
    [ SrcAlphaSaturateFactor ]: gl.SRC_ALPHA_SATURATE,

    [ DstColorFactor ]: gl.DST_COLOR,
    [ DstAlphaFactor ]: gl.DST_ALPHA,

    [ OneMinusSrcColorFactor ]: gl.ONE_MINUS_SRC_COLOR,
    [ OneMinusSrcAlphaFactor ]: gl.ONE_MINUS_SRC_ALPHA,
    [ OneMinusDstColorFactor ]: gl.ONE_MINUS_DST_COLOR,
    [ OneMinusDstAlphaFactor ]: gl.ONE_MINUS_DST_ALPHA
};

R

S

,

G

S

,

B

S

,

A

S

R_S, G_S, B_S, A_S

RS?,GS?,BS?,AS?, source of RGBA.

R

D

,

G

D

,

B

D

,

A

D

R_D, G_D, B_D, A_D

RD?,GD?,BD?,AD?, RGBA of destination.

Factor RGB A
Zero

(

0

,

0

,

0

)

(0,0,0)

(0,0,0)

0
One

(

1

,

1

,

1

)

(1,1,1)

(1,1,1)

1
SrcColor

(

R

S

,

G

S

,

B

S

)

(R_S, G_S, B_S)

(RS?,GS?,BS?)

A

S

A_S

AS?

SrcAlpha

(

A

S

,

A

S

,

A

S

)

(A_S, A_S, A_S)

(AS?,AS?,AS?)

A

S

A_S

AS?

SrcAlphaSaturate

(

f

,

f

,

f

)

;

f

=

m

i

n

(

A

S

,

1

?

A

D

)

(f,f,f);f=min(A_S, 1 – A_D)

(f,f,f);f=min(AS?,1?AD?)

1

1

1

DstColor

(

R

D

,

G

D

,

B

D

)

(R_D, G_D, B_D)

(RD?,GD?,BD?)

A

D

{A_D}

AD?

DstAlpha

(

A

D

,

A

D

,

A

D

)

(A_D, A_D, A_D)

(AD?,AD?,AD?)

A

D

{A_D}

AD?

OneMinusSrcColor $(1,1,1) – (R_S, G_S, B_S) $

A

S

A_S

AS?

OneMinusSrcAlpha

(

1

,

1

,

1

)

?

(

A

S

,

A

S

,

A

S

)

(1,1,1) – (A_S, A_S, A_S)

(1,1,1)?(AS?,AS?,AS?)

1

?

A

S

1-A_S

1?AS?

OneMinusDstColor

(

1

,

1

,

1

)

?

(

R

D

,

G

D

,

B

D

)

(1,1,1) – (R_D, G_D, B_D)

(1,1,1)?(RD?,GD?,BD?)

1

?

A

D

1-A_D

1?AD?

OneMinusDstAlpha

(

1

,

1

,

1

)

?

(

A

D

,

A

D

,

A

D

)

(1,1,1) – (A_D, A_D, A_D)

(1,1,1)?(AD?,AD?,AD?)

1

?

A

D

1-A_D

1?AD?

4. live examples

WebGL “port” of this.

gl.blendFunc()
gl.blendFuncSeparate()