@shaderfrog/core 1.0.10 → 1.1.0
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 +7 -0
- package/dist/engine.d.ts +8 -5
- package/dist/engine.js +1 -1
- package/dist/graph/base-node.d.ts +5 -3
- package/dist/graph/code-nodes.d.ts +6 -8
- package/dist/graph/code-nodes.js +1 -1
- package/dist/graph/context.d.ts +7 -5
- package/dist/graph/context.js +44 -31
- package/dist/graph/data-nodes.d.ts +22 -22
- package/dist/graph/data-nodes.js +9 -1
- package/dist/graph/edge.d.ts +3 -2
- package/dist/graph/edge.js +6 -0
- package/dist/graph/{engine-node.d.ts → graph-node.d.ts} +1 -8
- package/dist/graph/{engine-node.js → graph-node.js} +11 -65
- package/dist/graph/graph-types.d.ts +13 -0
- package/dist/graph/graph-types.js +15 -0
- package/dist/graph/graph.d.ts +22 -12
- package/dist/graph/graph.js +107 -50
- package/dist/graph/graph.test.js +3 -2
- package/dist/graph/index.d.ts +1 -1
- package/dist/graph/index.js +1 -1
- package/dist/graph/parsers.d.ts +2 -2
- package/dist/graph/parsers.js +7 -7
- package/dist/plugins/babylon/bablyengine.d.ts +2 -2
- package/dist/plugins/babylon/bablyengine.js +23 -16
- package/dist/plugins/playcanvas/playengine.d.ts +2 -2
- package/dist/plugins/playcanvas/playengine.js +32 -25
- package/dist/plugins/three/threngine.d.ts +5 -5
- package/dist/plugins/three/threngine.js +103 -38
- package/dist/strategy/assignemntTo.js +2 -2
- package/dist/strategy/declarationOf.js +2 -2
- package/dist/strategy/hardCode.js +1 -1
- package/dist/strategy/index.d.ts +1 -0
- package/dist/strategy/index.js +1 -0
- package/dist/strategy/inject.js +2 -2
- package/dist/strategy/namedAttribute.js +2 -2
- package/dist/strategy/strategy.d.ts +2 -2
- package/dist/strategy/strategy.js +1 -1
- package/dist/strategy/stratgies.test.js +7 -7
- package/dist/strategy/texture2D.js +2 -2
- package/dist/strategy/uniform.js +3 -3
- package/dist/strategy/variable.js +2 -2
- package/dist/util/ast.js +0 -1
- package/dist/util/id.js +1 -1
- package/package.json +4 -5
|
@@ -1,25 +1,19 @@
|
|
|
1
|
-
import { EngineNodeType } from '../engine';
|
|
2
|
-
import { prepopulatePropertyInputs } from './graph';
|
|
3
1
|
import { NodeType } from './graph-types';
|
|
4
|
-
import { assignemntToStrategy,
|
|
5
|
-
import { SourceType
|
|
6
|
-
|
|
7
|
-
* TODO: These definitions should live outside of core since I'm trying to
|
|
8
|
-
* refactor out this core folder to only know about nodes with config config,
|
|
9
|
-
* where nodes like output/phong/physical are all configured at the
|
|
10
|
-
* implementation level. "phong" shouldn't be in the core
|
|
11
|
-
*/
|
|
12
|
-
export var sourceNode = function (id, name, position, config, source, stage, originalEngine, nextStageNodeId) { return ({
|
|
2
|
+
import { assignemntToStrategy, variableStrategy } from '../strategy';
|
|
3
|
+
import { SourceType } from './code-nodes';
|
|
4
|
+
export var sourceNode = function (id, name, position, config, source, stage, originalEngine) { return ({
|
|
13
5
|
id: id,
|
|
14
6
|
name: name,
|
|
15
|
-
groupId: undefined,
|
|
16
7
|
type: NodeType.SOURCE,
|
|
8
|
+
sourceType: SourceType.SHADER_PROGRAM,
|
|
9
|
+
engine: false,
|
|
17
10
|
config: config,
|
|
18
11
|
position: position,
|
|
19
12
|
inputs: [],
|
|
20
13
|
outputs: [
|
|
21
14
|
{
|
|
22
15
|
name: 'vector4',
|
|
16
|
+
dataType: 'vector4',
|
|
23
17
|
category: 'data',
|
|
24
18
|
id: '1',
|
|
25
19
|
},
|
|
@@ -27,14 +21,14 @@ export var sourceNode = function (id, name, position, config, source, stage, ori
|
|
|
27
21
|
source: source,
|
|
28
22
|
stage: stage,
|
|
29
23
|
originalEngine: originalEngine,
|
|
30
|
-
nextStageNodeId: nextStageNodeId,
|
|
31
24
|
}); };
|
|
32
25
|
export var outputNode = function (id, name, position, stage) { return ({
|
|
33
26
|
id: id,
|
|
34
27
|
name: name,
|
|
35
28
|
position: position,
|
|
36
|
-
groupId: undefined,
|
|
37
29
|
type: NodeType.OUTPUT,
|
|
30
|
+
sourceType: SourceType.SHADER_PROGRAM,
|
|
31
|
+
engine: false,
|
|
38
32
|
config: {
|
|
39
33
|
version: 3,
|
|
40
34
|
mangle: false,
|
|
@@ -65,8 +59,8 @@ export var expressionNode = function (id, name, position, source) { return ({
|
|
|
65
59
|
name: name,
|
|
66
60
|
position: position,
|
|
67
61
|
type: NodeType.SOURCE,
|
|
62
|
+
engine: false,
|
|
68
63
|
sourceType: SourceType.EXPRESSION,
|
|
69
|
-
groupId: undefined,
|
|
70
64
|
stage: undefined,
|
|
71
65
|
config: {
|
|
72
66
|
uniforms: [],
|
|
@@ -85,60 +79,12 @@ export var expressionNode = function (id, name, position, source) { return ({
|
|
|
85
79
|
],
|
|
86
80
|
source: source,
|
|
87
81
|
}); };
|
|
88
|
-
export var phongNode = function (id, name, groupId, position, stage, nextStageNodeId) {
|
|
89
|
-
return prepopulatePropertyInputs({
|
|
90
|
-
id: id,
|
|
91
|
-
name: name,
|
|
92
|
-
groupId: groupId,
|
|
93
|
-
position: position,
|
|
94
|
-
type: EngineNodeType.phong,
|
|
95
|
-
config: {
|
|
96
|
-
version: 3,
|
|
97
|
-
uniforms: [],
|
|
98
|
-
preprocess: true,
|
|
99
|
-
mangle: false,
|
|
100
|
-
properties: [
|
|
101
|
-
property('Color', 'color', 'rgb', 'uniform_diffuse'),
|
|
102
|
-
property('Emissive', 'emissive', 'rgb', 'uniform_emissive'),
|
|
103
|
-
property('Emissive Map', 'emissiveMap', 'texture', 'filler_emissiveMap'),
|
|
104
|
-
property('Emissive Intensity', 'emissiveIntensity', 'number', 'uniform_emissive'),
|
|
105
|
-
property('Texture', 'map', 'texture', 'filler_map'),
|
|
106
|
-
property('Normal Map', 'normalMap', 'texture', 'filler_normalMap'),
|
|
107
|
-
property('Normal Scale', 'normalScale', 'vector2'),
|
|
108
|
-
property('Shininess', 'shininess', 'number'),
|
|
109
|
-
property('Reflectivity', 'reflectivity', 'number'),
|
|
110
|
-
property('Refraction Ratio', 'refractionRatio', 'number'),
|
|
111
|
-
property('Specular', 'specular', 'rgb', 'uniform_specular'),
|
|
112
|
-
property('Specular Map', 'specularMap', 'texture', 'filler_specularMap'),
|
|
113
|
-
property('Displacement Map', 'displacementMap', 'texture'),
|
|
114
|
-
property('Env Map', 'envMap', 'samplerCube'),
|
|
115
|
-
],
|
|
116
|
-
strategies: [
|
|
117
|
-
uniformStrategy(),
|
|
118
|
-
stage === 'fragment'
|
|
119
|
-
? texture2DStrategy()
|
|
120
|
-
: namedAttributeStrategy('position'),
|
|
121
|
-
],
|
|
122
|
-
},
|
|
123
|
-
inputs: [],
|
|
124
|
-
outputs: [
|
|
125
|
-
{
|
|
126
|
-
name: 'vector4',
|
|
127
|
-
category: 'data',
|
|
128
|
-
id: '1',
|
|
129
|
-
},
|
|
130
|
-
],
|
|
131
|
-
source: '',
|
|
132
|
-
stage: stage,
|
|
133
|
-
nextStageNodeId: nextStageNodeId,
|
|
134
|
-
});
|
|
135
|
-
};
|
|
136
82
|
export var addNode = function (id, position) { return ({
|
|
137
83
|
id: id,
|
|
138
84
|
name: 'add',
|
|
139
85
|
position: position,
|
|
140
86
|
type: NodeType.BINARY,
|
|
141
|
-
|
|
87
|
+
engine: false,
|
|
142
88
|
stage: undefined,
|
|
143
89
|
config: {
|
|
144
90
|
mangle: false,
|
|
@@ -164,7 +110,7 @@ export var multiplyNode = function (id, position) { return ({
|
|
|
164
110
|
id: id,
|
|
165
111
|
name: 'multiply',
|
|
166
112
|
type: NodeType.BINARY,
|
|
167
|
-
|
|
113
|
+
engine: false,
|
|
168
114
|
stage: undefined,
|
|
169
115
|
position: position,
|
|
170
116
|
config: {
|
|
@@ -12,6 +12,19 @@ import { SourceNode } from './code-nodes';
|
|
|
12
12
|
* by then.
|
|
13
13
|
*/
|
|
14
14
|
export type ShaderStage = 'fragment' | 'vertex';
|
|
15
|
+
/**
|
|
16
|
+
* The type applied to the edge representing a link between node stages
|
|
17
|
+
*/
|
|
18
|
+
export declare enum EdgeLink {
|
|
19
|
+
NEXT_STAGE = "next_stage"
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* The handle types for links. These become <Handle /> ids
|
|
23
|
+
*/
|
|
24
|
+
export declare enum LinkHandle {
|
|
25
|
+
NEXT_STAGE = "next_stage",
|
|
26
|
+
PREVIOUS_STAGE = "previous_stage"
|
|
27
|
+
}
|
|
15
28
|
export declare enum NodeType {
|
|
16
29
|
OUTPUT = "output",
|
|
17
30
|
BINARY = "binary",
|
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The type applied to the edge representing a link between node stages
|
|
3
|
+
*/
|
|
4
|
+
export var EdgeLink;
|
|
5
|
+
(function (EdgeLink) {
|
|
6
|
+
EdgeLink["NEXT_STAGE"] = "next_stage";
|
|
7
|
+
})(EdgeLink || (EdgeLink = {}));
|
|
8
|
+
/**
|
|
9
|
+
* The handle types for links. These become <Handle /> ids
|
|
10
|
+
*/
|
|
11
|
+
export var LinkHandle;
|
|
12
|
+
(function (LinkHandle) {
|
|
13
|
+
LinkHandle["NEXT_STAGE"] = "next_stage";
|
|
14
|
+
LinkHandle["PREVIOUS_STAGE"] = "previous_stage";
|
|
15
|
+
})(LinkHandle || (LinkHandle = {}));
|
|
1
16
|
export var NodeType;
|
|
2
17
|
(function (NodeType) {
|
|
3
18
|
NodeType["OUTPUT"] = "output";
|
package/dist/graph/graph.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Program } from '@shaderfrog/glsl-parser/ast';
|
|
2
2
|
import { Engine, EngineContext } from '../engine';
|
|
3
|
+
import { NodeErrors } from './context';
|
|
3
4
|
import { ShaderSections } from './shader-sections';
|
|
4
5
|
import { DataNode } from './data-nodes';
|
|
5
6
|
import { Edge } from './edge';
|
|
@@ -12,18 +13,29 @@ export declare const isSourceNode: (node: GraphNode) => node is SourceNode;
|
|
|
12
13
|
export declare const findNode: (graph: Graph, id: string) => GraphNode;
|
|
13
14
|
export declare const doesLinkThruShader: (graph: Graph, node: GraphNode) => boolean;
|
|
14
15
|
export declare const nodeName: (node: GraphNode) => string;
|
|
15
|
-
export declare const mangleName: (name: string, node: GraphNode) => string;
|
|
16
|
-
export declare const mangleVar: (name: string, engine: Engine, node: GraphNode) => string;
|
|
17
|
-
export declare const mangleEntireProgram: (ast: Program, node:
|
|
18
|
-
export declare const mangleMainFn: (ast: Program, node:
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
export declare const mangleName: (name: string, node: GraphNode, nextSibling?: GraphNode) => string;
|
|
17
|
+
export declare const mangleVar: (name: string, engine: Engine, node: GraphNode, sibling?: GraphNode) => string;
|
|
18
|
+
export declare const mangleEntireProgram: (engine: Engine, ast: Program, node: GraphNode, sibling?: GraphNode) => void;
|
|
19
|
+
export declare const mangleMainFn: (ast: Program, node: GraphNode, sibling?: GraphNode) => void;
|
|
20
|
+
export declare const ensureFromNode: (graph: Graph, inputEdge: Edge) => GraphNode;
|
|
21
|
+
export declare const resetGraphIds: (graph: Graph) => Graph;
|
|
22
|
+
export declare const findLinkedNode: (graph: Graph, id: string) => GraphNode;
|
|
23
|
+
/**
|
|
24
|
+
* Find any unconnected vertex nodes linked to collected fragment nodes
|
|
25
|
+
*/
|
|
26
|
+
export declare const findLinkedVertexNodes: (graph: Graph, existingIds?: NodeIds) => GraphNode[];
|
|
27
|
+
export type Predicates = {
|
|
28
|
+
node?: (node: GraphNode, inputEdges: Edge[], lastResult: SearchResult) => boolean;
|
|
29
|
+
edge?: (input: NodeInput | undefined, node: GraphNode, inputEdge: Edge | undefined, fromNode: GraphNode | undefined, lastResult: SearchResult) => boolean;
|
|
30
|
+
input?: (input: NodeInput, node: GraphNode, inputEdge: Edge | undefined, fromNode: GraphNode | undefined, lastResult: SearchResult) => boolean;
|
|
22
31
|
};
|
|
23
32
|
export type SearchResult = {
|
|
24
33
|
nodes: Record<string, GraphNode>;
|
|
25
34
|
inputs: Record<string, NodeInput[]>;
|
|
35
|
+
edges: Edge[];
|
|
26
36
|
};
|
|
37
|
+
export declare const consSearchResult: () => SearchResult;
|
|
38
|
+
export declare const mergeSearchResults: (a: SearchResult, b: SearchResult) => SearchResult;
|
|
27
39
|
/**
|
|
28
40
|
* Create the inputs on a node from the properties. This used to be done at
|
|
29
41
|
* context time. Doing it at node creation time lets us auto-bake edges into
|
|
@@ -32,14 +44,12 @@ export type SearchResult = {
|
|
|
32
44
|
export declare const prepopulatePropertyInputs: (node: CodeNode) => CodeNode;
|
|
33
45
|
/**
|
|
34
46
|
* Recursively filter the graph, starting from a specific node, looking for
|
|
35
|
-
* nodes and edges that match predicates.
|
|
36
|
-
* matched edges, not the edges themselves, as a convenience for the only
|
|
37
|
-
* consumer of this function, which is finding input names to use as uniforms.
|
|
47
|
+
* nodes and edges that match predicates.
|
|
38
48
|
*
|
|
39
49
|
* Inputs can only be filtered if the graph context has been computed, since
|
|
40
50
|
* inputs aren't created until then.
|
|
41
51
|
*/
|
|
42
|
-
export declare const filterGraphFromNode: (graph: Graph, node: GraphNode, predicates: Predicates, depth?: number) => SearchResult;
|
|
52
|
+
export declare const filterGraphFromNode: (graph: Graph, node: GraphNode, predicates: Predicates, depth?: number, lastResult?: SearchResult) => SearchResult;
|
|
43
53
|
export declare const collectConnectedNodes: (graph: Graph, node: GraphNode) => NodeIds;
|
|
44
54
|
export declare const filterGraphNodes: (graph: Graph, nodes: GraphNode[], filter: Predicates, depth?: number) => SearchResult;
|
|
45
55
|
type NodeIds = Record<string, GraphNode>;
|
|
@@ -75,5 +85,5 @@ export type CompileResult = {
|
|
|
75
85
|
dataNodes: Record<string, GraphNode>;
|
|
76
86
|
dataInputs: IndexedDataInputs;
|
|
77
87
|
};
|
|
78
|
-
export declare const compileSource: (graph: Graph, engine: Engine, ctx: EngineContext) => Promise<CompileResult>;
|
|
88
|
+
export declare const compileSource: (graph: Graph, engine: Engine, ctx: EngineContext) => Promise<CompileResult | NodeErrors>;
|
|
79
89
|
export {};
|
package/dist/graph/graph.js
CHANGED
|
@@ -71,7 +71,7 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
|
71
71
|
return to.concat(ar || Array.prototype.slice.call(from));
|
|
72
72
|
};
|
|
73
73
|
import { renameBindings, renameFunctions, } from '@shaderfrog/glsl-parser/parser/utils';
|
|
74
|
-
import { computeGraphContext } from './context';
|
|
74
|
+
import { computeGraphContext, isError, } from './context';
|
|
75
75
|
import { emptyShaderSections, findShaderSections, mergeShaderSections, shaderSectionsToProgram, } from './shader-sections';
|
|
76
76
|
import { makeExpression } from '../util/ast';
|
|
77
77
|
import { ensure } from '../util/ensure';
|
|
@@ -80,7 +80,7 @@ import { nodeInput } from './base-node';
|
|
|
80
80
|
import { makeId } from '../util/id';
|
|
81
81
|
import { coreParsers } from './parsers';
|
|
82
82
|
import { toGlsl } from './evaluate';
|
|
83
|
-
import { MAGIC_OUTPUT_STMTS, NodeType } from './graph-types';
|
|
83
|
+
import { EdgeLink, MAGIC_OUTPUT_STMTS, NodeType, } from './graph-types';
|
|
84
84
|
import { generate } from '@shaderfrog/glsl-parser';
|
|
85
85
|
var log = function () {
|
|
86
86
|
var _a;
|
|
@@ -100,7 +100,7 @@ export var findNode = function (graph, id) {
|
|
|
100
100
|
return ensure(graph.nodes.find(function (node) { return node.id === id; }));
|
|
101
101
|
};
|
|
102
102
|
export var doesLinkThruShader = function (graph, node) {
|
|
103
|
-
var edges = graph.edges.filter(function (edge) { return edge.from === node.id; });
|
|
103
|
+
var edges = graph.edges.filter(function (edge) { return edge.type !== EdgeLink.NEXT_STAGE && edge.from === node.id; });
|
|
104
104
|
if (edges.length === 0) {
|
|
105
105
|
return false;
|
|
106
106
|
}
|
|
@@ -120,72 +120,128 @@ export var doesLinkThruShader = function (graph, node) {
|
|
|
120
120
|
export var nodeName = function (node) {
|
|
121
121
|
return 'main_' + node.name.replace(/[^a-zA-Z0-9]/g, ' ').replace(/ +/g, '_');
|
|
122
122
|
};
|
|
123
|
-
export var mangleName = function (name, node) {
|
|
124
|
-
// Mangle
|
|
125
|
-
|
|
123
|
+
export var mangleName = function (name, node, nextSibling) {
|
|
124
|
+
// Mangle a name to its next stage node, so the vertex suffix becomes the
|
|
125
|
+
// fragment id, but not the other way around.
|
|
126
|
+
var id = (nextSibling === null || nextSibling === void 0 ? void 0 : nextSibling.stage) === 'fragment'
|
|
127
|
+
? nextSibling === null || nextSibling === void 0 ? void 0 : nextSibling.id
|
|
128
|
+
: node.id;
|
|
126
129
|
return "".concat(name, "_").concat(id);
|
|
127
130
|
};
|
|
128
|
-
export var mangleVar = function (name, engine, node) {
|
|
129
|
-
|
|
130
|
-
};
|
|
131
|
-
export var mangleEntireProgram = function (ast, node, engine) {
|
|
131
|
+
export var mangleVar = function (name, engine, node, sibling) { return (engine.preserve.has(name) ? name : mangleName(name, node, sibling)); };
|
|
132
|
+
export var mangleEntireProgram = function (engine, ast, node, sibling) {
|
|
132
133
|
renameBindings(ast.scopes[0], function (name, n) {
|
|
133
|
-
return n.doNotDescope ? name : mangleVar(name, engine, node);
|
|
134
|
+
return n.doNotDescope ? name : mangleVar(name, engine, node, sibling);
|
|
134
135
|
});
|
|
135
|
-
mangleMainFn(ast, node);
|
|
136
|
+
mangleMainFn(ast, node, sibling);
|
|
136
137
|
};
|
|
137
|
-
export var mangleMainFn = function (ast, node) {
|
|
138
|
+
export var mangleMainFn = function (ast, node, sibling) {
|
|
138
139
|
renameFunctions(ast.scopes[0], function (name) {
|
|
139
|
-
return name === 'main' ? nodeName(node) : mangleName(name, node);
|
|
140
|
+
return name === 'main' ? nodeName(node) : mangleName(name, node, sibling);
|
|
140
141
|
});
|
|
141
142
|
};
|
|
143
|
+
export var ensureFromNode = function (graph, inputEdge) {
|
|
144
|
+
return ensure(graph.nodes.find(function (_a) {
|
|
145
|
+
var id = _a.id;
|
|
146
|
+
return id === inputEdge.from;
|
|
147
|
+
}), "Orphaned edge! There is an edge fro \"".concat(inputEdge.from, "\" to \"").concat(inputEdge.to, "\", but from node ").concat(inputEdge.from, " does not exist in the graph."));
|
|
148
|
+
};
|
|
149
|
+
export var resetGraphIds = function (graph) {
|
|
150
|
+
var idMap = {};
|
|
151
|
+
var map = function (id) {
|
|
152
|
+
idMap[id] = idMap[id] || makeId();
|
|
153
|
+
return idMap[id];
|
|
154
|
+
};
|
|
155
|
+
return {
|
|
156
|
+
nodes: graph.nodes.map(function (n) { return (__assign(__assign(__assign({}, n), { id: map(n.id) }), (n.parentId ? { parentId: map(n.parentId) } : {}))); }),
|
|
157
|
+
edges: graph.edges.map(function (e) { return (__assign(__assign({}, e), { id: map(e.id), from: map(e.from), to: map(e.to) })); }),
|
|
158
|
+
};
|
|
159
|
+
};
|
|
160
|
+
export var findLinkedNode = function (graph, id) {
|
|
161
|
+
var edgeLink = graph.edges.find(function (e) { return e.type === EdgeLink.NEXT_STAGE && (e.from === id || e.to === id); });
|
|
162
|
+
var otherId = (edgeLink === null || edgeLink === void 0 ? void 0 : edgeLink.from) === id ? edgeLink === null || edgeLink === void 0 ? void 0 : edgeLink.to : edgeLink === null || edgeLink === void 0 ? void 0 : edgeLink.from;
|
|
163
|
+
return graph.nodes.find(function (node) { return node.id === otherId; });
|
|
164
|
+
};
|
|
165
|
+
/**
|
|
166
|
+
* Find any unconnected vertex nodes linked to collected fragment nodes
|
|
167
|
+
*/
|
|
168
|
+
export var findLinkedVertexNodes = function (graph, existingIds) {
|
|
169
|
+
if (existingIds === void 0) { existingIds = {}; }
|
|
170
|
+
// Group edges by where they point
|
|
171
|
+
var edgeLinks = graph.edges
|
|
172
|
+
.filter(function (e) { return e.type === EdgeLink.NEXT_STAGE; })
|
|
173
|
+
.reduce(function (edges, edge) {
|
|
174
|
+
var _a;
|
|
175
|
+
return (__assign(__assign({}, edges), (_a = {}, _a[edge.to] = edge, _a[edge.from] = edge, _a)));
|
|
176
|
+
}, {});
|
|
177
|
+
return graph.nodes.filter(function (node) {
|
|
178
|
+
// If this is a vertex node
|
|
179
|
+
return isSourceNode(node) &&
|
|
180
|
+
node.stage === 'vertex' &&
|
|
181
|
+
// That's linked
|
|
182
|
+
node.id in edgeLinks &&
|
|
183
|
+
// And not already captured (this should probably just be a set)
|
|
184
|
+
!existingIds[node.id];
|
|
185
|
+
});
|
|
186
|
+
};
|
|
187
|
+
export var consSearchResult = function () { return ({
|
|
188
|
+
nodes: {},
|
|
189
|
+
inputs: {},
|
|
190
|
+
edges: [],
|
|
191
|
+
}); };
|
|
192
|
+
export var mergeSearchResults = function (a, b) { return ({
|
|
193
|
+
nodes: __assign(__assign({}, a.nodes), b.nodes),
|
|
194
|
+
inputs: __assign(__assign({}, a.inputs), b.inputs),
|
|
195
|
+
edges: __spreadArray(__spreadArray([], __read(a.edges), false), __read(b.edges), false),
|
|
196
|
+
}); };
|
|
142
197
|
/**
|
|
143
198
|
* Create the inputs on a node from the properties. This used to be done at
|
|
144
199
|
* context time. Doing it at node creation time lets us auto-bake edges into
|
|
145
200
|
* the node at initial graph creation time.
|
|
146
201
|
*/
|
|
147
202
|
export var prepopulatePropertyInputs = function (node) { return (__assign(__assign({}, node), { inputs: __spreadArray(__spreadArray([], __read(node.inputs), false), __read((node.config.properties || []).map(function (property) {
|
|
148
|
-
return nodeInput(property.displayName, "property_".concat(property.property), 'property', property.type,
|
|
203
|
+
return nodeInput(property.displayName, "property_".concat(property.property), 'property', property.type, ['data'], !!property.fillerName, // bakeable
|
|
149
204
|
property.property);
|
|
150
205
|
})), false) })); };
|
|
151
206
|
/**
|
|
152
207
|
* Recursively filter the graph, starting from a specific node, looking for
|
|
153
|
-
* nodes and edges that match predicates.
|
|
154
|
-
* matched edges, not the edges themselves, as a convenience for the only
|
|
155
|
-
* consumer of this function, which is finding input names to use as uniforms.
|
|
208
|
+
* nodes and edges that match predicates.
|
|
156
209
|
*
|
|
157
210
|
* Inputs can only be filtered if the graph context has been computed, since
|
|
158
211
|
* inputs aren't created until then.
|
|
159
212
|
*/
|
|
160
|
-
export var filterGraphFromNode = function (graph, node, predicates, depth) {
|
|
213
|
+
export var filterGraphFromNode = function (graph, node, predicates, depth, lastResult) {
|
|
161
214
|
var _a;
|
|
162
215
|
if (depth === void 0) { depth = Infinity; }
|
|
216
|
+
if (lastResult === void 0) { lastResult = consSearchResult(); }
|
|
163
217
|
var inputs = node.inputs;
|
|
164
218
|
var inputEdges = graph.edges.filter(function (edge) { return edge.to === node.id; });
|
|
165
|
-
var nodeAcc = __assign({}, (predicates.node && predicates.node(node, inputEdges)
|
|
219
|
+
var nodeAcc = __assign({}, (predicates.node && predicates.node(node, inputEdges, lastResult)
|
|
166
220
|
? (_a = {}, _a[node.id] = node, _a) : {}));
|
|
221
|
+
var accumulatedResult = __assign(__assign({}, lastResult), { nodes: __assign(__assign({}, lastResult.nodes), nodeAcc) });
|
|
167
222
|
return inputEdges.reduce(function (acc, inputEdge) {
|
|
168
223
|
var _a;
|
|
169
224
|
var input = inputs.find(function (i) { return i.id === inputEdge.input; });
|
|
170
|
-
var fromNode = inputEdge
|
|
171
|
-
? ensure(graph.nodes.find(function (_a) {
|
|
172
|
-
var id = _a.id;
|
|
173
|
-
return id === inputEdge.from;
|
|
174
|
-
}))
|
|
175
|
-
: undefined;
|
|
225
|
+
var fromNode = inputEdge ? ensureFromNode(graph, inputEdge) : undefined;
|
|
176
226
|
var inputAcc = __assign(__assign({}, acc.inputs), (input &&
|
|
177
227
|
predicates.input &&
|
|
178
|
-
predicates.input(input, node, inputEdge, fromNode)
|
|
228
|
+
predicates.input(input, node, inputEdge, fromNode, lastResult)
|
|
179
229
|
? (_a = {}, _a[node.id] = __spreadArray(__spreadArray([], __read((acc.inputs[node.id] || [])), false), [input], false), _a) : {}));
|
|
230
|
+
var edgeAcc = __spreadArray(__spreadArray([], __read(acc.edges), false), __read((predicates.edge &&
|
|
231
|
+
predicates.edge(input, node, inputEdge, fromNode, lastResult)
|
|
232
|
+
? [inputEdge]
|
|
233
|
+
: [])), false);
|
|
234
|
+
// Add in the latest result of edges and inputs so that when we recurse into
|
|
235
|
+
// the next node, it has the latest accumulator
|
|
236
|
+
var intermediateAcc = __assign(__assign({}, acc), { inputs: inputAcc, edges: edgeAcc });
|
|
180
237
|
if (inputEdge && fromNode && depth > 1) {
|
|
181
|
-
var result = filterGraphFromNode(graph, fromNode, predicates, depth - 1);
|
|
182
|
-
return
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
238
|
+
var result = filterGraphFromNode(graph, fromNode, predicates, depth - 1, intermediateAcc);
|
|
239
|
+
return mergeSearchResults(intermediateAcc, result);
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
return intermediateAcc;
|
|
186
243
|
}
|
|
187
|
-
|
|
188
|
-
}, { inputs: {}, nodes: nodeAcc });
|
|
244
|
+
}, accumulatedResult);
|
|
189
245
|
};
|
|
190
246
|
export var collectConnectedNodes = function (graph, node) {
|
|
191
247
|
return filterGraphFromNode(graph, node, { node: function () { return true; } }).nodes;
|
|
@@ -197,11 +253,9 @@ export var filterGraphNodes = function (graph, nodes, filter, depth) {
|
|
|
197
253
|
return {
|
|
198
254
|
nodes: __assign(__assign({}, acc.nodes), result.nodes),
|
|
199
255
|
inputs: __assign(__assign({}, acc.inputs), result.inputs),
|
|
256
|
+
edges: __assign(__assign({}, acc.edges), result.edges),
|
|
200
257
|
};
|
|
201
|
-
},
|
|
202
|
-
nodes: {},
|
|
203
|
-
inputs: {},
|
|
204
|
-
});
|
|
258
|
+
}, consSearchResult());
|
|
205
259
|
};
|
|
206
260
|
// before data inputs were known by the input.category being node or data. I
|
|
207
261
|
// tried updating inputs to have acepts: [code|data] and "baked" now is there a
|
|
@@ -231,16 +285,19 @@ export var compileNode = function (engine, graph, edges, engineContext, node, ac
|
|
|
231
285
|
if (inputEdges.length) {
|
|
232
286
|
var continuation_1 = emptyShaderSections();
|
|
233
287
|
inputEdges
|
|
288
|
+
.filter(function (edge) { return edge.type !== EdgeLink.NEXT_STAGE; })
|
|
234
289
|
.map(function (edge) { return ({
|
|
235
290
|
edge: edge,
|
|
236
291
|
fromNode: ensure(graph.nodes.find(function (node) { return edge.from === node.id; }), "GraphNode for edge ".concat(edge.from, " not found")),
|
|
237
292
|
input: ensure(inputs.find(function (_a) {
|
|
238
293
|
var id = _a.id;
|
|
239
294
|
return id == edge.input;
|
|
240
|
-
}), "GraphNode \"".concat(node.name, "\" has no input ").concat(edge.input, "!\nAvailable:").concat(inputs
|
|
295
|
+
}), "GraphNode \"".concat(node.name, "\"").concat(node.stage ? " (".concat(node.stage, ")") : '', " has no input ").concat(edge.input, "!\nAvailable:").concat(inputs
|
|
296
|
+
.map(function (_a) {
|
|
241
297
|
var id = _a.id;
|
|
242
298
|
return id;
|
|
243
|
-
})
|
|
299
|
+
})
|
|
300
|
+
.join(', '))),
|
|
244
301
|
}); })
|
|
245
302
|
.filter(function (_a) {
|
|
246
303
|
var input = _a.input;
|
|
@@ -272,7 +329,9 @@ export var compileNode = function (engine, graph, edges, engineContext, node, ac
|
|
|
272
329
|
inputFillers: inputFillers,
|
|
273
330
|
fillerName: fillerName,
|
|
274
331
|
});
|
|
275
|
-
throw new Error("Node \"".concat(node.name, "\"
|
|
332
|
+
throw new Error("Node \"".concat(node.name, "\"").concat(node.stage
|
|
333
|
+
? " (".concat(node.stage, ")")
|
|
334
|
+
: '', " has no filler for input \"").concat(input.displayName, "\" named ").concat(fillerName));
|
|
276
335
|
}
|
|
277
336
|
/**
|
|
278
337
|
* +------+ +------+
|
|
@@ -363,13 +422,7 @@ export var compileGraph = function (engineContext, engine, graph) {
|
|
|
363
422
|
// given edges in the graph. Build invisible edges from these vertex nodes to
|
|
364
423
|
// the hidden "mainStmts" input on the output node, which inlines the function
|
|
365
424
|
// calls to those vertex main() statements and includes them in the output
|
|
366
|
-
var orphanNodes = graph
|
|
367
|
-
return isSourceNode(node) &&
|
|
368
|
-
node.stage === 'vertex' &&
|
|
369
|
-
node.nextStageNodeId &&
|
|
370
|
-
fragmentIds[node.nextStageNodeId] &&
|
|
371
|
-
!vertexIds[node.id];
|
|
372
|
-
});
|
|
425
|
+
var orphanNodes = findLinkedVertexNodes(graph, vertexIds);
|
|
373
426
|
var orphanEdges = orphanNodes.map(function (node) { return ({
|
|
374
427
|
id: makeId(),
|
|
375
428
|
from: node.id,
|
|
@@ -415,15 +468,19 @@ export var collectNodeProperties = function (graph) {
|
|
|
415
468
|
return {
|
|
416
469
|
nodes: __assign(__assign({}, fragProperties.nodes), vertProperties.nodes),
|
|
417
470
|
inputs: __assign(__assign({}, fragProperties.inputs), vertProperties.inputs),
|
|
471
|
+
edges: __assign(__assign({}, fragProperties.edges), vertProperties.edges),
|
|
418
472
|
};
|
|
419
473
|
};
|
|
420
474
|
export var compileSource = function (graph, engine, ctx) { return __awaiter(void 0, void 0, void 0, function () {
|
|
421
|
-
var compileResult, fragmentResult, vertexResult, dataInputs, dataNodes;
|
|
475
|
+
var result, compileResult, fragmentResult, vertexResult, dataInputs, dataNodes;
|
|
422
476
|
return __generator(this, function (_a) {
|
|
423
477
|
switch (_a.label) {
|
|
424
478
|
case 0: return [4 /*yield*/, computeGraphContext(ctx, engine, graph)];
|
|
425
479
|
case 1:
|
|
426
|
-
_a.sent();
|
|
480
|
+
result = _a.sent();
|
|
481
|
+
if (isError(result)) {
|
|
482
|
+
return [2 /*return*/, result];
|
|
483
|
+
}
|
|
427
484
|
compileResult = compileGraph(ctx, engine, graph);
|
|
428
485
|
fragmentResult = generate(shaderSectionsToProgram(compileResult.fragment, engine.mergeOptions).program);
|
|
429
486
|
vertexResult = generate(shaderSectionsToProgram(compileResult.vertex, engine.mergeOptions).program);
|
package/dist/graph/graph.test.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import util from 'util';
|
|
2
2
|
import { parser } from '@shaderfrog/glsl-parser';
|
|
3
3
|
import { generate } from '@shaderfrog/glsl-parser';
|
|
4
|
-
import { addNode } from './
|
|
4
|
+
import { addNode } from './graph-node';
|
|
5
5
|
import { shaderSectionsToProgram, mergeShaderSections, findShaderSections, } from './shader-sections';
|
|
6
6
|
import { numberNode } from './data-nodes';
|
|
7
7
|
import { makeEdge } from './edge';
|
|
@@ -36,16 +36,17 @@ var constructor = function () { return ({
|
|
|
36
36
|
},
|
|
37
37
|
id: '1',
|
|
38
38
|
name: '1',
|
|
39
|
+
engine: true,
|
|
39
40
|
type: '',
|
|
40
41
|
inputs: [],
|
|
41
42
|
outputs: [],
|
|
42
43
|
position: { x: 0, y: 0 },
|
|
43
44
|
source: '',
|
|
44
45
|
stage: undefined,
|
|
45
|
-
groupId: null,
|
|
46
46
|
}); };
|
|
47
47
|
var engine = {
|
|
48
48
|
name: 'three',
|
|
49
|
+
displayName: 'Three.js',
|
|
49
50
|
evaluateNode: function (node) {
|
|
50
51
|
if (node.type === 'number') {
|
|
51
52
|
return parseFloat(node.value);
|
package/dist/graph/index.d.ts
CHANGED
package/dist/graph/index.js
CHANGED
package/dist/graph/parsers.d.ts
CHANGED
|
@@ -17,14 +17,14 @@ type FillerArguments = AstNode[];
|
|
|
17
17
|
export type ComputedInput = [NodeInput, InputFiller, FillerArguments?];
|
|
18
18
|
export type ProduceAst = (engineContext: EngineContext, engine: Engine, graph: Graph, node: SourceNode, inputEdges: Edge[]) => AstNode | Program;
|
|
19
19
|
export type OnBeforeCompile = (graph: Graph, engineContext: EngineContext, node: SourceNode, sibling?: SourceNode) => Promise<void>;
|
|
20
|
-
export type ManipulateAst = (engineContext: EngineContext, engine: Engine, graph: Graph,
|
|
20
|
+
export type ManipulateAst = (engineContext: EngineContext, engine: Engine, graph: Graph, ast: AstNode | Program, inputEdges: Edge[], node: SourceNode, sibling: SourceNode) => AstNode | Program;
|
|
21
21
|
export type NodeParser = {
|
|
22
22
|
onBeforeCompile?: OnBeforeCompile;
|
|
23
23
|
manipulateAst?: ManipulateAst;
|
|
24
24
|
findInputs?: FindInputs;
|
|
25
25
|
produceFiller?: ProduceNodeFiller;
|
|
26
26
|
};
|
|
27
|
-
export type FindInputs = (engineContext: EngineContext,
|
|
27
|
+
export type FindInputs = (engineContext: EngineContext, ast: Program | AstNode, inputEdges: Edge[], node: SourceNode, sibling: SourceNode) => ComputedInput[];
|
|
28
28
|
export type ProduceNodeFiller = (node: SourceNode, ast: Program | AstNode) => Filler;
|
|
29
29
|
type CoreNodeParser = {
|
|
30
30
|
produceAst: ProduceAst;
|
package/dist/graph/parsers.js
CHANGED
|
@@ -98,10 +98,10 @@ export var coreParsers = (_a = {},
|
|
|
98
98
|
}
|
|
99
99
|
return ast;
|
|
100
100
|
},
|
|
101
|
-
findInputs: function (engineContext, node,
|
|
101
|
+
findInputs: function (engineContext, ast, edges, node, sibling) {
|
|
102
102
|
var seen = new Set();
|
|
103
103
|
return node.config.strategies
|
|
104
|
-
.flatMap(function (strategy) { return applyStrategy(strategy, node,
|
|
104
|
+
.flatMap(function (strategy) { return applyStrategy(strategy, ast, node, sibling); })
|
|
105
105
|
.filter(function (_a) {
|
|
106
106
|
var _b = __read(_a, 2), input = _b[0], _ = _b[1];
|
|
107
107
|
if (!seen.has(input.id)) {
|
|
@@ -125,12 +125,12 @@ export var coreParsers = (_a = {},
|
|
|
125
125
|
produceAst: function (engineContext, engine, graph, node, inputEdges) {
|
|
126
126
|
return parser.parse(node.source);
|
|
127
127
|
},
|
|
128
|
-
findInputs: function (engineContext, node,
|
|
128
|
+
findInputs: function (engineContext, ast, edges, node, sibling) {
|
|
129
129
|
return __spreadArray(__spreadArray([], __read(node.config.strategies.flatMap(function (strategy) {
|
|
130
|
-
return applyStrategy(strategy, node,
|
|
130
|
+
return applyStrategy(strategy, ast, node, sibling);
|
|
131
131
|
})), false), [
|
|
132
132
|
[
|
|
133
|
-
nodeInput(MAGIC_OUTPUT_STMTS, "filler_".concat(MAGIC_OUTPUT_STMTS), 'filler', 'rgba',
|
|
133
|
+
nodeInput(MAGIC_OUTPUT_STMTS, "filler_".concat(MAGIC_OUTPUT_STMTS), 'filler', 'rgba', ['code'], false),
|
|
134
134
|
function (fillerAst) {
|
|
135
135
|
var fn = ast.program.find(function (stmt) { return stmt.type === 'function'; });
|
|
136
136
|
fn === null || fn === void 0 ? void 0 : fn.body.statements.unshift(makeFnStatement(generateFiller(fillerAst)));
|
|
@@ -154,13 +154,13 @@ export var coreParsers = (_a = {},
|
|
|
154
154
|
: "a ".concat(node.operator, " b")) +
|
|
155
155
|
')');
|
|
156
156
|
},
|
|
157
|
-
findInputs: function (engineContext,
|
|
157
|
+
findInputs: function (engineContext, ast, inputEdges, node, sibling) {
|
|
158
158
|
return new Array(Math.max(inputEdges.length + 1, 2))
|
|
159
159
|
.fill(0)
|
|
160
160
|
.map(function (_, index) {
|
|
161
161
|
var letter = alphabet.charAt(index);
|
|
162
162
|
return [
|
|
163
|
-
nodeInput(letter, letter, 'filler', undefined,
|
|
163
|
+
nodeInput(letter, letter, 'filler', undefined, ['data', 'code'], false),
|
|
164
164
|
function (fillerAst) {
|
|
165
165
|
var foundPath;
|
|
166
166
|
var visitors = {
|
|
@@ -5,7 +5,7 @@ import { CodeNode } from '../../graph/code-nodes';
|
|
|
5
5
|
import { NodePosition } from '../../graph/base-node';
|
|
6
6
|
import { UniformDataType } from '../../graph/data-nodes';
|
|
7
7
|
export declare const physicalDefaultProperties: Partial<Record<keyof PBRMaterial, any>>;
|
|
8
|
-
export declare const physicalNode: (id: string, name: string,
|
|
8
|
+
export declare const physicalNode: (id: string, name: string, position: NodePosition, uniforms: UniformDataType[], stage: ShaderStage | undefined) => CodeNode;
|
|
9
9
|
export type RuntimeContext = {
|
|
10
10
|
scene: Scene;
|
|
11
11
|
camera: Camera;
|
|
@@ -23,6 +23,6 @@ export type RuntimeContext = {
|
|
|
23
23
|
};
|
|
24
24
|
};
|
|
25
25
|
};
|
|
26
|
-
export declare const toonNode: (id: string, name: string,
|
|
26
|
+
export declare const toonNode: (id: string, name: string, position: NodePosition, uniforms: UniformDataType[], stage: ShaderStage | undefined) => CodeNode;
|
|
27
27
|
export declare let mIdx: number;
|
|
28
28
|
export declare const babylengine: Engine;
|