@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,173 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import { Logger } from "core/Misc/logger.js";
|
|
3
|
+
import { ParseFragmentShader, type FragmentShaderInfo } from "./shaderConverter.js";
|
|
4
|
+
|
|
5
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
6
|
+
const TYPE_IMPORT_PATH = "@TYPE_IMPORT_PATH@";
|
|
7
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
8
|
+
const VERTEX_SHADER = "@VERTEX_SHADER@";
|
|
9
|
+
const UNIFORMS = "@UNIFORMS@";
|
|
10
|
+
const CONSTS_VALUE = "@CONSTS@";
|
|
11
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
12
|
+
const CONSTS_PROPERTY = "@CONSTS_PROPERTY@";
|
|
13
|
+
const MAIN_INPUT_NAME = "@MAIN_INPUT_NAME@";
|
|
14
|
+
const MAIN_FUNCTION_NAME = "@MAIN_FUNCTION_NAME@";
|
|
15
|
+
const FUNCTIONS = "@FUNCTIONS@";
|
|
16
|
+
const FUNCTION_NAME = "@FUNCTION_NAME@";
|
|
17
|
+
const FUNCTION_PARAMS = "@FUNCTION_PARAMS@";
|
|
18
|
+
const FUNCTION_CODE = "@FUNCTION_CODE@";
|
|
19
|
+
const UNIFORM_NAMES = "@UNIFORM_NAMES@";
|
|
20
|
+
const EXPORT = "@EXPORT_SHADER_PROGRAM@";
|
|
21
|
+
const IMPORTS = "@IMPORT@";
|
|
22
|
+
|
|
23
|
+
const ConstsTemplate = `
|
|
24
|
+
const: \`${CONSTS_VALUE}\`,`;
|
|
25
|
+
|
|
26
|
+
const FunctionTemplate = `
|
|
27
|
+
{
|
|
28
|
+
name: "${FUNCTION_NAME}",
|
|
29
|
+
code: \`
|
|
30
|
+
${FUNCTION_CODE}
|
|
31
|
+
\`,
|
|
32
|
+
params: "${FUNCTION_PARAMS}",
|
|
33
|
+
},`;
|
|
34
|
+
|
|
35
|
+
const CodeLinePrefix = " ";
|
|
36
|
+
const UniformLinePrefix = " ";
|
|
37
|
+
const ConstLinePrefix = " ";
|
|
38
|
+
|
|
39
|
+
const ImportTemplate = `import type { ShaderProgram } from "${TYPE_IMPORT_PATH}";`;
|
|
40
|
+
const ShaderTemplate = `${IMPORTS}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* The shader program for the block.
|
|
44
|
+
*/
|
|
45
|
+
const BlockShaderProgram: ShaderProgram = {
|
|
46
|
+
vertex: ${VERTEX_SHADER},
|
|
47
|
+
fragment: {
|
|
48
|
+
uniform: \`${UNIFORMS}\`,${CONSTS_PROPERTY}
|
|
49
|
+
mainInputTexture: "${MAIN_INPUT_NAME}",
|
|
50
|
+
mainFunctionName: "${MAIN_FUNCTION_NAME}",
|
|
51
|
+
functions: [${FUNCTIONS}
|
|
52
|
+
],
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* The uniform names for this shader, to be used in the shader binding so
|
|
58
|
+
* that the names are always in sync.
|
|
59
|
+
*/
|
|
60
|
+
const Uniforms = {
|
|
61
|
+
${UNIFORM_NAMES}
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
${EXPORT}`;
|
|
65
|
+
|
|
66
|
+
const UniformNameLinePrefix = " ";
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Converts a single shader to a .ts file which exports a ShaderProgram which can be imported by a hardcoded block
|
|
70
|
+
* @param fragmentShaderPath - The path to the fragment file for the shader
|
|
71
|
+
* @param importPath - The path to import the Smart Filters core from
|
|
72
|
+
*/
|
|
73
|
+
export function ConvertGlslIntoShaderProgram(fragmentShaderPath: string, importPath: string): void {
|
|
74
|
+
const { shaderProgramCode } = ExtractShaderProgramFromGlsl(fragmentShaderPath, importPath, true, true);
|
|
75
|
+
const shaderFile = fragmentShaderPath.replace(".glsl", ".ts");
|
|
76
|
+
fs.writeFileSync(shaderFile, shaderProgramCode);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Extracts the shader program from a glsl file(s) and returns it as a string which can be written to a .ts file
|
|
81
|
+
* @param fragmentShaderPath - The path to the fragment file for the shader
|
|
82
|
+
* @param smartFiltersCorePath - The path to import the Smart Filters core from
|
|
83
|
+
* @param exportObjects - Whether to export the shaderProgram and uniforms objects
|
|
84
|
+
* @param includeImports - Whether to include the imports in the output
|
|
85
|
+
* @returns The string to write to the .ts file
|
|
86
|
+
*/
|
|
87
|
+
export function ExtractShaderProgramFromGlsl(
|
|
88
|
+
fragmentShaderPath: string,
|
|
89
|
+
smartFiltersCorePath: string,
|
|
90
|
+
exportObjects: boolean,
|
|
91
|
+
includeImports: boolean
|
|
92
|
+
): {
|
|
93
|
+
/**
|
|
94
|
+
* The shader program code
|
|
95
|
+
*/
|
|
96
|
+
shaderProgramCode: string;
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* The FragmentShaderInfo
|
|
100
|
+
*/
|
|
101
|
+
fragmentShaderInfo: FragmentShaderInfo;
|
|
102
|
+
} {
|
|
103
|
+
// See if there is a corresponding vertex shader
|
|
104
|
+
let vertexShader: string | undefined = undefined;
|
|
105
|
+
let extensionToFind: string;
|
|
106
|
+
if (fragmentShaderPath.endsWith(".block.glsl")) {
|
|
107
|
+
extensionToFind = ".block.glsl";
|
|
108
|
+
} else if (fragmentShaderPath.endsWith(".fragment.glsl")) {
|
|
109
|
+
extensionToFind = ".fragment.glsl";
|
|
110
|
+
} else {
|
|
111
|
+
throw new Error("The shader file must end with .fragment.glsl or .block.glsl");
|
|
112
|
+
}
|
|
113
|
+
const vertexShaderPath = fragmentShaderPath.replace(extensionToFind, ".vertex.glsl");
|
|
114
|
+
if (fs.existsSync(vertexShaderPath)) {
|
|
115
|
+
vertexShader = fs.readFileSync(vertexShaderPath, "utf8");
|
|
116
|
+
}
|
|
117
|
+
if (vertexShader) {
|
|
118
|
+
Logger.Log("Found vertex shader");
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Read the fragment shader
|
|
122
|
+
const fragmentShader = fs.readFileSync(fragmentShaderPath, "utf8");
|
|
123
|
+
const fragmentShaderInfo = ParseFragmentShader(fragmentShader);
|
|
124
|
+
|
|
125
|
+
// Generate the shader program code
|
|
126
|
+
const functionsSection: string[] = [];
|
|
127
|
+
for (const shaderFunction of fragmentShaderInfo.shaderCode.functions) {
|
|
128
|
+
functionsSection.push(
|
|
129
|
+
FunctionTemplate.replace(FUNCTION_NAME, shaderFunction.name)
|
|
130
|
+
.replace(FUNCTION_PARAMS, shaderFunction.params || "")
|
|
131
|
+
.replace(FUNCTION_CODE, AddLinePrefixes(shaderFunction.code, CodeLinePrefix))
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
const imports = includeImports ? ImportTemplate.replace(TYPE_IMPORT_PATH, smartFiltersCorePath) : "";
|
|
135
|
+
const finalContents = ShaderTemplate.replace(VERTEX_SHADER, vertexShader ? `\`${vertexShader}\`` : "undefined")
|
|
136
|
+
.replace(IMPORTS, imports)
|
|
137
|
+
.replace(UNIFORMS, "\n" + AddLinePrefixes(fragmentShaderInfo.shaderCode.uniform || "", UniformLinePrefix))
|
|
138
|
+
.replace(MAIN_FUNCTION_NAME, fragmentShaderInfo.shaderCode.mainFunctionName)
|
|
139
|
+
.replace(MAIN_INPUT_NAME, fragmentShaderInfo.shaderCode.mainInputTexture || "")
|
|
140
|
+
.replace(
|
|
141
|
+
CONSTS_PROPERTY,
|
|
142
|
+
fragmentShaderInfo.shaderCode.const ? ConstsTemplate.replace(CONSTS_VALUE, AddLinePrefixes(fragmentShaderInfo.shaderCode.const, ConstLinePrefix)) : ""
|
|
143
|
+
)
|
|
144
|
+
.replace(FUNCTIONS, functionsSection.join(""))
|
|
145
|
+
.replace(UNIFORM_NAMES, AddLinePrefixes(fragmentShaderInfo.uniforms.map((u) => `${u.name}: "${u.name}",`).join("\n"), UniformNameLinePrefix))
|
|
146
|
+
.replace(
|
|
147
|
+
new RegExp(EXPORT, "g"),
|
|
148
|
+
exportObjects
|
|
149
|
+
? `export { BlockShaderProgram, Uniforms };
|
|
150
|
+
// Back compat for when camelCase was used
|
|
151
|
+
export { BlockShaderProgram as shaderProgram, Uniforms as uniforms };
|
|
152
|
+
`
|
|
153
|
+
: ""
|
|
154
|
+
);
|
|
155
|
+
|
|
156
|
+
return {
|
|
157
|
+
shaderProgramCode: finalContents,
|
|
158
|
+
fragmentShaderInfo,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Prefixes each line in the input
|
|
164
|
+
* @param input - The input string
|
|
165
|
+
* @param prefix - The prefix to add to each line
|
|
166
|
+
* @returns The input with each line prefixed
|
|
167
|
+
*/
|
|
168
|
+
function AddLinePrefixes(input: string, prefix: string): string {
|
|
169
|
+
return input
|
|
170
|
+
.split("\n")
|
|
171
|
+
.map((line) => prefix + line)
|
|
172
|
+
.join("\n");
|
|
173
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
import { Logger } from "core/Misc/logger.js";
|
|
4
|
+
import { ConvertGlslIntoShaderProgram } from "./convertGlslIntoShaderProgram.js";
|
|
5
|
+
import { ConvertGlslIntoBlock } from "./convertGlslIntoBlock.js";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Converts all GLSL files in a path into blocks for use in the build system.
|
|
9
|
+
* @param shaderPath - The path to the .glsl files to convert, or a single .glsl file.
|
|
10
|
+
* @param smartFiltersCorePath - The path to import the Smart Filters core from.
|
|
11
|
+
* @param babylonCorePath - The path to import the Babylon core from (optional).
|
|
12
|
+
|
|
13
|
+
*/
|
|
14
|
+
export function ConvertShaders(shaderPath: string, smartFiltersCorePath: string, babylonCorePath?: string) {
|
|
15
|
+
const stats = fs.statSync(shaderPath);
|
|
16
|
+
|
|
17
|
+
let shaderFiles: fs.Dirent[];
|
|
18
|
+
|
|
19
|
+
if (stats.isFile()) {
|
|
20
|
+
// If it's a file, create a Dirent-like object for consistency
|
|
21
|
+
const fileName = path.basename(shaderPath);
|
|
22
|
+
const dirPath = path.dirname(shaderPath);
|
|
23
|
+
shaderFiles = [
|
|
24
|
+
{
|
|
25
|
+
name: fileName,
|
|
26
|
+
path: dirPath,
|
|
27
|
+
isFile: () => true,
|
|
28
|
+
isDirectory: () => false,
|
|
29
|
+
} as fs.Dirent,
|
|
30
|
+
];
|
|
31
|
+
} else if (stats.isDirectory()) {
|
|
32
|
+
// Get all files in the directory
|
|
33
|
+
const allFiles = fs.readdirSync(shaderPath, { withFileTypes: true, recursive: true });
|
|
34
|
+
|
|
35
|
+
// Find all shaders (files with .fragment.glsl or .block.glsl extensions)
|
|
36
|
+
shaderFiles = allFiles.filter((file) => file.isFile() && (file.name.endsWith(".fragment.glsl") || file.name.endsWith(".block.glsl")));
|
|
37
|
+
} else {
|
|
38
|
+
Logger.Log(`Error: ${shaderPath} is neither a file nor a directory.`);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Convert all shaders
|
|
43
|
+
for (const shaderFile of shaderFiles) {
|
|
44
|
+
const fullPathAndFileName = path.join(shaderFile.path, shaderFile.name);
|
|
45
|
+
ConvertShader(fullPathAndFileName, smartFiltersCorePath, babylonCorePath);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Converts a single GLSL file into a block class or a ShaderProgram for use in the build system.
|
|
51
|
+
* @param fullPathAndFileName - The full path and file name of the .glsl file to convert.
|
|
52
|
+
* @param smartFiltersCorePath - The path to import the Smart Filters core from.
|
|
53
|
+
* @param babylonCorePath - The path to import the Babylon core from (optional).
|
|
54
|
+
*/
|
|
55
|
+
export function ConvertShader(fullPathAndFileName: string, smartFiltersCorePath: string, babylonCorePath?: string): void {
|
|
56
|
+
Logger.Log(`\nProcessing shader: ${fullPathAndFileName}`);
|
|
57
|
+
|
|
58
|
+
if (fullPathAndFileName.endsWith(".fragment.glsl")) {
|
|
59
|
+
Logger.Log("Generating a .ts file that exports a ShaderProgram.");
|
|
60
|
+
ConvertGlslIntoShaderProgram(fullPathAndFileName, smartFiltersCorePath);
|
|
61
|
+
} else if (fullPathAndFileName.endsWith(".block.glsl")) {
|
|
62
|
+
Logger.Log("Generating a .ts file that exports the block as a class.");
|
|
63
|
+
ConvertGlslIntoBlock(fullPathAndFileName, smartFiltersCorePath, babylonCorePath);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
import * as fs from "fs";
|
|
3
|
+
import * as path from "path";
|
|
4
|
+
|
|
5
|
+
// Get package.json path from command line argument or default to current directory
|
|
6
|
+
const packageJsonDirectory = process.argv[2] || ".";
|
|
7
|
+
const packageJsonFullPath = path.resolve(path.join(packageJsonDirectory, "package.json"));
|
|
8
|
+
|
|
9
|
+
console.log("Reading package.json from:", packageJsonFullPath);
|
|
10
|
+
|
|
11
|
+
const PackageText = fs.readFileSync(packageJsonFullPath);
|
|
12
|
+
const PackageJSON = JSON.parse(PackageText.toString());
|
|
13
|
+
|
|
14
|
+
const PackageName = PackageJSON.name;
|
|
15
|
+
console.log("Processing package:", PackageName);
|
|
16
|
+
console.log("Current package.json version:", PackageJSON.version);
|
|
17
|
+
|
|
18
|
+
// Write out to version.ts
|
|
19
|
+
const VersionTsText = `/**
|
|
20
|
+
* The version of the SmartFilter core. During publish, this file is overwritten by recordVersionNumber.ts with the same version that is used for the NPM publish.
|
|
21
|
+
*/
|
|
22
|
+
export const SmartFilterCoreVersion = "${PackageJSON.version}";\n`;
|
|
23
|
+
fs.writeFileSync("src/version.ts", VersionTsText);
|
|
24
|
+
console.log("Wrote version.ts with version:", PackageJSON.version);
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Describes a shader function.
|
|
3
|
+
*/
|
|
4
|
+
export type ShaderFunction = {
|
|
5
|
+
/**
|
|
6
|
+
* The name of the function.
|
|
7
|
+
*/
|
|
8
|
+
name: string;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* The code of the function.
|
|
12
|
+
*/
|
|
13
|
+
code: string;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* The parameters of the function.
|
|
17
|
+
*/
|
|
18
|
+
params?: string;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Describes a shader code.
|
|
23
|
+
*/
|
|
24
|
+
export type ShaderCode = {
|
|
25
|
+
/**
|
|
26
|
+
* The declaration of the const variables.
|
|
27
|
+
*/
|
|
28
|
+
const?: string;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* The declaration of the uniform variables.
|
|
32
|
+
*/
|
|
33
|
+
uniform?: string;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* The declaration of the uniform variables that should be common for all ShaderBlock instances using this shader code.
|
|
37
|
+
*/
|
|
38
|
+
uniformSingle?: string;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* The name of the main function.
|
|
42
|
+
*/
|
|
43
|
+
mainFunctionName: string;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* The name of the input texture which is passed through if the block is disabled.
|
|
47
|
+
*/
|
|
48
|
+
mainInputTexture?: string;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* The list of functions used in the shader.
|
|
52
|
+
*/
|
|
53
|
+
functions: ShaderFunction[];
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* The declaration of define statements.
|
|
57
|
+
*/
|
|
58
|
+
defines?: string[];
|
|
59
|
+
};
|