@skenora/procedural 0.1.2

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.
@@ -0,0 +1,132 @@
1
+ import { getMaterialProgramNodeValueType, validateMaterialProgram, } from "@skenora/contracts";
2
+ export class MaterialProgramCompilationError extends Error {
3
+ issues;
4
+ constructor(issues) {
5
+ super(issues
6
+ .map((issue) => `${formatPath(issue.path)}: ${issue.message}`)
7
+ .join("; "));
8
+ this.name = "MaterialProgramCompilationError";
9
+ this.issues = issues.map((issue) => ({
10
+ ...issue,
11
+ path: [...issue.path],
12
+ }));
13
+ }
14
+ }
15
+ /** Validate and lower a material graph into deterministic, renderer-neutral IR. */
16
+ export function compileMaterialProgram(program) {
17
+ const validation = validateMaterialProgram(program);
18
+ if (!validation.valid)
19
+ throw new MaterialProgramCompilationError(validation.issues);
20
+ const byId = new Map(program.nodes.map((node) => [node.id, node]));
21
+ const ordered = [];
22
+ const visited = new Set();
23
+ const visit = (id) => {
24
+ if (visited.has(id))
25
+ return;
26
+ const node = byId.get(id);
27
+ if (!node)
28
+ return;
29
+ for (const reference of references(node))
30
+ visit(reference);
31
+ visited.add(id);
32
+ ordered.push(structuredClone(node));
33
+ };
34
+ if (program.outputs.baseColor)
35
+ visit(program.outputs.baseColor);
36
+ if (program.outputs.emissive)
37
+ visit(program.outputs.emissive);
38
+ if (program.outputs.roughness)
39
+ visit(program.outputs.roughness);
40
+ if (program.outputs.metallic)
41
+ visit(program.outputs.metallic);
42
+ if (program.outputs.opacity)
43
+ visit(program.outputs.opacity);
44
+ const parameters = Object.entries(program.parameters ?? {})
45
+ .sort(([left], [right]) => left.localeCompare(right))
46
+ .map(([name, definition], index) => ({
47
+ name,
48
+ uniform: `skProgramParameter${index}`,
49
+ definition: structuredClone(definition),
50
+ }));
51
+ const requirements = {
52
+ localPosition: ordered.some((node) => node.type === "input.coordinate" && node.space === "local"),
53
+ worldPosition: ordered.some((node) => node.type === "input.coordinate" && node.space === "world"),
54
+ fresnel: ordered.some((node) => node.type === "input.fresnel"),
55
+ noise: ordered.some((node) => node.type.startsWith("noise.")),
56
+ };
57
+ const topology = {
58
+ nodes: ordered,
59
+ outputs: program.outputs,
60
+ parameters: parameters.map(({ name, uniform, definition }) => ({
61
+ name,
62
+ uniform,
63
+ type: definition.type,
64
+ })),
65
+ };
66
+ return {
67
+ instructions: ordered.map((node) => ({
68
+ node,
69
+ valueType: getMaterialProgramNodeValueType(node),
70
+ })),
71
+ parameters,
72
+ outputs: structuredClone(program.outputs),
73
+ requirements,
74
+ topologySignature: fnv1a(stableStringify(topology)),
75
+ contentSignature: fnv1a(stableStringify(program)),
76
+ };
77
+ }
78
+ function references(node) {
79
+ switch (node.type) {
80
+ case "math.add":
81
+ case "math.subtract":
82
+ case "math.multiply":
83
+ case "math.divide":
84
+ case "math.min":
85
+ case "math.max":
86
+ case "color.multiply":
87
+ return [node.a, node.b];
88
+ case "noise.fbm3d":
89
+ case "noise.voronoi3d":
90
+ return [node.x, node.y, node.z, node.scale];
91
+ case "math.sin":
92
+ case "math.abs":
93
+ case "math.fract":
94
+ return [node.input];
95
+ case "math.clamp":
96
+ return [node.input, node.minimum, node.maximum];
97
+ case "math.smoothstep":
98
+ return [node.edge0, node.edge1, node.input];
99
+ case "color.mix":
100
+ return [node.a, node.b, node.factor];
101
+ case "color.scale":
102
+ return [node.color, node.factor];
103
+ default:
104
+ return [];
105
+ }
106
+ }
107
+ function stableStringify(value) {
108
+ if (Array.isArray(value))
109
+ return `[${value.map(stableStringify).join(",")}]`;
110
+ if (value && typeof value === "object")
111
+ return `{${Object.entries(value)
112
+ .sort(([left], [right]) => left.localeCompare(right))
113
+ .map(([key, item]) => `${JSON.stringify(key)}:${stableStringify(item)}`)
114
+ .join(",")}}`;
115
+ return JSON.stringify(value) ?? "null";
116
+ }
117
+ function fnv1a(value) {
118
+ let hash = 0x811c9dc5;
119
+ for (let index = 0; index < value.length; index += 1) {
120
+ hash ^= value.charCodeAt(index);
121
+ hash = Math.imul(hash, 0x01000193);
122
+ }
123
+ return `fnv1a:${(hash >>> 0).toString(16).padStart(8, "0")}`;
124
+ }
125
+ function formatPath(path) {
126
+ return path.reduce((result, part) => typeof part === "number"
127
+ ? `${result}[${part}]`
128
+ : result
129
+ ? `${result}.${part}`
130
+ : part, "");
131
+ }
132
+ //# sourceMappingURL=material-compiler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"material-compiler.js","sourceRoot":"","sources":["../src/material-compiler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ import type { CompiledMaterialProgram } from "./material-compiler.js";
2
+ export interface MaterialProgramEmitter<TArtifact> {
3
+ readonly id: string;
4
+ readonly version: string;
5
+ readonly language: "glsl" | "wgsl";
6
+ emit(program: Readonly<CompiledMaterialProgram>): TArtifact;
7
+ }
8
+ export interface MaterialProgramGlslArtifact {
9
+ readonly emitterId: string;
10
+ readonly emitterVersion: string;
11
+ readonly language: "glsl";
12
+ readonly uniforms: readonly string[];
13
+ readonly vertex: Readonly<{
14
+ definitions: string;
15
+ updatePosition: string;
16
+ }>;
17
+ readonly fragment: Readonly<{
18
+ definitions: string;
19
+ declarations: string;
20
+ baseColor?: string;
21
+ emissive?: string;
22
+ roughness?: string;
23
+ metallic?: string;
24
+ opacity?: string;
25
+ }>;
26
+ }
27
+ export interface MaterialProgramWgslArtifact {
28
+ readonly emitterId: string;
29
+ readonly emitterVersion: string;
30
+ readonly language: "wgsl";
31
+ readonly source: string;
32
+ readonly functionName: "skenora_material_program";
33
+ readonly parameterFields: readonly Readonly<{
34
+ name: string;
35
+ field: string;
36
+ type: "f32" | "vec3<f32>";
37
+ }>[];
38
+ readonly requirements: CompiledMaterialProgram["requirements"];
39
+ }
40
+ export declare const materialProgramGlslEmitter: MaterialProgramEmitter<MaterialProgramGlslArtifact>;
41
+ export declare const materialProgramWgslEmitter: MaterialProgramEmitter<MaterialProgramWgslArtifact>;
42
+ export declare function emitMaterialProgramGlsl(compiled: Readonly<CompiledMaterialProgram>): MaterialProgramGlslArtifact;
43
+ export declare function emitMaterialProgramWgsl(compiled: Readonly<CompiledMaterialProgram>): MaterialProgramWgslArtifact;
44
+ //# sourceMappingURL=material-program-emitters.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"material-program-emitters.d.ts","sourceRoot":"","sources":["../src/material-program-emitters.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAEnE,MAAM,WAAW,sBAAsB,CAAC,SAAS;IAC/C,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;IACnC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,uBAAuB,CAAC,GAAG,SAAS,CAAC;CAC7D;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC;QACxB,WAAW,EAAE,MAAM,CAAC;QACpB,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC,CAAC;IACH,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;QAC1B,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;QACrB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,YAAY,EAAE,0BAA0B,CAAC;IAClD,QAAQ,CAAC,eAAe,EAAE,SAAS,QAAQ,CAAC;QAC1C,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,KAAK,GAAG,WAAW,CAAC;KAC3B,CAAC,EAAE,CAAC;IACL,QAAQ,CAAC,YAAY,EAAE,uBAAuB,CAAC,cAAc,CAAC,CAAC;CAChE;AAED,eAAO,MAAM,0BAA0B,EAAE,sBAAsB,CAAC,2BAA2B,CAMvF,CAAC;AAEL,eAAO,MAAM,0BAA0B,EAAE,sBAAsB,CAAC,2BAA2B,CAMvF,CAAC;AAEL,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,QAAQ,CAAC,uBAAuB,CAAC,GAC1C,2BAA2B,CA4C7B;AAED,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,QAAQ,CAAC,uBAAuB,CAAC,GAC1C,2BAA2B,CAyE7B"}
@@ -0,0 +1,335 @@
1
+ export const materialProgramGlslEmitter = Object.freeze({
2
+ id: "skenora.material-program.glsl-babylon-pbr",
3
+ version: "2",
4
+ language: "glsl",
5
+ emit: emitMaterialProgramGlsl,
6
+ });
7
+ export const materialProgramWgslEmitter = Object.freeze({
8
+ id: "skenora.material-program.wgsl",
9
+ version: "2",
10
+ language: "wgsl",
11
+ emit: emitMaterialProgramWgsl,
12
+ });
13
+ export function emitMaterialProgramGlsl(compiled) {
14
+ const names = instructionNames(compiled);
15
+ const declarations = compiled.instructions
16
+ .map(({ node, valueType }) => {
17
+ const name = names.get(node.id);
18
+ return `${valueType === "color" ? "vec3" : "float"} ${name} = ${glslNodeExpression(node, names, compiled)};`;
19
+ })
20
+ .join("\n");
21
+ const baseColor = compiled.outputs.baseColor;
22
+ const emissive = compiled.outputs.emissive;
23
+ const roughness = compiled.outputs.roughness;
24
+ const metallic = compiled.outputs.metallic;
25
+ const opacity = compiled.outputs.opacity;
26
+ const helpers = compiled.requirements.noise ? GLSL_NOISE_HELPERS : "";
27
+ return Object.freeze({
28
+ emitterId: materialProgramGlslEmitter.id,
29
+ emitterVersion: materialProgramGlslEmitter.version,
30
+ language: "glsl",
31
+ uniforms: Object.freeze(compiled.parameters.map(({ uniform }) => uniform)),
32
+ vertex: Object.freeze({
33
+ definitions: compiled.requirements.localPosition
34
+ ? "#ifdef SKENORA_PROGRAM\nvarying vec3 vSkenoraProgramLocalPosition;\n#endif"
35
+ : "",
36
+ updatePosition: compiled.requirements.localPosition
37
+ ? "#ifdef SKENORA_PROGRAM\nvSkenoraProgramLocalPosition = positionUpdated;\n#endif"
38
+ : "",
39
+ }),
40
+ fragment: Object.freeze({
41
+ definitions: [
42
+ compiled.requirements.localPosition
43
+ ? "#ifdef SKENORA_PROGRAM\nvarying vec3 vSkenoraProgramLocalPosition;\n#endif"
44
+ : "",
45
+ helpers,
46
+ ]
47
+ .filter(Boolean)
48
+ .join("\n"),
49
+ declarations,
50
+ ...(baseColor === undefined ? {} : { baseColor: names.get(baseColor) }),
51
+ ...(emissive === undefined ? {} : { emissive: names.get(emissive) }),
52
+ ...(roughness === undefined ? {} : { roughness: names.get(roughness) }),
53
+ ...(metallic === undefined ? {} : { metallic: names.get(metallic) }),
54
+ ...(opacity === undefined ? {} : { opacity: names.get(opacity) }),
55
+ }),
56
+ });
57
+ }
58
+ export function emitMaterialProgramWgsl(compiled) {
59
+ const names = instructionNames(compiled);
60
+ const parameters = new Map(compiled.parameters.map((parameter) => [
61
+ parameter.name,
62
+ `parameter_${parameter.uniform}`,
63
+ ]));
64
+ const parameterFields = compiled.parameters.map((parameter) => ({
65
+ name: parameter.name,
66
+ field: parameters.get(parameter.name),
67
+ type: parameter.definition.type === "number"
68
+ ? "f32"
69
+ : "vec3<f32>",
70
+ }));
71
+ const hasDivision = compiled.instructions.some(({ node }) => node.type === "math.divide");
72
+ const declarations = compiled.instructions
73
+ .map(({ node, valueType }) => {
74
+ const name = names.get(node.id);
75
+ return ` let ${name}: ${valueType === "color" ? "vec3<f32>" : "f32"} = ${wgslNodeExpression(node, names, parameters)};`;
76
+ })
77
+ .join("\n");
78
+ const baseColor = compiled.outputs.baseColor;
79
+ const emissive = compiled.outputs.emissive;
80
+ const roughness = compiled.outputs.roughness;
81
+ const metallic = compiled.outputs.metallic;
82
+ const opacity = compiled.outputs.opacity;
83
+ const source = `${hasDivision ? `${WGSL_SAFE_DIVISOR}\n\n` : ""}${compiled.requirements.noise ? `${WGSL_NOISE_HELPERS}\n\n` : ""}struct SkenoraMaterialProgramInputs {
84
+ local_position: vec3<f32>,
85
+ world_position: vec3<f32>,
86
+ normal: vec3<f32>,
87
+ view_direction: vec3<f32>,
88
+ }
89
+
90
+ struct SkenoraMaterialProgramParameters {
91
+ ${parameterFields.length ? parameterFields.map((field) => ` ${field.field}: ${field.type},`).join("\n") : " unused: f32,"}
92
+ }
93
+
94
+ struct SkenoraMaterialProgramOutputs {
95
+ base_color: vec3<f32>,
96
+ emissive: vec3<f32>,
97
+ roughness: f32,
98
+ metallic: f32,
99
+ opacity: f32,
100
+ }
101
+
102
+ fn skenora_material_program(
103
+ inputs: SkenoraMaterialProgramInputs,
104
+ parameters: SkenoraMaterialProgramParameters,
105
+ ) -> SkenoraMaterialProgramOutputs {
106
+ ${declarations}
107
+ return SkenoraMaterialProgramOutputs(
108
+ ${baseColor === undefined ? "vec3<f32>(0.0)" : names.get(baseColor)},
109
+ ${emissive === undefined ? "vec3<f32>(0.0)" : names.get(emissive)},
110
+ ${roughness === undefined ? "0.5" : names.get(roughness)},
111
+ ${metallic === undefined ? "0.0" : names.get(metallic)},
112
+ ${opacity === undefined ? "1.0" : names.get(opacity)},
113
+ );
114
+ }`;
115
+ return Object.freeze({
116
+ emitterId: materialProgramWgslEmitter.id,
117
+ emitterVersion: materialProgramWgslEmitter.version,
118
+ language: "wgsl",
119
+ source,
120
+ functionName: "skenora_material_program",
121
+ parameterFields: Object.freeze(parameterFields.map((field) => Object.freeze(field))),
122
+ requirements: Object.freeze({ ...compiled.requirements }),
123
+ });
124
+ }
125
+ function instructionNames(compiled) {
126
+ return new Map(compiled.instructions.map((instruction, index) => [
127
+ instruction.node.id,
128
+ `sk_program_value_${index}`,
129
+ ]));
130
+ }
131
+ function glslNodeExpression(node, names, compiled) {
132
+ const ref = (id) => names.get(id);
133
+ const parameter = (name) => compiled.parameters.find((item) => item.name === name).uniform;
134
+ switch (node.type) {
135
+ case "value.number":
136
+ return shaderFloat(node.value);
137
+ case "value.color":
138
+ return `vec3(${shaderFloat(node.value.r)}, ${shaderFloat(node.value.g)}, ${shaderFloat(node.value.b)})`;
139
+ case "parameter.number":
140
+ return `${parameter(node.parameter)}.x`;
141
+ case "parameter.color":
142
+ return `${parameter(node.parameter)}.rgb`;
143
+ case "input.coordinate": {
144
+ const position = node.space === "local" ? "vSkenoraProgramLocalPosition" : "vPositionW";
145
+ return `${position}.${node.axis}`;
146
+ }
147
+ case "input.fresnel":
148
+ return `pow(1.0 - clamp(abs(dot(normalize(normalW), viewDirectionW)), 0.0, 1.0), ${shaderFloat(node.power ?? 2)})`;
149
+ case "noise.fbm3d":
150
+ return `skenora_fbm3(vec3(${ref(node.x)}, ${ref(node.y)}, ${ref(node.z)}) * ${ref(node.scale)}, ${node.octaves}, ${shaderFloat(node.seed)})`;
151
+ case "noise.voronoi3d":
152
+ return `skenora_voronoi3(vec3(${ref(node.x)}, ${ref(node.y)}, ${ref(node.z)}) * ${ref(node.scale)}, ${shaderFloat(node.seed)})`;
153
+ case "math.add":
154
+ return `(${ref(node.a)} + ${ref(node.b)})`;
155
+ case "math.subtract":
156
+ return `(${ref(node.a)} - ${ref(node.b)})`;
157
+ case "math.multiply":
158
+ return `(${ref(node.a)} * ${ref(node.b)})`;
159
+ case "math.divide": {
160
+ const denominator = ref(node.b);
161
+ return `(${ref(node.a)} / (abs(${denominator}) < 0.000001 ? (${denominator} < 0.0 ? -0.000001 : 0.000001) : ${denominator}))`;
162
+ }
163
+ case "math.min":
164
+ return `min(${ref(node.a)}, ${ref(node.b)})`;
165
+ case "math.max":
166
+ return `max(${ref(node.a)}, ${ref(node.b)})`;
167
+ case "math.sin":
168
+ return `sin(${ref(node.input)})`;
169
+ case "math.abs":
170
+ return `abs(${ref(node.input)})`;
171
+ case "math.fract":
172
+ return `fract(${ref(node.input)})`;
173
+ case "math.clamp":
174
+ return `clamp(${ref(node.input)}, ${ref(node.minimum)}, ${ref(node.maximum)})`;
175
+ case "math.smoothstep":
176
+ return `smoothstep(${ref(node.edge0)}, ${ref(node.edge1)}, ${ref(node.input)})`;
177
+ case "color.mix":
178
+ return `mix(${ref(node.a)}, ${ref(node.b)}, clamp(${ref(node.factor)}, 0.0, 1.0))`;
179
+ case "color.multiply":
180
+ return `(${ref(node.a)} * ${ref(node.b)})`;
181
+ case "color.scale":
182
+ return `(${ref(node.color)} * ${ref(node.factor)})`;
183
+ }
184
+ }
185
+ function wgslNodeExpression(node, names, parameters) {
186
+ const ref = (id) => names.get(id);
187
+ const parameter = (name) => `parameters.${parameters.get(name)}`;
188
+ switch (node.type) {
189
+ case "value.number":
190
+ return shaderFloat(node.value);
191
+ case "value.color":
192
+ return `vec3<f32>(${shaderFloat(node.value.r)}, ${shaderFloat(node.value.g)}, ${shaderFloat(node.value.b)})`;
193
+ case "parameter.number":
194
+ case "parameter.color":
195
+ return parameter(node.parameter);
196
+ case "input.coordinate": {
197
+ const position = node.space === "local"
198
+ ? "inputs.local_position"
199
+ : "inputs.world_position";
200
+ return `${position}.${node.axis}`;
201
+ }
202
+ case "input.fresnel":
203
+ return `pow(1.0 - clamp(abs(dot(normalize(inputs.normal), normalize(inputs.view_direction))), 0.0, 1.0), ${shaderFloat(node.power ?? 2)})`;
204
+ case "noise.fbm3d":
205
+ return `skenora_fbm3(vec3<f32>(${ref(node.x)}, ${ref(node.y)}, ${ref(node.z)}) * ${ref(node.scale)}, ${node.octaves}u, ${shaderFloat(node.seed)})`;
206
+ case "noise.voronoi3d":
207
+ return `skenora_voronoi3(vec3<f32>(${ref(node.x)}, ${ref(node.y)}, ${ref(node.z)}) * ${ref(node.scale)}, ${shaderFloat(node.seed)})`;
208
+ case "math.add":
209
+ return `(${ref(node.a)} + ${ref(node.b)})`;
210
+ case "math.subtract":
211
+ return `(${ref(node.a)} - ${ref(node.b)})`;
212
+ case "math.multiply":
213
+ return `(${ref(node.a)} * ${ref(node.b)})`;
214
+ case "math.divide":
215
+ return `(${ref(node.a)} / skenora_safe_divisor(${ref(node.b)}))`;
216
+ case "math.min":
217
+ return `min(${ref(node.a)}, ${ref(node.b)})`;
218
+ case "math.max":
219
+ return `max(${ref(node.a)}, ${ref(node.b)})`;
220
+ case "math.sin":
221
+ return `sin(${ref(node.input)})`;
222
+ case "math.abs":
223
+ return `abs(${ref(node.input)})`;
224
+ case "math.fract":
225
+ return `fract(${ref(node.input)})`;
226
+ case "math.clamp":
227
+ return `clamp(${ref(node.input)}, ${ref(node.minimum)}, ${ref(node.maximum)})`;
228
+ case "math.smoothstep":
229
+ return `smoothstep(${ref(node.edge0)}, ${ref(node.edge1)}, ${ref(node.input)})`;
230
+ case "color.mix":
231
+ return `mix(${ref(node.a)}, ${ref(node.b)}, clamp(${ref(node.factor)}, 0.0, 1.0))`;
232
+ case "color.multiply":
233
+ return `(${ref(node.a)} * ${ref(node.b)})`;
234
+ case "color.scale":
235
+ return `(${ref(node.color)} * ${ref(node.factor)})`;
236
+ }
237
+ }
238
+ function shaderFloat(value) {
239
+ const text = Number(value).toString();
240
+ return /[.eE]/u.test(text) ? text : `${text}.0`;
241
+ }
242
+ const WGSL_SAFE_DIVISOR = `fn skenora_safe_divisor(value: f32) -> f32 {
243
+ if (abs(value) >= 0.000001) {
244
+ return value;
245
+ }
246
+ if (value < 0.0) {
247
+ return -0.000001;
248
+ }
249
+ return 0.000001;
250
+ }`;
251
+ const GLSL_NOISE_HELPERS = `
252
+ #ifdef SKENORA_PROGRAM
253
+ float skenora_hash31(vec3 point, float seed) {
254
+ return fract(sin(dot(point + seed, vec3(127.1, 311.7, 74.7))) * 43758.5453123);
255
+ }
256
+ float skenora_value_noise3(vec3 point, float seed) {
257
+ vec3 cell = floor(point);
258
+ vec3 local = fract(point);
259
+ vec3 blend = local * local * (3.0 - 2.0 * local);
260
+ float n000 = skenora_hash31(cell, seed);
261
+ float n100 = skenora_hash31(cell + vec3(1.0, 0.0, 0.0), seed);
262
+ float n010 = skenora_hash31(cell + vec3(0.0, 1.0, 0.0), seed);
263
+ float n110 = skenora_hash31(cell + vec3(1.0, 1.0, 0.0), seed);
264
+ float n001 = skenora_hash31(cell + vec3(0.0, 0.0, 1.0), seed);
265
+ float n101 = skenora_hash31(cell + vec3(1.0, 0.0, 1.0), seed);
266
+ float n011 = skenora_hash31(cell + vec3(0.0, 1.0, 1.0), seed);
267
+ float n111 = skenora_hash31(cell + vec3(1.0), seed);
268
+ return mix(mix(mix(n000, n100, blend.x), mix(n010, n110, blend.x), blend.y), mix(mix(n001, n101, blend.x), mix(n011, n111, blend.x), blend.y), blend.z);
269
+ }
270
+ float skenora_fbm3(vec3 point, int octaves, float seed) {
271
+ float value = 0.0;
272
+ float amplitude = 0.5;
273
+ float total = 0.0;
274
+ for (int index = 0; index < 6; index++) {
275
+ if (index >= octaves) break;
276
+ value += skenora_value_noise3(point, seed + float(index) * 1013.0) * amplitude;
277
+ total += amplitude;
278
+ point = point * 2.03 + vec3(17.17, -9.23, 4.11);
279
+ amplitude *= 0.5;
280
+ }
281
+ return value / max(total, 0.000001);
282
+ }
283
+ float skenora_voronoi3(vec3 point, float seed) {
284
+ vec3 cell = floor(point);
285
+ vec3 local = fract(point);
286
+ float distanceValue = 2.0;
287
+ for (int z = -1; z <= 1; z++) for (int y = -1; y <= 1; y++) for (int x = -1; x <= 1; x++) {
288
+ vec3 neighbor = vec3(float(x), float(y), float(z));
289
+ vec3 feature = vec3(
290
+ skenora_hash31(cell + neighbor, seed),
291
+ skenora_hash31(cell + neighbor, seed + 19.0),
292
+ skenora_hash31(cell + neighbor, seed + 41.0)
293
+ );
294
+ distanceValue = min(distanceValue, length(neighbor + feature - local));
295
+ }
296
+ return clamp(distanceValue, 0.0, 1.0);
297
+ }
298
+ #endif`;
299
+ const WGSL_NOISE_HELPERS = `fn skenora_hash31(point: vec3<f32>, seed: f32) -> f32 {
300
+ return fract(sin(dot(point + vec3<f32>(seed), vec3<f32>(127.1, 311.7, 74.7))) * 43758.5453123);
301
+ }
302
+ fn skenora_value_noise3(point: vec3<f32>, seed: f32) -> f32 {
303
+ let cell = floor(point);
304
+ let local = fract(point);
305
+ let blend = local * local * (vec3<f32>(3.0) - 2.0 * local);
306
+ let low = mix(mix(skenora_hash31(cell, seed), skenora_hash31(cell + vec3<f32>(1.0, 0.0, 0.0), seed), blend.x), mix(skenora_hash31(cell + vec3<f32>(0.0, 1.0, 0.0), seed), skenora_hash31(cell + vec3<f32>(1.0, 1.0, 0.0), seed), blend.x), blend.y);
307
+ let high = mix(mix(skenora_hash31(cell + vec3<f32>(0.0, 0.0, 1.0), seed), skenora_hash31(cell + vec3<f32>(1.0, 0.0, 1.0), seed), blend.x), mix(skenora_hash31(cell + vec3<f32>(0.0, 1.0, 1.0), seed), skenora_hash31(cell + vec3<f32>(1.0), seed), blend.x), blend.y);
308
+ return mix(low, high, blend.z);
309
+ }
310
+ fn skenora_fbm3(initial_point: vec3<f32>, octaves: u32, seed: f32) -> f32 {
311
+ var point = initial_point;
312
+ var value = 0.0;
313
+ var amplitude = 0.5;
314
+ var total = 0.0;
315
+ for (var index = 0u; index < 6u; index += 1u) {
316
+ if (index >= octaves) { break; }
317
+ value += skenora_value_noise3(point, seed + f32(index) * 1013.0) * amplitude;
318
+ total += amplitude;
319
+ point = point * 2.03 + vec3<f32>(17.17, -9.23, 4.11);
320
+ amplitude *= 0.5;
321
+ }
322
+ return value / max(total, 0.000001);
323
+ }
324
+ fn skenora_voronoi3(point: vec3<f32>, seed: f32) -> f32 {
325
+ let cell = floor(point);
326
+ let local = fract(point);
327
+ var result = 2.0;
328
+ for (var z = -1; z <= 1; z += 1) { for (var y = -1; y <= 1; y += 1) { for (var x = -1; x <= 1; x += 1) {
329
+ let neighbor = vec3<f32>(f32(x), f32(y), f32(z));
330
+ let feature = vec3<f32>(skenora_hash31(cell + neighbor, seed), skenora_hash31(cell + neighbor, seed + 19.0), skenora_hash31(cell + neighbor, seed + 41.0));
331
+ result = min(result, length(neighbor + feature - local));
332
+ }}}
333
+ return clamp(result, 0.0, 1.0);
334
+ }`;
335
+ //# sourceMappingURL=material-program-emitters.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"material-program-emitters.js","sourceRoot":"","sources":["../src/material-program-emitters.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import { type RenderGraphIssue, type RenderGraphPass, type RenderGraphProgram, type RenderGraphTarget } from "@skenora/contracts";
2
+ export interface CompiledRenderGraph {
3
+ readonly targets: readonly Readonly<RenderGraphTarget & {
4
+ scale: number;
5
+ bytesPerPixel: number;
6
+ }>[];
7
+ readonly passes: readonly Readonly<RenderGraphPass>[];
8
+ readonly estimatedBytesAt1080p: number;
9
+ readonly topologySignature: string;
10
+ }
11
+ export declare class RenderGraphCompilationError extends Error {
12
+ readonly issues: readonly RenderGraphIssue[];
13
+ constructor(issues: readonly RenderGraphIssue[]);
14
+ }
15
+ /** Validate and lower authored declarations to ordered renderer-neutral target/pass IR. */
16
+ export declare function compileRenderGraph(graph: Readonly<RenderGraphProgram>): CompiledRenderGraph;
17
+ //# sourceMappingURL=render-graph-compiler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render-graph-compiler.d.ts","sourceRoot":"","sources":["../src/render-graph-compiler.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACvB,MAAM,oBAAoB,CAAC;AAE5B,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,OAAO,EAAE,SAAS,QAAQ,CACjC,iBAAiB,GAAG;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CAC7D,EAAE,CAAC;IACJ,QAAQ,CAAC,MAAM,EAAE,SAAS,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC;IACtD,QAAQ,CAAC,qBAAqB,EAAE,MAAM,CAAC;IACvC,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;CACpC;AAED,qBAAa,2BAA4B,SAAQ,KAAK;IACpD,QAAQ,CAAC,MAAM,EAAE,SAAS,gBAAgB,EAAE,CAAC;gBACjC,MAAM,EAAE,SAAS,gBAAgB,EAAE;CAKhD;AAED,2FAA2F;AAC3F,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,QAAQ,CAAC,kBAAkB,CAAC,GAClC,mBAAmB,CAoBrB"}
@@ -0,0 +1,46 @@
1
+ import { validateRenderGraph, } from "@skenora/contracts";
2
+ export class RenderGraphCompilationError extends Error {
3
+ issues;
4
+ constructor(issues) {
5
+ super(issues.map((issue) => issue.message).join("; "));
6
+ this.name = "RenderGraphCompilationError";
7
+ this.issues = issues.map((issue) => ({ ...issue, path: [...issue.path] }));
8
+ }
9
+ }
10
+ /** Validate and lower authored declarations to ordered renderer-neutral target/pass IR. */
11
+ export function compileRenderGraph(graph) {
12
+ const result = validateRenderGraph(graph);
13
+ if (!result.valid)
14
+ throw new RenderGraphCompilationError(result.issues);
15
+ const targets = graph.targets.map((target) => Object.freeze({
16
+ ...structuredClone(target),
17
+ scale: target.size === "half" ? 0.5 : target.size === "quarter" ? 0.25 : 1,
18
+ bytesPerPixel: target.format === "rgba16float" ? 8 : 4,
19
+ }));
20
+ const passes = graph.passes.map((pass) => Object.freeze(structuredClone(pass)));
21
+ return Object.freeze({
22
+ targets: Object.freeze(targets),
23
+ passes: Object.freeze(passes),
24
+ estimatedBytesAt1080p: result.estimatedBytesAt1080p,
25
+ topologySignature: fnv1a(stableStringify(graph)),
26
+ });
27
+ }
28
+ function stableStringify(value) {
29
+ if (Array.isArray(value))
30
+ return `[${value.map(stableStringify).join(",")}]`;
31
+ if (value && typeof value === "object")
32
+ return `{${Object.entries(value)
33
+ .sort(([left], [right]) => left.localeCompare(right))
34
+ .map(([key, item]) => `${JSON.stringify(key)}:${stableStringify(item)}`)
35
+ .join(",")}}`;
36
+ return JSON.stringify(value) ?? "null";
37
+ }
38
+ function fnv1a(value) {
39
+ let hash = 0x811c9dc5;
40
+ for (let index = 0; index < value.length; index += 1) {
41
+ hash ^= value.charCodeAt(index);
42
+ hash = Math.imul(hash, 0x01000193);
43
+ }
44
+ return `fnv1a:${(hash >>> 0).toString(16).padStart(8, "0")}`;
45
+ }
46
+ //# sourceMappingURL=render-graph-compiler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render-graph-compiler.js","sourceRoot":"","sources":["../src/render-graph-compiler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import { type SimulationProgram, type SimulationProgramIssue, type SimulationKernel } from "@skenora/contracts";
2
+ export type SimulationOperation = "fluid.inject" | "fluid.advect" | "fluid.project" | "ocean.spectrum" | "ocean.bit-reverse-horizontal" | "ocean.fft-horizontal" | "ocean.bit-reverse-vertical" | "ocean.fft-vertical" | "radiance.seed" | "radiance.jump-flood" | "radiance.cascade" | "radiance.resolve";
3
+ export interface CompiledSimulationPass {
4
+ readonly id: string;
5
+ readonly operation: SimulationOperation;
6
+ readonly iteration: number;
7
+ readonly span: number;
8
+ }
9
+ export interface CompiledSimulationProgram {
10
+ readonly kernel: SimulationKernel;
11
+ readonly width: number;
12
+ readonly height: number;
13
+ readonly workgroupSize: 8 | 16;
14
+ readonly dispatch: readonly [number, number, 1];
15
+ readonly fixedStepMilliseconds: number;
16
+ readonly maxSubsteps: number;
17
+ readonly resourceIds: readonly [string, string];
18
+ readonly estimatedBytes: number;
19
+ readonly passes: readonly CompiledSimulationPass[];
20
+ readonly topologySignature: string;
21
+ readonly program: SimulationProgram;
22
+ }
23
+ export declare class SimulationProgramCompilationError extends Error {
24
+ readonly issues: readonly SimulationProgramIssue[];
25
+ constructor(issues: readonly SimulationProgramIssue[]);
26
+ }
27
+ /** Lower trusted simulation declarations to deterministic pass and resource IR. */
28
+ export declare function compileSimulationProgram(program: Readonly<SimulationProgram>): CompiledSimulationProgram;
29
+ //# sourceMappingURL=simulation-compiler.d.ts.map