reze-engine 0.17.1 → 0.18.1
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/engine.d.ts +34 -0
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +258 -15
- package/dist/gpu-profile.d.ts +19 -0
- package/dist/gpu-profile.d.ts.map +1 -0
- package/dist/gpu-profile.js +120 -0
- package/dist/graph/compile.d.ts +34 -0
- package/dist/graph/compile.d.ts.map +1 -0
- package/dist/graph/compile.js +299 -0
- package/dist/graph/presets/body.d.ts +3 -0
- package/dist/graph/presets/body.d.ts.map +1 -0
- package/dist/graph/presets/body.js +100 -0
- package/dist/graph/presets/cloth_rough.d.ts +3 -0
- package/dist/graph/presets/cloth_rough.d.ts.map +1 -0
- package/dist/graph/presets/cloth_rough.js +61 -0
- package/dist/graph/presets/cloth_smooth.d.ts +3 -0
- package/dist/graph/presets/cloth_smooth.d.ts.map +1 -0
- package/dist/graph/presets/cloth_smooth.js +53 -0
- package/dist/graph/presets/default.d.ts +3 -0
- package/dist/graph/presets/default.d.ts.map +1 -0
- package/dist/graph/presets/default.js +20 -0
- package/dist/graph/presets/eye.d.ts +3 -0
- package/dist/graph/presets/eye.d.ts.map +1 -0
- package/dist/graph/presets/eye.js +30 -0
- package/dist/graph/presets/face.d.ts +3 -0
- package/dist/graph/presets/face.d.ts.map +1 -0
- package/dist/graph/presets/face.js +125 -0
- package/dist/graph/presets/hair.d.ts +3 -0
- package/dist/graph/presets/hair.d.ts.map +1 -0
- package/dist/graph/presets/hair.js +79 -0
- package/dist/graph/presets/metal.d.ts +3 -0
- package/dist/graph/presets/metal.d.ts.map +1 -0
- package/dist/graph/presets/metal.js +58 -0
- package/dist/graph/presets/stockings.d.ts +3 -0
- package/dist/graph/presets/stockings.d.ts.map +1 -0
- package/dist/graph/presets/stockings.js +54 -0
- package/dist/graph/registry.d.ts +28 -0
- package/dist/graph/registry.d.ts.map +1 -0
- package/dist/graph/registry.js +322 -0
- package/dist/graph/schema.d.ts +66 -0
- package/dist/graph/schema.d.ts.map +1 -0
- package/dist/graph/schema.js +6 -0
- package/dist/graph/slots.d.ts +14 -0
- package/dist/graph/slots.d.ts.map +1 -0
- package/dist/graph/slots.js +155 -0
- package/dist/index.d.ts +13 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -0
- package/dist/physics/profile.d.ts +18 -0
- package/dist/physics/profile.d.ts.map +1 -0
- package/dist/physics/profile.js +44 -0
- package/package.json +2 -1
- package/src/engine.ts +290 -15
- package/src/graph/compile.ts +342 -0
- package/src/graph/presets/body.ts +103 -0
- package/src/graph/presets/cloth_rough.ts +64 -0
- package/src/graph/presets/cloth_smooth.ts +56 -0
- package/src/graph/presets/default.ts +23 -0
- package/src/graph/presets/eye.ts +33 -0
- package/src/graph/presets/face.ts +136 -0
- package/src/graph/presets/hair.ts +82 -0
- package/src/graph/presets/metal.ts +61 -0
- package/src/graph/presets/stockings.ts +57 -0
- package/src/graph/registry.ts +351 -0
- package/src/graph/schema.ts +60 -0
- package/src/graph/slots.ts +178 -0
- package/src/index.ts +27 -0
- package/dist/physics-debug.d.ts +0 -30
- package/dist/physics-debug.d.ts.map +0 -1
- package/dist/physics-debug.js +0 -526
- package/dist/shaders/passes/physics-debug.d.ts +0 -2
- package/dist/shaders/passes/physics-debug.d.ts.map +0 -1
- package/dist/shaders/passes/physics-debug.js +0 -69
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
// Node registry: one entry per Blender-equivalent node backed by NODES_WGSL (nodes.ts).
|
|
2
|
+
// The registry adds no WGSL of its own — a node type exists here only if its function
|
|
3
|
+
// already exists (validated against EEVEE) in the shader library, or is a WGSL builtin.
|
|
4
|
+
// Semantics are frozen Blender 3.6 legacy-EEVEE; enum modes (math op, mix blend type,
|
|
5
|
+
// ramp interpolation) are part of the type string so they are unambiguously topology.
|
|
6
|
+
// ─── Literal formatting ───────────────────────────────────────────────
|
|
7
|
+
// Deterministic: same graph JSON → byte-identical WGSL. String(x) is JS shortest
|
|
8
|
+
// round-trip, so full-precision Blender constants (0.15000000596046448) survive.
|
|
9
|
+
export function fmtFloat(x) {
|
|
10
|
+
if (!Number.isFinite(x))
|
|
11
|
+
throw new Error(`non-finite literal: ${x}`);
|
|
12
|
+
const s = String(x);
|
|
13
|
+
return /[.e]/.test(s) ? s : s + ".0";
|
|
14
|
+
}
|
|
15
|
+
export function fmtValue(value, type) {
|
|
16
|
+
if (typeof value === "number") {
|
|
17
|
+
if (type === "float")
|
|
18
|
+
return fmtFloat(value);
|
|
19
|
+
if (type === "color" || type === "vector")
|
|
20
|
+
return `vec3f(${fmtFloat(value)})`;
|
|
21
|
+
return `vec4f(vec3f(${fmtFloat(value)}), 1.0)`;
|
|
22
|
+
}
|
|
23
|
+
if (value.length === 3) {
|
|
24
|
+
const [x, y, z] = value;
|
|
25
|
+
if (type === "vec4")
|
|
26
|
+
return `vec4f(${fmtFloat(x)}, ${fmtFloat(y)}, ${fmtFloat(z)}, 1.0)`;
|
|
27
|
+
if (type === "float")
|
|
28
|
+
throw new Error(`vector literal on float socket`);
|
|
29
|
+
// All-equal shorthand matches the hand-written shaders (vec3f(0.167…)).
|
|
30
|
+
if (x === y && y === z)
|
|
31
|
+
return `vec3f(${fmtFloat(x)})`;
|
|
32
|
+
return `vec3f(${fmtFloat(x)}, ${fmtFloat(y)}, ${fmtFloat(z)})`;
|
|
33
|
+
}
|
|
34
|
+
if (type !== "vec4")
|
|
35
|
+
throw new Error(`vec4 literal on ${type} socket`);
|
|
36
|
+
return `vec4f(${value.map(fmtFloat).join(", ")})`;
|
|
37
|
+
}
|
|
38
|
+
/** Does a literal's shape fit a socket type? (Scalar splats onto color/vector/vec4.) */
|
|
39
|
+
export function literalFits(value, type) {
|
|
40
|
+
if (typeof value === "number")
|
|
41
|
+
return true;
|
|
42
|
+
if (value.length === 3)
|
|
43
|
+
return type !== "float";
|
|
44
|
+
return type === "vec4";
|
|
45
|
+
}
|
|
46
|
+
// ─── Implicit socket conversions (Blender-faithful) ──────────────────
|
|
47
|
+
// vec4 appears only on ramp stop-color literals — never linkable, so conversions
|
|
48
|
+
// cover float/color/vector. vector→float is NOT implicit in Blender; rejected.
|
|
49
|
+
export function canConvert(from, to) {
|
|
50
|
+
if (from === to)
|
|
51
|
+
return true;
|
|
52
|
+
if (from === "color" && to === "float")
|
|
53
|
+
return true; // BT.601 via color_to_value
|
|
54
|
+
if (from === "float" && (to === "color" || to === "vector"))
|
|
55
|
+
return true;
|
|
56
|
+
if ((from === "color" && to === "vector") || (from === "vector" && to === "color"))
|
|
57
|
+
return true;
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
export function convert(from, to, expr) {
|
|
61
|
+
if (from === to)
|
|
62
|
+
return expr;
|
|
63
|
+
if (from === "color" && to === "float")
|
|
64
|
+
return `color_to_value(${expr})`;
|
|
65
|
+
if (from === "float")
|
|
66
|
+
return `vec3f(${expr})`;
|
|
67
|
+
return expr; // color ↔ vector: bit-identical vec3f pass-through
|
|
68
|
+
}
|
|
69
|
+
// ─── Registry ─────────────────────────────────────────────────────────
|
|
70
|
+
const F = (d, requiresLink = false) => ({ type: "float", default: d, requiresLink });
|
|
71
|
+
const C = (d = [1, 1, 1], requiresLink = false) => ({
|
|
72
|
+
type: "color",
|
|
73
|
+
default: d,
|
|
74
|
+
requiresLink,
|
|
75
|
+
});
|
|
76
|
+
const V = (d = [0, 0, 0], requiresLink = false) => ({
|
|
77
|
+
type: "vector",
|
|
78
|
+
default: d,
|
|
79
|
+
requiresLink,
|
|
80
|
+
});
|
|
81
|
+
const V4 = (d) => ({ type: "vec4", default: d });
|
|
82
|
+
const RAMP_INPUTS = {
|
|
83
|
+
fac: F(0.5, true),
|
|
84
|
+
pos0: F(0),
|
|
85
|
+
color0: V4([0, 0, 0, 1]),
|
|
86
|
+
pos1: F(1),
|
|
87
|
+
color1: V4([1, 1, 1, 1]),
|
|
88
|
+
};
|
|
89
|
+
const RAMP_OUTPUTS = { color: "color", alpha: "float", fac_out: "float" };
|
|
90
|
+
// fac_out (.r) matches how a grayscale ramp feeds a scalar consumer in the hand ports —
|
|
91
|
+
// routing through the BT.601 color→float conversion instead would change the value.
|
|
92
|
+
const RAMP_SELECT = { color: ".rgb", alpha: ".a", fac_out: ".r" };
|
|
93
|
+
export const NODE_REGISTRY = {
|
|
94
|
+
// ── Context inputs (template locals; no emission) ──
|
|
95
|
+
texture: {
|
|
96
|
+
inputs: {},
|
|
97
|
+
outputs: { color: "color", alpha: "float" },
|
|
98
|
+
contextOutputs: { color: "tex_color", alpha: "tex_s.a" },
|
|
99
|
+
},
|
|
100
|
+
geometry: {
|
|
101
|
+
inputs: {},
|
|
102
|
+
outputs: {
|
|
103
|
+
normal: "vector",
|
|
104
|
+
view: "vector",
|
|
105
|
+
world_pos: "vector",
|
|
106
|
+
rest_pos: "vector",
|
|
107
|
+
uv: "vector",
|
|
108
|
+
// Blender Texture Coordinate → Reflection (view ray mirrored on the normal);
|
|
109
|
+
// drives env-tracking patterns like metal's voronoi sparkle.
|
|
110
|
+
reflection: "vector",
|
|
111
|
+
},
|
|
112
|
+
contextOutputs: {
|
|
113
|
+
normal: "n",
|
|
114
|
+
view: "v",
|
|
115
|
+
world_pos: "input.worldPos",
|
|
116
|
+
rest_pos: "input.restPos",
|
|
117
|
+
uv: "vec3f(input.uv, 0.0)",
|
|
118
|
+
reflection: "reflect(-v, n)",
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
// ── Literals as nodes (for editor ergonomics; inlined literals work too) ──
|
|
122
|
+
value: { inputs: { value: F(0) }, outputs: { value: "float" }, emit: (a) => a.value },
|
|
123
|
+
rgb: { inputs: { color: C() }, outputs: { color: "color" }, emit: (a) => a.color },
|
|
124
|
+
// ── Color ──
|
|
125
|
+
hue_sat: {
|
|
126
|
+
inputs: { hue: F(0.5), saturation: F(1), value: F(1), fac: F(1), color: C([1, 1, 1], true) },
|
|
127
|
+
outputs: { color: "color" },
|
|
128
|
+
emit: (a) => `hue_sat(${a.hue}, ${a.saturation}, ${a.value}, ${a.fac}, ${a.color})`,
|
|
129
|
+
},
|
|
130
|
+
bright_contrast: {
|
|
131
|
+
inputs: { color: C([1, 1, 1], true), bright: F(0), contrast: F(0) },
|
|
132
|
+
outputs: { color: "color" },
|
|
133
|
+
emit: (a) => `bright_contrast(${a.color}, ${a.bright}, ${a.contrast})`,
|
|
134
|
+
},
|
|
135
|
+
invert: {
|
|
136
|
+
inputs: { fac: F(1), color: C([1, 1, 1], true) },
|
|
137
|
+
outputs: { color: "color" },
|
|
138
|
+
emit: (a) => `invert(${a.fac}, ${a.color})`,
|
|
139
|
+
},
|
|
140
|
+
ramp_constant: {
|
|
141
|
+
inputs: RAMP_INPUTS,
|
|
142
|
+
outputs: RAMP_OUTPUTS,
|
|
143
|
+
outputSelect: RAMP_SELECT,
|
|
144
|
+
emit: (a) => `ramp_constant(${a.fac}, ${a.pos0}, ${a.color0}, ${a.pos1}, ${a.color1})`,
|
|
145
|
+
},
|
|
146
|
+
ramp_linear: {
|
|
147
|
+
inputs: RAMP_INPUTS,
|
|
148
|
+
outputs: RAMP_OUTPUTS,
|
|
149
|
+
outputSelect: RAMP_SELECT,
|
|
150
|
+
emit: (a) => `ramp_linear(${a.fac}, ${a.pos0}, ${a.color0}, ${a.pos1}, ${a.color1})`,
|
|
151
|
+
},
|
|
152
|
+
ramp_cardinal: {
|
|
153
|
+
inputs: RAMP_INPUTS,
|
|
154
|
+
outputs: RAMP_OUTPUTS,
|
|
155
|
+
outputSelect: RAMP_SELECT,
|
|
156
|
+
emit: (a) => `ramp_cardinal(${a.fac}, ${a.pos0}, ${a.color0}, ${a.pos1}, ${a.color1})`,
|
|
157
|
+
},
|
|
158
|
+
ramp_constant_aa: {
|
|
159
|
+
inputs: { fac: F(0.5, true), edge: F(0.5), color0: V4([0, 0, 0, 1]), color1: V4([1, 1, 1, 1]) },
|
|
160
|
+
outputs: RAMP_OUTPUTS,
|
|
161
|
+
outputSelect: RAMP_SELECT,
|
|
162
|
+
emit: (a) => `ramp_constant_edge_aa(${a.fac}, ${a.edge}, ${a.color0}, ${a.color1})`,
|
|
163
|
+
},
|
|
164
|
+
// Blender ColorRamp LINEAR with 3 stops black→white→black (triangular peak at 0.5).
|
|
165
|
+
// The only >2-stop ramp the presets use; folded to closed form like the hand port.
|
|
166
|
+
ramp_tri: {
|
|
167
|
+
inputs: { fac: F(0.5, true) },
|
|
168
|
+
outputs: { value: "float" },
|
|
169
|
+
emit: (a) => `1.0 - abs(2.0 * ${a.fac} - 1.0)`,
|
|
170
|
+
},
|
|
171
|
+
// ── Math (enum op in type string) ──
|
|
172
|
+
"math/add": { inputs: { a: F(0), b: F(0) }, outputs: { value: "float" }, emit: (a) => `math_add(${a.a}, ${a.b})` },
|
|
173
|
+
"math/multiply": {
|
|
174
|
+
inputs: { a: F(0), b: F(0) },
|
|
175
|
+
outputs: { value: "float" },
|
|
176
|
+
emit: (a) => `math_multiply(${a.a}, ${a.b})`,
|
|
177
|
+
},
|
|
178
|
+
"math/power": {
|
|
179
|
+
inputs: { a: F(0), b: F(1) },
|
|
180
|
+
outputs: { value: "float" },
|
|
181
|
+
emit: (a) => `math_power(${a.a}, ${a.b})`,
|
|
182
|
+
},
|
|
183
|
+
"math/greater_than": {
|
|
184
|
+
inputs: { a: F(0), b: F(0.5) },
|
|
185
|
+
outputs: { value: "float" },
|
|
186
|
+
emit: (a) => `math_greater_than(${a.a}, ${a.b})`,
|
|
187
|
+
},
|
|
188
|
+
"math/clamp01": { inputs: { a: F(0) }, outputs: { value: "float" }, emit: (a) => `saturate(${a.a})` },
|
|
189
|
+
// ── Mix (blend type in type string) ──
|
|
190
|
+
"mix/blend": {
|
|
191
|
+
inputs: { fac: F(0.5), a: C([1, 1, 1], true), b: C() },
|
|
192
|
+
outputs: { color: "color" },
|
|
193
|
+
emit: (a) => `mix_blend(${a.fac}, ${a.a}, ${a.b})`,
|
|
194
|
+
},
|
|
195
|
+
"mix/overlay": {
|
|
196
|
+
inputs: { fac: F(0.5), a: C([1, 1, 1], true), b: C() },
|
|
197
|
+
outputs: { color: "color" },
|
|
198
|
+
emit: (a) => `mix_overlay(${a.fac}, ${a.a}, ${a.b})`,
|
|
199
|
+
},
|
|
200
|
+
"mix/multiply": {
|
|
201
|
+
inputs: { fac: F(0.5), a: C([1, 1, 1], true), b: C() },
|
|
202
|
+
outputs: { color: "color" },
|
|
203
|
+
emit: (a) => `mix_multiply(${a.fac}, ${a.a}, ${a.b})`,
|
|
204
|
+
},
|
|
205
|
+
"mix/lighten": {
|
|
206
|
+
inputs: { fac: F(0.5), a: C([1, 1, 1], true), b: C() },
|
|
207
|
+
outputs: { color: "color" },
|
|
208
|
+
emit: (a) => `mix_lighten(${a.fac}, ${a.a}, ${a.b})`,
|
|
209
|
+
},
|
|
210
|
+
"mix/linear_light": {
|
|
211
|
+
inputs: { fac: F(0.5), a: C([1, 1, 1], true), b: C() },
|
|
212
|
+
outputs: { color: "color" },
|
|
213
|
+
emit: (a) => `mix_linear_light(${a.fac}, ${a.a}, ${a.b})`,
|
|
214
|
+
},
|
|
215
|
+
// Emission-add: color + scalar-gated emission. Stand-in for Blender's
|
|
216
|
+
// Emission → Add Shader pair in the ShaderToRGB era (see hair's bright-tex gate).
|
|
217
|
+
"mix/add_emit": {
|
|
218
|
+
inputs: { a: C([0, 0, 0], true), b: F(0) },
|
|
219
|
+
outputs: { color: "color" },
|
|
220
|
+
emit: (a) => `${a.a} + vec3f(${a.b})`,
|
|
221
|
+
},
|
|
222
|
+
// Blender Emission shader: color × strength. In the ShaderToRGB-era ports the
|
|
223
|
+
// emission result feeds a Mix Shader directly as radiance. Color may be a literal
|
|
224
|
+
// (body's rim tints) or linked.
|
|
225
|
+
emission: {
|
|
226
|
+
inputs: { color: C([1, 1, 1]), strength: F(1) },
|
|
227
|
+
outputs: { color: "color" },
|
|
228
|
+
emit: (a) => `${a.color} * ${a.strength}`,
|
|
229
|
+
},
|
|
230
|
+
// Blender Add Shader — radiance sum of two evaluated shading results.
|
|
231
|
+
add_shader: {
|
|
232
|
+
inputs: { a: C([0, 0, 0], true), b: C([0, 0, 0], true) },
|
|
233
|
+
outputs: { color: "color" },
|
|
234
|
+
emit: (a) => `${a.a} + ${a.b}`,
|
|
235
|
+
},
|
|
236
|
+
// Mix Shader — plain lerp between two evaluated shading results.
|
|
237
|
+
mix_shader: {
|
|
238
|
+
inputs: { fac: F(0.5), a: C([0, 0, 0], true), b: C([0, 0, 0]) },
|
|
239
|
+
outputs: { color: "color" },
|
|
240
|
+
emit: (a) => `mix(${a.a}, ${a.b}, ${a.fac})`,
|
|
241
|
+
},
|
|
242
|
+
// ── View-dependent scalars ──
|
|
243
|
+
fresnel: { inputs: { ior: F(1.45) }, outputs: { value: "float" }, emit: (a) => `fresnel(${a.ior}, n, v)` },
|
|
244
|
+
"layer_weight/fresnel": {
|
|
245
|
+
inputs: { blend: F(0.5) },
|
|
246
|
+
outputs: { value: "float" },
|
|
247
|
+
emit: (a) => `layer_weight_fresnel(${a.blend}, n, v)`,
|
|
248
|
+
},
|
|
249
|
+
"layer_weight/facing": {
|
|
250
|
+
inputs: { blend: F(0.5) },
|
|
251
|
+
outputs: { value: "float" },
|
|
252
|
+
emit: (a) => `layer_weight_facing(${a.blend}, n, v)`,
|
|
253
|
+
},
|
|
254
|
+
// ── Lighting capture ──
|
|
255
|
+
shader_to_rgb_diffuse: {
|
|
256
|
+
inputs: {},
|
|
257
|
+
outputs: { value: "float" },
|
|
258
|
+
emit: () => `shader_to_rgb_diffuse(n, l, sun, amb, shadow)`,
|
|
259
|
+
},
|
|
260
|
+
// ── Vector ──
|
|
261
|
+
separate_xyz: {
|
|
262
|
+
inputs: { vector: V([0, 0, 0], true) },
|
|
263
|
+
outputs: { x: "float", y: "float", z: "float" },
|
|
264
|
+
outputSelect: { x: ".x", y: ".y", z: ".z" },
|
|
265
|
+
emit: (a) => a.vector,
|
|
266
|
+
},
|
|
267
|
+
vect_cross: {
|
|
268
|
+
// b may be a literal constant (metal crosses the reflection dir with (0,1,0)).
|
|
269
|
+
inputs: { a: V([0, 0, 0], true), b: V([0, 1, 0]) },
|
|
270
|
+
outputs: { vector: "vector" },
|
|
271
|
+
emit: (a) => `vect_math_cross(${a.a}, ${a.b})`,
|
|
272
|
+
},
|
|
273
|
+
mapping: {
|
|
274
|
+
inputs: { vector: V([0, 0, 0], true), loc: V([0, 0, 0]), rot: V([0, 0, 0]), scl: V([1, 1, 1]) },
|
|
275
|
+
outputs: { vector: "vector" },
|
|
276
|
+
emit: (a) => `mapping_point(${a.vector}, ${a.loc}, ${a.rot}, ${a.scl})`,
|
|
277
|
+
},
|
|
278
|
+
bump: {
|
|
279
|
+
// Screen-space bump; world position comes from context (matches bump_lh's port).
|
|
280
|
+
inputs: { strength: F(0.1), height: F(0, true), normal: V([0, 0, 0], true) },
|
|
281
|
+
outputs: { vector: "vector" },
|
|
282
|
+
emit: (a) => `bump_lh(${a.strength}, ${a.height}, ${a.normal}, input.worldPos)`,
|
|
283
|
+
},
|
|
284
|
+
// ── Procedural textures ──
|
|
285
|
+
tex_noise: {
|
|
286
|
+
inputs: { vector: V([0, 0, 0], true), scale: F(5), detail: F(2), roughness: F(0.5), distortion: F(0) },
|
|
287
|
+
outputs: { value: "float" },
|
|
288
|
+
emit: (a) => `tex_noise(${a.vector}, ${a.scale}, ${a.detail}, ${a.roughness}, ${a.distortion})`,
|
|
289
|
+
},
|
|
290
|
+
tex_gradient: {
|
|
291
|
+
inputs: { vector: V([0, 0, 0], true) },
|
|
292
|
+
outputs: { value: "float" },
|
|
293
|
+
emit: (a) => `tex_gradient_linear(${a.vector})`,
|
|
294
|
+
},
|
|
295
|
+
"tex_voronoi/f1": {
|
|
296
|
+
inputs: { vector: V([0, 0, 0], true), scale: F(5) },
|
|
297
|
+
outputs: { value: "float" },
|
|
298
|
+
emit: (a) => `tex_voronoi_f1(${a.vector}, ${a.scale})`,
|
|
299
|
+
},
|
|
300
|
+
"tex_voronoi/color": {
|
|
301
|
+
inputs: { vector: V([0, 0, 0], true), scale: F(5) },
|
|
302
|
+
outputs: { color: "color" },
|
|
303
|
+
emit: (a) => `tex_voronoi_color(${a.vector}, ${a.scale})`,
|
|
304
|
+
},
|
|
305
|
+
// ── Principled BSDF (frozen 3.6 legacy-EEVEE semantics: eval_principled port) ──
|
|
306
|
+
// normal defaults to the template's shading normal; link a bump/normal_map chain
|
|
307
|
+
// to perturb it (body/cloth_rough noise bump).
|
|
308
|
+
principled: {
|
|
309
|
+
inputs: {
|
|
310
|
+
base: C([0.8, 0.8, 0.8], true),
|
|
311
|
+
metallic: F(0),
|
|
312
|
+
specular: F(0.5),
|
|
313
|
+
roughness: F(0.5),
|
|
314
|
+
spec_clamp: F(1e30),
|
|
315
|
+
sheen: F(0),
|
|
316
|
+
sheen_tint: F(0),
|
|
317
|
+
normal: { type: "vector", contextDefault: "n" },
|
|
318
|
+
},
|
|
319
|
+
outputs: { color: "color" },
|
|
320
|
+
emit: (a) => `eval_principled(PrincipledIn(${a.base}, ${a.metallic}, ${a.specular}, ${a.roughness}, ${a.spec_clamp}, ${a.sheen}, ${a.sheen_tint}), ${a.normal}, l, v, sun, amb, shadow)`,
|
|
321
|
+
},
|
|
322
|
+
};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { MaterialPreset } from "../engine";
|
|
2
|
+
export type SocketValue = number | [number, number, number] | [number, number, number, number];
|
|
3
|
+
export type GraphNode = {
|
|
4
|
+
/** Unique within the graph, /^[a-z0-9_]+$/ — becomes the WGSL variable suffix. */
|
|
5
|
+
id: string;
|
|
6
|
+
/** Node registry key, e.g. "hue_sat", "math/power", "mix/blend". */
|
|
7
|
+
type: string;
|
|
8
|
+
/** Literal defaults for unlinked input sockets. */
|
|
9
|
+
inputs?: Record<string, SocketValue>;
|
|
10
|
+
/** Editor-only metadata (React Flow position). Ignored by the compiler, round-tripped
|
|
11
|
+
* by serialization so engine-side tooling never strips an editor's layout. */
|
|
12
|
+
ui?: {
|
|
13
|
+
position?: {
|
|
14
|
+
x: number;
|
|
15
|
+
y: number;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
export type GraphLink = {
|
|
20
|
+
from: {
|
|
21
|
+
node: string;
|
|
22
|
+
socket: string;
|
|
23
|
+
};
|
|
24
|
+
to: {
|
|
25
|
+
node: string;
|
|
26
|
+
socket: string;
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
/** Adjust-tier slider: overrides one unlinked literal input with a StyleUniforms read. */
|
|
30
|
+
export type ExposedParam = {
|
|
31
|
+
/** Stable key — slot assignment and serialization identity. */
|
|
32
|
+
id: string;
|
|
33
|
+
label: string;
|
|
34
|
+
target: {
|
|
35
|
+
node: string;
|
|
36
|
+
socket: string;
|
|
37
|
+
};
|
|
38
|
+
kind: "float" | "color";
|
|
39
|
+
min?: number;
|
|
40
|
+
max?: number;
|
|
41
|
+
default: SocketValue;
|
|
42
|
+
};
|
|
43
|
+
export type StyleGraph = {
|
|
44
|
+
version: 1;
|
|
45
|
+
name: string;
|
|
46
|
+
/** Which preset slot this style targets. The slot owns pass integration (stencil
|
|
47
|
+
* variants like hair-over-eyes, alpha semantics, draw order) — always on,
|
|
48
|
+
* graph-invisible. The graph only restyles the slot's shading. */
|
|
49
|
+
slot: MaterialPreset;
|
|
50
|
+
nodes: GraphNode[];
|
|
51
|
+
links: GraphLink[];
|
|
52
|
+
/** Must resolve to a color (vec3f) or float (auto-splatted) socket. */
|
|
53
|
+
output: {
|
|
54
|
+
node: string;
|
|
55
|
+
socket: string;
|
|
56
|
+
};
|
|
57
|
+
params?: ExposedParam[];
|
|
58
|
+
};
|
|
59
|
+
export type Diagnostic = {
|
|
60
|
+
severity: "error" | "warning";
|
|
61
|
+
nodeId?: string;
|
|
62
|
+
message: string;
|
|
63
|
+
};
|
|
64
|
+
export declare const MAX_NODES = 64;
|
|
65
|
+
export declare const MAX_PARAMS = 16;
|
|
66
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/graph/schema.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAE/C,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;AAE9F,MAAM,MAAM,SAAS,GAAG;IACtB,kFAAkF;IAClF,EAAE,EAAE,MAAM,CAAA;IACV,oEAAoE;IACpE,IAAI,EAAE,MAAM,CAAA;IACZ,mDAAmD;IACnD,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;IACpC;mFAC+E;IAC/E,EAAE,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE;YAAE,CAAC,EAAE,MAAM,CAAC;YAAC,CAAC,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAA;CAC7C,CAAA;AAED,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;IACtC,EAAE,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;CACrC,CAAA;AAED,0FAA0F;AAC1F,MAAM,MAAM,YAAY,GAAG;IACzB,+DAA+D;IAC/D,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;IACxC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAA;IACvB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,WAAW,CAAA;CACrB,CAAA;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,OAAO,EAAE,CAAC,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ;;uEAEmE;IACnE,IAAI,EAAE,cAAc,CAAA;IACpB,KAAK,EAAE,SAAS,EAAE,CAAA;IAClB,KAAK,EAAE,SAAS,EAAE,CAAA;IAClB,uEAAuE;IACvE,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;IACxC,MAAM,CAAC,EAAE,YAAY,EAAE,CAAA;CACxB,CAAA;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAA;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,eAAO,MAAM,SAAS,KAAK,CAAA;AAC3B,eAAO,MAAM,UAAU,KAAK,CAAA"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// Material style graph — JSON-serializable node graph compiled to WGSL by compile.ts.
|
|
2
|
+
// Engine-space (LH, Y-up): porting a Blender graph converts coordinates at authoring
|
|
3
|
+
// time (Blender Normal Z → engine Y), the compiler never sees Blender conventions.
|
|
4
|
+
// See docs/graph-compiler-spec.md.
|
|
5
|
+
export const MAX_NODES = 64;
|
|
6
|
+
export const MAX_PARAMS = 16;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { MaterialPreset } from "../engine";
|
|
2
|
+
export type SlotTemplate = {
|
|
3
|
+
/** Module-scope declarations (pipeline-override constants, helper fns). */
|
|
4
|
+
decls: string;
|
|
5
|
+
/** Optional replacement for the standard fs() prelude (custom alpha semantics). */
|
|
6
|
+
prelude?: string;
|
|
7
|
+
/** Tail of fs(): consumes `final_color` + template locals, writes FSOut. */
|
|
8
|
+
epilogue: string;
|
|
9
|
+
};
|
|
10
|
+
export declare const SLOT_TEMPLATES: Partial<Record<MaterialPreset, SlotTemplate>>;
|
|
11
|
+
export declare function slotTemplate(slot: MaterialPreset): SlotTemplate;
|
|
12
|
+
export declare const STYLE_UNIFORMS_WGSL = "struct StyleUniforms { p: array<vec4f, 16> };\n@group(2) @binding(4) var<uniform> style: StyleUniforms;\n\n";
|
|
13
|
+
export declare function assembleModule(slot: MaterialPreset, fsBody: string, includeStyleUniforms: boolean): string;
|
|
14
|
+
//# sourceMappingURL=slots.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slots.d.ts","sourceRoot":"","sources":["../../src/graph/slots.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAE/C,MAAM,MAAM,YAAY,GAAG;IACzB,2EAA2E;IAC3E,KAAK,EAAE,MAAM,CAAA;IACb,mFAAmF;IACnF,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,4EAA4E;IAC5E,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAgHD,eAAO,MAAM,cAAc,EAAE,OAAO,CAAC,MAAM,CAAC,cAAc,EAAE,YAAY,CAAC,CAIxE,CAAA;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,cAAc,GAAG,YAAY,CAE/D;AAID,eAAO,MAAM,mBAAmB,gHAG/B,CAAA;AAqBD,wBAAgB,cAAc,CAAC,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,oBAAoB,EAAE,OAAO,GAAG,MAAM,CAa1G"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
// Per-slot WGSL templates. The graph computes only `final_color`; everything the slot
|
|
2
|
+
// owns — texture sample, MMD alpha semantics, discard, lighting context, FSOut/mask
|
|
3
|
+
// writes, and built-in pass effects like hair's over-eyes stencil variant — lives here,
|
|
4
|
+
// always on, graph-invisible. Mirrors the hand-written material shaders line-for-line.
|
|
5
|
+
import { NODES_WGSL } from "../shaders/materials/nodes";
|
|
6
|
+
import { COMMON_MATERIAL_PRELUDE_WGSL } from "../shaders/materials/common";
|
|
7
|
+
const DEFAULT_EPILOGUE = ` var out: FSOut;
|
|
8
|
+
out.color = vec4f(final_color, alpha);
|
|
9
|
+
out.mask = vec4f(1.0, 1.0, 0.0, out.color.a);
|
|
10
|
+
return out;
|
|
11
|
+
`;
|
|
12
|
+
const DEFAULT_TEMPLATE = { decls: "", epilogue: DEFAULT_EPILOGUE };
|
|
13
|
+
// Hair's built-in over-eyes effect (see hair.ts): the engine compiles two pipeline
|
|
14
|
+
// variants from the same module — normal opaque hair, and a stencil-matched re-draw
|
|
15
|
+
// at 25% alpha so eyes read through the silhouette. Always on for the hair slot.
|
|
16
|
+
const HAIR_TEMPLATE = {
|
|
17
|
+
decls: `override IS_OVER_EYES: bool = false;
|
|
18
|
+
|
|
19
|
+
`,
|
|
20
|
+
epilogue: ` var outAlpha = alpha;
|
|
21
|
+
if (IS_OVER_EYES) { outAlpha = alpha * 0.25; }
|
|
22
|
+
|
|
23
|
+
var out: FSOut;
|
|
24
|
+
out.color = vec4f(final_color, outAlpha);
|
|
25
|
+
out.mask = vec4f(1.0, 1.0, 0.0, out.color.a);
|
|
26
|
+
return out;
|
|
27
|
+
`,
|
|
28
|
+
};
|
|
29
|
+
// Stockings' built-in alpha behavior (see stockings.ts): Wyman & McGuire hashed
|
|
30
|
+
// alpha testing on bind-pose restPos replaces the standard threshold discard —
|
|
31
|
+
// sort-independent through self-overlap, dither pinned to the fabric. The graph
|
|
32
|
+
// only computes final_color; the hash gate and the alpha=1 output are slot-owned.
|
|
33
|
+
const STOCKINGS_TEMPLATE = {
|
|
34
|
+
decls: `fn _hash3d_wm(a: vec3f) -> f32 {
|
|
35
|
+
return _hash33(a).x * 0.5 + 0.5;
|
|
36
|
+
}
|
|
37
|
+
fn hashed_alpha_threshold(co: vec3f) -> f32 {
|
|
38
|
+
let alphaHashScale: f32 = 1.0;
|
|
39
|
+
let max_deriv = max(length(dpdx(co)), length(dpdy(co)));
|
|
40
|
+
let pix_scale = 1.0 / max(alphaHashScale * max_deriv, 1e-6);
|
|
41
|
+
let pix_scale_log = log2(pix_scale);
|
|
42
|
+
let px_lo = exp2(floor(pix_scale_log));
|
|
43
|
+
let px_hi = exp2(ceil(pix_scale_log));
|
|
44
|
+
let a_lo = _hash3d_wm(floor(px_lo * co));
|
|
45
|
+
let a_hi = _hash3d_wm(floor(px_hi * co));
|
|
46
|
+
let fac = fract(pix_scale_log);
|
|
47
|
+
let x = mix(a_lo, a_hi, fac);
|
|
48
|
+
let a = min(fac, 1.0 - fac);
|
|
49
|
+
let one_a = 1.0 - a;
|
|
50
|
+
let denom = 1.0 / max(2.0 * a * one_a, 1e-6);
|
|
51
|
+
let one_x = 1.0 - x;
|
|
52
|
+
let case_lo = (x * x) * denom;
|
|
53
|
+
let case_mid = (x - 0.5 * a) / max(one_a, 1e-6);
|
|
54
|
+
let case_hi = 1.0 - (one_x * one_x) * denom;
|
|
55
|
+
var threshold = select(case_hi, select(case_lo, case_mid, x >= a), x < one_a);
|
|
56
|
+
return clamp(threshold, 1e-6, 1.0);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
`,
|
|
60
|
+
prelude: `@fragment fn fs(input: VertexOutput) -> FSOut {
|
|
61
|
+
let tex_s = textureSample(diffuseTexture, diffuseSampler, input.uv);
|
|
62
|
+
// Hashed alpha test (EEVEE "Hashed" blend) instead of the standard threshold.
|
|
63
|
+
let alpha = material.alpha * tex_s.a;
|
|
64
|
+
if (alpha < hashed_alpha_threshold(input.restPos)) { discard; }
|
|
65
|
+
|
|
66
|
+
let n = safe_normal(input.normal);
|
|
67
|
+
let v = normalize(camera.viewPos - input.worldPos);
|
|
68
|
+
let l = -light.lights[0].direction.xyz;
|
|
69
|
+
let sun = light.lights[0].color.xyz * light.lights[0].color.w;
|
|
70
|
+
let amb = light.ambientColor.xyz;
|
|
71
|
+
let shadow = sampleShadow(input.worldPos, n);
|
|
72
|
+
let tex_color = tex_s.rgb;
|
|
73
|
+
|
|
74
|
+
`,
|
|
75
|
+
epilogue: ` var out: FSOut;
|
|
76
|
+
out.color = vec4f(final_color, 1.0);
|
|
77
|
+
out.mask = vec4f(1.0, 1.0, 0.0, out.color.a);
|
|
78
|
+
return out;
|
|
79
|
+
`,
|
|
80
|
+
};
|
|
81
|
+
// Eye's built-in rear-view gate (see eye.ts): open-shell PMX heads don't occlude
|
|
82
|
+
// the eye from behind, so it would draw (and stamp the see-through stencil) through
|
|
83
|
+
// the back of the head. Gate by camera-vs-face hemisphere via the 頭 bone's skinning
|
|
84
|
+
// matrix. Discarding here drops color, depth, and the stencil stamp together. The
|
|
85
|
+
// stencil-stamp pipeline state + front-face cull are slot-owned in createSlotPipeline;
|
|
86
|
+
// the graph only computes the eye's shading (Principled + emission).
|
|
87
|
+
const EYE_TEMPLATE = {
|
|
88
|
+
decls: "",
|
|
89
|
+
prelude: `@fragment fn fs(input: VertexOutput) -> FSOut {
|
|
90
|
+
let tex_s = textureSample(diffuseTexture, diffuseSampler, input.uv);
|
|
91
|
+
let alpha = material.alpha * tex_s.a;
|
|
92
|
+
if (alpha < 0.001) { discard; }
|
|
93
|
+
|
|
94
|
+
let n = safe_normal(input.normal);
|
|
95
|
+
let v = normalize(camera.viewPos - input.worldPos);
|
|
96
|
+
|
|
97
|
+
if (material.headBoneIndex >= 0.0) {
|
|
98
|
+
let hm = skinMats[u32(material.headBoneIndex)];
|
|
99
|
+
let faceDir = -normalize(hm[2].xyz);
|
|
100
|
+
if (dot(faceDir, v) < -0.15) { discard; }
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
let l = -light.lights[0].direction.xyz;
|
|
104
|
+
let sun = light.lights[0].color.xyz * light.lights[0].color.w;
|
|
105
|
+
let amb = light.ambientColor.xyz;
|
|
106
|
+
let shadow = sampleShadow(input.worldPos, n);
|
|
107
|
+
let tex_color = tex_s.rgb;
|
|
108
|
+
|
|
109
|
+
`,
|
|
110
|
+
epilogue: DEFAULT_EPILOGUE,
|
|
111
|
+
};
|
|
112
|
+
export const SLOT_TEMPLATES = {
|
|
113
|
+
hair: HAIR_TEMPLATE,
|
|
114
|
+
stockings: STOCKINGS_TEMPLATE,
|
|
115
|
+
eye: EYE_TEMPLATE,
|
|
116
|
+
};
|
|
117
|
+
export function slotTemplate(slot) {
|
|
118
|
+
return SLOT_TEMPLATES[slot] ?? DEFAULT_TEMPLATE;
|
|
119
|
+
}
|
|
120
|
+
// Adjust-tier uniforms — fixed 16-vec4f block (256 B) so the single shared material
|
|
121
|
+
// bind group layout serves every graph; non-graph presets bind a zero buffer.
|
|
122
|
+
export const STYLE_UNIFORMS_WGSL = `struct StyleUniforms { p: array<vec4f, 16> };
|
|
123
|
+
@group(2) @binding(4) var<uniform> style: StyleUniforms;
|
|
124
|
+
|
|
125
|
+
`;
|
|
126
|
+
// fs() prelude — identical to the hand-written materials so template locals keep the
|
|
127
|
+
// exact names the registry's context nodes and emit functions reference.
|
|
128
|
+
const FS_PRELUDE = `@fragment fn fs(input: VertexOutput) -> FSOut {
|
|
129
|
+
let tex_s = textureSample(diffuseTexture, diffuseSampler, input.uv);
|
|
130
|
+
// MMD alpha semantics: material alpha × texture alpha (hair/lace textures cut
|
|
131
|
+
// their shapes in the alpha channel).
|
|
132
|
+
let alpha = material.alpha * tex_s.a;
|
|
133
|
+
if (alpha < 0.001) { discard; }
|
|
134
|
+
|
|
135
|
+
let n = safe_normal(input.normal);
|
|
136
|
+
let v = normalize(camera.viewPos - input.worldPos);
|
|
137
|
+
let l = -light.lights[0].direction.xyz;
|
|
138
|
+
let sun = light.lights[0].color.xyz * light.lights[0].color.w;
|
|
139
|
+
let amb = light.ambientColor.xyz;
|
|
140
|
+
let shadow = sampleShadow(input.worldPos, n);
|
|
141
|
+
let tex_color = tex_s.rgb;
|
|
142
|
+
|
|
143
|
+
`;
|
|
144
|
+
export function assembleModule(slot, fsBody, includeStyleUniforms) {
|
|
145
|
+
const tmpl = slotTemplate(slot);
|
|
146
|
+
return (NODES_WGSL +
|
|
147
|
+
COMMON_MATERIAL_PRELUDE_WGSL +
|
|
148
|
+
(includeStyleUniforms ? STYLE_UNIFORMS_WGSL : "") +
|
|
149
|
+
tmpl.decls +
|
|
150
|
+
(tmpl.prelude ?? FS_PRELUDE) +
|
|
151
|
+
fsBody +
|
|
152
|
+
"\n" +
|
|
153
|
+
tmpl.epilogue +
|
|
154
|
+
"}\n");
|
|
155
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
|
-
export { Engine, DEFAULT_BLOOM_OPTIONS, DEFAULT_VIEW_TRANSFORM, type EngineStats, type EngineOptions, type BloomOptions, type ViewTransformOptions, type LoadModelFromFilesOptions, type MaterialPreset, type ResolvedMaterialPreset, type MaterialPresetMap, type GizmoDragEvent, type GizmoDragCallback, type GizmoDragKind, } from "./engine";
|
|
1
|
+
export { Engine, DEFAULT_BLOOM_OPTIONS, DEFAULT_VIEW_TRANSFORM, type EngineStats, type EngineOptions, type BloomOptions, type ViewTransformOptions, type LoadModelFromFilesOptions, type MaterialPreset, type ResolvedMaterialPreset, type MaterialPresetMap, type ApplyStyleResult, type GizmoDragEvent, type GizmoDragCallback, type GizmoDragKind, } from "./engine";
|
|
2
2
|
export { parsePmxFolderInput, pmxFileAtRelativePath, type PmxFolderInputResult } from "./folder-upload";
|
|
3
|
+
export { compileGraph, validateGraph, assignStyleSlots, type CompileOptions, type CompileResult, type StyleSlot, } from "./graph/compile";
|
|
4
|
+
export type { StyleGraph, GraphNode, GraphLink, ExposedParam, SocketValue, Diagnostic, } from "./graph/schema";
|
|
5
|
+
export { NODE_REGISTRY, type NodeSpec, type SockT } from "./graph/registry";
|
|
6
|
+
export { HAIR_GRAPH } from "./graph/presets/hair";
|
|
7
|
+
export { DEFAULT_GRAPH } from "./graph/presets/default";
|
|
8
|
+
export { CLOTH_SMOOTH_GRAPH } from "./graph/presets/cloth_smooth";
|
|
9
|
+
export { CLOTH_ROUGH_GRAPH } from "./graph/presets/cloth_rough";
|
|
10
|
+
export { METAL_GRAPH } from "./graph/presets/metal";
|
|
11
|
+
export { BODY_GRAPH } from "./graph/presets/body";
|
|
12
|
+
export { STOCKINGS_GRAPH } from "./graph/presets/stockings";
|
|
13
|
+
export { EYE_GRAPH } from "./graph/presets/eye";
|
|
14
|
+
export { FACE_GRAPH } from "./graph/presets/face";
|
|
3
15
|
export { Model } from "./model";
|
|
4
16
|
export { Vec3, Quat, Mat4 } from "./math";
|
|
5
17
|
export type { AnimationClip, AnimationPlayOptions, AnimationProgress, BoneKeyframe, MorphKeyframe, BoneInterpolation, ControlPoint, } from "./animation";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,EACN,qBAAqB,EACrB,sBAAsB,EACtB,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,oBAAoB,EACzB,KAAK,yBAAyB,EAC9B,KAAK,cAAc,EACnB,KAAK,sBAAsB,EAC3B,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,aAAa,GACnB,MAAM,UAAU,CAAA;AACjB,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,KAAK,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AACvG,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAC/B,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AACzC,YAAY,EACV,aAAa,EACb,oBAAoB,EACpB,iBAAiB,EACjB,YAAY,EACZ,aAAa,EACb,iBAAiB,EACjB,YAAY,GACb,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAA;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,EACN,qBAAqB,EACrB,sBAAsB,EACtB,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,oBAAoB,EACzB,KAAK,yBAAyB,EAC9B,KAAK,cAAc,EACnB,KAAK,sBAAsB,EAC3B,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,aAAa,GACnB,MAAM,UAAU,CAAA;AACjB,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,KAAK,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AACvG,OAAO,EACL,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,SAAS,GACf,MAAM,iBAAiB,CAAA;AACxB,YAAY,EACV,UAAU,EACV,SAAS,EACT,SAAS,EACT,YAAY,EACZ,WAAW,EACX,UAAU,GACX,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAE,aAAa,EAAE,KAAK,QAAQ,EAAE,KAAK,KAAK,EAAE,MAAM,kBAAkB,CAAA;AAC3E,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAA;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAA;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAA;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAA;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AACjD,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAC/B,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AACzC,YAAY,EACV,aAAa,EACb,oBAAoB,EACpB,iBAAiB,EACjB,YAAY,EACZ,aAAa,EACb,iBAAiB,EACjB,YAAY,GACb,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAA;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
export { Engine, DEFAULT_BLOOM_OPTIONS, DEFAULT_VIEW_TRANSFORM, } from "./engine";
|
|
2
2
|
export { parsePmxFolderInput, pmxFileAtRelativePath } from "./folder-upload";
|
|
3
|
+
export { compileGraph, validateGraph, assignStyleSlots, } from "./graph/compile";
|
|
4
|
+
export { NODE_REGISTRY } from "./graph/registry";
|
|
5
|
+
export { HAIR_GRAPH } from "./graph/presets/hair";
|
|
6
|
+
export { DEFAULT_GRAPH } from "./graph/presets/default";
|
|
7
|
+
export { CLOTH_SMOOTH_GRAPH } from "./graph/presets/cloth_smooth";
|
|
8
|
+
export { CLOTH_ROUGH_GRAPH } from "./graph/presets/cloth_rough";
|
|
9
|
+
export { METAL_GRAPH } from "./graph/presets/metal";
|
|
10
|
+
export { BODY_GRAPH } from "./graph/presets/body";
|
|
11
|
+
export { STOCKINGS_GRAPH } from "./graph/presets/stockings";
|
|
12
|
+
export { EYE_GRAPH } from "./graph/presets/eye";
|
|
13
|
+
export { FACE_GRAPH } from "./graph/presets/face";
|
|
3
14
|
export { Model } from "./model";
|
|
4
15
|
export { Vec3, Quat, Mat4 } from "./math";
|
|
5
16
|
export { FPS } from "./animation";
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
declare class PhysicsProfiler {
|
|
2
|
+
enabled: boolean;
|
|
3
|
+
private sums;
|
|
4
|
+
private counts;
|
|
5
|
+
begin(): number;
|
|
6
|
+
end(label: string, t0: number): void;
|
|
7
|
+
record(label: string, ms: number): void;
|
|
8
|
+
snapshot(): Record<string, {
|
|
9
|
+
avgMs: number;
|
|
10
|
+
calls: number;
|
|
11
|
+
totalMs: number;
|
|
12
|
+
}>;
|
|
13
|
+
reset(): void;
|
|
14
|
+
}
|
|
15
|
+
export declare const profiler: PhysicsProfiler;
|
|
16
|
+
export type ProfileSnapshot = ReturnType<PhysicsProfiler["snapshot"]>;
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=profile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile.d.ts","sourceRoot":"","sources":["../../src/physics/profile.ts"],"names":[],"mappings":"AAIA,cAAM,eAAe;IACnB,OAAO,UAAQ;IACf,OAAO,CAAC,IAAI,CAA8C;IAC1D,OAAO,CAAC,MAAM,CAA8C;IAE5D,KAAK,IAAI,MAAM;IAIf,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI;IASpC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI;IAQvC,QAAQ,IAAI,MAAM,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAU7E,KAAK,IAAI,IAAI;CAId;AAED,eAAO,MAAM,QAAQ,iBAAwB,CAAA;AAC7C,MAAM,MAAM,eAAe,GAAG,UAAU,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC,CAAA"}
|