@onerjs/smart-filters 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.
- package/license.md +21 -0
- package/package.json +52 -0
- package/readme.md +9 -0
- package/src/IDisposable.ts +9 -0
- package/src/blockFoundation/aggregateBlock.ts +148 -0
- package/src/blockFoundation/baseBlock.ts +339 -0
- package/src/blockFoundation/customAggregateBlock.ts +88 -0
- package/src/blockFoundation/customShaderBlock.ts +362 -0
- package/src/blockFoundation/disableableShaderBlock.ts +91 -0
- package/src/blockFoundation/index.ts +9 -0
- package/src/blockFoundation/inputBlock.deserializer.ts +72 -0
- package/src/blockFoundation/inputBlock.serialization.types.ts +126 -0
- package/src/blockFoundation/inputBlock.serializer.ts +150 -0
- package/src/blockFoundation/inputBlock.ts +181 -0
- package/src/blockFoundation/outputBlock.ts +144 -0
- package/src/blockFoundation/shaderBlock.ts +156 -0
- package/src/blockFoundation/textureOptions.ts +57 -0
- package/src/command/command.ts +59 -0
- package/src/command/commandBuffer.ts +71 -0
- package/src/command/commandBufferDebugger.ts +14 -0
- package/src/command/index.ts +7 -0
- package/src/connection/connectionPoint.ts +205 -0
- package/src/connection/connectionPointCompatibilityState.ts +31 -0
- package/src/connection/connectionPointDirection.ts +9 -0
- package/src/connection/connectionPointType.ts +45 -0
- package/src/connection/connectionPointWithDefault.ts +27 -0
- package/src/connection/index.ts +8 -0
- package/src/editorUtils/editableInPropertyPage.ts +106 -0
- package/src/editorUtils/index.ts +3 -0
- package/src/index.ts +16 -0
- package/src/optimization/dependencyGraph.ts +96 -0
- package/src/optimization/index.ts +1 -0
- package/src/optimization/optimizedShaderBlock.ts +131 -0
- package/src/optimization/smartFilterOptimizer.ts +757 -0
- package/src/runtime/index.ts +8 -0
- package/src/runtime/renderTargetGenerator.ts +222 -0
- package/src/runtime/shaderRuntime.ts +174 -0
- package/src/runtime/smartFilterRuntime.ts +112 -0
- package/src/runtime/strongRef.ts +18 -0
- package/src/serialization/importCustomBlockDefinition.ts +86 -0
- package/src/serialization/index.ts +10 -0
- package/src/serialization/serializedBlockDefinition.ts +12 -0
- package/src/serialization/serializedShaderBlockDefinition.ts +7 -0
- package/src/serialization/serializedSmartFilter.ts +6 -0
- package/src/serialization/smartFilterDeserializer.ts +190 -0
- package/src/serialization/smartFilterSerializer.ts +110 -0
- package/src/serialization/v1/defaultBlockSerializer.ts +21 -0
- package/src/serialization/v1/index.ts +4 -0
- package/src/serialization/v1/shaderBlockSerialization.types.ts +85 -0
- package/src/serialization/v1/smartFilterSerialization.types.ts +129 -0
- package/src/smartFilter.ts +255 -0
- package/src/utils/buildTools/buildShaders.ts +14 -0
- package/src/utils/buildTools/convertGlslIntoBlock.ts +370 -0
- package/src/utils/buildTools/convertGlslIntoShaderProgram.ts +173 -0
- package/src/utils/buildTools/convertShaders.ts +65 -0
- package/src/utils/buildTools/recordVersionNumber.js +24 -0
- package/src/utils/buildTools/shaderCode.types.ts +59 -0
- package/src/utils/buildTools/shaderConverter.ts +466 -0
- package/src/utils/buildTools/watchShaders.ts +44 -0
- package/src/utils/index.ts +4 -0
- package/src/utils/renderTargetUtils.ts +30 -0
- package/src/utils/shaderCodeUtils.ts +192 -0
- package/src/utils/textureLoaders.ts +31 -0
- package/src/utils/textureUtils.ts +28 -0
- package/src/utils/uniqueIdGenerator.ts +28 -0
- package/src/version.ts +4 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { Logger } from "core/Misc/logger.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Implementation of a dependency graph.
|
|
5
|
+
*/
|
|
6
|
+
export class DependencyGraph<T> {
|
|
7
|
+
private _list: Set<T>;
|
|
8
|
+
private _dependOn: Map<T, Set<T>>;
|
|
9
|
+
private _requiredBy: Map<T, Set<T>>;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Creates a new instance of a dependency graph.
|
|
13
|
+
*/
|
|
14
|
+
constructor() {
|
|
15
|
+
this._list = new Set();
|
|
16
|
+
this._dependOn = new Map();
|
|
17
|
+
this._requiredBy = new Map();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Adds an element to the graph.
|
|
22
|
+
* @param element - The element to add to the graph.
|
|
23
|
+
*/
|
|
24
|
+
public addElement(element: T) {
|
|
25
|
+
if (this._list.has(element)) {
|
|
26
|
+
throw new Error(`Element "${element}" already added to the graph!`);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
this._list.add(element);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Adds a dependency between two elements.
|
|
34
|
+
* @param element - The element that depends on another element.
|
|
35
|
+
* @param dependency - The element that is required by the element passed as the first parameter.
|
|
36
|
+
*/
|
|
37
|
+
public addDependency(element: T, dependency: T) {
|
|
38
|
+
if (!this._dependOn.has(element)) {
|
|
39
|
+
this._dependOn.set(element, new Set());
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (!this._requiredBy.has(dependency)) {
|
|
43
|
+
this._requiredBy.set(dependency, new Set());
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
this._dependOn.get(element)!.add(dependency);
|
|
47
|
+
this._requiredBy.get(dependency)!.add(element);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Walks through the graph and calls the callback for each element.
|
|
52
|
+
* The elements that depend on other elements will be traversed after the elements they depend on.
|
|
53
|
+
* Note: the graph will be modified during the walk, so don't call walk twice on the same graph!
|
|
54
|
+
* @param callback - The callback to call for each element.
|
|
55
|
+
*/
|
|
56
|
+
public walk(callback: (element: T) => void) {
|
|
57
|
+
const toVisit: T[] = [];
|
|
58
|
+
|
|
59
|
+
// Collect all elements that have no dependency
|
|
60
|
+
for (const element of this._list) {
|
|
61
|
+
if (!this._dependOn.get(element)) {
|
|
62
|
+
toVisit.push(element);
|
|
63
|
+
this._list.delete(element);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Loop over all elements that have no dependency
|
|
68
|
+
while (toVisit.length > 0) {
|
|
69
|
+
const element = toVisit.shift()!;
|
|
70
|
+
|
|
71
|
+
callback(element);
|
|
72
|
+
|
|
73
|
+
this._list.delete(element);
|
|
74
|
+
|
|
75
|
+
const requiredBy = this._requiredBy.get(element);
|
|
76
|
+
if (requiredBy) {
|
|
77
|
+
for (const dependingElement of requiredBy) {
|
|
78
|
+
const dependencies = this._dependOn.get(dependingElement);
|
|
79
|
+
|
|
80
|
+
if (dependencies) {
|
|
81
|
+
dependencies.delete(element);
|
|
82
|
+
|
|
83
|
+
if (dependencies.size === 0) {
|
|
84
|
+
toVisit.push(dependingElement);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (this._list.size > 0) {
|
|
92
|
+
Logger.Error(JSON.stringify(this._list));
|
|
93
|
+
throw new Error("Circular dependency detected!");
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SmartFilterOptimizer } from "./smartFilterOptimizer.js";
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import type { Effect } from "core/Materials/effect.js";
|
|
2
|
+
import type { Nullable } from "core/types.js";
|
|
3
|
+
|
|
4
|
+
import type { SmartFilter } from "../smartFilter.js";
|
|
5
|
+
import type { ShaderProgram } from "../utils/shaderCodeUtils.js";
|
|
6
|
+
import type { RuntimeData } from "../connection/connectionPoint.js";
|
|
7
|
+
import { ShaderBlock } from "../blockFoundation/shaderBlock.js";
|
|
8
|
+
import { ShaderBinding } from "../runtime/shaderRuntime.js";
|
|
9
|
+
import { ConnectionPointType } from "../connection/connectionPointType.js";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* The shader bindings for the OptimizedShader block.
|
|
13
|
+
* @internal
|
|
14
|
+
*/
|
|
15
|
+
export class OptimizedShaderBinding extends ShaderBinding {
|
|
16
|
+
private _shaderBindings: ShaderBinding[];
|
|
17
|
+
private _inputTextures: { [name: string]: RuntimeData<ConnectionPointType.Texture> };
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Creates a new shader binding instance for the OptimizedShader block.
|
|
21
|
+
* @param shaderBindings - The list of shader bindings to process
|
|
22
|
+
* @param inputTextures - The list of input textures to bind
|
|
23
|
+
*/
|
|
24
|
+
constructor(shaderBindings: ShaderBinding[], inputTextures: { [name: string]: RuntimeData<ConnectionPointType.Texture> }) {
|
|
25
|
+
super();
|
|
26
|
+
|
|
27
|
+
this._shaderBindings = shaderBindings;
|
|
28
|
+
this._inputTextures = inputTextures;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Binds all the required data to the shader when rendering.
|
|
33
|
+
* @param effect - defines the effect to bind the data to
|
|
34
|
+
* @param width - defines the width of the output
|
|
35
|
+
* @param height - defines the height of the output
|
|
36
|
+
*/
|
|
37
|
+
public override bind(effect: Effect, width: number, height: number): void {
|
|
38
|
+
for (const shaderBinding of this._shaderBindings) {
|
|
39
|
+
shaderBinding.bind(effect, width, height);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
for (const name in this._inputTextures) {
|
|
43
|
+
const texture = this._inputTextures[name];
|
|
44
|
+
// texture can't be undefined, so let's add "!" to make Typescript happy
|
|
45
|
+
effect.setTexture(this.getRemappedName(name), texture!.value);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* A block used by the smart filter optimizer to group shader blocks together.
|
|
52
|
+
* Should be for internal use only.
|
|
53
|
+
* @internal
|
|
54
|
+
*/
|
|
55
|
+
export class OptimizedShaderBlock extends ShaderBlock {
|
|
56
|
+
private _shaderBindings: Nullable<ShaderBinding[]>;
|
|
57
|
+
private _inputTextures: { [name: string]: RuntimeData<ConnectionPointType.Texture> } = {};
|
|
58
|
+
private _shaderProgram: ShaderProgram;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* The class name of the block.
|
|
62
|
+
*/
|
|
63
|
+
public static override ClassName = "OptimizedShaderBlock";
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Returns if the block is an input block.
|
|
67
|
+
*/
|
|
68
|
+
public override get isInput(): boolean {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Creates a new OptimizedShaderBlock.
|
|
74
|
+
* @param smartFilter - The smart filter to add the block to
|
|
75
|
+
* @param name - The name of the block
|
|
76
|
+
*/
|
|
77
|
+
constructor(smartFilter: SmartFilter, name: string) {
|
|
78
|
+
super(smartFilter, name, true);
|
|
79
|
+
|
|
80
|
+
this._shaderBindings = null;
|
|
81
|
+
this._shaderProgram = undefined as any;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Gets the shader program to use to render the block.
|
|
86
|
+
* @returns The shader program to use to render the block
|
|
87
|
+
*/
|
|
88
|
+
public override getShaderProgram(): ShaderProgram {
|
|
89
|
+
return this._shaderProgram;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Sets the shader program to use to render the block.
|
|
94
|
+
* @param shaderProgram - The shader program to use to render the block
|
|
95
|
+
*/
|
|
96
|
+
public setShaderProgram(shaderProgram: ShaderProgram): void {
|
|
97
|
+
this._shaderProgram = shaderProgram;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Sets the list of shader bindings to use to render the block.
|
|
102
|
+
* @param shaderBindings - The list of shader bindings to use to render the block
|
|
103
|
+
*/
|
|
104
|
+
public setShaderBindings(shaderBindings: ShaderBinding[]): void {
|
|
105
|
+
this._shaderBindings = shaderBindings;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Get the class instance that binds all the required data to the shader (effect) when rendering.
|
|
110
|
+
* @returns The class instance that binds the data to the effect
|
|
111
|
+
*/
|
|
112
|
+
public getShaderBinding(): ShaderBinding {
|
|
113
|
+
if (this._shaderBindings === null) {
|
|
114
|
+
throw new Error("Shader bindings not set!");
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
for (const input of this.inputs) {
|
|
118
|
+
const name = input.name;
|
|
119
|
+
|
|
120
|
+
if (input.type === ConnectionPointType.Texture) {
|
|
121
|
+
/**
|
|
122
|
+
* These are the inputs created by the OptimizedShaderBlock
|
|
123
|
+
* We pass them to OptimizedShaderBinding so that their value can be set appropriately at runtime (in the bind method)
|
|
124
|
+
*/
|
|
125
|
+
this._inputTextures[name] = input.runtimeData as RuntimeData<ConnectionPointType.Texture>;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return new OptimizedShaderBinding(this._shaderBindings, this._inputTextures);
|
|
130
|
+
}
|
|
131
|
+
}
|