@onerjs/smart-filters-blocks 8.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/license.md +21 -0
  2. package/package.json +54 -0
  3. package/readme.md +7 -0
  4. package/src/blocks/babylon/demo/effects/blackAndWhiteBlock.block.glsl +18 -0
  5. package/src/blocks/babylon/demo/effects/blackAndWhiteBlock.block.ts +133 -0
  6. package/src/blocks/babylon/demo/effects/blurBlock.deserializer.ts +37 -0
  7. package/src/blocks/babylon/demo/effects/blurBlock.serializer.ts +31 -0
  8. package/src/blocks/babylon/demo/effects/blurBlock.ts +115 -0
  9. package/src/blocks/babylon/demo/effects/compositionBlock.deserializer.ts +31 -0
  10. package/src/blocks/babylon/demo/effects/compositionBlock.fragment.glsl +38 -0
  11. package/src/blocks/babylon/demo/effects/compositionBlock.fragment.ts +74 -0
  12. package/src/blocks/babylon/demo/effects/compositionBlock.serializer.ts +28 -0
  13. package/src/blocks/babylon/demo/effects/compositionBlock.ts +211 -0
  14. package/src/blocks/babylon/demo/effects/contrastBlock.block.glsl +36 -0
  15. package/src/blocks/babylon/demo/effects/contrastBlock.block.ts +178 -0
  16. package/src/blocks/babylon/demo/effects/desaturateBlock.block.glsl +24 -0
  17. package/src/blocks/babylon/demo/effects/desaturateBlock.block.ts +155 -0
  18. package/src/blocks/babylon/demo/effects/directionalBlurBlock.deserializer.ts +43 -0
  19. package/src/blocks/babylon/demo/effects/directionalBlurBlock.serializer.ts +30 -0
  20. package/src/blocks/babylon/demo/effects/directionalBlurBlock.ts +192 -0
  21. package/src/blocks/babylon/demo/effects/exposureBlock.block.glsl +15 -0
  22. package/src/blocks/babylon/demo/effects/exposureBlock.block.ts +142 -0
  23. package/src/blocks/babylon/demo/effects/greenScreenBlock.block.glsl +23 -0
  24. package/src/blocks/babylon/demo/effects/greenScreenBlock.block.ts +174 -0
  25. package/src/blocks/babylon/demo/effects/index.ts +14 -0
  26. package/src/blocks/babylon/demo/effects/kaleidoscopeBlock.ts +188 -0
  27. package/src/blocks/babylon/demo/effects/maskBlock.block.glsl +18 -0
  28. package/src/blocks/babylon/demo/effects/maskBlock.block.ts +145 -0
  29. package/src/blocks/babylon/demo/effects/pixelateBlock.block.glsl +29 -0
  30. package/src/blocks/babylon/demo/effects/pixelateBlock.block.ts +174 -0
  31. package/src/blocks/babylon/demo/effects/posterizeBlock.block.glsl +25 -0
  32. package/src/blocks/babylon/demo/effects/posterizeBlock.block.ts +156 -0
  33. package/src/blocks/babylon/demo/effects/spritesheetBlock.fragment.glsl +26 -0
  34. package/src/blocks/babylon/demo/effects/spritesheetBlock.fragment.ts +63 -0
  35. package/src/blocks/babylon/demo/effects/spritesheetBlock.ts +135 -0
  36. package/src/blocks/babylon/demo/effects/tintBlock.ts +51 -0
  37. package/src/blocks/babylon/demo/transitions/index.ts +1 -0
  38. package/src/blocks/babylon/demo/transitions/wipeBlock.block.glsl +11 -0
  39. package/src/blocks/babylon/demo/transitions/wipeBlock.block.ts +152 -0
  40. package/src/blocks/babylon/demo/utilities/index.ts +1 -0
  41. package/src/blocks/babylon/demo/utilities/premultiplyAlphaBlock.block.glsl +14 -0
  42. package/src/blocks/babylon/demo/utilities/premultiplyAlphaBlock.block.ts +129 -0
  43. package/src/blocks/blockNamespaces.ts +6 -0
  44. package/src/blocks/blockTypes.ts +23 -0
  45. package/src/blocks/index.ts +6 -0
  46. package/src/index.ts +3 -0
  47. package/src/registration/IBlockRegistration.ts +43 -0
  48. package/src/registration/blockSerializers.ts +50 -0
  49. package/src/registration/builtInBlockRegistrations.ts +293 -0
  50. package/src/registration/index.ts +4 -0
package/license.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Babylon.js
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "@onerjs/smart-filters-blocks",
3
+ "version": "8.25.0",
4
+ "description": "Babylon.js Smart Filter Block Library",
5
+ "keywords": [
6
+ "video",
7
+ "composition",
8
+ "3D",
9
+ "2D",
10
+ "javascript",
11
+ "html5",
12
+ "webgl",
13
+ "webgl2",
14
+ "webgpu",
15
+ "babylon"
16
+ ],
17
+ "license": "MIT",
18
+ "readme": "README.md",
19
+ "main": "dist/index",
20
+ "module": "dist/index",
21
+ "esnext": "dist/index",
22
+ "types": "dist/index",
23
+ "type": "module",
24
+ "sideEffects": false,
25
+ "repository": {
26
+ "type": "git",
27
+ "url": "git+https://github.com/BabylonJS/Babylon.js.git"
28
+ },
29
+ "files": [
30
+ "dist",
31
+ "src",
32
+ "license.md",
33
+ "readme.md"
34
+ ],
35
+ "scripts": {
36
+ "build": "npm run clean && npm run copySrc && npm run compile",
37
+ "clean": "rimraf dist && rimraf src && rimraf *.tsbuildinfo -g && rimraf \"./**/*.!(cmd|md|json|build.json|lts.json|tasks.json|cjs)\" -g",
38
+ "copySrc": "node -e \"require('fs').cpSync('../../../dev/smartFilterBlocks/src', './src', { recursive: true })\"",
39
+ "precompile": "tsx ../../../dev/smartFilters/src/utils/buildTools/buildShaders.ts ./src/blocks smart-filters core",
40
+ "compile": "tsc -b tsconfig.build.json",
41
+ "postcompile": "build-tools -c add-js-to-es6"
42
+ },
43
+ "devDependencies": {
44
+ "@dev/build-tools": "^1.0.0",
45
+ "@dev/core": "1.0.0",
46
+ "@dev/smart-filters": "1.0.0"
47
+ },
48
+ "peerDependencies": {
49
+ "@onerjs/core": "^7.47.3 || ^8.0.1"
50
+ },
51
+ "dependencies": {
52
+ "@onerjs/smart-filters": "^8.25.0"
53
+ }
54
+ }
package/readme.md ADDED
@@ -0,0 +1,7 @@
1
+ # Babylon.js Smart Filters
2
+
3
+ ## Blocks
4
+
5
+ This package contains a library of blocks for use with Babylon Smart Filters (see @babylonjs/smart-filters).
6
+
7
+ See the full documentation at [doc.babylonjs.com](https://doc.babylonjs.com/features/featuresDeepDive/smartFilters/)
@@ -0,0 +1,18 @@
1
+ /*
2
+ {
3
+ "smartFilterBlockType": "BlackAndWhiteBlock",
4
+ "namespace": "Babylon.Demo.Effects",
5
+ "blockDisableStrategy": "AutoSample"
6
+ }
7
+ */
8
+
9
+ uniform sampler2D input; // main
10
+
11
+ vec4 blackAndWhite(vec2 vUV) { // main
12
+ vec4 color = texture2D(input, vUV);
13
+
14
+ float luminance = dot(color.rgb, vec3(0.3, 0.59, 0.11));
15
+ vec3 bg = vec3(luminance, luminance, luminance);
16
+
17
+ return vec4(bg, color.a);
18
+ }
@@ -0,0 +1,133 @@
1
+ /* eslint-disable prettier/prettier */
2
+ // ************************************************************
3
+ // Note: this file is auto-generated, do not modify it directly
4
+ // ************************************************************
5
+
6
+ // It was generated by convertGlslIntoBlock() from
7
+ // an annotated .glsl file. Modify the .glsl file to make changes
8
+ // to the block. This file will get overwritten when the build
9
+ // is run or during a watch when the .glsl file is updated.
10
+
11
+ import type { Effect } from "core/Materials/effect.js";
12
+
13
+ import {
14
+ DisableableShaderBinding,
15
+ type RuntimeData,
16
+ ConnectionPointType,
17
+ type SmartFilter,
18
+ DisableableShaderBlock,
19
+ type ShaderProgram,
20
+ type IDisableableBlock,
21
+ BlockDisableStrategy} from "smart-filters";
22
+
23
+ /**
24
+ * The shader program for the block.
25
+ */
26
+ const BlockShaderProgram: ShaderProgram = {
27
+ vertex: undefined,
28
+ fragment: {
29
+ uniform: `
30
+ uniform sampler2D _input_; // main`,
31
+ mainInputTexture: "_input_",
32
+ mainFunctionName: "_blackAndWhite_",
33
+ functions: [
34
+ {
35
+ name: "_blackAndWhite_",
36
+ code: `
37
+ vec4 _blackAndWhite_(vec2 vUV) {
38
+ vec4 color = texture2D(_input_, vUV);
39
+
40
+ float luminance = dot(color.rgb, vec3(0.3, 0.59, 0.11));
41
+ vec3 bg = vec3(luminance, luminance, luminance);
42
+
43
+ return vec4(bg, color.a);
44
+ }
45
+ `,
46
+ params: "vec2 vUV",
47
+ },
48
+ ],
49
+ },
50
+ };
51
+
52
+ /**
53
+ * The uniform names for this shader, to be used in the shader binding so
54
+ * that the names are always in sync.
55
+ */
56
+ const Uniforms = {
57
+ input: "input",
58
+ };
59
+
60
+
61
+ /**
62
+ * The shader binding for the BlackAndWhiteBlock, used by the runtime
63
+ */
64
+ class BlackAndWhiteBlockShaderBinding extends DisableableShaderBinding {
65
+ private readonly _input: RuntimeData<ConnectionPointType.Texture>;
66
+
67
+ /**
68
+ * Creates a new shader binding instance for the block.
69
+ * @param parentBlock - IDisableableBlock
70
+ * @param input - The input runtime value
71
+ */
72
+ constructor(
73
+ parentBlock: IDisableableBlock,
74
+ input: RuntimeData<ConnectionPointType.Texture>
75
+ ) {
76
+ super(parentBlock);
77
+ this._input = input;
78
+ }
79
+
80
+ /**
81
+ * Binds all the required data to the shader when rendering.
82
+ * @param effect - defines the effect to bind the data to
83
+ */
84
+ public override bind(effect: Effect): void {
85
+ super.bind(effect);
86
+ effect.setTexture(this.getRemappedName(Uniforms.input), this._input.value);
87
+ }
88
+ }
89
+
90
+ /**
91
+ * The implementation of the BlackAndWhiteBlock
92
+ */
93
+ export class BlackAndWhiteBlock extends DisableableShaderBlock {
94
+ /**
95
+ * The class name of the block.
96
+ */
97
+ public static override ClassName = "BlackAndWhiteBlock";
98
+
99
+ /**
100
+ * The namespace of the block.
101
+ */
102
+ public static override Namespace = "Babylon.Demo.Effects";
103
+
104
+ /**
105
+ * The input connection point.
106
+ */
107
+ public readonly input = this._registerInput(Uniforms.input, ConnectionPointType.Texture);
108
+
109
+ /**
110
+ * The shader program (vertex and fragment code) to use to render the block
111
+ */
112
+ public static override ShaderCode = BlockShaderProgram;
113
+
114
+ /**
115
+ * Instantiates a new BlackAndWhiteBlock.
116
+ * @param smartFilter - The smart filter this block belongs to
117
+ * @param name - The friendly name of the block
118
+ */
119
+ constructor(smartFilter: SmartFilter, name: string) {
120
+ super(smartFilter, name, false, BlockDisableStrategy.AutoSample);
121
+ }
122
+
123
+ /**
124
+ * Get the class instance that binds all the required data to the shader (effect) when rendering.
125
+ * @returns The class instance that binds the data to the effect
126
+ */
127
+ public getShaderBinding(): DisableableShaderBinding {
128
+ const input = this._confirmRuntimeDataSupplied(this.input);
129
+
130
+ return new BlackAndWhiteBlockShaderBinding(this,input);
131
+ }
132
+ }
133
+
@@ -0,0 +1,37 @@
1
+ import { type SmartFilter, type ISerializedBlockV1 } from "smart-filters";
2
+ import { BlurBlock } from "./blurBlock.js";
3
+
4
+ /**
5
+ * The definition of the extra data serialized for blur blocks.
6
+ */
7
+ export interface ISerializedBlurBlockV1 extends ISerializedBlockV1 {
8
+ /**
9
+ * The extra data of the block.
10
+ */
11
+ data: {
12
+ /**
13
+ * The blur texture ratio per pass.
14
+ */
15
+ blurTextureRatioPerPass: number;
16
+
17
+ /**
18
+ * The size of the blur.
19
+ */
20
+ blurSize: number;
21
+ };
22
+ }
23
+
24
+ /**
25
+ * V1 Blur Deserializer.
26
+ * @param smartFilter - The SmartFilter to deserialize the block into
27
+ * @param serializedBlock - The serialized block data
28
+ * @returns A deserialized BlurBlock
29
+ */
30
+ export function BlurBlockDeserializer(smartFilter: SmartFilter, serializedBlock: ISerializedBlurBlockV1) {
31
+ const block = new BlurBlock(smartFilter, serializedBlock.name);
32
+
33
+ // If data is missing, use the default value set by the block
34
+ block.blurTextureRatioPerPass = serializedBlock.data.blurTextureRatioPerPass ?? block.blurSize;
35
+ block.blurSize = serializedBlock.data.blurSize ?? block.blurSize;
36
+ return block;
37
+ }
@@ -0,0 +1,31 @@
1
+ import type { BaseBlock, IBlockSerializerV1 } from "smart-filters";
2
+ import type { BlurBlock } from "./blurBlock.js";
3
+ import { blurBlockType } from "../../../blockTypes.js";
4
+ import { babylonDemoEffectsNamespace } from "../../../blockNamespaces.js";
5
+
6
+ /**
7
+ * The V1 serializer for a Blur Block.
8
+ * Though it is an aggregate block, Blur creates and manages its own blocks
9
+ * internally, so there's no need to worry about serializing them.
10
+ */
11
+ export const BlurBlockSerializer: IBlockSerializerV1 = {
12
+ blockType: blurBlockType,
13
+ serialize: (block: BaseBlock) => {
14
+ if (block.getClassName() !== blurBlockType) {
15
+ throw new Error("Was asked to serialize an unrecognized block type");
16
+ }
17
+
18
+ const blurBlock = block as unknown as BlurBlock;
19
+ return {
20
+ name: block.name,
21
+ uniqueId: block.uniqueId,
22
+ blockType: blurBlockType,
23
+ namespace: babylonDemoEffectsNamespace,
24
+ comments: block.comments,
25
+ data: {
26
+ blurTextureRatioPerPass: blurBlock.blurTextureRatioPerPass,
27
+ blurSize: blurBlock.blurSize,
28
+ },
29
+ };
30
+ },
31
+ };
@@ -0,0 +1,115 @@
1
+ import { type ConnectionPointType, AggregateBlock, type ConnectionPoint, editableInPropertyPage, PropertyTypeForEdition, SmartFilter } from "smart-filters";
2
+ import { DirectionalBlurBlock } from "./directionalBlurBlock.js";
3
+ import { blurBlockType } from "../../../blockTypes.js";
4
+ import { babylonDemoEffectsNamespace } from "../../../blockNamespaces.js";
5
+
6
+ const DefaultBlurTextureRatioPerPass = 0.5;
7
+ const DefaultBlurSize = 2;
8
+
9
+ /**
10
+ * A block performing a blur on the input texture.
11
+ *
12
+ * It performs the blur in 4 consecutive passes, 2 verticals and 2 horizontals downsizing the texture as we go.
13
+ */
14
+ export class BlurBlock extends AggregateBlock {
15
+ /**
16
+ * The class name of the block.
17
+ */
18
+ public static override ClassName = blurBlockType;
19
+
20
+ /**
21
+ * The namespace of the block.
22
+ */
23
+ public static override Namespace = babylonDemoEffectsNamespace;
24
+
25
+ /**
26
+ * The input texture connection point.
27
+ */
28
+ public readonly input: ConnectionPoint<ConnectionPointType.Texture>;
29
+
30
+ /**
31
+ * The output blurred texture connection point.
32
+ */
33
+ public readonly output: ConnectionPoint<ConnectionPointType.Texture>;
34
+
35
+ private _blurTextureRatioPerPass = DefaultBlurTextureRatioPerPass;
36
+ private _blurSize = DefaultBlurSize;
37
+
38
+ private readonly _intermediateBlurV: DirectionalBlurBlock;
39
+ private readonly _intermediateBlurH: DirectionalBlurBlock;
40
+ private readonly _finalBlurV: DirectionalBlurBlock;
41
+ private readonly _finalBlurH: DirectionalBlurBlock;
42
+
43
+ /**
44
+ * Gets how much smaller we should make the texture between the 2 consecutive bi lateral passes.
45
+ */
46
+ public get blurTextureRatioPerPass(): number {
47
+ return this._blurTextureRatioPerPass;
48
+ }
49
+
50
+ /**
51
+ * Sets how much smaller we should make the texture between the 2 consecutive bi lateral passes.
52
+ */
53
+ @editableInPropertyPage("Pass Texture Ratio", PropertyTypeForEdition.Float, "PROPERTIES", {
54
+ min: 0,
55
+ max: 1,
56
+ notifiers: { rebuild: true },
57
+ })
58
+ public set blurTextureRatioPerPass(value: number) {
59
+ this._blurTextureRatioPerPass = value;
60
+ this._intermediateBlurV.blurTextureRatio = value;
61
+ this._intermediateBlurH.blurTextureRatio = value;
62
+ this._finalBlurV.blurTextureRatio = value * value;
63
+ this._finalBlurH.blurTextureRatio = value * value;
64
+ }
65
+
66
+ /**
67
+ * Gets how far the kernel might fetch the data from.
68
+ */
69
+ public get blurSize(): number {
70
+ return this._blurSize;
71
+ }
72
+
73
+ /**
74
+ * Sets how far the kernel might fetch the data from.
75
+ */
76
+ @editableInPropertyPage("Size", PropertyTypeForEdition.Float, "PROPERTIES", {
77
+ notifiers: { rebuild: true },
78
+ })
79
+ public set blurSize(value: number) {
80
+ this._blurSize = value;
81
+ this._intermediateBlurV.blurHorizontalWidth = value;
82
+ this._intermediateBlurH.blurVerticalWidth = value;
83
+ this._finalBlurV.blurHorizontalWidth = value;
84
+ this._finalBlurH.blurVerticalWidth = value;
85
+ }
86
+
87
+ /**
88
+ * Instantiates a new Block.
89
+ * @param smartFilter - The smart filter this block belongs to
90
+ * @param name - The friendly name of the block
91
+ */
92
+ constructor(smartFilter: SmartFilter, name: string) {
93
+ super(smartFilter, name);
94
+
95
+ const internalFilter = new SmartFilter(name + "_BlurBlock_Aggregated");
96
+ this._intermediateBlurV = new DirectionalBlurBlock(internalFilter, name + "IV");
97
+ this._intermediateBlurH = new DirectionalBlurBlock(internalFilter, name + "IH");
98
+ this._finalBlurV = new DirectionalBlurBlock(internalFilter, name + "V");
99
+ this._finalBlurH = new DirectionalBlurBlock(internalFilter, name + "H");
100
+
101
+ this._intermediateBlurV.output.connectTo(this._intermediateBlurH.input);
102
+ this._intermediateBlurH.output.connectTo(this._finalBlurV.input);
103
+ this._finalBlurV.output.connectTo(this._finalBlurH.input);
104
+
105
+ this.input = this._registerSubfilterInput("input", [this._intermediateBlurV.input]);
106
+ this.output = this._registerSubfilterOutput("output", this._finalBlurH.output);
107
+
108
+ this.blurSize = DefaultBlurSize;
109
+ this.blurTextureRatioPerPass = DefaultBlurTextureRatioPerPass;
110
+ this._intermediateBlurV.blurVerticalWidth = 0;
111
+ this._intermediateBlurH.blurHorizontalWidth = 0;
112
+ this._finalBlurV.blurVerticalWidth = 0;
113
+ this._finalBlurH.blurHorizontalWidth = 0;
114
+ }
115
+ }
@@ -0,0 +1,31 @@
1
+ import type { ISerializedBlockV1, SmartFilter } from "smart-filters";
2
+ import { CompositionBlock } from "./compositionBlock.js";
3
+
4
+ /**
5
+ * The definition of the extra data serialized for composition blocks.
6
+ */
7
+ export interface ISerializedCompositionBlockV1 extends ISerializedBlockV1 {
8
+ /**
9
+ * The extra data of the block.
10
+ */
11
+ data: {
12
+ /**
13
+ * The alpha mode of the composition.
14
+ */
15
+ alphaMode: number;
16
+ };
17
+ }
18
+
19
+ /**
20
+ * V1 Composition Deserializer.
21
+ * @param smartFilter - The SmartFilter to deserialize the block into
22
+ * @param serializedBlock - The serialized block data
23
+ * @returns A deserialized CompositionBlock
24
+ */
25
+ export function CompositionDeserializer(smartFilter: SmartFilter, serializedBlock: ISerializedCompositionBlockV1) {
26
+ const block = new CompositionBlock(smartFilter, serializedBlock.name);
27
+
28
+ // If data is missing, use the default value set by the block
29
+ block.alphaMode = serializedBlock.data.alphaMode ?? block.alphaMode;
30
+ return block;
31
+ }
@@ -0,0 +1,38 @@
1
+ uniform sampler2D background; // main
2
+ uniform sampler2D foreground;
3
+
4
+ uniform vec2 scaleUV;
5
+ uniform vec2 translateUV;
6
+ uniform float alphaMode;
7
+ uniform float foregroundAlphaScale;
8
+
9
+ vec4 composition(vec2 vUV) { // main
10
+ vec4 background = texture2D(background, vUV);
11
+
12
+ vec2 transformedUV = vUV * (1.0 / scaleUV) + translateUV;
13
+ if (transformedUV.x < 0.0 || transformedUV.x > 1.0 || transformedUV.y < 0.0 || transformedUV.y > 1.0) {
14
+ return background;
15
+ }
16
+
17
+ vec4 foreground = texture2D(foreground, transformedUV);
18
+ foreground.a *= foregroundAlphaScale;
19
+
20
+ // SRC is foreground, DEST is background
21
+ if (alphaMode == 0.) {
22
+ return foreground;
23
+ }
24
+ else if (alphaMode == 1.) {
25
+ return foreground.a * foreground + background;
26
+ }
27
+ else if (alphaMode == 2.) {
28
+ return mix(background, foreground, foreground.a);
29
+ }
30
+ else if (alphaMode == 3.) {
31
+ return background - foreground * background;
32
+ }
33
+ else if (alphaMode == 4.) {
34
+ return foreground * background;
35
+ }
36
+
37
+ return background;
38
+ }
@@ -0,0 +1,74 @@
1
+ import type { ShaderProgram } from "smart-filters";
2
+
3
+ /**
4
+ * The shader program for the block.
5
+ */
6
+ const BlockShaderProgram: ShaderProgram = {
7
+ vertex: undefined,
8
+ fragment: {
9
+ uniform: `
10
+ uniform sampler2D _background_; // main
11
+ uniform sampler2D _foreground_;
12
+ uniform vec2 _scaleUV_;
13
+ uniform vec2 _translateUV_;
14
+ uniform float _alphaMode_;
15
+ uniform float _foregroundAlphaScale_;`,
16
+ mainInputTexture: "_background_",
17
+ mainFunctionName: "_composition_",
18
+ functions: [
19
+ {
20
+ name: "_composition_",
21
+ code: `
22
+ vec4 _composition_(vec2 vUV) {
23
+ vec4 _background_ = texture2D(_background_, vUV);
24
+
25
+ vec2 transformedUV = vUV * (1.0 / _scaleUV_) + _translateUV_;
26
+ if (transformedUV.x < 0.0 || transformedUV.x > 1.0 || transformedUV.y < 0.0 || transformedUV.y > 1.0) {
27
+ return _background_;
28
+ }
29
+
30
+ vec4 _foreground_ = texture2D(_foreground_, transformedUV);
31
+ _foreground_.a *= _foregroundAlphaScale_;
32
+
33
+ // SRC is _foreground_, DEST is _background_
34
+ if (_alphaMode_ == 0.) {
35
+ return _foreground_;
36
+ }
37
+ else if (_alphaMode_ == 1.) {
38
+ return _foreground_.a * _foreground_ + _background_;
39
+ }
40
+ else if (_alphaMode_ == 2.) {
41
+ return mix(_background_, _foreground_, _foreground_.a);
42
+ }
43
+ else if (_alphaMode_ == 3.) {
44
+ return _background_ - _foreground_ * _background_;
45
+ }
46
+ else if (_alphaMode_ == 4.) {
47
+ return _foreground_ * _background_;
48
+ }
49
+
50
+ return _background_;
51
+ }
52
+ `,
53
+ params: "vec2 vUV",
54
+ },
55
+ ],
56
+ },
57
+ };
58
+
59
+ /**
60
+ * The uniform names for this shader, to be used in the shader binding so
61
+ * that the names are always in sync.
62
+ */
63
+ const Uniforms = {
64
+ background: "background",
65
+ foreground: "foreground",
66
+ scaleUV: "scaleUV",
67
+ translateUV: "translateUV",
68
+ alphaMode: "alphaMode",
69
+ foregroundAlphaScale: "foregroundAlphaScale",
70
+ };
71
+
72
+ export { BlockShaderProgram, Uniforms };
73
+ // Back compat for when camelCase was used
74
+ export { BlockShaderProgram as shaderProgram, Uniforms as uniforms };
@@ -0,0 +1,28 @@
1
+ import type { CompositionBlock } from "./compositionBlock.js";
2
+ import { compositionBlockType } from "../../../blockTypes.js";
3
+ import { babylonDemoEffectsNamespace } from "../../../blockNamespaces.js";
4
+ import type { IBlockSerializerV1, BaseBlock } from "smart-filters";
5
+
6
+ /**
7
+ * The V1 serializer for a Composition Block
8
+ */
9
+ export const CompositionBlockSerializer: IBlockSerializerV1 = {
10
+ blockType: compositionBlockType,
11
+ serialize: (block: BaseBlock) => {
12
+ if (block.getClassName() !== compositionBlockType) {
13
+ throw new Error("Was asked to serialize an unrecognized block type");
14
+ }
15
+
16
+ const compositionBlock = block as unknown as CompositionBlock;
17
+ return {
18
+ name: block.name,
19
+ uniqueId: block.uniqueId,
20
+ blockType: compositionBlockType,
21
+ namespace: babylonDemoEffectsNamespace,
22
+ comments: block.comments,
23
+ data: {
24
+ alphaMode: compositionBlock.alphaMode,
25
+ },
26
+ };
27
+ },
28
+ };