material-designer-runtime 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +79 -4
- package/dist/document.d.ts +1 -1
- package/dist/graph/bake-service.d.ts +5 -2
- package/dist/graph/compiler.d.ts +35 -5
- package/dist/graph/material-textures.d.ts +3 -0
- package/dist/graph/mesh-material.d.ts +6 -0
- package/dist/graph/nodes/shader/shader-material.d.ts +2 -0
- package/dist/graph/nodes/vector/vector-rotate.d.ts +2 -0
- package/dist/graph/textured-surface.d.ts +5 -3
- package/dist/graph/types.d.ts +21 -2
- package/dist/index.d.ts +2 -1
- package/dist/index.js +1583 -901
- package/dist/runtime.d.ts +5 -5
- package/dist/tsl/tile.d.ts +2 -0
- package/dist/tsl/vector-rotate.d.ts +4 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -13,19 +13,94 @@ supported version alongside it.
|
|
|
13
13
|
|
|
14
14
|
## Usage
|
|
15
15
|
|
|
16
|
+
There are two ways to put a document's material on a mesh: let the runtime hand you a
|
|
17
|
+
**ready-made material** (all config loaded for you), or bake the **channel textures** and assign
|
|
18
|
+
them to a material you build yourself. Everything bakes on a `WebGPURenderer`, which must be
|
|
19
|
+
initialized (`await renderer.init()`) first.
|
|
20
|
+
|
|
21
|
+
### Get a ready-made material
|
|
22
|
+
|
|
23
|
+
`getNodeMaterial()` and `getMeshMaterial()` both load the document's family and every setting
|
|
24
|
+
(metalness, roughness, the physical lobes, phong shininess, toon gradient, …) — you never copy
|
|
25
|
+
config by hand. Pick based on what you need:
|
|
26
|
+
|
|
27
|
+
- **`getNodeMaterial()`** — the TSL node material (`MeshStandardNodeMaterial`, `MeshPhysicalNodeMaterial`, …)
|
|
28
|
+
with full procedural fidelity: triplanar projection, parallax-occlusion, per-vertex AO, and
|
|
29
|
+
procedurally-driven lobes. WebGPU only.
|
|
30
|
+
- **`getMeshMaterial()`** — a plain Three.js material (`MeshStandardMaterial`, `MeshPhysicalMaterial`,
|
|
31
|
+
`MeshLambertMaterial`, `MeshToonMaterial`, `MeshPhongMaterial`, `MeshMatcapMaterial`) with the baked
|
|
32
|
+
maps in the standard slots. Drops the node-only features above.
|
|
33
|
+
|
|
16
34
|
```ts
|
|
17
35
|
import { MaterialGraphRuntime } from "material-designer-runtime";
|
|
36
|
+
import { WebGPURenderer } from "three/webgpu";
|
|
37
|
+
import { Mesh, SphereGeometry } from "three";
|
|
38
|
+
|
|
39
|
+
const renderer = new WebGPURenderer();
|
|
40
|
+
await renderer.init();
|
|
18
41
|
|
|
19
42
|
const runtime = new MaterialGraphRuntime()
|
|
20
43
|
.setRenderer(renderer)
|
|
21
|
-
.setBackend("offline")
|
|
22
44
|
.fromDocument(document);
|
|
45
|
+
await runtime.refresh(); // bake the graph to channel textures
|
|
23
46
|
|
|
24
|
-
|
|
25
|
-
mesh.material = runtime.material;
|
|
47
|
+
const geometry = new SphereGeometry(1, 128, 64);
|
|
26
48
|
|
|
27
|
-
|
|
49
|
+
// (a) TSL node material — full fidelity (triplanar, parallax, procedural lobes), WebGPU only:
|
|
50
|
+
const mesh = new Mesh(geometry, runtime.getNodeMaterial());
|
|
51
|
+
// The node material object can change on a re-bake (e.g. a family switch) — keep the mesh current:
|
|
52
|
+
runtime.surface.onRebuilt(() => { mesh.material = runtime.getNodeMaterial(); });
|
|
53
|
+
|
|
54
|
+
// (b) …or a plain Three.js material with the baked maps + settings loaded in (pick one path):
|
|
55
|
+
// geometry.setAttribute("uv1", geometry.getAttribute("uv")); // .aoMap samples the 2nd UV set
|
|
56
|
+
// const mesh = new Mesh(geometry, runtime.getMeshMaterial());
|
|
57
|
+
|
|
58
|
+
// Live edits re-bake implicitly — await whenIdle() before reading back:
|
|
28
59
|
runtime.setNodeParam("noise", "scale", 18);
|
|
60
|
+
runtime.setOutputResolution(1024);
|
|
61
|
+
await runtime.whenIdle();
|
|
62
|
+
|
|
63
|
+
runtime.dispose(); // release GPU resources when done
|
|
29
64
|
```
|
|
30
65
|
|
|
66
|
+
### Bring your own material
|
|
67
|
+
|
|
68
|
+
Bake just the PBR channel maps with the shared `bakeService` (no material surface is created) and
|
|
69
|
+
assign them to your own material. The baked textures already carry the correct `.colorSpace`
|
|
70
|
+
(base color / emission are sRGB, data channels linear), so you assign them as-is:
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
import { bakeService, MaterialGraphSession, defaultRegistry } from "material-designer-runtime";
|
|
74
|
+
import { WebGPURenderer } from "three/webgpu";
|
|
75
|
+
import { Mesh, BoxGeometry, MeshStandardMaterial } from "three";
|
|
76
|
+
|
|
77
|
+
const renderer = new WebGPURenderer();
|
|
78
|
+
await renderer.init();
|
|
79
|
+
bakeService.attachRenderer(renderer);
|
|
80
|
+
|
|
81
|
+
const session = new MaterialGraphSession(document, defaultRegistry);
|
|
82
|
+
const set = await bakeService.bake(session, { size: 1024 }); // set.present = the channels actually baked
|
|
83
|
+
|
|
84
|
+
const material = new MeshStandardMaterial();
|
|
85
|
+
material.map = set.texture("baseColor"); // THREE.Texture | null, keyed by channel
|
|
86
|
+
material.roughnessMap = set.texture("roughness");
|
|
87
|
+
material.metalnessMap = set.texture("metallic");
|
|
88
|
+
material.normalMap = set.texture("normal");
|
|
89
|
+
material.aoMap = set.texture("ambientOcclusion");
|
|
90
|
+
material.emissiveMap = set.texture("emission");
|
|
91
|
+
material.emissive.set(0xffffff);
|
|
92
|
+
material.roughness = 1;
|
|
93
|
+
material.metalness = 1; // the maps carry the values — keep the multipliers at 1
|
|
94
|
+
|
|
95
|
+
const geometry = new BoxGeometry(1, 1, 1);
|
|
96
|
+
geometry.setAttribute("uv1", geometry.getAttribute("uv")); // aoMap samples the 2nd UV set
|
|
97
|
+
const mesh = new Mesh(geometry, material);
|
|
98
|
+
// Keep `set` alive while the material is in use — set.dispose() frees the render targets (and the textures).
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
`height` is baked separately (`set.heightTarget?.texture`). To read a channel back as CPU pixels
|
|
102
|
+
for PNG export, use `bakeService.readImage(session, channel, 1024)` → `ImageData` (size must be a
|
|
103
|
+
multiple of 64). If you keep a live `MaterialGraphRuntime`, the same baked textures are also
|
|
104
|
+
reachable via `runtime.surface.getChannelTexture(channel)` and `runtime.surface.getHeightTexture()`.
|
|
105
|
+
|
|
31
106
|
The editor owns UI state, selection, storage, presets, and undo history. This package owns only graph document loading, compilation, baking, direct parameter updates, and the material surface.
|
package/dist/document.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type NodeRegistry } from "./graph/registry";
|
|
2
2
|
import { type GraphChange, type MaterialGraphDocument, type MaterialGraphSource } from "./graph/types";
|
|
3
|
-
export declare const MATERIAL_DOCUMENT_VERSION =
|
|
3
|
+
export declare const MATERIAL_DOCUMENT_VERSION = 4;
|
|
4
4
|
export declare function cloneMaterialDocument(doc: MaterialGraphDocument): MaterialGraphDocument;
|
|
5
5
|
export declare function createDefaultMaterialDocument(): MaterialGraphDocument;
|
|
6
6
|
export declare function migrateMaterialDocument(doc: MaterialGraphDocument): MaterialGraphDocument;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as THREE from "three";
|
|
2
2
|
import { RenderTarget, type WebGPURenderer, type MeshBasicNodeMaterial } from "three/webgpu";
|
|
3
|
-
import { type CacheEntry } from "./compiler";
|
|
3
|
+
import { type CacheEntry, type ParamUsage } from "./compiler";
|
|
4
4
|
import type { MaterialGraphSource, MaterialValue, PbrSocket } from "./types";
|
|
5
5
|
export declare const SURFACE_CHANNELS: PbrSocket[];
|
|
6
6
|
export interface BakeOptions {
|
|
@@ -27,9 +27,11 @@ export declare class BakedTextureSet {
|
|
|
27
27
|
private readonly cacheMats;
|
|
28
28
|
cachePlan: CacheEntry[];
|
|
29
29
|
uniforms: Map<string, Record<string, MaterialValue>>;
|
|
30
|
+
paramUsage: ParamUsage;
|
|
31
|
+
private readonly constArrays;
|
|
30
32
|
heightTarget: RenderTarget | null;
|
|
31
33
|
hasHeight: boolean;
|
|
32
|
-
present: Set<"roughness" | "normal" | "baseColor" | "metallic" | "
|
|
34
|
+
present: Set<"roughness" | "normal" | "baseColor" | "metallic" | "ambientOcclusion" | "emission">;
|
|
33
35
|
signature: string;
|
|
34
36
|
size: number;
|
|
35
37
|
constructor(size: number, channels: PbrSocket[]);
|
|
@@ -43,6 +45,7 @@ export declare class BakedTextureSet {
|
|
|
43
45
|
firstTarget(): RenderTarget | null;
|
|
44
46
|
ensureHeightTarget(): RenderTarget;
|
|
45
47
|
texture(ch: PbrSocket): THREE.Texture | null;
|
|
48
|
+
allocConstantArray(nodeId: string, key: string, data: ArrayLike<number>, elementType: "float" | "vec3"): MaterialValue;
|
|
46
49
|
flushCaches(): void;
|
|
47
50
|
dispose(): void;
|
|
48
51
|
}
|
package/dist/graph/compiler.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import * as THREE from "three";
|
|
2
|
-
import {
|
|
3
|
-
import { type MaterialBackend, type MaterialBundle, type MaterialGraphDocument, type MaterialValue, type PortKind } from "./types";
|
|
2
|
+
import { type NodeMaterial } from "three/webgpu";
|
|
3
|
+
import { type MaterialBackend, type MaterialBundle, type MaterialGraphDocument, type MaterialType, type MaterialTypeSettings, type MaterialValue, type PortKind } from "./types";
|
|
4
4
|
import { type NodeRegistry } from "./registry";
|
|
5
|
+
import { gradientMapFor, matcapFor } from "./material-textures";
|
|
6
|
+
export { gradientMapFor, matcapFor };
|
|
5
7
|
export interface CompiledMaterial {
|
|
6
|
-
material:
|
|
8
|
+
material: NodeMaterial;
|
|
7
9
|
uniforms: Map<string, Record<string, MaterialValue>>;
|
|
8
10
|
}
|
|
9
11
|
export interface CacheSizing {
|
|
@@ -11,6 +13,8 @@ export interface CacheSizing {
|
|
|
11
13
|
size?: number;
|
|
12
14
|
}
|
|
13
15
|
export type CacheAlloc = (cacheId: string, kind: PortKind, sizing?: CacheSizing) => THREE.Texture;
|
|
16
|
+
export type ParamUsage = Map<string, Record<string, "live" | "constant">>;
|
|
17
|
+
export type ConstantArrayAlloc = (nodeId: string, key: string, data: ArrayLike<number>, elementType: "float" | "vec3") => MaterialValue;
|
|
14
18
|
export interface CacheEntry {
|
|
15
19
|
cacheId: string;
|
|
16
20
|
kind: PortKind;
|
|
@@ -21,16 +25,42 @@ export interface CompileOptions {
|
|
|
21
25
|
backend: MaterialBackend;
|
|
22
26
|
soloNodeId?: string;
|
|
23
27
|
allocCache?: CacheAlloc;
|
|
28
|
+
allocConstantArray?: ConstantArrayAlloc;
|
|
24
29
|
outputResolution?: number;
|
|
25
30
|
}
|
|
26
31
|
export interface CompiledSockets {
|
|
27
32
|
bundle: MaterialBundle;
|
|
28
33
|
uniforms: Map<string, Record<string, MaterialValue>>;
|
|
29
34
|
cachePlan: CacheEntry[];
|
|
35
|
+
paramUsage: ParamUsage;
|
|
30
36
|
}
|
|
31
37
|
export declare function readOutputResolution(doc: MaterialGraphDocument): number;
|
|
38
|
+
export declare function readMaterialSurface(doc: MaterialGraphDocument): {
|
|
39
|
+
type: MaterialType;
|
|
40
|
+
settings: MaterialTypeSettings;
|
|
41
|
+
};
|
|
42
|
+
export interface MaterialConfig {
|
|
43
|
+
type: MaterialType;
|
|
44
|
+
baseColor: string;
|
|
45
|
+
metallic: number;
|
|
46
|
+
roughness: number;
|
|
47
|
+
ior: number;
|
|
48
|
+
alpha: number;
|
|
49
|
+
coat: number;
|
|
50
|
+
coatRoughness: number;
|
|
51
|
+
sheen: number;
|
|
52
|
+
sheenRoughness: number;
|
|
53
|
+
transmission: number;
|
|
54
|
+
emission: string;
|
|
55
|
+
emissionStrength: number;
|
|
56
|
+
shininess: number;
|
|
57
|
+
specular: string;
|
|
58
|
+
gradientSteps: number;
|
|
59
|
+
matcap: string;
|
|
60
|
+
}
|
|
61
|
+
export declare function readMaterialConfig(doc: MaterialGraphDocument): MaterialConfig;
|
|
32
62
|
export declare function countGraphNodes(doc: MaterialGraphDocument): number;
|
|
33
63
|
export declare function compileSockets(doc: MaterialGraphDocument, registry: NodeRegistry, optsIn: CompileOptions): CompiledSockets;
|
|
34
|
-
export declare function newSurfaceMaterial():
|
|
35
|
-
export declare function applyBundle(material:
|
|
64
|
+
export declare function newSurfaceMaterial(type?: MaterialType, settings?: MaterialTypeSettings): NodeMaterial;
|
|
65
|
+
export declare function applyBundle(material: NodeMaterial, bundle: MaterialBundle, type: MaterialType): void;
|
|
36
66
|
export declare function compileGraph(doc: MaterialGraphDocument, registry: NodeRegistry, opts: CompileOptions): CompiledMaterial;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import * as THREE from "three";
|
|
2
|
+
import { type MaterialGraphDocument, type PbrSocket } from "./types";
|
|
3
|
+
export interface ChannelTextures {
|
|
4
|
+
get(channel: PbrSocket): THREE.Texture | null;
|
|
5
|
+
}
|
|
6
|
+
export declare function buildMeshMaterial(doc: MaterialGraphDocument, textures: ChannelTextures): THREE.Material;
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import * as THREE from "three";
|
|
2
|
-
import type {
|
|
2
|
+
import type { NodeMaterial } from "three/webgpu";
|
|
3
3
|
import { type MaterialBackend, type MaterialGraphSource, type PbrSocket } from "./types";
|
|
4
4
|
import { type MaterialBakeService } from "./bake-service";
|
|
5
5
|
export declare class TexturedSurface {
|
|
6
6
|
private readonly graph;
|
|
7
7
|
private readonly service;
|
|
8
8
|
private readonly source?;
|
|
9
|
-
private
|
|
9
|
+
private offlineMat;
|
|
10
|
+
private matType;
|
|
11
|
+
private matSig;
|
|
10
12
|
private liveUniforms;
|
|
11
13
|
private material_;
|
|
12
14
|
readonly scaleUniform: import("three/webgpu").UniformNode<"float", number>;
|
|
@@ -31,7 +33,7 @@ export declare class TexturedSurface {
|
|
|
31
33
|
private processingDepth;
|
|
32
34
|
private idleWaiters;
|
|
33
35
|
constructor(graph: MaterialGraphSource, service: MaterialBakeService, source?: string | undefined);
|
|
34
|
-
get material():
|
|
36
|
+
get material(): NodeMaterial;
|
|
35
37
|
get lastError(): string | null;
|
|
36
38
|
get busy(): boolean;
|
|
37
39
|
whenIdle(): Promise<void>;
|
package/dist/graph/types.d.ts
CHANGED
|
@@ -31,8 +31,25 @@ export interface ParamDef {
|
|
|
31
31
|
options?: string[];
|
|
32
32
|
default: unknown;
|
|
33
33
|
bakeStructural?: boolean;
|
|
34
|
+
structural?: boolean;
|
|
34
35
|
}
|
|
35
36
|
export type MaterialBackend = "live" | "offline";
|
|
37
|
+
export type MaterialType = "standard" | "physical" | "lambert" | "toon" | "phong" | "matcap";
|
|
38
|
+
export declare const MATERIAL_TYPES: MaterialType[];
|
|
39
|
+
export interface MaterialTypeSettings {
|
|
40
|
+
shininess?: number;
|
|
41
|
+
specular?: string;
|
|
42
|
+
gradientSteps?: number;
|
|
43
|
+
matcap?: string;
|
|
44
|
+
}
|
|
45
|
+
export interface MaterialTypeCaps {
|
|
46
|
+
roughMetal: boolean;
|
|
47
|
+
physicalLobes: boolean;
|
|
48
|
+
ao: boolean;
|
|
49
|
+
emissive: boolean;
|
|
50
|
+
}
|
|
51
|
+
export declare const MATERIAL_TYPE_CAPS: Record<MaterialType, MaterialTypeCaps>;
|
|
52
|
+
export declare function normalizeMaterialType(raw: unknown): MaterialType;
|
|
36
53
|
export type GraphChange = {
|
|
37
54
|
kind: "structural";
|
|
38
55
|
} | {
|
|
@@ -47,8 +64,9 @@ export type GraphChange = {
|
|
|
47
64
|
};
|
|
48
65
|
export interface BuildCtx {
|
|
49
66
|
inputs: Record<string, MaterialValue | undefined>;
|
|
50
|
-
|
|
51
|
-
|
|
67
|
+
live(key: string): MaterialValue;
|
|
68
|
+
constant(key: string): unknown;
|
|
69
|
+
constantArray(key: string, compute: () => ArrayLike<number>, elementType?: "float" | "vec3"): MaterialValue;
|
|
52
70
|
coord: MaterialValue;
|
|
53
71
|
backend: MaterialBackend;
|
|
54
72
|
tileRepeat?: number;
|
|
@@ -130,6 +148,7 @@ export interface MaterialGraphSource {
|
|
|
130
148
|
onChange(fn: (change: GraphChange) => void): () => void;
|
|
131
149
|
}
|
|
132
150
|
export declare const MATERIAL_OUTPUT_TYPE = "material-output";
|
|
151
|
+
export declare const SHADER_MATERIAL_TYPE = "shader-material";
|
|
133
152
|
export declare const PBR_SOCKETS: readonly ["baseColor", "normal", "emission", "roughness", "metallic", "ambientOcclusion"];
|
|
134
153
|
export type PbrSocket = (typeof PBR_SOCKETS)[number];
|
|
135
154
|
export interface MaterialBundle {
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,8 @@ export { MaterialGraphRuntime, type MaterialGraphRuntimeOptions } from "./runtim
|
|
|
2
2
|
export { MATERIAL_DOCUMENT_VERSION, MaterialGraphSession, cloneMaterialDocument, createDefaultMaterialDocument, migrateMaterialDocument, } from "./document";
|
|
3
3
|
export { createMaterialTopologyKey } from "./topology";
|
|
4
4
|
export { MaterialBakeService, BakedTextureSet, SURFACE_CHANNELS, bakeService, type BakeOptions, type BakeReport, } from "./graph/bake-service";
|
|
5
|
-
export { compileGraph, compileSockets, countGraphNodes, newSurfaceMaterial, readOutputResolution, type CompileOptions, type CompiledSockets, } from "./graph/compiler";
|
|
5
|
+
export { compileGraph, compileSockets, countGraphNodes, newSurfaceMaterial, readMaterialSurface, readMaterialConfig, readOutputResolution, type CompileOptions, type CompiledSockets, type MaterialConfig, } from "./graph/compiler";
|
|
6
|
+
export { buildMeshMaterial, type ChannelTextures } from "./graph/mesh-material";
|
|
6
7
|
export { NodeRegistry, createDefaultRegistry, defaultRegistry, nodeParamDefs, nodePorts, } from "./graph/registry";
|
|
7
8
|
export { TexturedSurface } from "./graph/textured-surface";
|
|
8
9
|
export { runTilingTest } from "./graph/tiling-test";
|