@luma.gl/shaders 10.0.0-alpha.7 → 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 +233 -249
- package/dist/dist.min.js +124 -124
- 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 +6 -17
- package/dist/lib/shader-assembly/assemble-glsl-shaders.d.ts +5 -4
- package/dist/lib/shader-assembly/assemble-glsl-shaders.d.ts.map +1 -1
- package/dist/lib/shader-assembly/assemble-glsl-shaders.js +14 -19
- package/dist/lib/shader-assembly/assemble-glsl-shaders.js.map +1 -1
- package/dist/lib/shader-assembly/assemble-wgsl-shaders.cjs +6 -25
- 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 +14 -27
- 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 +11 -7
- package/dist/lib/shader-assembly/shader-assembly-types.d.ts.map +1 -1
- package/dist/lib/shader-assembly/shader-hooks.cjs +26 -29
- 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 +29 -33
- 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 +38 -17
- package/dist/lib/shader-plugin.d.ts +9 -17
- package/dist/lib/shader-plugin.d.ts.map +1 -1
- package/dist/lib/shader-plugin.js +43 -16
- package/dist/lib/shader-plugin.js.map +1 -1
- package/dist/modules/engine/clip/clip.cjs +4 -2
- package/dist/modules/engine/clip/clip.d.ts.map +1 -1
- package/dist/modules/engine/clip/clip.js +4 -2
- package/dist/modules/engine/clip/clip.js.map +1 -1
- package/dist/modules/engine/filter/filter.cjs +2 -1
- package/dist/modules/engine/filter/filter.d.ts.map +1 -1
- package/dist/modules/engine/filter/filter.js +2 -1
- package/dist/modules/engine/filter/filter.js.map +1 -1
- package/dist/modules/lighting/lights/lighting.d.ts +1 -1
- package/dist/modules/lighting/lights/lighting.d.ts.map +1 -1
- package/dist/modules/lighting/pbr-material/pbr-material-glsl.cjs +2 -2
- package/dist/modules/lighting/pbr-material/pbr-material-glsl.d.ts +1 -1
- package/dist/modules/lighting/pbr-material/pbr-material-glsl.d.ts.map +1 -1
- package/dist/modules/lighting/pbr-material/pbr-material-glsl.js +2 -2
- package/dist/modules/lighting/pbr-material/pbr-material-wgsl.cjs +2 -2
- package/dist/modules/lighting/pbr-material/pbr-material-wgsl.d.ts +1 -1
- package/dist/modules/lighting/pbr-material/pbr-material-wgsl.d.ts.map +1 -1
- package/dist/modules/lighting/pbr-material/pbr-material-wgsl.js +2 -2
- package/dist/modules/lighting/pbr-material/pbr-material.d.ts +2 -2
- package/dist/types/texture-formats.d.ts +1 -1
- package/dist/types/texture-formats.d.ts.map +1 -1
- package/dist/wgsl.cjs.map +2 -2
- package/package.json +3 -3
- package/src/index.ts +5 -4
- package/src/lib/shader-assembler-base.ts +5 -6
- package/src/lib/shader-assembly/assemble-glsl-shaders.ts +27 -26
- package/src/lib/shader-assembly/assemble-wgsl-shaders.ts +28 -43
- package/src/lib/shader-assembly/shader-assembly-shared.ts +5 -5
- package/src/lib/shader-assembly/shader-assembly-types.ts +11 -7
- package/src/lib/shader-assembly/shader-hooks.ts +65 -68
- 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 +59 -48
- package/src/modules/engine/clip/clip.ts +4 -2
- package/src/modules/engine/filter/filter.ts +2 -1
- package/src/modules/lighting/lights/lighting.ts +1 -1
- package/src/modules/lighting/pbr-material/pbr-material-glsl.ts +2 -2
- package/src/modules/lighting/pbr-material/pbr-material-wgsl.ts +2 -2
- package/src/types/texture-formats.ts +2 -0
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,10 +1374,10 @@ ${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: [],
|
|
1380
|
+
hooks: [],
|
|
1389
1381
|
defines: {},
|
|
1390
1382
|
injections: {},
|
|
1391
1383
|
vertexInputs: {},
|
|
@@ -1450,19 +1442,41 @@ ${fragmentString}${source7.slice(insertionIndex)}`;
|
|
|
1450
1442
|
}
|
|
1451
1443
|
resolved.interStageVariables[name] = normalizedVarying;
|
|
1452
1444
|
}
|
|
1453
|
-
for (const
|
|
1454
|
-
const
|
|
1455
|
-
if (
|
|
1456
|
-
|
|
1457
|
-
if (
|
|
1458
|
-
|
|
1445
|
+
for (const hook of plugin.hooks || []) {
|
|
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)) {
|
|
1450
|
+
throw new Error(`Invalid ShaderPlugin hook ${target}`);
|
|
1459
1451
|
}
|
|
1460
|
-
const
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
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)) {
|
|
1457
|
+
throw new Error(`Conflicting ShaderPlugin hook ${target}`);
|
|
1458
|
+
}
|
|
1459
|
+
if (!existing)
|
|
1460
|
+
resolved.hooks.push({ name: hook.name, stage: hook.stage, [shaderLanguage]: implementation });
|
|
1461
|
+
}
|
|
1462
|
+
const pluginInjections = Array.isArray(plugin.injections) ? plugin.injections : Object.entries(plugin.injections || {}).flatMap(([key, source7]) => {
|
|
1463
|
+
const target = selectShaderLanguage(key, shaderLanguage);
|
|
1464
|
+
if (target === void 0) return [];
|
|
1465
|
+
const [stage, ...name] = target.split(":");
|
|
1466
|
+
if (stage !== "vs" && stage !== "fs")
|
|
1467
|
+
throw new Error(`Invalid ShaderPlugin injection ${key}`);
|
|
1468
|
+
return [
|
|
1469
|
+
{
|
|
1470
|
+
stage: stage === "vs" ? "vertex" : "fragment",
|
|
1471
|
+
target: name.join(":"),
|
|
1472
|
+
[shaderLanguage]: source7
|
|
1473
|
+
}
|
|
1474
|
+
];
|
|
1475
|
+
});
|
|
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);
|
|
1466
1480
|
}
|
|
1467
1481
|
}
|
|
1468
1482
|
function assertShaderPluginInterfaceName(name, kind) {
|
|
@@ -1479,12 +1493,9 @@ ${fragmentString}${source7.slice(insertionIndex)}`;
|
|
|
1479
1493
|
}
|
|
1480
1494
|
return { type: varying.type, interpolation };
|
|
1481
1495
|
}
|
|
1482
|
-
function
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
`ShaderPlugin injection target "${target}" must be a named shader anchor or hook`
|
|
1486
|
-
);
|
|
1487
|
-
}
|
|
1496
|
+
function selectShaderLanguage(value, language) {
|
|
1497
|
+
const match = /^(glsl|wgsl):([\s\S]+)$/.exec(value);
|
|
1498
|
+
return match ? match[1] === language ? match[2] : void 0 : value;
|
|
1488
1499
|
}
|
|
1489
1500
|
|
|
1490
1501
|
// src/lib/shader-module/shader-module-uniform-layout.ts
|
|
@@ -2691,8 +2702,10 @@ return ${outputName};
|
|
|
2691
2702
|
let result = "";
|
|
2692
2703
|
for (const hookName in hookFunctions) {
|
|
2693
2704
|
const hookFunction = hookFunctions[hookName];
|
|
2694
|
-
const
|
|
2695
|
-
|
|
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} {
|
|
2696
2709
|
`;
|
|
2697
2710
|
if (hookFunction.header) {
|
|
2698
2711
|
result += ` ${hookFunction.header}`;
|
|
@@ -2712,10 +2725,29 @@ return ${outputName};
|
|
|
2712
2725
|
}
|
|
2713
2726
|
return result;
|
|
2714
2727
|
}
|
|
2715
|
-
function normalizeShaderHooks(hookFunctions) {
|
|
2728
|
+
function normalizeShaderHooks(hookFunctions, pluginHooks = [], language = "glsl") {
|
|
2716
2729
|
const result = { vertex: {}, fragment: {} };
|
|
2717
|
-
for (const
|
|
2718
|
-
|
|
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
|
+
}
|
|
2739
|
+
}
|
|
2740
|
+
for (const hook of pluginHooks) {
|
|
2741
|
+
const selected = normalizeShaderHooks([hook], [], language);
|
|
2742
|
+
for (const stage of ["vertex", "fragment"]) {
|
|
2743
|
+
for (const [name, declaration] of Object.entries(selected[stage])) {
|
|
2744
|
+
const existing = result[stage][name];
|
|
2745
|
+
if (existing && (existing.signature !== declaration.signature || (existing.returnType || "void") !== (declaration.returnType || "void"))) {
|
|
2746
|
+
throw new Error(`Conflicting ShaderPlugin hook ${name}`);
|
|
2747
|
+
}
|
|
2748
|
+
result[stage][name] = existing || declaration;
|
|
2749
|
+
}
|
|
2750
|
+
}
|
|
2719
2751
|
}
|
|
2720
2752
|
return result;
|
|
2721
2753
|
}
|
|
@@ -2739,30 +2771,6 @@ return ${outputName};
|
|
|
2739
2771
|
}
|
|
2740
2772
|
}
|
|
2741
2773
|
}
|
|
2742
|
-
function addShaderHookToRegistry(registry, hookFunction) {
|
|
2743
|
-
const options = typeof hookFunction === "string" ? {} : hookFunction;
|
|
2744
|
-
const hook = (typeof hookFunction === "string" ? hookFunction : hookFunction.hook).trim();
|
|
2745
|
-
const stageSeparatorIndex = hook.indexOf(":");
|
|
2746
|
-
const shaderStage = hook.slice(0, stageSeparatorIndex);
|
|
2747
|
-
const signature = hook.slice(stageSeparatorIndex + 1);
|
|
2748
|
-
const name = hook.replace(/\(.+/, "");
|
|
2749
|
-
const normalizedHook = {
|
|
2750
|
-
hook: name,
|
|
2751
|
-
signature,
|
|
2752
|
-
header: options.header || "",
|
|
2753
|
-
footer: options.footer || ""
|
|
2754
|
-
};
|
|
2755
|
-
switch (shaderStage) {
|
|
2756
|
-
case "vs":
|
|
2757
|
-
registry.vertex[name] = normalizedHook;
|
|
2758
|
-
break;
|
|
2759
|
-
case "fs":
|
|
2760
|
-
registry.fragment[name] = normalizedHook;
|
|
2761
|
-
break;
|
|
2762
|
-
default:
|
|
2763
|
-
throw new Error(shaderStage);
|
|
2764
|
-
}
|
|
2765
|
-
}
|
|
2766
2774
|
|
|
2767
2775
|
// src/lib/shader-assembly/assemble-wgsl-shaders.ts
|
|
2768
2776
|
var RESERVED_APPLICATION_GROUP_0_BINDING_LIMIT = 100;
|
|
@@ -2812,13 +2820,16 @@ return ${outputName};
|
|
|
2812
2820
|
);
|
|
2813
2821
|
const coreSource = pluginVaryingAssembly.source;
|
|
2814
2822
|
let assembledSource = "";
|
|
2815
|
-
const hookFunctionMap = normalizeShaderHooks(hookFunctions);
|
|
2823
|
+
const hookFunctionMap = normalizeShaderHooks(hookFunctions, options.pluginHooks, "wgsl");
|
|
2816
2824
|
const hookInjections = {};
|
|
2817
2825
|
const declInjections = {};
|
|
2818
2826
|
const mainInjections = {};
|
|
2819
2827
|
appendInjections(pluginInjections, hookInjections, declInjections, mainInjections);
|
|
2820
|
-
|
|
2821
|
-
|
|
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];
|
|
2822
2833
|
const match = /^(v|f)s:(#)?([\w-]+)$/.exec(key);
|
|
2823
2834
|
if (match) {
|
|
2824
2835
|
const hash = match[2];
|
|
@@ -2872,19 +2883,6 @@ return ${outputName};
|
|
|
2872
2883
|
checkShaderModuleDeprecations(module, coreSource, log);
|
|
2873
2884
|
}
|
|
2874
2885
|
assembledSource += moduleSource;
|
|
2875
|
-
const injections = getWGSLModuleInjections(module);
|
|
2876
|
-
for (const key in injections) {
|
|
2877
|
-
const match = /^(v|f)s:#([\w-]+)$/.exec(key);
|
|
2878
|
-
if (match) {
|
|
2879
|
-
const name = match[2];
|
|
2880
|
-
const injectionType = name === "decl" ? declInjections : mainInjections;
|
|
2881
|
-
injectionType[key] = injectionType[key] || [];
|
|
2882
|
-
injectionType[key].push(injections[key]);
|
|
2883
|
-
} else if (isShaderHookRegistered(hookFunctionMap, key)) {
|
|
2884
|
-
hookInjections[key] = hookInjections[key] || [];
|
|
2885
|
-
hookInjections[key].push(injections[key]);
|
|
2886
|
-
}
|
|
2887
|
-
}
|
|
2888
2886
|
}
|
|
2889
2887
|
assembledSource += INJECT_SHADER_DECLARATIONS;
|
|
2890
2888
|
assembledSource = injectShader(
|
|
@@ -2944,12 +2942,6 @@ return ${outputName};
|
|
|
2944
2942
|
});
|
|
2945
2943
|
}
|
|
2946
2944
|
}
|
|
2947
|
-
function getWGSLModuleInjections(module) {
|
|
2948
|
-
return {
|
|
2949
|
-
...module.instance?.normalizedInjections.vertex || {},
|
|
2950
|
-
...module.instance?.normalizedInjections.fragment || {}
|
|
2951
|
-
};
|
|
2952
|
-
}
|
|
2953
2945
|
function getWGSLDeclarationInjections(declarationInjections) {
|
|
2954
2946
|
const unifiedDeclarations = [
|
|
2955
2947
|
...declarationInjections["vs:#decl"] || [],
|
|
@@ -3470,13 +3462,16 @@ ${getApplicationDefines(allDefines)}
|
|
|
3470
3462
|
`;
|
|
3471
3463
|
break;
|
|
3472
3464
|
}
|
|
3473
|
-
const hookFunctionMap = normalizeShaderHooks(hookFunctions);
|
|
3465
|
+
const hookFunctionMap = normalizeShaderHooks(hookFunctions, options.pluginHooks, "glsl");
|
|
3474
3466
|
const hookInjections = {};
|
|
3475
3467
|
const declInjections = {};
|
|
3476
3468
|
const mainInjections = {};
|
|
3477
3469
|
appendInjections(pluginInjections, hookInjections, declInjections, mainInjections);
|
|
3478
|
-
|
|
3479
|
-
|
|
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];
|
|
3480
3475
|
const match = /^(v|f)s:(#)?([\w-]+)$/.exec(key);
|
|
3481
3476
|
if (match) {
|
|
3482
3477
|
const hash = match[2];
|
|
@@ -3521,19 +3516,6 @@ ${getApplicationDefines(allDefines)}
|
|
|
3521
3516
|
}
|
|
3522
3517
|
const moduleSource = getShaderModuleSource(module, stage, log);
|
|
3523
3518
|
assembledSource += moduleSource;
|
|
3524
|
-
const injections = module.instance?.normalizedInjections[stage] || {};
|
|
3525
|
-
for (const key in injections) {
|
|
3526
|
-
const match = /^(v|f)s:#([\w-]+)$/.exec(key);
|
|
3527
|
-
if (match) {
|
|
3528
|
-
const name = match[2];
|
|
3529
|
-
const injectionType = name === "decl" ? declInjections : mainInjections;
|
|
3530
|
-
injectionType[key] = injectionType[key] || [];
|
|
3531
|
-
injectionType[key].push(injections[key]);
|
|
3532
|
-
} else {
|
|
3533
|
-
hookInjections[key] = hookInjections[key] || [];
|
|
3534
|
-
hookInjections[key].push(injections[key]);
|
|
3535
|
-
}
|
|
3536
|
-
}
|
|
3537
3519
|
}
|
|
3538
3520
|
validateShaderHookInjections(hookFunctionMap, hookInjections, stage);
|
|
3539
3521
|
assembledSource += "// ----- MAIN SHADER SOURCE -------------------------";
|
|
@@ -3638,11 +3620,10 @@ ${getApplicationDefines(allDefines)}
|
|
|
3638
3620
|
}
|
|
3639
3621
|
/**
|
|
3640
3622
|
* Register a shader hook
|
|
3641
|
-
* @param hook
|
|
3642
|
-
* @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.
|
|
3643
3624
|
*/
|
|
3644
|
-
addShaderHook(hook
|
|
3645
|
-
this._hookFunctions.push(
|
|
3625
|
+
addShaderHook(hook) {
|
|
3626
|
+
this._hookFunctions.push(hook);
|
|
3646
3627
|
}
|
|
3647
3628
|
/**
|
|
3648
3629
|
* Remove all registered shader hooks, for example before re-registering hooks for a new
|
|
@@ -11673,7 +11654,8 @@ fn filter_isVisible(value: f32) -> bool {
|
|
|
11673
11654
|
},
|
|
11674
11655
|
injections: [
|
|
11675
11656
|
{
|
|
11676
|
-
|
|
11657
|
+
stage: "vertex",
|
|
11658
|
+
target: "FILTER_POSITION",
|
|
11677
11659
|
glsl: `if (!filter_isVisible(filterValues)) {
|
|
11678
11660
|
position = vec4(2.0, 2.0, 2.0, 1.0);
|
|
11679
11661
|
}`,
|
|
@@ -11774,7 +11756,8 @@ fn clip_isInBounds(coordinates: vec2<f32>) -> bool {
|
|
|
11774
11756
|
},
|
|
11775
11757
|
injections: [
|
|
11776
11758
|
{
|
|
11777
|
-
|
|
11759
|
+
stage: "vertex",
|
|
11760
|
+
target: "CLIP_POSITION",
|
|
11778
11761
|
glsl: `clipCoordinates = geometryCoordinates;
|
|
11779
11762
|
if (clipState.enabled != 0 && clipState.mode == ${CLIP_MODE_INSTANCE} &&
|
|
11780
11763
|
!clip_isInBounds(instanceCoordinates)) {
|
|
@@ -11787,7 +11770,8 @@ if (clipUniforms.enabled != 0 && clipUniforms.mode == ${CLIP_MODE_INSTANCE} &&
|
|
|
11787
11770
|
}`
|
|
11788
11771
|
},
|
|
11789
11772
|
{
|
|
11790
|
-
|
|
11773
|
+
stage: "fragment",
|
|
11774
|
+
target: "CLIP_COLOR",
|
|
11791
11775
|
glsl: `if (clipState.enabled != 0 && clipState.mode == ${CLIP_MODE_GEOMETRY} &&
|
|
11792
11776
|
!clip_isInBounds(clipCoordinates)) {
|
|
11793
11777
|
discard;
|
|
@@ -15589,7 +15573,7 @@ vec4 pbr_filterColorWithSpotShadows(vec4 vertexColor, vec4 spotVisibility)
|
|
|
15589
15573
|
|
|
15590
15574
|
for(int i = 0; i < lighting.directionalLightCount; i++) {
|
|
15591
15575
|
if (i < lighting.directionalLightCount) {
|
|
15592
|
-
PBRInfo_setDirectionalLight(pbrInfo, lighting_getDirectionalLight(i).direction);
|
|
15576
|
+
PBRInfo_setDirectionalLight(pbrInfo, -lighting_getDirectionalLight(i).direction);
|
|
15593
15577
|
color += calculateFinalColor(pbrInfo, lighting_getDirectionalLight(i).color);
|
|
15594
15578
|
}
|
|
15595
15579
|
}
|
|
@@ -15877,7 +15861,7 @@ vec4 pbr_filterColorWithSpotShadows(vec4 vertexColor, vec4 spotVisibility)
|
|
|
15877
15861
|
// Apply directional light
|
|
15878
15862
|
for(int i = 0; i < lighting.directionalLightCount; i++) {
|
|
15879
15863
|
if (i < lighting.directionalLightCount) {
|
|
15880
|
-
PBRInfo_setDirectionalLight(pbrInfo, lighting_getDirectionalLight(i).direction);
|
|
15864
|
+
PBRInfo_setDirectionalLight(pbrInfo, -lighting_getDirectionalLight(i).direction);
|
|
15881
15865
|
color += calculateMaterialLightColor(
|
|
15882
15866
|
pbrInfo,
|
|
15883
15867
|
lighting_getDirectionalLight(i).color,
|
|
@@ -17406,7 +17390,7 @@ fn pbr_filterColorWithSpotShadows(vertexColor: vec4<f32>, spotVisibility: vec4f)
|
|
|
17406
17390
|
|
|
17407
17391
|
for (var i = 0; i < lighting.directionalLightCount; i++) {
|
|
17408
17392
|
if (i < lighting.directionalLightCount) {
|
|
17409
|
-
PBRInfo_setDirectionalLight(&pbrInfo, lighting_getDirectionalLight(i).direction);
|
|
17393
|
+
PBRInfo_setDirectionalLight(&pbrInfo, -lighting_getDirectionalLight(i).direction);
|
|
17410
17394
|
color += calculateFinalColor(pbrInfo, lighting_getDirectionalLight(i).color);
|
|
17411
17395
|
}
|
|
17412
17396
|
}
|
|
@@ -17766,7 +17750,7 @@ fn pbr_filterColorWithSpotShadows(vertexColor: vec4<f32>, spotVisibility: vec4f)
|
|
|
17766
17750
|
// Apply directional light
|
|
17767
17751
|
for (var i = 0; i < lighting.directionalLightCount; i++) {
|
|
17768
17752
|
if (i < lighting.directionalLightCount) {
|
|
17769
|
-
PBRInfo_setDirectionalLight(&pbrInfo, lighting_getDirectionalLight(i).direction);
|
|
17753
|
+
PBRInfo_setDirectionalLight(&pbrInfo, -lighting_getDirectionalLight(i).direction);
|
|
17770
17754
|
color += calculateMaterialLightColor(
|
|
17771
17755
|
pbrInfo,
|
|
17772
17756
|
lighting_getDirectionalLight(i).color,
|