Skip to content

Commit

Permalink
feat(shader-ast-stdlib): add porter-duff operators
Browse files Browse the repository at this point in the history
  • Loading branch information
postspectacular committed Jul 29, 2019
1 parent bc17ac9 commit 285197d
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 0 deletions.
21 changes: 21 additions & 0 deletions packages/shader-ast-stdlib/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ This project is part of the
- [Using higher order functions](#using-higher-order-functions)
- [API](#api)
- [Color](#color)
- [Porter-Duff alpha blending](#porter-duff-alpha-blending)
- [Fog](#fog)
- [Lighting](#lighting)
- [Math](#math)
Expand Down Expand Up @@ -286,6 +287,26 @@ TODO. For now, please see doc strings in source for details...
- `toSRGB`
- `luminanceRGB`

### Porter-Duff alpha blending

Use the `porterDuff` higher order function to define new blend modes.
See
[@thi.ng/porter-duff](https://github.com/thi-ng/umbrella/tree/develop/packages/porter-duff)
for reference.

12 standard PD operators for `vec4` RGBA colors:

- `blendSrcOver`
- `blendDestOver`
- `blendSrcIn`
- `blendDestIn`
- `blendSrcOut`
- `blendDestOut`
- `blendSrcAtop`
- `blendDestAtop`
- `blendXor`
- `blendPlus`

### Fog

[/src/fog](https://github.com/thi-ng/umbrella/tree/master/packages/shader-ast-stdlib/src/fog/)
Expand Down
73 changes: 73 additions & 0 deletions packages/shader-ast-stdlib/src/color/porter-duff.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { Fn2 } from "@thi.ng/api";
import {
$w,
add,
defn,
FLOAT0,
FLOAT1,
FloatTerm,
mul,
ret,
sub
} from "@thi.ng/shader-ast";
import { clamp01 } from "../math/clamp";

/**
* Higher-order Porter-Duff alpha compositing operator. See
* thi.ng/porter-duff for reference. Returns an optimized AST function
* which accepts 2 RGBA colors (`vec4`) and returns blended & clamped
* result (also `vec4`). All built-in PD operators are defined via this
* HOF.
*
* The two given JS functions are used to extract blending coefficients
* for src/dest colors and are called with the alpha components of both
* colors.
*
* @param name function name
* @param fa src coeff fn
* @param fb dest coeff fn
*/
export const porterDuff = (
name: string,
fa: Fn2<FloatTerm, FloatTerm, FloatTerm>,
fb: Fn2<FloatTerm, FloatTerm, FloatTerm>
) =>
defn("vec4", name, ["vec4", "vec4"], (a, b) => {
const src =
fa === ZERO ? FLOAT0 : fa === ONE ? a : mul(a, fa($w(a), $w(b)));
const dest =
fb === ZERO ? FLOAT0 : fb === ONE ? b : mul(b, fb($w(a), $w(b)));
return [
ret(
clamp01(
src === FLOAT0
? dest
: dest === FLOAT0
? src
: add(src, dest)
)
)
];
});

// coefficient functions

export const ZERO = () => FLOAT0;
export const ONE = () => FLOAT1;
export const A = (a: FloatTerm) => a;
export const B = (_: FloatTerm, b: FloatTerm) => b;
export const ONE_MINUS_A = (a: FloatTerm) => sub(FLOAT1, a);
export const ONE_MINUS_B = (_: FloatTerm, b: FloatTerm) => sub(FLOAT1, b);

// standard Porter-Duff operators

export const blendSrcOver = porterDuff("blendSrcOver", ONE, ONE_MINUS_A);
export const blendDestOver = porterDuff("blendDestOver", ONE_MINUS_B, ONE);
export const blendSrcIn = porterDuff("blendSrcIn", B, ZERO);
export const blendDestIn = porterDuff("blendDestIn", ZERO, A);
export const blendSrcOut = porterDuff("blendSrcOut", ONE_MINUS_B, ZERO);
export const blendDestOut = porterDuff("blendDestOut", ZERO, ONE_MINUS_A);
export const blendSrcAtop = porterDuff("blendSrcAtop", B, ONE_MINUS_A);
export const blendDestAtop = porterDuff("blendDestAtop", ONE_MINUS_B, A);
export const blendXor = porterDuff("blendXor", ONE_MINUS_B, ONE_MINUS_A);
export const blendPlus = porterDuff("blendPlus", ONE, ONE);
1 change: 1 addition & 0 deletions packages/shader-ast-stdlib/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export * from "./api";

export * from "./color/linear-srgb";
export * from "./color/luminance";
export * from "./color/porter-duff";

export * from "./fog/exp";
export * from "./fog/exp2";
Expand Down

0 comments on commit 285197d

Please sign in to comment.