reze-engine 0.18.0 → 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/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/slots.d.ts.map +1 -1
- package/dist/graph/slots.js +32 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/package.json +1 -1
- package/src/graph/presets/eye.ts +33 -0
- package/src/graph/presets/face.ts +136 -0
- package/src/graph/slots.ts +33 -0
- package/src/index.ts +2 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eye.d.ts","sourceRoot":"","sources":["../../../src/graph/presets/eye.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AAE3C,eAAO,MAAM,SAAS,EAAE,UAqBvB,CAAA"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// Eye as a StyleGraph — port of shaders/materials/eye.ts. The published preset
|
|
2
|
+
// author's instruction: "keep eyes in the default nodegraph, add emission 1.5".
|
|
3
|
+
// So it's the default Principled BSDF plus an Emission of the diffuse texture at
|
|
4
|
+
// 1.5× (Blender's Principled Emission socket, decomposed as a separate Emission +
|
|
5
|
+
// Add Shader — the emission feeds bloom pre-tonemap).
|
|
6
|
+
//
|
|
7
|
+
// The rear-view gate and the see-through stencil stamp are slot-owned (built-in eye
|
|
8
|
+
// behavior, see EYE_TEMPLATE in slots.ts + createSlotPipeline) — not in this graph.
|
|
9
|
+
export const EYE_GRAPH = {
|
|
10
|
+
version: 1,
|
|
11
|
+
name: "Eye",
|
|
12
|
+
slot: "eye",
|
|
13
|
+
nodes: [
|
|
14
|
+
{ id: "tex", type: "texture" },
|
|
15
|
+
{
|
|
16
|
+
id: "principled",
|
|
17
|
+
type: "principled",
|
|
18
|
+
inputs: { metallic: 0.0, specular: 0.5, roughness: 0.5, spec_clamp: 1e30, sheen: 0.0, sheen_tint: 0.0 },
|
|
19
|
+
},
|
|
20
|
+
{ id: "emission", type: "emission", inputs: { strength: 1.5 } },
|
|
21
|
+
{ id: "add", type: "add_shader" },
|
|
22
|
+
],
|
|
23
|
+
links: [
|
|
24
|
+
{ from: { node: "tex", socket: "color" }, to: { node: "principled", socket: "base" } },
|
|
25
|
+
{ from: { node: "tex", socket: "color" }, to: { node: "emission", socket: "color" } },
|
|
26
|
+
{ from: { node: "principled", socket: "color" }, to: { node: "add", socket: "a" } },
|
|
27
|
+
{ from: { node: "emission", socket: "color" }, to: { node: "add", socket: "b" } },
|
|
28
|
+
],
|
|
29
|
+
output: { node: "add", socket: "color" },
|
|
30
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"face.d.ts","sourceRoot":"","sources":["../../../src/graph/presets/face.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AAE3C,eAAO,MAAM,UAAU,EAAE,UA6HxB,CAAA"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
// M_Face as a StyleGraph — port of shaders/materials/face.ts (仿深空之眼 "M_Face").
|
|
2
|
+
// Toon + warm rim + dual fresnel rim + BT.601 bright-tex gate, mixed 50/50 against a
|
|
3
|
+
// Principled BSDF with noise bump. Structurally close to body, but: the toon uses the
|
|
4
|
+
// edge-AA ramp, hue tints are 0.46 (full hue_sat, not the 0.5 _id specialization),
|
|
5
|
+
// rim2 is the hair-style fresnel×layer_weight_fresnel rim, and there's an extra
|
|
6
|
+
// near-white texture gate that emits (freckle/highlight paint). Plain material — no
|
|
7
|
+
// built-in slot effect, so it uses the default prelude/epilogue.
|
|
8
|
+
export const FACE_GRAPH = {
|
|
9
|
+
version: 1,
|
|
10
|
+
name: "Face",
|
|
11
|
+
slot: "face",
|
|
12
|
+
nodes: [
|
|
13
|
+
{ id: "tex", type: "texture" },
|
|
14
|
+
{ id: "geo", type: "geometry" },
|
|
15
|
+
// ── toon shading ──
|
|
16
|
+
{ id: "str", type: "shader_to_rgb_diffuse" },
|
|
17
|
+
{ id: "toon", type: "ramp_constant_aa", inputs: { edge: 0.2966 } },
|
|
18
|
+
{ id: "shadow_tint", type: "hue_sat", inputs: { hue: 0.46000000834465027, saturation: 2.0, value: 0.3499999940395355, fac: 1.0 } },
|
|
19
|
+
{ id: "lit_tint", type: "hue_sat", inputs: { hue: 0.46000000834465027, saturation: 1.600000023841858, value: 1.5, fac: 1.0 } },
|
|
20
|
+
{ id: "toon_color", type: "mix/blend" },
|
|
21
|
+
{ id: "bc", type: "bright_contrast", inputs: { bright: 0.1, contrast: 0.2 } },
|
|
22
|
+
{ id: "emission3", type: "emission", inputs: { strength: 2.5 } },
|
|
23
|
+
// ── warm rim (toon*0.5+0.5 → cardinal ramp) ──
|
|
24
|
+
{ id: "warm_mul", type: "math/multiply", inputs: { b: 0.5 } },
|
|
25
|
+
{ id: "warm_add", type: "math/add", inputs: { b: 0.5 } },
|
|
26
|
+
{ id: "warm_clamp", type: "math/clamp01" },
|
|
27
|
+
{
|
|
28
|
+
id: "warm_ramp",
|
|
29
|
+
type: "ramp_cardinal",
|
|
30
|
+
inputs: {
|
|
31
|
+
pos0: 0.2409,
|
|
32
|
+
color0: [0.2426, 0.068, 0.0588, 1.0],
|
|
33
|
+
pos1: 0.4663,
|
|
34
|
+
color1: [0.6677, 0.5024, 0.5126, 1.0],
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
{ id: "warm_emit", type: "emission", inputs: { strength: 0.30000001192092896 } },
|
|
38
|
+
// ── rim1: fresnel × facing ──
|
|
39
|
+
{ id: "rim1_fres", type: "fresnel", inputs: { ior: 2.0 } },
|
|
40
|
+
{ id: "rim1_lw", type: "layer_weight/facing", inputs: { blend: 0.24 } },
|
|
41
|
+
{ id: "rim1_str", type: "math/multiply" },
|
|
42
|
+
{ id: "rim1", type: "emission", inputs: { color: [0.984157919883728, 0.6110184788703918, 0.5736401677131653] } },
|
|
43
|
+
// ── rim2: fresnel × fresnel-layer-weight, powered (hair-style) ──
|
|
44
|
+
{ id: "rim2_fres", type: "fresnel", inputs: { ior: 1.45 } },
|
|
45
|
+
{ id: "rim2_lw", type: "layer_weight/fresnel", inputs: { blend: 0.61 } },
|
|
46
|
+
{ id: "rim2_raw", type: "math/multiply" },
|
|
47
|
+
{ id: "rim2_pow", type: "math/power", inputs: { b: 0.6300000548362732 } },
|
|
48
|
+
{ id: "rim2_mix", type: "mix_shader", inputs: { b: [1.0, 0.4684903025627136, 0.3698573112487793] } },
|
|
49
|
+
// ── near-white texture gate emission ──
|
|
50
|
+
{ id: "gate", type: "math/greater_than", inputs: { b: 0.9300000071525574 } },
|
|
51
|
+
{ id: "gate_scale", type: "math/multiply", inputs: { b: 3.0 } },
|
|
52
|
+
// ── npr stack (rim1 + rim2 + bright_emit + warm) ──
|
|
53
|
+
{ id: "npr_add1", type: "add_shader" },
|
|
54
|
+
{ id: "npr_add2", type: "add_shader" },
|
|
55
|
+
{ id: "npr_stack", type: "add_shader" },
|
|
56
|
+
// ── principled with noise bump ──
|
|
57
|
+
{ id: "map", type: "mapping", inputs: { scl: [1.0, 1.0, 1.5] } },
|
|
58
|
+
{ id: "noise", type: "tex_noise", inputs: { scale: 1.0 } },
|
|
59
|
+
{ id: "noise_ramp", type: "ramp_linear", inputs: { pos0: 0.0, pos1: 1.0 } },
|
|
60
|
+
{ id: "bump", type: "bump", inputs: { strength: 0.324644535779953 } },
|
|
61
|
+
{ id: "principled_base", type: "mix/blend", inputs: { b: [0.6832, 0.1947, 0.1373] } },
|
|
62
|
+
{ id: "p_emit", type: "emission", inputs: { strength: 0.2 } },
|
|
63
|
+
{
|
|
64
|
+
id: "principled",
|
|
65
|
+
type: "principled",
|
|
66
|
+
inputs: { metallic: 0.0, specular: 0.5, roughness: 0.3, spec_clamp: 10.0, sheen: 0.0, sheen_tint: 0.0 },
|
|
67
|
+
},
|
|
68
|
+
{ id: "p_sum", type: "add_shader" },
|
|
69
|
+
{ id: "mix_shader_001", type: "mix_shader", inputs: { fac: 0.5 } },
|
|
70
|
+
],
|
|
71
|
+
links: [
|
|
72
|
+
// toon
|
|
73
|
+
{ from: { node: "str", socket: "value" }, to: { node: "toon", socket: "fac" } },
|
|
74
|
+
{ from: { node: "tex", socket: "color" }, to: { node: "shadow_tint", socket: "color" } },
|
|
75
|
+
{ from: { node: "tex", socket: "color" }, to: { node: "lit_tint", socket: "color" } },
|
|
76
|
+
{ from: { node: "toon", socket: "fac_out" }, to: { node: "toon_color", socket: "fac" } },
|
|
77
|
+
{ from: { node: "shadow_tint", socket: "color" }, to: { node: "toon_color", socket: "a" } },
|
|
78
|
+
{ from: { node: "lit_tint", socket: "color" }, to: { node: "toon_color", socket: "b" } },
|
|
79
|
+
{ from: { node: "toon_color", socket: "color" }, to: { node: "bc", socket: "color" } },
|
|
80
|
+
{ from: { node: "bc", socket: "color" }, to: { node: "emission3", socket: "color" } },
|
|
81
|
+
// warm rim
|
|
82
|
+
{ from: { node: "toon", socket: "fac_out" }, to: { node: "warm_mul", socket: "a" } },
|
|
83
|
+
{ from: { node: "warm_mul", socket: "value" }, to: { node: "warm_add", socket: "a" } },
|
|
84
|
+
{ from: { node: "warm_add", socket: "value" }, to: { node: "warm_clamp", socket: "a" } },
|
|
85
|
+
{ from: { node: "warm_clamp", socket: "value" }, to: { node: "warm_ramp", socket: "fac" } },
|
|
86
|
+
{ from: { node: "warm_ramp", socket: "color" }, to: { node: "warm_emit", socket: "color" } },
|
|
87
|
+
// rim1
|
|
88
|
+
{ from: { node: "rim1_fres", socket: "value" }, to: { node: "rim1_str", socket: "a" } },
|
|
89
|
+
{ from: { node: "rim1_lw", socket: "value" }, to: { node: "rim1_str", socket: "b" } },
|
|
90
|
+
{ from: { node: "rim1_str", socket: "value" }, to: { node: "rim1", socket: "strength" } },
|
|
91
|
+
// rim2
|
|
92
|
+
{ from: { node: "rim2_fres", socket: "value" }, to: { node: "rim2_raw", socket: "a" } },
|
|
93
|
+
{ from: { node: "rim2_lw", socket: "value" }, to: { node: "rim2_raw", socket: "b" } },
|
|
94
|
+
{ from: { node: "rim2_raw", socket: "value" }, to: { node: "rim2_pow", socket: "a" } },
|
|
95
|
+
{ from: { node: "emission3", socket: "color" }, to: { node: "rim2_mix", socket: "a" } },
|
|
96
|
+
{ from: { node: "rim2_pow", socket: "value" }, to: { node: "rim2_mix", socket: "fac" } },
|
|
97
|
+
// gate
|
|
98
|
+
{ from: { node: "tex", socket: "color" }, to: { node: "gate", socket: "a" } },
|
|
99
|
+
{ from: { node: "gate", socket: "value" }, to: { node: "gate_scale", socket: "a" } },
|
|
100
|
+
// npr stack
|
|
101
|
+
{ from: { node: "rim1", socket: "color" }, to: { node: "npr_add1", socket: "a" } },
|
|
102
|
+
{ from: { node: "rim2_mix", socket: "color" }, to: { node: "npr_add1", socket: "b" } },
|
|
103
|
+
{ from: { node: "npr_add1", socket: "color" }, to: { node: "npr_add2", socket: "a" } },
|
|
104
|
+
{ from: { node: "gate_scale", socket: "value" }, to: { node: "npr_add2", socket: "b" } },
|
|
105
|
+
{ from: { node: "npr_add2", socket: "color" }, to: { node: "npr_stack", socket: "a" } },
|
|
106
|
+
{ from: { node: "warm_emit", socket: "color" }, to: { node: "npr_stack", socket: "b" } },
|
|
107
|
+
// principled + noise bump
|
|
108
|
+
{ from: { node: "geo", socket: "rest_pos" }, to: { node: "map", socket: "vector" } },
|
|
109
|
+
{ from: { node: "map", socket: "vector" }, to: { node: "noise", socket: "vector" } },
|
|
110
|
+
{ from: { node: "noise", socket: "value" }, to: { node: "noise_ramp", socket: "fac" } },
|
|
111
|
+
{ from: { node: "noise_ramp", socket: "fac_out" }, to: { node: "bump", socket: "height" } },
|
|
112
|
+
{ from: { node: "geo", socket: "normal" }, to: { node: "bump", socket: "normal" } },
|
|
113
|
+
{ from: { node: "noise_ramp", socket: "fac_out" }, to: { node: "principled_base", socket: "fac" } },
|
|
114
|
+
{ from: { node: "bc", socket: "color" }, to: { node: "principled_base", socket: "a" } },
|
|
115
|
+
{ from: { node: "bc", socket: "color" }, to: { node: "p_emit", socket: "color" } },
|
|
116
|
+
{ from: { node: "principled_base", socket: "color" }, to: { node: "principled", socket: "base" } },
|
|
117
|
+
{ from: { node: "bump", socket: "vector" }, to: { node: "principled", socket: "normal" } },
|
|
118
|
+
{ from: { node: "principled", socket: "color" }, to: { node: "p_sum", socket: "a" } },
|
|
119
|
+
{ from: { node: "p_emit", socket: "color" }, to: { node: "p_sum", socket: "b" } },
|
|
120
|
+
// final mix
|
|
121
|
+
{ from: { node: "npr_stack", socket: "color" }, to: { node: "mix_shader_001", socket: "a" } },
|
|
122
|
+
{ from: { node: "p_sum", socket: "color" }, to: { node: "mix_shader_001", socket: "b" } },
|
|
123
|
+
],
|
|
124
|
+
output: { node: "mix_shader_001", socket: "color" },
|
|
125
|
+
};
|
|
@@ -1 +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;
|
|
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"}
|
package/dist/graph/slots.js
CHANGED
|
@@ -78,9 +78,41 @@ fn hashed_alpha_threshold(co: vec3f) -> f32 {
|
|
|
78
78
|
return out;
|
|
79
79
|
`,
|
|
80
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
|
+
};
|
|
81
112
|
export const SLOT_TEMPLATES = {
|
|
82
113
|
hair: HAIR_TEMPLATE,
|
|
83
114
|
stockings: STOCKINGS_TEMPLATE,
|
|
115
|
+
eye: EYE_TEMPLATE,
|
|
84
116
|
};
|
|
85
117
|
export function slotTemplate(slot) {
|
|
86
118
|
return SLOT_TEMPLATES[slot] ?? DEFAULT_TEMPLATE;
|
package/dist/index.d.ts
CHANGED
|
@@ -10,6 +10,8 @@ export { CLOTH_ROUGH_GRAPH } from "./graph/presets/cloth_rough";
|
|
|
10
10
|
export { METAL_GRAPH } from "./graph/presets/metal";
|
|
11
11
|
export { BODY_GRAPH } from "./graph/presets/body";
|
|
12
12
|
export { STOCKINGS_GRAPH } from "./graph/presets/stockings";
|
|
13
|
+
export { EYE_GRAPH } from "./graph/presets/eye";
|
|
14
|
+
export { FACE_GRAPH } from "./graph/presets/face";
|
|
13
15
|
export { Model } from "./model";
|
|
14
16
|
export { Vec3, Quat, Mat4 } from "./math";
|
|
15
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,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,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
|
@@ -9,6 +9,8 @@ export { CLOTH_ROUGH_GRAPH } from "./graph/presets/cloth_rough";
|
|
|
9
9
|
export { METAL_GRAPH } from "./graph/presets/metal";
|
|
10
10
|
export { BODY_GRAPH } from "./graph/presets/body";
|
|
11
11
|
export { STOCKINGS_GRAPH } from "./graph/presets/stockings";
|
|
12
|
+
export { EYE_GRAPH } from "./graph/presets/eye";
|
|
13
|
+
export { FACE_GRAPH } from "./graph/presets/face";
|
|
12
14
|
export { Model } from "./model";
|
|
13
15
|
export { Vec3, Quat, Mat4 } from "./math";
|
|
14
16
|
export { FPS } from "./animation";
|
package/package.json
CHANGED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// Eye as a StyleGraph — port of shaders/materials/eye.ts. The published preset
|
|
2
|
+
// author's instruction: "keep eyes in the default nodegraph, add emission 1.5".
|
|
3
|
+
// So it's the default Principled BSDF plus an Emission of the diffuse texture at
|
|
4
|
+
// 1.5× (Blender's Principled Emission socket, decomposed as a separate Emission +
|
|
5
|
+
// Add Shader — the emission feeds bloom pre-tonemap).
|
|
6
|
+
//
|
|
7
|
+
// The rear-view gate and the see-through stencil stamp are slot-owned (built-in eye
|
|
8
|
+
// behavior, see EYE_TEMPLATE in slots.ts + createSlotPipeline) — not in this graph.
|
|
9
|
+
|
|
10
|
+
import type { StyleGraph } from "../schema"
|
|
11
|
+
|
|
12
|
+
export const EYE_GRAPH: StyleGraph = {
|
|
13
|
+
version: 1,
|
|
14
|
+
name: "Eye",
|
|
15
|
+
slot: "eye",
|
|
16
|
+
nodes: [
|
|
17
|
+
{ id: "tex", type: "texture" },
|
|
18
|
+
{
|
|
19
|
+
id: "principled",
|
|
20
|
+
type: "principled",
|
|
21
|
+
inputs: { metallic: 0.0, specular: 0.5, roughness: 0.5, spec_clamp: 1e30, sheen: 0.0, sheen_tint: 0.0 },
|
|
22
|
+
},
|
|
23
|
+
{ id: "emission", type: "emission", inputs: { strength: 1.5 } },
|
|
24
|
+
{ id: "add", type: "add_shader" },
|
|
25
|
+
],
|
|
26
|
+
links: [
|
|
27
|
+
{ from: { node: "tex", socket: "color" }, to: { node: "principled", socket: "base" } },
|
|
28
|
+
{ from: { node: "tex", socket: "color" }, to: { node: "emission", socket: "color" } },
|
|
29
|
+
{ from: { node: "principled", socket: "color" }, to: { node: "add", socket: "a" } },
|
|
30
|
+
{ from: { node: "emission", socket: "color" }, to: { node: "add", socket: "b" } },
|
|
31
|
+
],
|
|
32
|
+
output: { node: "add", socket: "color" },
|
|
33
|
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
// M_Face as a StyleGraph — port of shaders/materials/face.ts (仿深空之眼 "M_Face").
|
|
2
|
+
// Toon + warm rim + dual fresnel rim + BT.601 bright-tex gate, mixed 50/50 against a
|
|
3
|
+
// Principled BSDF with noise bump. Structurally close to body, but: the toon uses the
|
|
4
|
+
// edge-AA ramp, hue tints are 0.46 (full hue_sat, not the 0.5 _id specialization),
|
|
5
|
+
// rim2 is the hair-style fresnel×layer_weight_fresnel rim, and there's an extra
|
|
6
|
+
// near-white texture gate that emits (freckle/highlight paint). Plain material — no
|
|
7
|
+
// built-in slot effect, so it uses the default prelude/epilogue.
|
|
8
|
+
|
|
9
|
+
import type { StyleGraph } from "../schema"
|
|
10
|
+
|
|
11
|
+
export const FACE_GRAPH: StyleGraph = {
|
|
12
|
+
version: 1,
|
|
13
|
+
name: "Face",
|
|
14
|
+
slot: "face",
|
|
15
|
+
nodes: [
|
|
16
|
+
{ id: "tex", type: "texture" },
|
|
17
|
+
{ id: "geo", type: "geometry" },
|
|
18
|
+
|
|
19
|
+
// ── toon shading ──
|
|
20
|
+
{ id: "str", type: "shader_to_rgb_diffuse" },
|
|
21
|
+
{ id: "toon", type: "ramp_constant_aa", inputs: { edge: 0.2966 } },
|
|
22
|
+
{ id: "shadow_tint", type: "hue_sat", inputs: { hue: 0.46000000834465027, saturation: 2.0, value: 0.3499999940395355, fac: 1.0 } },
|
|
23
|
+
{ id: "lit_tint", type: "hue_sat", inputs: { hue: 0.46000000834465027, saturation: 1.600000023841858, value: 1.5, fac: 1.0 } },
|
|
24
|
+
{ id: "toon_color", type: "mix/blend" },
|
|
25
|
+
{ id: "bc", type: "bright_contrast", inputs: { bright: 0.1, contrast: 0.2 } },
|
|
26
|
+
{ id: "emission3", type: "emission", inputs: { strength: 2.5 } },
|
|
27
|
+
|
|
28
|
+
// ── warm rim (toon*0.5+0.5 → cardinal ramp) ──
|
|
29
|
+
{ id: "warm_mul", type: "math/multiply", inputs: { b: 0.5 } },
|
|
30
|
+
{ id: "warm_add", type: "math/add", inputs: { b: 0.5 } },
|
|
31
|
+
{ id: "warm_clamp", type: "math/clamp01" },
|
|
32
|
+
{
|
|
33
|
+
id: "warm_ramp",
|
|
34
|
+
type: "ramp_cardinal",
|
|
35
|
+
inputs: {
|
|
36
|
+
pos0: 0.2409,
|
|
37
|
+
color0: [0.2426, 0.068, 0.0588, 1.0],
|
|
38
|
+
pos1: 0.4663,
|
|
39
|
+
color1: [0.6677, 0.5024, 0.5126, 1.0],
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
{ id: "warm_emit", type: "emission", inputs: { strength: 0.30000001192092896 } },
|
|
43
|
+
|
|
44
|
+
// ── rim1: fresnel × facing ──
|
|
45
|
+
{ id: "rim1_fres", type: "fresnel", inputs: { ior: 2.0 } },
|
|
46
|
+
{ id: "rim1_lw", type: "layer_weight/facing", inputs: { blend: 0.24 } },
|
|
47
|
+
{ id: "rim1_str", type: "math/multiply" },
|
|
48
|
+
{ id: "rim1", type: "emission", inputs: { color: [0.984157919883728, 0.6110184788703918, 0.5736401677131653] } },
|
|
49
|
+
|
|
50
|
+
// ── rim2: fresnel × fresnel-layer-weight, powered (hair-style) ──
|
|
51
|
+
{ id: "rim2_fres", type: "fresnel", inputs: { ior: 1.45 } },
|
|
52
|
+
{ id: "rim2_lw", type: "layer_weight/fresnel", inputs: { blend: 0.61 } },
|
|
53
|
+
{ id: "rim2_raw", type: "math/multiply" },
|
|
54
|
+
{ id: "rim2_pow", type: "math/power", inputs: { b: 0.6300000548362732 } },
|
|
55
|
+
{ id: "rim2_mix", type: "mix_shader", inputs: { b: [1.0, 0.4684903025627136, 0.3698573112487793] } },
|
|
56
|
+
|
|
57
|
+
// ── near-white texture gate emission ──
|
|
58
|
+
{ id: "gate", type: "math/greater_than", inputs: { b: 0.9300000071525574 } },
|
|
59
|
+
{ id: "gate_scale", type: "math/multiply", inputs: { b: 3.0 } },
|
|
60
|
+
|
|
61
|
+
// ── npr stack (rim1 + rim2 + bright_emit + warm) ──
|
|
62
|
+
{ id: "npr_add1", type: "add_shader" },
|
|
63
|
+
{ id: "npr_add2", type: "add_shader" },
|
|
64
|
+
{ id: "npr_stack", type: "add_shader" },
|
|
65
|
+
|
|
66
|
+
// ── principled with noise bump ──
|
|
67
|
+
{ id: "map", type: "mapping", inputs: { scl: [1.0, 1.0, 1.5] } },
|
|
68
|
+
{ id: "noise", type: "tex_noise", inputs: { scale: 1.0 } },
|
|
69
|
+
{ id: "noise_ramp", type: "ramp_linear", inputs: { pos0: 0.0, pos1: 1.0 } },
|
|
70
|
+
{ id: "bump", type: "bump", inputs: { strength: 0.324644535779953 } },
|
|
71
|
+
{ id: "principled_base", type: "mix/blend", inputs: { b: [0.6832, 0.1947, 0.1373] } },
|
|
72
|
+
{ id: "p_emit", type: "emission", inputs: { strength: 0.2 } },
|
|
73
|
+
{
|
|
74
|
+
id: "principled",
|
|
75
|
+
type: "principled",
|
|
76
|
+
inputs: { metallic: 0.0, specular: 0.5, roughness: 0.3, spec_clamp: 10.0, sheen: 0.0, sheen_tint: 0.0 },
|
|
77
|
+
},
|
|
78
|
+
{ id: "p_sum", type: "add_shader" },
|
|
79
|
+
|
|
80
|
+
{ id: "mix_shader_001", type: "mix_shader", inputs: { fac: 0.5 } },
|
|
81
|
+
],
|
|
82
|
+
links: [
|
|
83
|
+
// toon
|
|
84
|
+
{ from: { node: "str", socket: "value" }, to: { node: "toon", socket: "fac" } },
|
|
85
|
+
{ from: { node: "tex", socket: "color" }, to: { node: "shadow_tint", socket: "color" } },
|
|
86
|
+
{ from: { node: "tex", socket: "color" }, to: { node: "lit_tint", socket: "color" } },
|
|
87
|
+
{ from: { node: "toon", socket: "fac_out" }, to: { node: "toon_color", socket: "fac" } },
|
|
88
|
+
{ from: { node: "shadow_tint", socket: "color" }, to: { node: "toon_color", socket: "a" } },
|
|
89
|
+
{ from: { node: "lit_tint", socket: "color" }, to: { node: "toon_color", socket: "b" } },
|
|
90
|
+
{ from: { node: "toon_color", socket: "color" }, to: { node: "bc", socket: "color" } },
|
|
91
|
+
{ from: { node: "bc", socket: "color" }, to: { node: "emission3", socket: "color" } },
|
|
92
|
+
// warm rim
|
|
93
|
+
{ from: { node: "toon", socket: "fac_out" }, to: { node: "warm_mul", socket: "a" } },
|
|
94
|
+
{ from: { node: "warm_mul", socket: "value" }, to: { node: "warm_add", socket: "a" } },
|
|
95
|
+
{ from: { node: "warm_add", socket: "value" }, to: { node: "warm_clamp", socket: "a" } },
|
|
96
|
+
{ from: { node: "warm_clamp", socket: "value" }, to: { node: "warm_ramp", socket: "fac" } },
|
|
97
|
+
{ from: { node: "warm_ramp", socket: "color" }, to: { node: "warm_emit", socket: "color" } },
|
|
98
|
+
// rim1
|
|
99
|
+
{ from: { node: "rim1_fres", socket: "value" }, to: { node: "rim1_str", socket: "a" } },
|
|
100
|
+
{ from: { node: "rim1_lw", socket: "value" }, to: { node: "rim1_str", socket: "b" } },
|
|
101
|
+
{ from: { node: "rim1_str", socket: "value" }, to: { node: "rim1", socket: "strength" } },
|
|
102
|
+
// rim2
|
|
103
|
+
{ from: { node: "rim2_fres", socket: "value" }, to: { node: "rim2_raw", socket: "a" } },
|
|
104
|
+
{ from: { node: "rim2_lw", socket: "value" }, to: { node: "rim2_raw", socket: "b" } },
|
|
105
|
+
{ from: { node: "rim2_raw", socket: "value" }, to: { node: "rim2_pow", socket: "a" } },
|
|
106
|
+
{ from: { node: "emission3", socket: "color" }, to: { node: "rim2_mix", socket: "a" } },
|
|
107
|
+
{ from: { node: "rim2_pow", socket: "value" }, to: { node: "rim2_mix", socket: "fac" } },
|
|
108
|
+
// gate
|
|
109
|
+
{ from: { node: "tex", socket: "color" }, to: { node: "gate", socket: "a" } },
|
|
110
|
+
{ from: { node: "gate", socket: "value" }, to: { node: "gate_scale", socket: "a" } },
|
|
111
|
+
// npr stack
|
|
112
|
+
{ from: { node: "rim1", socket: "color" }, to: { node: "npr_add1", socket: "a" } },
|
|
113
|
+
{ from: { node: "rim2_mix", socket: "color" }, to: { node: "npr_add1", socket: "b" } },
|
|
114
|
+
{ from: { node: "npr_add1", socket: "color" }, to: { node: "npr_add2", socket: "a" } },
|
|
115
|
+
{ from: { node: "gate_scale", socket: "value" }, to: { node: "npr_add2", socket: "b" } },
|
|
116
|
+
{ from: { node: "npr_add2", socket: "color" }, to: { node: "npr_stack", socket: "a" } },
|
|
117
|
+
{ from: { node: "warm_emit", socket: "color" }, to: { node: "npr_stack", socket: "b" } },
|
|
118
|
+
// principled + noise bump
|
|
119
|
+
{ from: { node: "geo", socket: "rest_pos" }, to: { node: "map", socket: "vector" } },
|
|
120
|
+
{ from: { node: "map", socket: "vector" }, to: { node: "noise", socket: "vector" } },
|
|
121
|
+
{ from: { node: "noise", socket: "value" }, to: { node: "noise_ramp", socket: "fac" } },
|
|
122
|
+
{ from: { node: "noise_ramp", socket: "fac_out" }, to: { node: "bump", socket: "height" } },
|
|
123
|
+
{ from: { node: "geo", socket: "normal" }, to: { node: "bump", socket: "normal" } },
|
|
124
|
+
{ from: { node: "noise_ramp", socket: "fac_out" }, to: { node: "principled_base", socket: "fac" } },
|
|
125
|
+
{ from: { node: "bc", socket: "color" }, to: { node: "principled_base", socket: "a" } },
|
|
126
|
+
{ from: { node: "bc", socket: "color" }, to: { node: "p_emit", socket: "color" } },
|
|
127
|
+
{ from: { node: "principled_base", socket: "color" }, to: { node: "principled", socket: "base" } },
|
|
128
|
+
{ from: { node: "bump", socket: "vector" }, to: { node: "principled", socket: "normal" } },
|
|
129
|
+
{ from: { node: "principled", socket: "color" }, to: { node: "p_sum", socket: "a" } },
|
|
130
|
+
{ from: { node: "p_emit", socket: "color" }, to: { node: "p_sum", socket: "b" } },
|
|
131
|
+
// final mix
|
|
132
|
+
{ from: { node: "npr_stack", socket: "color" }, to: { node: "mix_shader_001", socket: "a" } },
|
|
133
|
+
{ from: { node: "p_sum", socket: "color" }, to: { node: "mix_shader_001", socket: "b" } },
|
|
134
|
+
],
|
|
135
|
+
output: { node: "mix_shader_001", socket: "color" },
|
|
136
|
+
}
|
package/src/graph/slots.ts
CHANGED
|
@@ -94,9 +94,42 @@ fn hashed_alpha_threshold(co: vec3f) -> f32 {
|
|
|
94
94
|
`,
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
+
// Eye's built-in rear-view gate (see eye.ts): open-shell PMX heads don't occlude
|
|
98
|
+
// the eye from behind, so it would draw (and stamp the see-through stencil) through
|
|
99
|
+
// the back of the head. Gate by camera-vs-face hemisphere via the 頭 bone's skinning
|
|
100
|
+
// matrix. Discarding here drops color, depth, and the stencil stamp together. The
|
|
101
|
+
// stencil-stamp pipeline state + front-face cull are slot-owned in createSlotPipeline;
|
|
102
|
+
// the graph only computes the eye's shading (Principled + emission).
|
|
103
|
+
const EYE_TEMPLATE: SlotTemplate = {
|
|
104
|
+
decls: "",
|
|
105
|
+
prelude: `@fragment fn fs(input: VertexOutput) -> FSOut {
|
|
106
|
+
let tex_s = textureSample(diffuseTexture, diffuseSampler, input.uv);
|
|
107
|
+
let alpha = material.alpha * tex_s.a;
|
|
108
|
+
if (alpha < 0.001) { discard; }
|
|
109
|
+
|
|
110
|
+
let n = safe_normal(input.normal);
|
|
111
|
+
let v = normalize(camera.viewPos - input.worldPos);
|
|
112
|
+
|
|
113
|
+
if (material.headBoneIndex >= 0.0) {
|
|
114
|
+
let hm = skinMats[u32(material.headBoneIndex)];
|
|
115
|
+
let faceDir = -normalize(hm[2].xyz);
|
|
116
|
+
if (dot(faceDir, v) < -0.15) { discard; }
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
let l = -light.lights[0].direction.xyz;
|
|
120
|
+
let sun = light.lights[0].color.xyz * light.lights[0].color.w;
|
|
121
|
+
let amb = light.ambientColor.xyz;
|
|
122
|
+
let shadow = sampleShadow(input.worldPos, n);
|
|
123
|
+
let tex_color = tex_s.rgb;
|
|
124
|
+
|
|
125
|
+
`,
|
|
126
|
+
epilogue: DEFAULT_EPILOGUE,
|
|
127
|
+
}
|
|
128
|
+
|
|
97
129
|
export const SLOT_TEMPLATES: Partial<Record<MaterialPreset, SlotTemplate>> = {
|
|
98
130
|
hair: HAIR_TEMPLATE,
|
|
99
131
|
stockings: STOCKINGS_TEMPLATE,
|
|
132
|
+
eye: EYE_TEMPLATE,
|
|
100
133
|
}
|
|
101
134
|
|
|
102
135
|
export function slotTemplate(slot: MaterialPreset): SlotTemplate {
|
package/src/index.ts
CHANGED
|
@@ -40,6 +40,8 @@ export { CLOTH_ROUGH_GRAPH } from "./graph/presets/cloth_rough"
|
|
|
40
40
|
export { METAL_GRAPH } from "./graph/presets/metal"
|
|
41
41
|
export { BODY_GRAPH } from "./graph/presets/body"
|
|
42
42
|
export { STOCKINGS_GRAPH } from "./graph/presets/stockings"
|
|
43
|
+
export { EYE_GRAPH } from "./graph/presets/eye"
|
|
44
|
+
export { FACE_GRAPH } from "./graph/presets/face"
|
|
43
45
|
export { Model } from "./model"
|
|
44
46
|
export { Vec3, Quat, Mat4 } from "./math"
|
|
45
47
|
export type {
|