@luma.gl/shaders 10.0.0-alpha.8 → 10.0.0-alpha.9
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/dist/dist.dev.js +189 -268
- package/dist/dist.min.js +119 -119
- package/dist/glsl.cjs.map +2 -2
- package/dist/index.cjs.map +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/shader-assembler-base.cjs +3 -4
- package/dist/lib/shader-assembler-base.d.ts +4 -5
- package/dist/lib/shader-assembler-base.d.ts.map +1 -1
- package/dist/lib/shader-assembler-base.js +3 -4
- package/dist/lib/shader-assembler-base.js.map +1 -1
- package/dist/lib/shader-assembly/assemble-glsl-shaders.cjs +5 -16
- package/dist/lib/shader-assembly/assemble-glsl-shaders.d.ts +4 -4
- package/dist/lib/shader-assembly/assemble-glsl-shaders.d.ts.map +1 -1
- package/dist/lib/shader-assembly/assemble-glsl-shaders.js +13 -18
- package/dist/lib/shader-assembly/assemble-glsl-shaders.js.map +1 -1
- package/dist/lib/shader-assembly/assemble-wgsl-shaders.cjs +5 -24
- package/dist/lib/shader-assembly/assemble-wgsl-shaders.d.ts +5 -6
- package/dist/lib/shader-assembly/assemble-wgsl-shaders.d.ts.map +1 -1
- package/dist/lib/shader-assembly/assemble-wgsl-shaders.js +13 -26
- package/dist/lib/shader-assembly/assemble-wgsl-shaders.js.map +1 -1
- package/dist/lib/shader-assembly/shader-assembly-shared.d.ts +2 -2
- package/dist/lib/shader-assembly/shader-assembly-shared.d.ts.map +1 -1
- package/dist/lib/shader-assembly/shader-assembly-shared.js.map +1 -1
- package/dist/lib/shader-assembly/shader-assembly-types.d.ts +7 -7
- package/dist/lib/shader-assembly/shader-assembly-types.d.ts.map +1 -1
- package/dist/lib/shader-assembly/shader-hooks.cjs +17 -36
- package/dist/lib/shader-assembly/shader-hooks.d.ts +34 -32
- package/dist/lib/shader-assembly/shader-hooks.d.ts.map +1 -1
- package/dist/lib/shader-assembly/shader-hooks.js +20 -44
- package/dist/lib/shader-assembly/shader-hooks.js.map +1 -1
- package/dist/lib/shader-assembly/shader-injections.cjs +26 -2
- package/dist/lib/shader-assembly/shader-injections.d.ts +20 -7
- package/dist/lib/shader-assembly/shader-injections.d.ts.map +1 -1
- package/dist/lib/shader-assembly/shader-injections.js +24 -0
- package/dist/lib/shader-assembly/shader-injections.js.map +1 -1
- package/dist/lib/shader-module/shader-module.cjs +3 -9
- package/dist/lib/shader-module/shader-module.d.ts +4 -8
- package/dist/lib/shader-module/shader-module.d.ts.map +1 -1
- package/dist/lib/shader-module/shader-module.js +3 -6
- package/dist/lib/shader-module/shader-module.js.map +1 -1
- package/dist/lib/shader-plugin.cjs +13 -38
- package/dist/lib/shader-plugin.d.ts +5 -30
- package/dist/lib/shader-plugin.d.ts.map +1 -1
- package/dist/lib/shader-plugin.js +17 -40
- package/dist/lib/shader-plugin.js.map +1 -1
- package/dist/wgsl.cjs.map +2 -2
- package/package.json +2 -2
- package/src/index.ts +5 -6
- package/src/lib/shader-assembler-base.ts +5 -6
- package/src/lib/shader-assembly/assemble-glsl-shaders.ts +25 -25
- package/src/lib/shader-assembly/assemble-wgsl-shaders.ts +27 -42
- package/src/lib/shader-assembly/shader-assembly-shared.ts +5 -5
- package/src/lib/shader-assembly/shader-assembly-types.ts +7 -7
- package/src/lib/shader-assembly/shader-hooks.ts +55 -82
- package/src/lib/shader-assembly/shader-injections.ts +52 -8
- package/src/lib/shader-module/shader-module.ts +7 -14
- package/src/lib/shader-plugin.ts +31 -90
package/dist/dist.dev.js
CHANGED
|
@@ -864,6 +864,129 @@ var __exports__ = (() => {
|
|
|
864
864
|
return typeof value;
|
|
865
865
|
}
|
|
866
866
|
|
|
867
|
+
// src/lib/shader-module/shader-module.ts
|
|
868
|
+
function initializeShaderModules(modules) {
|
|
869
|
+
modules.map((module) => initializeShaderModule(module));
|
|
870
|
+
}
|
|
871
|
+
function initializeShaderModule(module) {
|
|
872
|
+
if (module.instance) {
|
|
873
|
+
return;
|
|
874
|
+
}
|
|
875
|
+
initializeShaderModules(module.dependencies || []);
|
|
876
|
+
const { propTypes = {}, deprecations = [] } = module;
|
|
877
|
+
const instance = {
|
|
878
|
+
parsedDeprecations: parseDeprecationDefinitions(deprecations),
|
|
879
|
+
normalizedInjections: { vertex: {}, fragment: {} }
|
|
880
|
+
};
|
|
881
|
+
if (propTypes) {
|
|
882
|
+
instance.propValidators = makePropValidators(propTypes);
|
|
883
|
+
}
|
|
884
|
+
module.instance = instance;
|
|
885
|
+
let defaultProps = {};
|
|
886
|
+
if (propTypes) {
|
|
887
|
+
defaultProps = Object.entries(propTypes).reduce(
|
|
888
|
+
(obj, [key, propType]) => {
|
|
889
|
+
const value = propType?.value;
|
|
890
|
+
if (value) {
|
|
891
|
+
obj[key] = value;
|
|
892
|
+
}
|
|
893
|
+
return obj;
|
|
894
|
+
},
|
|
895
|
+
{}
|
|
896
|
+
);
|
|
897
|
+
}
|
|
898
|
+
module.defaultUniforms = {
|
|
899
|
+
...module.defaultUniforms,
|
|
900
|
+
...defaultProps
|
|
901
|
+
};
|
|
902
|
+
}
|
|
903
|
+
function getShaderModuleUniforms(module, props, oldUniforms) {
|
|
904
|
+
initializeShaderModule(module);
|
|
905
|
+
const uniforms2 = oldUniforms || { ...module.defaultUniforms };
|
|
906
|
+
if (props && module.getUniforms) {
|
|
907
|
+
return module.getUniforms(props, uniforms2);
|
|
908
|
+
}
|
|
909
|
+
return getValidatedProperties(props, module.instance?.propValidators, module.name);
|
|
910
|
+
}
|
|
911
|
+
function checkShaderModuleDeprecations(shaderModule, shaderSource, log) {
|
|
912
|
+
shaderModule.deprecations?.forEach((def) => {
|
|
913
|
+
if (def.regex?.test(shaderSource)) {
|
|
914
|
+
if (def.deprecated) {
|
|
915
|
+
log.deprecated(def.old, def.new)();
|
|
916
|
+
} else {
|
|
917
|
+
log.removed(def.old, def.new)();
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
});
|
|
921
|
+
}
|
|
922
|
+
function parseDeprecationDefinitions(deprecations) {
|
|
923
|
+
deprecations.forEach((def) => {
|
|
924
|
+
switch (def.type) {
|
|
925
|
+
case "function":
|
|
926
|
+
def.regex = new RegExp(`\\b${def.old}\\(`);
|
|
927
|
+
break;
|
|
928
|
+
default:
|
|
929
|
+
def.regex = new RegExp(`${def.type} ${def.old};`);
|
|
930
|
+
}
|
|
931
|
+
});
|
|
932
|
+
return deprecations;
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
// src/lib/shader-module/shader-module-dependencies.ts
|
|
936
|
+
function getShaderModuleDependencies(modules) {
|
|
937
|
+
const visited = /* @__PURE__ */ new Set();
|
|
938
|
+
const recursionStack = /* @__PURE__ */ new Set();
|
|
939
|
+
const result = [];
|
|
940
|
+
const nameToModule = /* @__PURE__ */ new Map();
|
|
941
|
+
function checkNameCollision(module) {
|
|
942
|
+
const existing = nameToModule.get(module.name);
|
|
943
|
+
if (existing && existing !== module) {
|
|
944
|
+
throw new Error(
|
|
945
|
+
`Shader module name collision: Multiple different module objects share the name "${module.name}". Each module object must have a unique name.`
|
|
946
|
+
);
|
|
947
|
+
}
|
|
948
|
+
nameToModule.set(module.name, module);
|
|
949
|
+
}
|
|
950
|
+
function visit(module, path) {
|
|
951
|
+
if (recursionStack.has(module)) {
|
|
952
|
+
const cyclePath = [...path, module.name].join(" -> ");
|
|
953
|
+
throw new Error(`Shader module dependency cycle detected: ${cyclePath}`);
|
|
954
|
+
}
|
|
955
|
+
if (visited.has(module)) {
|
|
956
|
+
return;
|
|
957
|
+
}
|
|
958
|
+
checkNameCollision(module);
|
|
959
|
+
recursionStack.add(module);
|
|
960
|
+
const newPath = [...path, module.name];
|
|
961
|
+
if (module.dependencies) {
|
|
962
|
+
for (const dep of module.dependencies) {
|
|
963
|
+
visit(dep, newPath);
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
recursionStack.delete(module);
|
|
967
|
+
visited.add(module);
|
|
968
|
+
result.push(module);
|
|
969
|
+
}
|
|
970
|
+
for (const module of modules) {
|
|
971
|
+
visit(module, []);
|
|
972
|
+
}
|
|
973
|
+
const interfaceProviders = /* @__PURE__ */ new Set();
|
|
974
|
+
for (const module of result) {
|
|
975
|
+
if (module.implements !== void 0) {
|
|
976
|
+
assert(!interfaceProviders.has(module.implements));
|
|
977
|
+
interfaceProviders.add(module.implements);
|
|
978
|
+
}
|
|
979
|
+
}
|
|
980
|
+
initializeShaderModules(result);
|
|
981
|
+
return result;
|
|
982
|
+
}
|
|
983
|
+
function getShaderDependencies(modules) {
|
|
984
|
+
return getShaderModuleDependencies(modules);
|
|
985
|
+
}
|
|
986
|
+
function resolveModules(modules) {
|
|
987
|
+
return getShaderDependencies(modules);
|
|
988
|
+
}
|
|
989
|
+
|
|
867
990
|
// src/module-injectors.ts
|
|
868
991
|
var MODULE_INJECTORS_VS = (
|
|
869
992
|
/* glsl */
|
|
@@ -906,37 +1029,34 @@ var __exports__ = (() => {
|
|
|
906
1029
|
var REGEX_END_OF_MAIN = /}\n?[^{}]*$/;
|
|
907
1030
|
var fragments = [];
|
|
908
1031
|
var DECLARATION_INJECT_MARKER = "__LUMA_INJECT_DECLARATIONS__";
|
|
909
|
-
function
|
|
910
|
-
const
|
|
911
|
-
for (const
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
if (
|
|
915
|
-
injection
|
|
916
|
-
order: 0,
|
|
917
|
-
injection
|
|
918
|
-
};
|
|
1032
|
+
function resolveShaderInjections(declarations, language, pluginName) {
|
|
1033
|
+
const resolved = {};
|
|
1034
|
+
for (const declaration of declarations) {
|
|
1035
|
+
const source7 = declaration[language];
|
|
1036
|
+
if (source7 === void 0) continue;
|
|
1037
|
+
if (declaration.stage !== "vertex" && declaration.stage !== "fragment" || declaration.target.includes(":")) {
|
|
1038
|
+
throw new Error("Shader injection targets require an explicit stage and unqualified target");
|
|
919
1039
|
}
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
return "fragment";
|
|
931
|
-
default:
|
|
932
|
-
throw new Error(type);
|
|
1040
|
+
const target = `${declaration.stage === "vertex" ? "vs" : "fs"}:${declaration.target}`;
|
|
1041
|
+
if (!/^(vs|fs):(?:#(?:decl|main-start|main-end)|[A-Za-z_][A-Za-z0-9_]*)$/.test(target)) {
|
|
1042
|
+
throw new Error(`Shader injection target "${target}" must be a named shader anchor or hook`);
|
|
1043
|
+
}
|
|
1044
|
+
resolved[target] ||= [];
|
|
1045
|
+
resolved[target].push({
|
|
1046
|
+
injection: source7,
|
|
1047
|
+
order: declaration.order ?? 0,
|
|
1048
|
+
...pluginName ? { pluginName } : {}
|
|
1049
|
+
});
|
|
933
1050
|
}
|
|
1051
|
+
return resolved;
|
|
934
1052
|
}
|
|
935
1053
|
function injectShader(source7, stage, inject, injectStandardStubs = false, language = "glsl", entryPoints = {}) {
|
|
936
1054
|
const isVertex = stage === "vertex";
|
|
937
1055
|
for (const key in inject) {
|
|
938
1056
|
const fragmentData = inject[key];
|
|
939
|
-
fragmentData.sort(
|
|
1057
|
+
fragmentData.sort(
|
|
1058
|
+
(a, b) => a.order - b.order
|
|
1059
|
+
);
|
|
940
1060
|
fragments.length = fragmentData.length;
|
|
941
1061
|
for (let i = 0, len = fragmentData.length; i < len; ++i) {
|
|
942
1062
|
fragments[i] = fragmentData[i].injection;
|
|
@@ -1053,134 +1173,6 @@ ${fragmentString}${source7.slice(insertionIndex)}`;
|
|
|
1053
1173
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1054
1174
|
}
|
|
1055
1175
|
|
|
1056
|
-
// src/lib/shader-module/shader-module.ts
|
|
1057
|
-
function initializeShaderModules(modules) {
|
|
1058
|
-
modules.map((module) => initializeShaderModule(module));
|
|
1059
|
-
}
|
|
1060
|
-
function initializeShaderModule(module) {
|
|
1061
|
-
if (module.instance) {
|
|
1062
|
-
return;
|
|
1063
|
-
}
|
|
1064
|
-
initializeShaderModules(module.dependencies || []);
|
|
1065
|
-
const {
|
|
1066
|
-
propTypes = {},
|
|
1067
|
-
deprecations = [],
|
|
1068
|
-
// defines = {},
|
|
1069
|
-
inject = {}
|
|
1070
|
-
} = module;
|
|
1071
|
-
const instance = {
|
|
1072
|
-
normalizedInjections: normalizeInjections(inject),
|
|
1073
|
-
parsedDeprecations: parseDeprecationDefinitions(deprecations)
|
|
1074
|
-
};
|
|
1075
|
-
if (propTypes) {
|
|
1076
|
-
instance.propValidators = makePropValidators(propTypes);
|
|
1077
|
-
}
|
|
1078
|
-
module.instance = instance;
|
|
1079
|
-
let defaultProps = {};
|
|
1080
|
-
if (propTypes) {
|
|
1081
|
-
defaultProps = Object.entries(propTypes).reduce(
|
|
1082
|
-
(obj, [key, propType]) => {
|
|
1083
|
-
const value = propType?.value;
|
|
1084
|
-
if (value) {
|
|
1085
|
-
obj[key] = value;
|
|
1086
|
-
}
|
|
1087
|
-
return obj;
|
|
1088
|
-
},
|
|
1089
|
-
{}
|
|
1090
|
-
);
|
|
1091
|
-
}
|
|
1092
|
-
module.defaultUniforms = {
|
|
1093
|
-
...module.defaultUniforms,
|
|
1094
|
-
...defaultProps
|
|
1095
|
-
};
|
|
1096
|
-
}
|
|
1097
|
-
function getShaderModuleUniforms(module, props, oldUniforms) {
|
|
1098
|
-
initializeShaderModule(module);
|
|
1099
|
-
const uniforms2 = oldUniforms || { ...module.defaultUniforms };
|
|
1100
|
-
if (props && module.getUniforms) {
|
|
1101
|
-
return module.getUniforms(props, uniforms2);
|
|
1102
|
-
}
|
|
1103
|
-
return getValidatedProperties(props, module.instance?.propValidators, module.name);
|
|
1104
|
-
}
|
|
1105
|
-
function checkShaderModuleDeprecations(shaderModule, shaderSource, log) {
|
|
1106
|
-
shaderModule.deprecations?.forEach((def) => {
|
|
1107
|
-
if (def.regex?.test(shaderSource)) {
|
|
1108
|
-
if (def.deprecated) {
|
|
1109
|
-
log.deprecated(def.old, def.new)();
|
|
1110
|
-
} else {
|
|
1111
|
-
log.removed(def.old, def.new)();
|
|
1112
|
-
}
|
|
1113
|
-
}
|
|
1114
|
-
});
|
|
1115
|
-
}
|
|
1116
|
-
function parseDeprecationDefinitions(deprecations) {
|
|
1117
|
-
deprecations.forEach((def) => {
|
|
1118
|
-
switch (def.type) {
|
|
1119
|
-
case "function":
|
|
1120
|
-
def.regex = new RegExp(`\\b${def.old}\\(`);
|
|
1121
|
-
break;
|
|
1122
|
-
default:
|
|
1123
|
-
def.regex = new RegExp(`${def.type} ${def.old};`);
|
|
1124
|
-
}
|
|
1125
|
-
});
|
|
1126
|
-
return deprecations;
|
|
1127
|
-
}
|
|
1128
|
-
|
|
1129
|
-
// src/lib/shader-module/shader-module-dependencies.ts
|
|
1130
|
-
function getShaderModuleDependencies(modules) {
|
|
1131
|
-
const visited = /* @__PURE__ */ new Set();
|
|
1132
|
-
const recursionStack = /* @__PURE__ */ new Set();
|
|
1133
|
-
const result = [];
|
|
1134
|
-
const nameToModule = /* @__PURE__ */ new Map();
|
|
1135
|
-
function checkNameCollision(module) {
|
|
1136
|
-
const existing = nameToModule.get(module.name);
|
|
1137
|
-
if (existing && existing !== module) {
|
|
1138
|
-
throw new Error(
|
|
1139
|
-
`Shader module name collision: Multiple different module objects share the name "${module.name}". Each module object must have a unique name.`
|
|
1140
|
-
);
|
|
1141
|
-
}
|
|
1142
|
-
nameToModule.set(module.name, module);
|
|
1143
|
-
}
|
|
1144
|
-
function visit(module, path) {
|
|
1145
|
-
if (recursionStack.has(module)) {
|
|
1146
|
-
const cyclePath = [...path, module.name].join(" -> ");
|
|
1147
|
-
throw new Error(`Shader module dependency cycle detected: ${cyclePath}`);
|
|
1148
|
-
}
|
|
1149
|
-
if (visited.has(module)) {
|
|
1150
|
-
return;
|
|
1151
|
-
}
|
|
1152
|
-
checkNameCollision(module);
|
|
1153
|
-
recursionStack.add(module);
|
|
1154
|
-
const newPath = [...path, module.name];
|
|
1155
|
-
if (module.dependencies) {
|
|
1156
|
-
for (const dep of module.dependencies) {
|
|
1157
|
-
visit(dep, newPath);
|
|
1158
|
-
}
|
|
1159
|
-
}
|
|
1160
|
-
recursionStack.delete(module);
|
|
1161
|
-
visited.add(module);
|
|
1162
|
-
result.push(module);
|
|
1163
|
-
}
|
|
1164
|
-
for (const module of modules) {
|
|
1165
|
-
visit(module, []);
|
|
1166
|
-
}
|
|
1167
|
-
const interfaceProviders = /* @__PURE__ */ new Set();
|
|
1168
|
-
for (const module of result) {
|
|
1169
|
-
if (module.implements !== void 0) {
|
|
1170
|
-
assert(!interfaceProviders.has(module.implements));
|
|
1171
|
-
interfaceProviders.add(module.implements);
|
|
1172
|
-
}
|
|
1173
|
-
}
|
|
1174
|
-
initializeShaderModules(result);
|
|
1175
|
-
return result;
|
|
1176
|
-
}
|
|
1177
|
-
function getShaderDependencies(modules) {
|
|
1178
|
-
return getShaderModuleDependencies(modules);
|
|
1179
|
-
}
|
|
1180
|
-
function resolveModules(modules) {
|
|
1181
|
-
return getShaderDependencies(modules);
|
|
1182
|
-
}
|
|
1183
|
-
|
|
1184
1176
|
// src/types/shader-type-decoder.ts
|
|
1185
1177
|
function getVariableShaderTypeInfo(format) {
|
|
1186
1178
|
const resolvedFormat = resolveVariableShaderTypeAlias(format);
|
|
@@ -1382,7 +1374,6 @@ ${fragmentString}${source7.slice(insertionIndex)}`;
|
|
|
1382
1374
|
};
|
|
1383
1375
|
|
|
1384
1376
|
// src/lib/shader-plugin.ts
|
|
1385
|
-
var SHADER_PLUGIN_INJECTION_TARGET_REGEX = /^(vs|fs):(?:#(?:decl|main-start|main-end)|[A-Za-z_][\w-]*)$/;
|
|
1386
1377
|
function resolveShaderPlugins(plugins = [], shaderLanguage) {
|
|
1387
1378
|
const resolved = {
|
|
1388
1379
|
modules: [],
|
|
@@ -1452,20 +1443,21 @@ ${fragmentString}${source7.slice(insertionIndex)}`;
|
|
|
1452
1443
|
resolved.interStageVariables[name] = normalizedVarying;
|
|
1453
1444
|
}
|
|
1454
1445
|
for (const hook of plugin.hooks || []) {
|
|
1455
|
-
const
|
|
1456
|
-
if (
|
|
1457
|
-
const
|
|
1458
|
-
if (
|
|
1459
|
-
const target = typeof hook === "string" ? declarationSource.split("(")[0] : getShaderPluginTarget(hook);
|
|
1460
|
-
if (!/^(vs|fs):[A-Za-z_][A-Za-z0-9_]*$/.test(target) || !/^\([^]*\)$/.test(signature.trim())) {
|
|
1446
|
+
const implementation = hook[shaderLanguage];
|
|
1447
|
+
if (!implementation) continue;
|
|
1448
|
+
const target = `${hook.stage === "vertex" ? "vs" : "fs"}:${hook.name}`;
|
|
1449
|
+
if (!/^(vs|fs):[A-Za-z_][A-Za-z0-9_]*$/.test(target)) {
|
|
1461
1450
|
throw new Error(`Invalid ShaderPlugin hook ${target}`);
|
|
1462
1451
|
}
|
|
1463
|
-
const
|
|
1464
|
-
|
|
1465
|
-
|
|
1452
|
+
const existing = resolved.hooks.find(
|
|
1453
|
+
(value) => value.stage === hook.stage && value.name === hook.name
|
|
1454
|
+
);
|
|
1455
|
+
const previous = existing?.[shaderLanguage];
|
|
1456
|
+
if (previous && (previous.parameters !== implementation.parameters || (previous.returnType || "void") !== (implementation.returnType || "void") || previous.header !== implementation.header || previous.footer !== implementation.footer)) {
|
|
1466
1457
|
throw new Error(`Conflicting ShaderPlugin hook ${target}`);
|
|
1467
1458
|
}
|
|
1468
|
-
if (!existing)
|
|
1459
|
+
if (!existing)
|
|
1460
|
+
resolved.hooks.push({ name: hook.name, stage: hook.stage, [shaderLanguage]: implementation });
|
|
1469
1461
|
}
|
|
1470
1462
|
const pluginInjections = Array.isArray(plugin.injections) ? plugin.injections : Object.entries(plugin.injections || {}).flatMap(([key, source7]) => {
|
|
1471
1463
|
const target = selectShaderLanguage(key, shaderLanguage);
|
|
@@ -1481,20 +1473,10 @@ ${fragmentString}${source7.slice(insertionIndex)}`;
|
|
|
1481
1473
|
}
|
|
1482
1474
|
];
|
|
1483
1475
|
});
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
assertNamedShaderPluginInjectionTarget(target);
|
|
1489
|
-
if (!resolved.injections[target]) {
|
|
1490
|
-
resolved.injections[target] = [];
|
|
1491
|
-
}
|
|
1492
|
-
const injections = resolved.injections[target];
|
|
1493
|
-
injections.push({
|
|
1494
|
-
pluginName: plugin.name,
|
|
1495
|
-
injection: source7,
|
|
1496
|
-
order: injection.order ?? 0
|
|
1497
|
-
});
|
|
1476
|
+
const selectedInjections = resolveShaderInjections(pluginInjections, shaderLanguage, plugin.name);
|
|
1477
|
+
for (const [target, injections] of Object.entries(selectedInjections)) {
|
|
1478
|
+
resolved.injections[target] ||= [];
|
|
1479
|
+
resolved.injections[target].push(...injections);
|
|
1498
1480
|
}
|
|
1499
1481
|
}
|
|
1500
1482
|
function assertShaderPluginInterfaceName(name, kind) {
|
|
@@ -1511,19 +1493,6 @@ ${fragmentString}${source7.slice(insertionIndex)}`;
|
|
|
1511
1493
|
}
|
|
1512
1494
|
return { type: varying.type, interpolation };
|
|
1513
1495
|
}
|
|
1514
|
-
function assertNamedShaderPluginInjectionTarget(target) {
|
|
1515
|
-
if (!SHADER_PLUGIN_INJECTION_TARGET_REGEX.test(target)) {
|
|
1516
|
-
throw new Error(
|
|
1517
|
-
`ShaderPlugin injection target "${target}" must be a named shader anchor or hook`
|
|
1518
|
-
);
|
|
1519
|
-
}
|
|
1520
|
-
}
|
|
1521
|
-
function getShaderPluginTarget(value) {
|
|
1522
|
-
if (value.stage !== "vertex" && value.stage !== "fragment" || value.target.includes(":")) {
|
|
1523
|
-
throw new Error("ShaderPlugin object targets require an explicit stage and unqualified target");
|
|
1524
|
-
}
|
|
1525
|
-
return `${value.stage === "vertex" ? "vs" : "fs"}:${value.target}`;
|
|
1526
|
-
}
|
|
1527
1496
|
function selectShaderLanguage(value, language) {
|
|
1528
1497
|
const match = /^(glsl|wgsl):([\s\S]+)$/.exec(value);
|
|
1529
1498
|
return match ? match[1] === language ? match[2] : void 0 : value;
|
|
@@ -2733,8 +2702,10 @@ return ${outputName};
|
|
|
2733
2702
|
let result = "";
|
|
2734
2703
|
for (const hookName in hookFunctions) {
|
|
2735
2704
|
const hookFunction = hookFunctions[hookName];
|
|
2736
|
-
const
|
|
2737
|
-
|
|
2705
|
+
const returnType = hookFunction.returnType || "void";
|
|
2706
|
+
const functionPrefix = shaderLanguage === "wgsl" ? "fn" : returnType;
|
|
2707
|
+
const returnSuffix = shaderLanguage === "wgsl" && returnType !== "void" ? ` -> ${returnType}` : "";
|
|
2708
|
+
result += `${functionPrefix} ${hookFunction.signature}${returnSuffix} {
|
|
2738
2709
|
`;
|
|
2739
2710
|
if (hookFunction.header) {
|
|
2740
2711
|
result += ` ${hookFunction.header}`;
|
|
@@ -2754,23 +2725,24 @@ return ${outputName};
|
|
|
2754
2725
|
}
|
|
2755
2726
|
return result;
|
|
2756
2727
|
}
|
|
2757
|
-
function normalizeShaderHooks(hookFunctions, pluginHooks = [], language) {
|
|
2728
|
+
function normalizeShaderHooks(hookFunctions, pluginHooks = [], language = "glsl") {
|
|
2758
2729
|
const result = { vertex: {}, fragment: {} };
|
|
2759
|
-
for (const
|
|
2760
|
-
const
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2730
|
+
for (const hook of hookFunctions) {
|
|
2731
|
+
const implementation = hook[language];
|
|
2732
|
+
if (implementation) {
|
|
2733
|
+
const prefix = hook.stage === "vertex" ? "vs" : "fs";
|
|
2734
|
+
result[hook.stage][`${prefix}:${hook.name}`] = {
|
|
2735
|
+
...implementation,
|
|
2736
|
+
signature: `${hook.name}(${implementation.parameters})`
|
|
2737
|
+
};
|
|
2738
|
+
}
|
|
2767
2739
|
}
|
|
2768
2740
|
for (const hook of pluginHooks) {
|
|
2769
|
-
const
|
|
2741
|
+
const selected = normalizeShaderHooks([hook], [], language);
|
|
2770
2742
|
for (const stage of ["vertex", "fragment"]) {
|
|
2771
|
-
for (const [name, declaration] of Object.entries(
|
|
2743
|
+
for (const [name, declaration] of Object.entries(selected[stage])) {
|
|
2772
2744
|
const existing = result[stage][name];
|
|
2773
|
-
if (existing && existing.signature !== declaration.signature) {
|
|
2745
|
+
if (existing && (existing.signature !== declaration.signature || (existing.returnType || "void") !== (declaration.returnType || "void"))) {
|
|
2774
2746
|
throw new Error(`Conflicting ShaderPlugin hook ${name}`);
|
|
2775
2747
|
}
|
|
2776
2748
|
result[stage][name] = existing || declaration;
|
|
@@ -2799,30 +2771,6 @@ return ${outputName};
|
|
|
2799
2771
|
}
|
|
2800
2772
|
}
|
|
2801
2773
|
}
|
|
2802
|
-
function addShaderHookToRegistry(registry, hookFunction) {
|
|
2803
|
-
const options = typeof hookFunction === "string" ? {} : hookFunction;
|
|
2804
|
-
const hook = (typeof hookFunction === "string" ? hookFunction : hookFunction.hook).trim();
|
|
2805
|
-
const stageSeparatorIndex = hook.indexOf(":");
|
|
2806
|
-
const shaderStage = hook.slice(0, stageSeparatorIndex);
|
|
2807
|
-
const signature = hook.slice(stageSeparatorIndex + 1);
|
|
2808
|
-
const name = hook.split("(")[0].trim();
|
|
2809
|
-
const normalizedHook = {
|
|
2810
|
-
hook: name,
|
|
2811
|
-
signature,
|
|
2812
|
-
header: options.header || "",
|
|
2813
|
-
footer: options.footer || ""
|
|
2814
|
-
};
|
|
2815
|
-
switch (shaderStage) {
|
|
2816
|
-
case "vs":
|
|
2817
|
-
registry.vertex[name] = normalizedHook;
|
|
2818
|
-
break;
|
|
2819
|
-
case "fs":
|
|
2820
|
-
registry.fragment[name] = normalizedHook;
|
|
2821
|
-
break;
|
|
2822
|
-
default:
|
|
2823
|
-
throw new Error(shaderStage);
|
|
2824
|
-
}
|
|
2825
|
-
}
|
|
2826
2774
|
|
|
2827
2775
|
// src/lib/shader-assembly/assemble-wgsl-shaders.ts
|
|
2828
2776
|
var RESERVED_APPLICATION_GROUP_0_BINDING_LIMIT = 100;
|
|
@@ -2877,8 +2825,11 @@ return ${outputName};
|
|
|
2877
2825
|
const declInjections = {};
|
|
2878
2826
|
const mainInjections = {};
|
|
2879
2827
|
appendInjections(pluginInjections, hookInjections, declInjections, mainInjections);
|
|
2880
|
-
|
|
2881
|
-
|
|
2828
|
+
const applicationInjections = Array.isArray(inject) ? resolveShaderInjections(inject, "wgsl") : {};
|
|
2829
|
+
appendInjections(applicationInjections, hookInjections, declInjections, mainInjections);
|
|
2830
|
+
const injectionMap = Array.isArray(inject) ? {} : inject;
|
|
2831
|
+
for (const key in injectionMap) {
|
|
2832
|
+
const injection = typeof injectionMap[key] === "string" ? { injection: injectionMap[key], order: 0 } : injectionMap[key];
|
|
2882
2833
|
const match = /^(v|f)s:(#)?([\w-]+)$/.exec(key);
|
|
2883
2834
|
if (match) {
|
|
2884
2835
|
const hash = match[2];
|
|
@@ -2932,19 +2883,6 @@ return ${outputName};
|
|
|
2932
2883
|
checkShaderModuleDeprecations(module, coreSource, log);
|
|
2933
2884
|
}
|
|
2934
2885
|
assembledSource += moduleSource;
|
|
2935
|
-
const injections = getWGSLModuleInjections(module);
|
|
2936
|
-
for (const key in injections) {
|
|
2937
|
-
const match = /^(v|f)s:#([\w-]+)$/.exec(key);
|
|
2938
|
-
if (match) {
|
|
2939
|
-
const name = match[2];
|
|
2940
|
-
const injectionType = name === "decl" ? declInjections : mainInjections;
|
|
2941
|
-
injectionType[key] = injectionType[key] || [];
|
|
2942
|
-
injectionType[key].push(injections[key]);
|
|
2943
|
-
} else if (isShaderHookRegistered(hookFunctionMap, key)) {
|
|
2944
|
-
hookInjections[key] = hookInjections[key] || [];
|
|
2945
|
-
hookInjections[key].push(injections[key]);
|
|
2946
|
-
}
|
|
2947
|
-
}
|
|
2948
2886
|
}
|
|
2949
2887
|
assembledSource += INJECT_SHADER_DECLARATIONS;
|
|
2950
2888
|
assembledSource = injectShader(
|
|
@@ -3004,12 +2942,6 @@ return ${outputName};
|
|
|
3004
2942
|
});
|
|
3005
2943
|
}
|
|
3006
2944
|
}
|
|
3007
|
-
function getWGSLModuleInjections(module) {
|
|
3008
|
-
return {
|
|
3009
|
-
...module.instance?.normalizedInjections.vertex || {},
|
|
3010
|
-
...module.instance?.normalizedInjections.fragment || {}
|
|
3011
|
-
};
|
|
3012
|
-
}
|
|
3013
2945
|
function getWGSLDeclarationInjections(declarationInjections) {
|
|
3014
2946
|
const unifiedDeclarations = [
|
|
3015
2947
|
...declarationInjections["vs:#decl"] || [],
|
|
@@ -3535,8 +3467,11 @@ ${getApplicationDefines(allDefines)}
|
|
|
3535
3467
|
const declInjections = {};
|
|
3536
3468
|
const mainInjections = {};
|
|
3537
3469
|
appendInjections(pluginInjections, hookInjections, declInjections, mainInjections);
|
|
3538
|
-
|
|
3539
|
-
|
|
3470
|
+
const applicationInjections = Array.isArray(inject) ? resolveShaderInjections(inject, "glsl") : {};
|
|
3471
|
+
appendInjections(applicationInjections, hookInjections, declInjections, mainInjections);
|
|
3472
|
+
const injectionMap = Array.isArray(inject) ? {} : inject;
|
|
3473
|
+
for (const key in injectionMap) {
|
|
3474
|
+
const injection = typeof injectionMap[key] === "string" ? { injection: injectionMap[key], order: 0 } : injectionMap[key];
|
|
3540
3475
|
const match = /^(v|f)s:(#)?([\w-]+)$/.exec(key);
|
|
3541
3476
|
if (match) {
|
|
3542
3477
|
const hash = match[2];
|
|
@@ -3581,19 +3516,6 @@ ${getApplicationDefines(allDefines)}
|
|
|
3581
3516
|
}
|
|
3582
3517
|
const moduleSource = getShaderModuleSource(module, stage, log);
|
|
3583
3518
|
assembledSource += moduleSource;
|
|
3584
|
-
const injections = module.instance?.normalizedInjections[stage] || {};
|
|
3585
|
-
for (const key in injections) {
|
|
3586
|
-
const match = /^(v|f)s:#([\w-]+)$/.exec(key);
|
|
3587
|
-
if (match) {
|
|
3588
|
-
const name = match[2];
|
|
3589
|
-
const injectionType = name === "decl" ? declInjections : mainInjections;
|
|
3590
|
-
injectionType[key] = injectionType[key] || [];
|
|
3591
|
-
injectionType[key].push(injections[key]);
|
|
3592
|
-
} else {
|
|
3593
|
-
hookInjections[key] = hookInjections[key] || [];
|
|
3594
|
-
hookInjections[key].push(injections[key]);
|
|
3595
|
-
}
|
|
3596
|
-
}
|
|
3597
3519
|
}
|
|
3598
3520
|
validateShaderHookInjections(hookFunctionMap, hookInjections, stage);
|
|
3599
3521
|
assembledSource += "// ----- MAIN SHADER SOURCE -------------------------";
|
|
@@ -3698,11 +3620,10 @@ ${getApplicationDefines(allDefines)}
|
|
|
3698
3620
|
}
|
|
3699
3621
|
/**
|
|
3700
3622
|
* Register a shader hook
|
|
3701
|
-
* @param hook
|
|
3702
|
-
* @param options Optional hook metadata such as always-on header and footer source.
|
|
3623
|
+
* @param hook Shared stage and name with language-specific parameters, return type, and source.
|
|
3703
3624
|
*/
|
|
3704
|
-
addShaderHook(hook
|
|
3705
|
-
this._hookFunctions.push(
|
|
3625
|
+
addShaderHook(hook) {
|
|
3626
|
+
this._hookFunctions.push(hook);
|
|
3706
3627
|
}
|
|
3707
3628
|
/**
|
|
3708
3629
|
* Remove all registered shader hooks, for example before re-registering hooks for a new
|