reze-engine 0.20.0 → 0.21.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/README.md +30 -14
- package/dist/engine.d.ts +0 -1
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +12 -12
- package/dist/graph/compile.d.ts +3 -3
- package/dist/graph/compile.d.ts.map +1 -1
- package/dist/graph/presets/body.d.ts +2 -2
- package/dist/graph/presets/body.d.ts.map +1 -1
- package/dist/graph/presets/body.js +1 -1
- package/dist/graph/presets/cloth_rough.d.ts +2 -2
- package/dist/graph/presets/cloth_rough.d.ts.map +1 -1
- package/dist/graph/presets/cloth_rough.js +1 -1
- package/dist/graph/presets/cloth_smooth.d.ts +2 -2
- package/dist/graph/presets/cloth_smooth.d.ts.map +1 -1
- package/dist/graph/presets/cloth_smooth.js +1 -1
- package/dist/graph/presets/default.d.ts +2 -2
- package/dist/graph/presets/default.d.ts.map +1 -1
- package/dist/graph/presets/eye.d.ts +2 -2
- package/dist/graph/presets/eye.d.ts.map +1 -1
- package/dist/graph/presets/eye.js +1 -1
- package/dist/graph/presets/face.d.ts +2 -2
- package/dist/graph/presets/face.d.ts.map +1 -1
- package/dist/graph/presets/face.js +1 -1
- package/dist/graph/presets/hair.d.ts +2 -2
- package/dist/graph/presets/hair.d.ts.map +1 -1
- package/dist/graph/presets/hair.js +1 -1
- package/dist/graph/presets/metal.d.ts +2 -2
- package/dist/graph/presets/metal.d.ts.map +1 -1
- package/dist/graph/presets/metal.js +1 -1
- package/dist/graph/presets/stockings.d.ts +2 -2
- package/dist/graph/presets/stockings.d.ts.map +1 -1
- package/dist/graph/presets/stockings.js +1 -1
- package/dist/graph/render-class.js +1 -1
- package/dist/graph/schema.d.ts +1 -1
- package/dist/graph/schema.d.ts.map +1 -1
- package/dist/graph/schema.js +1 -1
- package/dist/graph/style-group.d.ts +3 -3
- package/dist/graph/style-group.d.ts.map +1 -1
- package/dist/graph/style-group.js +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/shaders/materials/common.d.ts +1 -1
- package/dist/shaders/materials/common.d.ts.map +1 -1
- package/dist/shaders/materials/common.js +5 -4
- package/package.json +1 -1
- package/src/engine.ts +14 -21
- package/src/graph/compile.ts +3 -3
- package/src/graph/presets/body.ts +3 -3
- package/src/graph/presets/cloth_rough.ts +3 -3
- package/src/graph/presets/cloth_smooth.ts +3 -3
- package/src/graph/presets/default.ts +2 -2
- package/src/graph/presets/eye.ts +3 -3
- package/src/graph/presets/face.ts +3 -3
- package/src/graph/presets/hair.ts +3 -3
- package/src/graph/presets/metal.ts +3 -3
- package/src/graph/presets/stockings.ts +3 -3
- package/src/graph/render-class.ts +1 -1
- package/src/graph/schema.ts +2 -2
- package/src/graph/style-group.ts +4 -4
- package/src/index.ts +61 -62
- package/src/shaders/materials/common.ts +5 -4
- package/src/shaders/materials/body.ts +0 -97
- package/src/shaders/materials/cloth_rough.ts +0 -71
- package/src/shaders/materials/cloth_smooth.ts +0 -63
- package/src/shaders/materials/default.ts +0 -45
- package/src/shaders/materials/eye.ts +0 -62
- package/src/shaders/materials/face.ts +0 -97
- package/src/shaders/materials/hair.ts +0 -92
- package/src/shaders/materials/metal.ts +0 -79
- package/src/shaders/materials/mmd_classic.ts +0 -68
- package/src/shaders/materials/stockings.ts +0 -124
|
@@ -39,10 +39,10 @@ struct LightUniforms {
|
|
|
39
39
|
|
|
40
40
|
// Per-material uniforms. Every material binds this layout even if it ignores fields;
|
|
41
41
|
// the engine keeps one bind group layout across all material pipelines. The PMX
|
|
42
|
-
// classic-material fields (ambient/specular/
|
|
43
|
-
//
|
|
42
|
+
// classic-material fields (ambient/specular/shininess) are carried for graph nodes that
|
|
43
|
+
// want them; most graphs read only diffuseColor + alpha.
|
|
44
44
|
struct MaterialUniforms {
|
|
45
|
-
diffuseColor: vec3f, // PMX diffuse rgb
|
|
45
|
+
diffuseColor: vec3f, // PMX diffuse rgb — the material_diffuse node reads this
|
|
46
46
|
alpha: f32, // 0 → discard; <1 → transparent draw call
|
|
47
47
|
ambient: vec3f, // PMX ambient rgb
|
|
48
48
|
shininess: f32, // PMX specular power
|
|
@@ -82,7 +82,8 @@ struct LightVP { viewProj: mat4x4f, };
|
|
|
82
82
|
@group(1) @binding(0) var<storage, read> skinMats: array<mat4x4f>;
|
|
83
83
|
@group(2) @binding(0) var diffuseTexture: texture_2d<f32>;
|
|
84
84
|
@group(2) @binding(1) var<uniform> material: MaterialUniforms;
|
|
85
|
-
//
|
|
85
|
+
// Reserved for future sphere/toon graph nodes; graphs that don't read them get the
|
|
86
|
+
// 1×1 white fallback bound here.
|
|
86
87
|
@group(2) @binding(2) var toonTexture: texture_2d<f32>;
|
|
87
88
|
@group(2) @binding(3) var sphereTexture: texture_2d<f32>;
|
|
88
89
|
|
package/package.json
CHANGED
package/src/engine.ts
CHANGED
|
@@ -31,7 +31,7 @@ import { COMPOSITE_SHADER_WGSL } from "./shaders/passes/composite"
|
|
|
31
31
|
import { PICK_SHADER_WGSL } from "./shaders/passes/pick"
|
|
32
32
|
import { MIPMAP_BLIT_SHADER_WGSL } from "./shaders/passes/mipmap"
|
|
33
33
|
import { compileGraph, type CompileOptions, type StyleSlot } from "./graph/compile"
|
|
34
|
-
import type { Diagnostic,
|
|
34
|
+
import type { Diagnostic, ShaderGraph } from "./graph/schema"
|
|
35
35
|
import type { AlphaMode, RenderClass } from "./graph/render-class"
|
|
36
36
|
import type {
|
|
37
37
|
ApplyStyleGroupResult,
|
|
@@ -62,20 +62,12 @@ export type MaterialPreset =
|
|
|
62
62
|
| "cloth_smooth"
|
|
63
63
|
| "cloth_rough"
|
|
64
64
|
|
|
65
|
-
// What a draw call actually resolves to. "mmd_classic" is the automatic
|
|
66
|
-
// authentic-MMD fallback for materials no preset map or name heuristic
|
|
67
|
-
// covers — deliberately NOT part of MaterialPreset, so consumer-side
|
|
68
|
-
// exhaustive Record<MaterialPreset, …> maps and switches don't have to
|
|
69
|
-
// carry an option users never assign.
|
|
70
|
-
export type ResolvedMaterialPreset = MaterialPreset | "mmd_classic"
|
|
71
|
-
|
|
72
65
|
export type MaterialPresetMap = Partial<Record<MaterialPreset, string[]>>
|
|
73
66
|
|
|
74
|
-
// Substring hints mapping common PMX material names (JP/CN/EN) to
|
|
75
|
-
// tried when a material isn't in the
|
|
76
|
-
//
|
|
77
|
-
//
|
|
78
|
-
// the author-tuned PMX material data faithfully.
|
|
67
|
+
// Substring hints mapping common PMX material names (JP/CN/EN) to a style category,
|
|
68
|
+
// tried when a material isn't in the caller's explicit override map. Ordered: more
|
|
69
|
+
// specific families first (靴下 must hit stockings before 靴 hits cloth). A material
|
|
70
|
+
// matching nothing resolves to null — it stays ungrouped (neutral default).
|
|
79
71
|
const PRESET_NAME_HINTS: Array<[MaterialPreset, string[]]> = [
|
|
80
72
|
["stockings", ["靴下", "ソックス", "タイツ", "ニーソ", "袜", "stocking", "socks", "tights"]],
|
|
81
73
|
[
|
|
@@ -117,7 +109,9 @@ const PRESET_NAME_HINTS: Array<[MaterialPreset, string[]]> = [
|
|
|
117
109
|
],
|
|
118
110
|
]
|
|
119
111
|
|
|
120
|
-
|
|
112
|
+
// Resolve a material name to a style category (override map first, then name hints), or
|
|
113
|
+
// null if nothing matches — a null-resolving material stays ungrouped (neutral default).
|
|
114
|
+
function resolvePreset(materialName: string, map: MaterialPresetMap | undefined): MaterialPreset | null {
|
|
121
115
|
if (map) {
|
|
122
116
|
for (const [preset, names] of Object.entries(map)) {
|
|
123
117
|
if (names && names.includes(materialName)) return preset as MaterialPreset
|
|
@@ -129,14 +123,13 @@ function resolvePreset(materialName: string, map: MaterialPresetMap | undefined)
|
|
|
129
123
|
if (lower.includes(hint)) return preset
|
|
130
124
|
}
|
|
131
125
|
}
|
|
132
|
-
return
|
|
126
|
+
return null
|
|
133
127
|
}
|
|
134
128
|
|
|
135
|
-
// Default-group recipe per
|
|
136
|
-
// (renderClass, alphaMode). This is the auto-default-groups mapping
|
|
137
|
-
//
|
|
138
|
-
|
|
139
|
-
const PRESET_GROUP_INFO: Partial<Record<MaterialPreset, { graph: StyleGraph; renderClass: RenderClass; alphaMode: AlphaMode }>> = {
|
|
129
|
+
// Default-group recipe per style category: the shipped graph + its natural pass-integration
|
|
130
|
+
// (renderClass, alphaMode). This is the auto-default-groups mapping — the same
|
|
131
|
+
// category→integration knowledge the old fixed slots encoded, now producing editable groups.
|
|
132
|
+
const PRESET_GROUP_INFO: Partial<Record<MaterialPreset, { graph: ShaderGraph; renderClass: RenderClass; alphaMode: AlphaMode }>> = {
|
|
140
133
|
default: { graph: DEFAULT_GRAPH, renderClass: "auto", alphaMode: "opaque" },
|
|
141
134
|
face: { graph: FACE_GRAPH, renderClass: "auto", alphaMode: "opaque" },
|
|
142
135
|
hair: { graph: HAIR_GRAPH, renderClass: "hair", alphaMode: "opaque" },
|
|
@@ -3972,7 +3965,7 @@ export class Engine {
|
|
|
3972
3965
|
for (const dc of inst.drawCalls) {
|
|
3973
3966
|
if (!dc.baseBindGroupEntries) continue // material draw calls only (skip outlines)
|
|
3974
3967
|
const preset = resolvePreset(dc.materialName, overrides)
|
|
3975
|
-
if (preset
|
|
3968
|
+
if (!preset) continue // unmatched → stays ungrouped (neutral default)
|
|
3976
3969
|
const arr = buckets.get(preset) ?? []
|
|
3977
3970
|
if (!arr.includes(dc.materialName)) arr.push(dc.materialName)
|
|
3978
3971
|
buckets.set(preset, arr)
|
package/src/graph/compile.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// See docs/graph-compiler-spec.md.
|
|
5
5
|
|
|
6
6
|
import { MAX_NODES, MAX_PARAMS } from "./schema"
|
|
7
|
-
import type { Diagnostic, ExposedParam, GraphNode, SocketValue,
|
|
7
|
+
import type { Diagnostic, ExposedParam, GraphNode, SocketValue, ShaderGraph } from "./schema"
|
|
8
8
|
import { NODE_REGISTRY, canConvert, convert, fmtValue, literalFits } from "./registry"
|
|
9
9
|
import type { NodeSpec, SockT } from "./registry"
|
|
10
10
|
import { assembleModule } from "./slots"
|
|
@@ -83,7 +83,7 @@ export function assignStyleSlots(params: ExposedParam[]): StyleSlot[] {
|
|
|
83
83
|
|
|
84
84
|
// ─── Validation ─────────────────────────────────────────────────────
|
|
85
85
|
|
|
86
|
-
export function validateGraph(graph:
|
|
86
|
+
export function validateGraph(graph: ShaderGraph, opts: CompileOptions = {}): Diagnostic[] {
|
|
87
87
|
const d: Diagnostic[] = []
|
|
88
88
|
const nodes = new Map<string, GraphNode>()
|
|
89
89
|
|
|
@@ -188,7 +188,7 @@ export function validateGraph(graph: StyleGraph, opts: CompileOptions = {}): Dia
|
|
|
188
188
|
|
|
189
189
|
// ─── Compile ────────────────────────────────────────────────────────
|
|
190
190
|
|
|
191
|
-
export function compileGraph(graph:
|
|
191
|
+
export function compileGraph(graph: ShaderGraph, opts: CompileOptions = {}): CompileResult {
|
|
192
192
|
const fail = (diagnostics: Diagnostic[]): CompileResult => ({
|
|
193
193
|
ok: false,
|
|
194
194
|
wgsl: "",
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
// M_Body as a
|
|
1
|
+
// M_Body as a ShaderGraph — port of shaders/materials/body.ts (仿深空之眼 "M_Body").
|
|
2
2
|
// Toon + warm rim + rim1/rim2 stack mixed 50/50 against a Principled BSDF with
|
|
3
3
|
// noise-bumped normal. The hand port's local ramp_ease is ramp_cardinal (identical
|
|
4
4
|
// smoothstep form); the Mapping node's zero loc/rot folds to a scale multiply.
|
|
5
5
|
|
|
6
|
-
import type {
|
|
6
|
+
import type { ShaderGraph } from "../schema"
|
|
7
7
|
|
|
8
|
-
export const BODY_GRAPH:
|
|
8
|
+
export const BODY_GRAPH: ShaderGraph = {
|
|
9
9
|
version: 1,
|
|
10
10
|
name: "Body",
|
|
11
11
|
tags: ["body"],
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
// M_Rough_Cloth as a
|
|
1
|
+
// M_Rough_Cloth as a ShaderGraph — port of shaders/materials/cloth_rough.ts.
|
|
2
2
|
// NPR graph identical to M_Smooth_Cloth, but the noise bump subtree IS live on
|
|
3
3
|
// Principled.Normal (weave bump in rest space) and Roughness is raised to 0.8187.
|
|
4
4
|
// The tex_noise node hits the detail=2 peephole → tex_noise_d2.
|
|
5
5
|
|
|
6
|
-
import type {
|
|
6
|
+
import type { ShaderGraph } from "../schema"
|
|
7
7
|
|
|
8
|
-
export const CLOTH_ROUGH_GRAPH:
|
|
8
|
+
export const CLOTH_ROUGH_GRAPH: ShaderGraph = {
|
|
9
9
|
version: 1,
|
|
10
10
|
name: "Rough Cloth",
|
|
11
11
|
tags: ["cloth_rough"],
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
// M_Smooth_Cloth as a
|
|
1
|
+
// M_Smooth_Cloth as a ShaderGraph — port of shaders/materials/cloth_smooth.ts.
|
|
2
2
|
// NPR toon + bevel + overlay-boosted emission (18.2×) mixed 10/90 against a plain
|
|
3
3
|
// Principled BSDF. The Blender graph's dead bump subtree is omitted (as in the hand
|
|
4
4
|
// port). hue_sat nodes with hue=0.5 compile to the hue_sat_id specialization.
|
|
5
5
|
|
|
6
|
-
import type {
|
|
6
|
+
import type { ShaderGraph } from "../schema"
|
|
7
7
|
|
|
8
|
-
export const CLOTH_SMOOTH_GRAPH:
|
|
8
|
+
export const CLOTH_SMOOTH_GRAPH: ShaderGraph = {
|
|
9
9
|
version: 1,
|
|
10
10
|
name: "Smooth Cloth",
|
|
11
11
|
tags: ["cloth_smooth"],
|
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
// The material-color multiply is what keeps untextured/solid-color materials from
|
|
6
6
|
// rendering white (they carry their color in material.diffuse, not a texture).
|
|
7
7
|
|
|
8
|
-
import type {
|
|
8
|
+
import type { ShaderGraph } from "../schema"
|
|
9
9
|
|
|
10
|
-
export const DEFAULT_GRAPH:
|
|
10
|
+
export const DEFAULT_GRAPH: ShaderGraph = {
|
|
11
11
|
version: 1,
|
|
12
12
|
name: "Principled BSDF",
|
|
13
13
|
tags: ["default"],
|
package/src/graph/presets/eye.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Eye as a
|
|
1
|
+
// Eye as a ShaderGraph — port of shaders/materials/eye.ts. The published preset
|
|
2
2
|
// author's instruction: "keep eyes in the default nodegraph, add emission 1.5".
|
|
3
3
|
// So it's the default Principled BSDF plus an Emission of the diffuse texture at
|
|
4
4
|
// 1.5× (Blender's Principled Emission socket, decomposed as a separate Emission +
|
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
// The rear-view gate and the see-through stencil stamp are slot-owned (built-in eye
|
|
8
8
|
// behavior, see EYE_TEMPLATE in slots.ts + createSlotPipeline) — not in this graph.
|
|
9
9
|
|
|
10
|
-
import type {
|
|
10
|
+
import type { ShaderGraph } from "../schema"
|
|
11
11
|
|
|
12
|
-
export const EYE_GRAPH:
|
|
12
|
+
export const EYE_GRAPH: ShaderGraph = {
|
|
13
13
|
version: 1,
|
|
14
14
|
name: "Eye",
|
|
15
15
|
tags: ["eye"],
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// M_Face as a
|
|
1
|
+
// M_Face as a ShaderGraph — port of shaders/materials/face.ts (仿深空之眼 "M_Face").
|
|
2
2
|
// Toon + warm rim + dual fresnel rim + BT.601 bright-tex gate, mixed 50/50 against a
|
|
3
3
|
// Principled BSDF with noise bump. Structurally close to body, but: the toon uses the
|
|
4
4
|
// edge-AA ramp, hue tints are 0.46 (full hue_sat, not the 0.5 _id specialization),
|
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
// near-white texture gate that emits (freckle/highlight paint). Plain material — no
|
|
7
7
|
// built-in slot effect, so it uses the default prelude/epilogue.
|
|
8
8
|
|
|
9
|
-
import type {
|
|
9
|
+
import type { ShaderGraph } from "../schema"
|
|
10
10
|
|
|
11
|
-
export const FACE_GRAPH:
|
|
11
|
+
export const FACE_GRAPH: ShaderGraph = {
|
|
12
12
|
version: 1,
|
|
13
13
|
name: "Face",
|
|
14
14
|
tags: ["face"],
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// M_Hair — 仿深空之眼渲染预设v1.0_by_小绿毛猫, as a
|
|
1
|
+
// M_Hair — 仿深空之眼渲染预设v1.0_by_小绿毛猫, as a ShaderGraph. Node ids mirror the
|
|
2
2
|
// Blender node names referenced in shaders/materials/hair.ts comments; compiled with
|
|
3
3
|
// { inlineParams: true } this graph must reproduce HAIR_SHADER_WGSL's fragment body
|
|
4
4
|
// (golden test #1 — see tests/graph.test.mjs).
|
|
@@ -10,9 +10,9 @@
|
|
|
10
10
|
// The object is pure JSON (no functions/undefined) — JSON.stringify round-trips it,
|
|
11
11
|
// which is how reze.design will ship additional presets.
|
|
12
12
|
|
|
13
|
-
import type {
|
|
13
|
+
import type { ShaderGraph } from "../schema"
|
|
14
14
|
|
|
15
|
-
export const HAIR_GRAPH:
|
|
15
|
+
export const HAIR_GRAPH: ShaderGraph = {
|
|
16
16
|
version: 1,
|
|
17
17
|
name: "Hair",
|
|
18
18
|
tags: ["hair"],
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
// M_Metal as a
|
|
1
|
+
// M_Metal as a ShaderGraph — port of shaders/materials/metal.ts.
|
|
2
2
|
// Metallic Principled (Metallic=1, Specular=1, Roughness=0.3) with a
|
|
3
3
|
// reflection-coord voronoi driving base color (metallic sparkle), plus an NPR
|
|
4
4
|
// toon/overlay emission stack mixed at Fac=0.6967. The voronoi Color→ramp Fac
|
|
5
5
|
// link goes through Blender's implicit BT.601 conversion (color_to_value).
|
|
6
6
|
|
|
7
|
-
import type {
|
|
7
|
+
import type { ShaderGraph } from "../schema"
|
|
8
8
|
|
|
9
|
-
export const METAL_GRAPH:
|
|
9
|
+
export const METAL_GRAPH: ShaderGraph = {
|
|
10
10
|
version: 1,
|
|
11
11
|
name: "Metal",
|
|
12
12
|
tags: ["metal"],
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// M_Stockings as a
|
|
1
|
+
// M_Stockings as a ShaderGraph — port of shaders/materials/stockings.ts.
|
|
2
2
|
// A bbox-gradient × facing-rim mask drives a Mix Shader between an HSV-boosted
|
|
3
3
|
// emission (val 5×) and a sheen Principled. The hashed-alpha discard and the
|
|
4
4
|
// alpha=1 output are slot-owned (see STOCKINGS_TEMPLATE in slots.ts) — the graph
|
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
// as in the hand port. The grayscale mask feeds Mix Shader Fac through Blender's
|
|
7
7
|
// implicit BT.601 color→float conversion (equal-component vector → same scalar).
|
|
8
8
|
|
|
9
|
-
import type {
|
|
9
|
+
import type { ShaderGraph } from "../schema"
|
|
10
10
|
|
|
11
|
-
export const STOCKINGS_GRAPH:
|
|
11
|
+
export const STOCKINGS_GRAPH: ShaderGraph = {
|
|
12
12
|
version: 1,
|
|
13
13
|
name: "Stockings",
|
|
14
14
|
tags: ["stockings"],
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Render-class + alpha-mode: the small, closed, engine-owned vocabularies that carry
|
|
2
|
-
// pass integration for a style group. A group's
|
|
2
|
+
// pass integration for a style group. A group's shader graph is pure shading; these select
|
|
3
3
|
// how the engine wires that shading into the passes. Not user-extensible — this is where
|
|
4
4
|
// rendering correctness lives (stencil, cull, draw order, alpha test). See
|
|
5
5
|
// docs/style-groups-spec.md §5.
|
package/src/graph/schema.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//
|
|
1
|
+
// ShaderGraph — a JSON-serializable graph of shading nodes, compiled to WGSL by compile.ts.
|
|
2
2
|
// Engine-space (LH, Y-up): porting a Blender graph converts coordinates at authoring
|
|
3
3
|
// time (Blender Normal Z → engine Y), the compiler never sees Blender conventions.
|
|
4
4
|
// See docs/graph-compiler-spec.md.
|
|
@@ -34,7 +34,7 @@ export type ExposedParam = {
|
|
|
34
34
|
default: SocketValue
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
export type
|
|
37
|
+
export type ShaderGraph = {
|
|
38
38
|
version: 1
|
|
39
39
|
name: string
|
|
40
40
|
nodes: GraphNode[]
|
package/src/graph/style-group.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
// Style groups — the user-facing unit of material styling. A group binds a set of
|
|
2
|
-
// materials to a
|
|
2
|
+
// materials to a shader graph (pure shading) plus the engine-owned pass-integration axes
|
|
3
3
|
// (renderClass + alphaMode). Each material belongs to at most one group; grouped
|
|
4
4
|
// materials render via the group's compiled-graph pipeline, ungrouped ones fall back to
|
|
5
5
|
// the hand-written preset path. See docs/style-groups-spec.md.
|
|
6
6
|
|
|
7
|
-
import type { Diagnostic,
|
|
7
|
+
import type { Diagnostic, ShaderGraph } from "./schema"
|
|
8
8
|
import type { AlphaMode, RenderClass } from "./render-class"
|
|
9
9
|
import type { StyleSlot } from "./compile"
|
|
10
10
|
|
|
@@ -16,8 +16,8 @@ export type StyleGroup = {
|
|
|
16
16
|
label?: string
|
|
17
17
|
/** Material names in this group; each material is in AT MOST one group. */
|
|
18
18
|
materials: string[]
|
|
19
|
-
/** Pure shading (
|
|
20
|
-
graph:
|
|
19
|
+
/** Pure shading (ShaderGraph has no `slot` — integration lives here on the group). */
|
|
20
|
+
graph: ShaderGraph
|
|
21
21
|
/** Pass-integration class: stencil/cull/draw-order. Default "auto". */
|
|
22
22
|
renderClass?: RenderClass
|
|
23
23
|
/** Alpha-handling axis, orthogonal to renderClass. Default "opaque". */
|
package/src/index.ts
CHANGED
|
@@ -1,63 +1,62 @@
|
|
|
1
|
-
export {
|
|
2
|
-
Engine,
|
|
3
|
-
DEFAULT_BLOOM_OPTIONS,
|
|
4
|
-
DEFAULT_VIEW_TRANSFORM,
|
|
5
|
-
type EngineStats,
|
|
6
|
-
type EngineOptions,
|
|
7
|
-
type BloomOptions,
|
|
8
|
-
type ViewTransformOptions,
|
|
9
|
-
type LoadModelFromFilesOptions,
|
|
10
|
-
type MaterialPreset,
|
|
11
|
-
type
|
|
12
|
-
type
|
|
13
|
-
type
|
|
14
|
-
type
|
|
15
|
-
|
|
16
|
-
} from "./
|
|
17
|
-
export {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
type
|
|
23
|
-
type
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
} from "./graph/
|
|
34
|
-
export {
|
|
35
|
-
export
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
} from "./graph/
|
|
42
|
-
export {
|
|
43
|
-
export {
|
|
44
|
-
export {
|
|
45
|
-
export {
|
|
46
|
-
export {
|
|
47
|
-
export {
|
|
48
|
-
export {
|
|
49
|
-
export {
|
|
50
|
-
export {
|
|
51
|
-
export {
|
|
52
|
-
export {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
} from "./animation"
|
|
62
|
-
export { FPS } from "./animation"
|
|
1
|
+
export {
|
|
2
|
+
Engine,
|
|
3
|
+
DEFAULT_BLOOM_OPTIONS,
|
|
4
|
+
DEFAULT_VIEW_TRANSFORM,
|
|
5
|
+
type EngineStats,
|
|
6
|
+
type EngineOptions,
|
|
7
|
+
type BloomOptions,
|
|
8
|
+
type ViewTransformOptions,
|
|
9
|
+
type LoadModelFromFilesOptions,
|
|
10
|
+
type MaterialPreset,
|
|
11
|
+
type MaterialPresetMap,
|
|
12
|
+
type GizmoDragEvent,
|
|
13
|
+
type GizmoDragCallback,
|
|
14
|
+
type GizmoDragKind,
|
|
15
|
+
} from "./engine"
|
|
16
|
+
export { parsePmxFolderInput, pmxFileAtRelativePath, type PmxFolderInputResult } from "./folder-upload"
|
|
17
|
+
export {
|
|
18
|
+
compileGraph,
|
|
19
|
+
validateGraph,
|
|
20
|
+
assignStyleSlots,
|
|
21
|
+
type CompileOptions,
|
|
22
|
+
type CompileResult,
|
|
23
|
+
type StyleSlot,
|
|
24
|
+
} from "./graph/compile"
|
|
25
|
+
export type {
|
|
26
|
+
ShaderGraph,
|
|
27
|
+
GraphNode,
|
|
28
|
+
GraphLink,
|
|
29
|
+
ExposedParam,
|
|
30
|
+
SocketValue,
|
|
31
|
+
Diagnostic,
|
|
32
|
+
} from "./graph/schema"
|
|
33
|
+
export { NODE_REGISTRY, type NodeSpec, type SockT } from "./graph/registry"
|
|
34
|
+
export { RENDER_CLASSES, type RenderClass, type AlphaMode, type RenderClassInfo } from "./graph/render-class"
|
|
35
|
+
export type {
|
|
36
|
+
StyleGroup,
|
|
37
|
+
GroupDiagnostic,
|
|
38
|
+
ApplyStyleGroupsResult,
|
|
39
|
+
ApplyStyleGroupResult,
|
|
40
|
+
} from "./graph/style-group"
|
|
41
|
+
export { HAIR_GRAPH } from "./graph/presets/hair"
|
|
42
|
+
export { DEFAULT_GRAPH } from "./graph/presets/default"
|
|
43
|
+
export { CLOTH_SMOOTH_GRAPH } from "./graph/presets/cloth_smooth"
|
|
44
|
+
export { CLOTH_ROUGH_GRAPH } from "./graph/presets/cloth_rough"
|
|
45
|
+
export { METAL_GRAPH } from "./graph/presets/metal"
|
|
46
|
+
export { BODY_GRAPH } from "./graph/presets/body"
|
|
47
|
+
export { STOCKINGS_GRAPH } from "./graph/presets/stockings"
|
|
48
|
+
export { EYE_GRAPH } from "./graph/presets/eye"
|
|
49
|
+
export { FACE_GRAPH } from "./graph/presets/face"
|
|
50
|
+
export { Model } from "./model"
|
|
51
|
+
export { Vec3, Quat, Mat4 } from "./math"
|
|
52
|
+
export type {
|
|
53
|
+
AnimationClip,
|
|
54
|
+
AnimationPlayOptions,
|
|
55
|
+
AnimationProgress,
|
|
56
|
+
BoneKeyframe,
|
|
57
|
+
MorphKeyframe,
|
|
58
|
+
BoneInterpolation,
|
|
59
|
+
ControlPoint,
|
|
60
|
+
} from "./animation"
|
|
61
|
+
export { FPS } from "./animation"
|
|
63
62
|
export { RezePhysics } from "./physics"
|
|
@@ -41,10 +41,10 @@ struct LightUniforms {
|
|
|
41
41
|
|
|
42
42
|
// Per-material uniforms. Every material binds this layout even if it ignores fields;
|
|
43
43
|
// the engine keeps one bind group layout across all material pipelines. The PMX
|
|
44
|
-
// classic-material fields (ambient/specular/
|
|
45
|
-
//
|
|
44
|
+
// classic-material fields (ambient/specular/shininess) are carried for graph nodes that
|
|
45
|
+
// want them; most graphs read only diffuseColor + alpha.
|
|
46
46
|
struct MaterialUniforms {
|
|
47
|
-
diffuseColor: vec3f, // PMX diffuse rgb
|
|
47
|
+
diffuseColor: vec3f, // PMX diffuse rgb — the material_diffuse node reads this
|
|
48
48
|
alpha: f32, // 0 → discard; <1 → transparent draw call
|
|
49
49
|
ambient: vec3f, // PMX ambient rgb
|
|
50
50
|
shininess: f32, // PMX specular power
|
|
@@ -84,7 +84,8 @@ struct LightVP { viewProj: mat4x4f, };
|
|
|
84
84
|
@group(1) @binding(0) var<storage, read> skinMats: array<mat4x4f>;
|
|
85
85
|
@group(2) @binding(0) var diffuseTexture: texture_2d<f32>;
|
|
86
86
|
@group(2) @binding(1) var<uniform> material: MaterialUniforms;
|
|
87
|
-
//
|
|
87
|
+
// Reserved for future sphere/toon graph nodes; graphs that don't read them get the
|
|
88
|
+
// 1×1 white fallback bound here.
|
|
88
89
|
@group(2) @binding(2) var toonTexture: texture_2d<f32>;
|
|
89
90
|
@group(2) @binding(3) var sphereTexture: texture_2d<f32>;
|
|
90
91
|
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
// M_Body — 仿深空之眼渲染预设v1.0_by_小绿毛猫 "M_Body". Toon + warm rim + rim1/rim2
|
|
2
|
-
// stack mixed 50/50 against a Principled BSDF with noise-bumped normal.
|
|
3
|
-
|
|
4
|
-
import { NODES_WGSL } from "./nodes"
|
|
5
|
-
import { COMMON_MATERIAL_PRELUDE_WGSL } from "./common"
|
|
6
|
-
|
|
7
|
-
export const BODY_SHADER_WGSL = /* wgsl */ `
|
|
8
|
-
|
|
9
|
-
${NODES_WGSL}
|
|
10
|
-
${COMMON_MATERIAL_PRELUDE_WGSL}
|
|
11
|
-
|
|
12
|
-
const BODY_ROUGHNESS: f32 = 0.3;
|
|
13
|
-
const BODY_SPECULAR: f32 = 0.5;
|
|
14
|
-
const BODY_MIX_NPR: f32 = 0.5;
|
|
15
|
-
const BODY_SPEC_CLAMP: f32 = 10.0;
|
|
16
|
-
const BODY_RIM2_LAYER_BLEND: f32 = 0.20000000298023224;
|
|
17
|
-
const BODY_RIM2_POW: f32 = 1.4300000667572021;
|
|
18
|
-
const BODY_RIM2_BG: vec3f = vec3f(1.0, 0.4303792119026184, 0.3315804898738861);
|
|
19
|
-
const BODY_WARM_STR: f32 = 0.30000001192092896;
|
|
20
|
-
|
|
21
|
-
// smoothstep-based ramp: t*t*(3-2*t) between two color stops
|
|
22
|
-
fn ramp_ease(f: f32, p0: f32, c0: vec4f, p1: f32, c1: vec4f) -> vec4f {
|
|
23
|
-
let t = saturate((f - p0) / max(p1 - p0, 1e-6));
|
|
24
|
-
let ss = t * t * (3.0 - 2.0 * t);
|
|
25
|
-
return mix(c0, c1, ss);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
@fragment fn fs(input: VertexOutput) -> FSOut {
|
|
29
|
-
let tex_s = textureSample(diffuseTexture, diffuseSampler, input.uv);
|
|
30
|
-
// MMD alpha semantics: material alpha × texture alpha. Hair/lace/accessory
|
|
31
|
-
// textures cut their shapes in the alpha channel — ignoring it renders each
|
|
32
|
-
// card's full quad with the texture's padding color (white shimmer on dark
|
|
33
|
-
// hair for models whose textures pad with white).
|
|
34
|
-
let alpha = material.alpha * tex_s.a;
|
|
35
|
-
if (alpha < 0.001) { discard; }
|
|
36
|
-
|
|
37
|
-
let n = safe_normal(input.normal);
|
|
38
|
-
let v = normalize(camera.viewPos - input.worldPos);
|
|
39
|
-
let l = -light.lights[0].direction.xyz;
|
|
40
|
-
let sun = light.lights[0].color.xyz * light.lights[0].color.w;
|
|
41
|
-
let amb = light.ambientColor.xyz;
|
|
42
|
-
let shadow = sampleShadow(input.worldPos, n);
|
|
43
|
-
|
|
44
|
-
let tex_color = tex_s.rgb;
|
|
45
|
-
|
|
46
|
-
// ═══ NPR STACK ═══
|
|
47
|
-
let ndotl_raw = shader_to_rgb_diffuse(n, l, sun, amb, shadow);
|
|
48
|
-
let toon = ramp_constant(ndotl_raw, 0.0, vec4f(0,0,0,1), 0.2966, vec4f(1,1,1,1)).r;
|
|
49
|
-
|
|
50
|
-
let shadow_tint = hue_sat_id(2.0, 0.3499999940395355, 1.0, tex_color);
|
|
51
|
-
let lit_tint = hue_sat_id(1.5, 1.0, 1.0, tex_color);
|
|
52
|
-
let toon_color = mix_blend(toon, shadow_tint, lit_tint);
|
|
53
|
-
let bc = bright_contrast(toon_color, 0.1, 0.2);
|
|
54
|
-
|
|
55
|
-
let emission3 = bc * 4.0;
|
|
56
|
-
|
|
57
|
-
let warm_input = clamp(toon + 0.5, 0.0, 1.0);
|
|
58
|
-
let warm_color = ramp_cardinal(warm_input, 0.2409,
|
|
59
|
-
vec4f(0.2426, 0.068, 0.0588, 1.0), 0.4663,
|
|
60
|
-
vec4f(0.6677, 0.5024, 0.5126, 1.0)).rgb;
|
|
61
|
-
let warm_emission = warm_color * BODY_WARM_STR;
|
|
62
|
-
|
|
63
|
-
let rim1_str = fresnel(2.0, n, v) * layer_weight_facing(0.24000005424022675, n, v);
|
|
64
|
-
let rim1 = vec3f(0.984157919883728, 0.6110184788703918, 0.5736401677131653) * rim1_str;
|
|
65
|
-
|
|
66
|
-
let facing_raw = layer_weight_facing(BODY_RIM2_LAYER_BLEND, n, v);
|
|
67
|
-
let facing_pow = math_power(facing_raw, BODY_RIM2_POW);
|
|
68
|
-
let rim2_fac = ramp_ease(facing_pow, 0.0, vec4f(0,0,0,1), 0.5052, vec4f(1,1,1,1)).r;
|
|
69
|
-
let rim2_mixed = mix(emission3, BODY_RIM2_BG, rim2_fac);
|
|
70
|
-
|
|
71
|
-
let npr_stack = rim1 + rim2_mixed + warm_emission;
|
|
72
|
-
|
|
73
|
-
// ═══ PRINCIPLED BSDF with noise bump ═══
|
|
74
|
-
// Mapping loc=rot=0 in the Blender graph folds to a plain scale multiply.
|
|
75
|
-
// Height in rest space (restPos) so the bump rides with the skin; geometric basis stays
|
|
76
|
-
// worldPos so the perturbed normal matches the world-space n (see face.ts note).
|
|
77
|
-
let noise_val = tex_noise_d2(input.restPos * vec3f(1.0, 1.0, 1.5), 1.0);
|
|
78
|
-
let noise_ramp = ramp_linear(noise_val, 0.0, vec4f(0,0,0,1), 1.0, vec4f(1,1,1,1)).r;
|
|
79
|
-
let bumped_n = bump_lh(0.324644535779953, noise_ramp, n, input.worldPos);
|
|
80
|
-
|
|
81
|
-
let principled_base = mix_blend(noise_ramp, bc, vec3f(0.6831911206245422, 0.19474034011363983, 0.13732507824897766));
|
|
82
|
-
let p_emission = bc * 0.2;
|
|
83
|
-
|
|
84
|
-
let principled = eval_principled(
|
|
85
|
-
PrincipledIn(principled_base, 0.0, BODY_SPECULAR, BODY_ROUGHNESS, BODY_SPEC_CLAMP, 0.0, 0.0),
|
|
86
|
-
bumped_n, l, v, sun, amb, shadow
|
|
87
|
-
) + p_emission;
|
|
88
|
-
|
|
89
|
-
let final_color = mix(npr_stack, principled, BODY_MIX_NPR);
|
|
90
|
-
|
|
91
|
-
var out: FSOut;
|
|
92
|
-
out.color = vec4f(final_color, alpha);
|
|
93
|
-
out.mask = vec4f(1.0, 1.0, 0.0, out.color.a);
|
|
94
|
-
return out;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
`
|