@shaderfrog/core 1.2.0 → 1.3.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/cjs/package.json +1 -0
- package/esm/engine.d.ts +69 -0
- package/esm/engine.js +209 -0
- package/esm/graph/base-node.d.ts +36 -0
- package/esm/graph/base-node.js +9 -0
- package/esm/graph/code-nodes.d.ts +44 -0
- package/esm/graph/code-nodes.js +18 -0
- package/esm/graph/context.d.ts +37 -0
- package/esm/graph/context.js +243 -0
- package/esm/graph/data-nodes.d.ts +83 -0
- package/esm/graph/data-nodes.js +131 -0
- package/esm/graph/edge.d.ts +13 -0
- package/esm/graph/edge.js +7 -0
- package/esm/graph/evaluate.d.ts +9 -0
- package/esm/graph/evaluate.js +27 -0
- package/esm/graph/graph-node.d.ts +8 -0
- package/esm/graph/graph-node.js +135 -0
- package/esm/graph/graph-types.d.ts +38 -0
- package/esm/graph/graph-types.js +22 -0
- package/esm/graph/graph.d.ts +89 -0
- package/esm/graph/graph.js +506 -0
- package/esm/graph/graph.test.d.ts +1 -0
- package/esm/graph/graph.test.js +168 -0
- package/esm/graph/index.d.ts +11 -0
- package/esm/graph/index.js +11 -0
- package/esm/graph/parsers.d.ts +39 -0
- package/esm/graph/parsers.js +213 -0
- package/esm/graph/shader-sections.d.ts +47 -0
- package/esm/graph/shader-sections.js +256 -0
- package/esm/index.d.ts +3 -0
- package/esm/index.js +3 -0
- package/esm/package.json +1 -0
- package/esm/plugins/babylon/bablyengine.d.ts +28 -0
- package/esm/plugins/babylon/bablyengine.js +589 -0
- package/esm/plugins/babylon/importers.d.ts +3 -0
- package/esm/plugins/babylon/importers.js +64 -0
- package/esm/plugins/babylon/index.d.ts +2 -0
- package/esm/plugins/babylon/index.js +2 -0
- package/esm/plugins/playcanvas/importers.d.ts +3 -0
- package/esm/plugins/playcanvas/importers.js +28 -0
- package/esm/plugins/playcanvas/index.d.ts +2 -0
- package/esm/plugins/playcanvas/index.js +2 -0
- package/esm/plugins/playcanvas/playengine.d.ts +39 -0
- package/esm/plugins/playcanvas/playengine.js +517 -0
- package/esm/plugins/three/importers.d.ts +3 -0
- package/esm/plugins/three/importers.js +15 -0
- package/esm/plugins/three/index.d.ts +2 -0
- package/esm/plugins/three/index.js +2 -0
- package/esm/plugins/three/threngine.d.ts +34 -0
- package/esm/plugins/three/threngine.js +608 -0
- package/esm/strategy/assignemntTo.d.ts +9 -0
- package/esm/strategy/assignemntTo.js +26 -0
- package/esm/strategy/declarationOf.d.ts +9 -0
- package/esm/strategy/declarationOf.js +23 -0
- package/esm/strategy/hardCode.d.ts +15 -0
- package/esm/strategy/hardCode.js +23 -0
- package/esm/strategy/index.d.ts +9 -0
- package/esm/strategy/index.js +9 -0
- package/esm/strategy/inject.d.ts +15 -0
- package/esm/strategy/inject.js +122 -0
- package/esm/strategy/namedAttribute.d.ts +9 -0
- package/esm/strategy/namedAttribute.js +48 -0
- package/esm/strategy/strategy.d.ts +28 -0
- package/esm/strategy/strategy.js +31 -0
- package/esm/strategy/stratgies.test.d.ts +1 -0
- package/esm/strategy/stratgies.test.js +164 -0
- package/esm/strategy/texture2D.d.ts +6 -0
- package/esm/strategy/texture2D.js +83 -0
- package/esm/strategy/uniform.d.ts +6 -0
- package/esm/strategy/uniform.js +190 -0
- package/esm/strategy/variable.d.ts +6 -0
- package/esm/strategy/variable.js +80 -0
- package/esm/util/ast.d.ts +30 -0
- package/esm/util/ast.js +332 -0
- package/esm/util/ensure.d.ts +1 -0
- package/esm/util/ensure.js +7 -0
- package/esm/util/id.d.ts +1 -0
- package/esm/util/id.js +2 -0
- package/package.json +9 -11
- /package/{engine.d.ts → cjs/engine.d.ts} +0 -0
- /package/{engine.js → cjs/engine.js} +0 -0
- /package/{graph → cjs/graph}/base-node.d.ts +0 -0
- /package/{graph → cjs/graph}/base-node.js +0 -0
- /package/{graph → cjs/graph}/code-nodes.d.ts +0 -0
- /package/{graph → cjs/graph}/code-nodes.js +0 -0
- /package/{graph → cjs/graph}/context.d.ts +0 -0
- /package/{graph → cjs/graph}/context.js +0 -0
- /package/{graph → cjs/graph}/data-nodes.d.ts +0 -0
- /package/{graph → cjs/graph}/data-nodes.js +0 -0
- /package/{graph → cjs/graph}/edge.d.ts +0 -0
- /package/{graph → cjs/graph}/edge.js +0 -0
- /package/{graph → cjs/graph}/evaluate.d.ts +0 -0
- /package/{graph → cjs/graph}/evaluate.js +0 -0
- /package/{graph → cjs/graph}/graph-node.d.ts +0 -0
- /package/{graph → cjs/graph}/graph-node.js +0 -0
- /package/{graph → cjs/graph}/graph-types.d.ts +0 -0
- /package/{graph → cjs/graph}/graph-types.js +0 -0
- /package/{graph → cjs/graph}/graph.d.ts +0 -0
- /package/{graph → cjs/graph}/graph.js +0 -0
- /package/{graph → cjs/graph}/graph.test.d.ts +0 -0
- /package/{graph → cjs/graph}/graph.test.js +0 -0
- /package/{graph → cjs/graph}/index.d.ts +0 -0
- /package/{graph → cjs/graph}/index.js +0 -0
- /package/{graph → cjs/graph}/parsers.d.ts +0 -0
- /package/{graph → cjs/graph}/parsers.js +0 -0
- /package/{graph → cjs/graph}/shader-sections.d.ts +0 -0
- /package/{graph → cjs/graph}/shader-sections.js +0 -0
- /package/{index.d.ts → cjs/index.d.ts} +0 -0
- /package/{index.js → cjs/index.js} +0 -0
- /package/{plugins → cjs/plugins}/babylon/bablyengine.d.ts +0 -0
- /package/{plugins → cjs/plugins}/babylon/bablyengine.js +0 -0
- /package/{plugins → cjs/plugins}/babylon/importers.d.ts +0 -0
- /package/{plugins → cjs/plugins}/babylon/importers.js +0 -0
- /package/{plugins → cjs/plugins}/babylon/index.d.ts +0 -0
- /package/{plugins → cjs/plugins}/babylon/index.js +0 -0
- /package/{plugins → cjs/plugins}/playcanvas/importers.d.ts +0 -0
- /package/{plugins → cjs/plugins}/playcanvas/importers.js +0 -0
- /package/{plugins → cjs/plugins}/playcanvas/index.d.ts +0 -0
- /package/{plugins → cjs/plugins}/playcanvas/index.js +0 -0
- /package/{plugins → cjs/plugins}/playcanvas/playengine.d.ts +0 -0
- /package/{plugins → cjs/plugins}/playcanvas/playengine.js +0 -0
- /package/{plugins → cjs/plugins}/three/importers.d.ts +0 -0
- /package/{plugins → cjs/plugins}/three/importers.js +0 -0
- /package/{plugins → cjs/plugins}/three/index.d.ts +0 -0
- /package/{plugins → cjs/plugins}/three/index.js +0 -0
- /package/{plugins → cjs/plugins}/three/threngine.d.ts +0 -0
- /package/{plugins → cjs/plugins}/three/threngine.js +0 -0
- /package/{strategy → cjs/strategy}/assignemntTo.d.ts +0 -0
- /package/{strategy → cjs/strategy}/assignemntTo.js +0 -0
- /package/{strategy → cjs/strategy}/declarationOf.d.ts +0 -0
- /package/{strategy → cjs/strategy}/declarationOf.js +0 -0
- /package/{strategy → cjs/strategy}/hardCode.d.ts +0 -0
- /package/{strategy → cjs/strategy}/hardCode.js +0 -0
- /package/{strategy → cjs/strategy}/index.d.ts +0 -0
- /package/{strategy → cjs/strategy}/index.js +0 -0
- /package/{strategy → cjs/strategy}/inject.d.ts +0 -0
- /package/{strategy → cjs/strategy}/inject.js +0 -0
- /package/{strategy → cjs/strategy}/namedAttribute.d.ts +0 -0
- /package/{strategy → cjs/strategy}/namedAttribute.js +0 -0
- /package/{strategy → cjs/strategy}/strategy.d.ts +0 -0
- /package/{strategy → cjs/strategy}/strategy.js +0 -0
- /package/{strategy → cjs/strategy}/stratgies.test.d.ts +0 -0
- /package/{strategy → cjs/strategy}/stratgies.test.js +0 -0
- /package/{strategy → cjs/strategy}/texture2D.d.ts +0 -0
- /package/{strategy → cjs/strategy}/texture2D.js +0 -0
- /package/{strategy → cjs/strategy}/uniform.d.ts +0 -0
- /package/{strategy → cjs/strategy}/uniform.js +0 -0
- /package/{strategy → cjs/strategy}/variable.d.ts +0 -0
- /package/{strategy → cjs/strategy}/variable.js +0 -0
- /package/{util → cjs/util}/ast.d.ts +0 -0
- /package/{util → cjs/util}/ast.js +0 -0
- /package/{util → cjs/util}/ensure.d.ts +0 -0
- /package/{util → cjs/util}/ensure.js +0 -0
- /package/{util → cjs/util}/id.d.ts +0 -0
- /package/{util → cjs/util}/id.js +0 -0
|
@@ -0,0 +1,506 @@
|
|
|
1
|
+
var __assign = (this && this.__assign) || function () {
|
|
2
|
+
__assign = Object.assign || function(t) {
|
|
3
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
4
|
+
s = arguments[i];
|
|
5
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
6
|
+
t[p] = s[p];
|
|
7
|
+
}
|
|
8
|
+
return t;
|
|
9
|
+
};
|
|
10
|
+
return __assign.apply(this, arguments);
|
|
11
|
+
};
|
|
12
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
13
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
14
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
15
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
16
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
17
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
18
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
22
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
23
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
24
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
25
|
+
function step(op) {
|
|
26
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
27
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
28
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
29
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
30
|
+
switch (op[0]) {
|
|
31
|
+
case 0: case 1: t = op; break;
|
|
32
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
33
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
34
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
35
|
+
default:
|
|
36
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
37
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
38
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
39
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
40
|
+
if (t[2]) _.ops.pop();
|
|
41
|
+
_.trys.pop(); continue;
|
|
42
|
+
}
|
|
43
|
+
op = body.call(thisArg, _);
|
|
44
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
45
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
var __read = (this && this.__read) || function (o, n) {
|
|
49
|
+
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
50
|
+
if (!m) return o;
|
|
51
|
+
var i = m.call(o), r, ar = [], e;
|
|
52
|
+
try {
|
|
53
|
+
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
|
54
|
+
}
|
|
55
|
+
catch (error) { e = { error: error }; }
|
|
56
|
+
finally {
|
|
57
|
+
try {
|
|
58
|
+
if (r && !r.done && (m = i["return"])) m.call(i);
|
|
59
|
+
}
|
|
60
|
+
finally { if (e) throw e.error; }
|
|
61
|
+
}
|
|
62
|
+
return ar;
|
|
63
|
+
};
|
|
64
|
+
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
65
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
66
|
+
if (ar || !(i in from)) {
|
|
67
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
68
|
+
ar[i] = from[i];
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
72
|
+
};
|
|
73
|
+
import { renameBindings, renameFunctions, } from '@shaderfrog/glsl-parser/parser/utils';
|
|
74
|
+
import { computeGraphContext, isError, } from './context';
|
|
75
|
+
import { emptyShaderSections, findShaderSections, mergeShaderSections, shaderSectionsToProgram, } from './shader-sections';
|
|
76
|
+
import { makeExpression } from '../util/ast';
|
|
77
|
+
import { ensure } from '../util/ensure';
|
|
78
|
+
import { SourceType } from './code-nodes';
|
|
79
|
+
import { nodeInput } from './base-node';
|
|
80
|
+
import { makeId } from '../util/id';
|
|
81
|
+
import { coreParsers } from './parsers';
|
|
82
|
+
import { toGlsl } from './evaluate';
|
|
83
|
+
import { EdgeLink, MAGIC_OUTPUT_STMTS, NodeType, } from './graph-types';
|
|
84
|
+
import { generate } from '@shaderfrog/glsl-parser';
|
|
85
|
+
var log = function () {
|
|
86
|
+
var _a;
|
|
87
|
+
var args = [];
|
|
88
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
89
|
+
args[_i] = arguments[_i];
|
|
90
|
+
}
|
|
91
|
+
return (_a = console.log).call.apply(_a, __spreadArray([console, '\x1b[31m(core.graph)\x1b[0m'], __read(args), false));
|
|
92
|
+
};
|
|
93
|
+
export var isDataNode = function (node) {
|
|
94
|
+
return 'value' in node;
|
|
95
|
+
};
|
|
96
|
+
export var isSourceNode = function (node) {
|
|
97
|
+
return !isDataNode(node);
|
|
98
|
+
};
|
|
99
|
+
export var findNode = function (graph, id) {
|
|
100
|
+
return ensure(graph.nodes.find(function (node) { return node.id === id; }));
|
|
101
|
+
};
|
|
102
|
+
export var doesLinkThruShader = function (graph, node) {
|
|
103
|
+
var edges = graph.edges.filter(function (edge) { return edge.type !== EdgeLink.NEXT_STAGE && edge.from === node.id; });
|
|
104
|
+
if (edges.length === 0) {
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
return edges.reduce(function (foundShader, edge) {
|
|
108
|
+
var upstreamNode = ensure(graph.nodes.find(function (node) { return node.id === edge.to; }));
|
|
109
|
+
return (foundShader ||
|
|
110
|
+
// TODO: LARD this probably will introduce some insidius hard to track
|
|
111
|
+
// down bug, as I try to pull toon and phong up out of core, I need to
|
|
112
|
+
// know if a graph links through a "shader" which now means somehting
|
|
113
|
+
// different... does a config object need isShader? Can we compute it from
|
|
114
|
+
// inputs/ outputs/source?
|
|
115
|
+
(upstreamNode.sourceType !== SourceType.EXPRESSION &&
|
|
116
|
+
upstreamNode.type !== NodeType.OUTPUT) ||
|
|
117
|
+
doesLinkThruShader(graph, upstreamNode));
|
|
118
|
+
}, false);
|
|
119
|
+
};
|
|
120
|
+
export var nodeName = function (node) {
|
|
121
|
+
return 'main_' + node.name.replace(/[^a-zA-Z0-9]/g, ' ').replace(/ +/g, '_');
|
|
122
|
+
};
|
|
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;
|
|
129
|
+
return "".concat(name, "_").concat(id);
|
|
130
|
+
};
|
|
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) {
|
|
133
|
+
renameBindings(ast.scopes[0], function (name, n) {
|
|
134
|
+
return n.doNotDescope ? name : mangleVar(name, engine, node, sibling);
|
|
135
|
+
});
|
|
136
|
+
mangleMainFn(ast, node, sibling);
|
|
137
|
+
};
|
|
138
|
+
export var mangleMainFn = function (ast, node, sibling) {
|
|
139
|
+
renameFunctions(ast.scopes[0], function (name) {
|
|
140
|
+
return name === 'main' ? nodeName(node) : mangleName(name, node, sibling);
|
|
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
|
+
}); };
|
|
197
|
+
/**
|
|
198
|
+
* Create the inputs on a node from the properties. This used to be done at
|
|
199
|
+
* context time. Doing it at node creation time lets us auto-bake edges into
|
|
200
|
+
* the node at initial graph creation time.
|
|
201
|
+
*/
|
|
202
|
+
export var prepopulatePropertyInputs = function (node) { return (__assign(__assign({}, node), { inputs: __spreadArray(__spreadArray([], __read(node.inputs), false), __read((node.config.properties || []).map(function (property) {
|
|
203
|
+
return nodeInput(property.displayName, "property_".concat(property.property), 'property', property.type, ['data'], !!property.fillerName, // bakeable
|
|
204
|
+
property.property);
|
|
205
|
+
})), false) })); };
|
|
206
|
+
/**
|
|
207
|
+
* Recursively filter the graph, starting from a specific node, looking for
|
|
208
|
+
* nodes and edges that match predicates.
|
|
209
|
+
*
|
|
210
|
+
* Inputs can only be filtered if the graph context has been computed, since
|
|
211
|
+
* inputs aren't created until then.
|
|
212
|
+
*/
|
|
213
|
+
export var filterGraphFromNode = function (graph, node, predicates, depth, lastResult) {
|
|
214
|
+
var _a;
|
|
215
|
+
if (depth === void 0) { depth = Infinity; }
|
|
216
|
+
if (lastResult === void 0) { lastResult = consSearchResult(); }
|
|
217
|
+
var inputs = node.inputs;
|
|
218
|
+
var inputEdges = graph.edges.filter(function (edge) { return edge.to === node.id; });
|
|
219
|
+
var nodeAcc = __assign({}, (predicates.node && predicates.node(node, inputEdges, lastResult)
|
|
220
|
+
? (_a = {}, _a[node.id] = node, _a) : {}));
|
|
221
|
+
var accumulatedResult = __assign(__assign({}, lastResult), { nodes: __assign(__assign({}, lastResult.nodes), nodeAcc) });
|
|
222
|
+
return inputEdges.reduce(function (acc, inputEdge) {
|
|
223
|
+
var _a;
|
|
224
|
+
var input = inputs.find(function (i) { return i.id === inputEdge.input; });
|
|
225
|
+
var fromNode = inputEdge ? ensureFromNode(graph, inputEdge) : undefined;
|
|
226
|
+
var inputAcc = __assign(__assign({}, acc.inputs), (input &&
|
|
227
|
+
predicates.input &&
|
|
228
|
+
predicates.input(input, node, inputEdge, fromNode, lastResult)
|
|
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 });
|
|
237
|
+
if (inputEdge && fromNode && depth > 1) {
|
|
238
|
+
var result = filterGraphFromNode(graph, fromNode, predicates, depth - 1, intermediateAcc);
|
|
239
|
+
return mergeSearchResults(intermediateAcc, result);
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
return intermediateAcc;
|
|
243
|
+
}
|
|
244
|
+
}, accumulatedResult);
|
|
245
|
+
};
|
|
246
|
+
export var collectConnectedNodes = function (graph, node) {
|
|
247
|
+
return filterGraphFromNode(graph, node, { node: function () { return true; } }).nodes;
|
|
248
|
+
};
|
|
249
|
+
export var filterGraphNodes = function (graph, nodes, filter, depth) {
|
|
250
|
+
if (depth === void 0) { depth = Infinity; }
|
|
251
|
+
return nodes.reduce(function (acc, node) {
|
|
252
|
+
var result = filterGraphFromNode(graph, node, filter, depth);
|
|
253
|
+
return {
|
|
254
|
+
nodes: __assign(__assign({}, acc.nodes), result.nodes),
|
|
255
|
+
inputs: __assign(__assign({}, acc.inputs), result.inputs),
|
|
256
|
+
edges: __assign(__assign({}, acc.edges), result.edges),
|
|
257
|
+
};
|
|
258
|
+
}, consSearchResult());
|
|
259
|
+
};
|
|
260
|
+
// before data inputs were known by the input.category being node or data. I
|
|
261
|
+
// tried updating inputs to have acepts: [code|data] and "baked" now is there a
|
|
262
|
+
// way to know if we're plugging in code or data?
|
|
263
|
+
export var isDataInput = function (input) {
|
|
264
|
+
return (input.type === 'uniform' || input.type === 'property') && !input.baked;
|
|
265
|
+
};
|
|
266
|
+
export var compileNode = function (engine, graph, edges, engineContext, node, activeIds) {
|
|
267
|
+
var _a, _b;
|
|
268
|
+
if (activeIds === void 0) { activeIds = {}; }
|
|
269
|
+
// THIS DUPLICATES OTHER LINE
|
|
270
|
+
var parser = __assign(__assign({}, (coreParsers[node.type] || coreParsers[NodeType.SOURCE])), (engine.parsers[node.type] || {}));
|
|
271
|
+
var inputs = node.inputs;
|
|
272
|
+
if (!parser) {
|
|
273
|
+
console.error(node);
|
|
274
|
+
throw new Error("No parser found for ".concat(node.name, " (").concat(node.type, ", id ").concat(node.id, ")"));
|
|
275
|
+
}
|
|
276
|
+
var nodeContext = isDataNode(node)
|
|
277
|
+
? null
|
|
278
|
+
: ensure(engineContext.nodes[node.id], "No node context found for \"".concat(node.name, "\" (id ").concat(node.id, ")!"));
|
|
279
|
+
var _c = (nodeContext || {}), ast = _c.ast, inputFillers = _c.inputFillers;
|
|
280
|
+
if (!inputs) {
|
|
281
|
+
throw new Error("I'm drunk and I think this case should be impossible");
|
|
282
|
+
}
|
|
283
|
+
var compiledIds = activeIds;
|
|
284
|
+
var inputEdges = edges.filter(function (edge) { return edge.to === node.id; });
|
|
285
|
+
if (inputEdges.length) {
|
|
286
|
+
var continuation_1 = emptyShaderSections();
|
|
287
|
+
inputEdges
|
|
288
|
+
.filter(function (edge) { return edge.type !== EdgeLink.NEXT_STAGE; })
|
|
289
|
+
.map(function (edge) { return ({
|
|
290
|
+
edge: edge,
|
|
291
|
+
fromNode: ensure(graph.nodes.find(function (node) { return edge.from === node.id; }), "GraphNode for edge ".concat(edge.from, " not found")),
|
|
292
|
+
input: ensure(inputs.find(function (_a) {
|
|
293
|
+
var id = _a.id;
|
|
294
|
+
return id == edge.input;
|
|
295
|
+
}), "GraphNode \"".concat(node.name, "\"").concat(node.stage ? " (".concat(node.stage, ")") : '', " has no input ").concat(edge.input, "!\nAvailable:").concat(inputs
|
|
296
|
+
.map(function (_a) {
|
|
297
|
+
var id = _a.id;
|
|
298
|
+
return id;
|
|
299
|
+
})
|
|
300
|
+
.join(', '))),
|
|
301
|
+
}); })
|
|
302
|
+
.filter(function (_a) {
|
|
303
|
+
var input = _a.input;
|
|
304
|
+
return !isDataInput(input);
|
|
305
|
+
})
|
|
306
|
+
.forEach(function (_a) {
|
|
307
|
+
var _b;
|
|
308
|
+
var fromNode = _a.fromNode, edge = _a.edge, input = _a.input;
|
|
309
|
+
var _c = __read(compileNode(engine, graph, edges, engineContext, fromNode, activeIds), 3), inputSections = _c[0], fillerAst = _c[1], childIds = _c[2];
|
|
310
|
+
if (!fillerAst) {
|
|
311
|
+
throw new TypeError("Expected a filler ast from node ID ".concat(fromNode.id, " (").concat(fromNode.type, ") but none was returned"));
|
|
312
|
+
}
|
|
313
|
+
continuation_1 = mergeShaderSections(continuation_1, inputSections);
|
|
314
|
+
compiledIds = __assign(__assign({}, compiledIds), childIds);
|
|
315
|
+
var filler;
|
|
316
|
+
var fillerName;
|
|
317
|
+
if (nodeContext) {
|
|
318
|
+
if (input.property) {
|
|
319
|
+
fillerName = ensure((_b = (node.config.properties || []).find(function (p) { return p.property === input.property; })) === null || _b === void 0 ? void 0 : _b.fillerName, "Node \"".concat(node.name, "\" has no property named \"").concat(input.property, "\" to find the filler for"));
|
|
320
|
+
filler = inputFillers[fillerName];
|
|
321
|
+
}
|
|
322
|
+
else {
|
|
323
|
+
filler = inputFillers[input.id];
|
|
324
|
+
}
|
|
325
|
+
if (!filler) {
|
|
326
|
+
console.error('No filler for property', {
|
|
327
|
+
input: input,
|
|
328
|
+
node: node,
|
|
329
|
+
inputFillers: inputFillers,
|
|
330
|
+
fillerName: fillerName,
|
|
331
|
+
});
|
|
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));
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* +------+ +------+
|
|
338
|
+
* a -- o add o -- o tex |
|
|
339
|
+
* b -- o | +------+
|
|
340
|
+
* +------+
|
|
341
|
+
*
|
|
342
|
+
* This could produce:
|
|
343
|
+
* main_a(v1) + main_b(v2)
|
|
344
|
+
* I guess it has to? or it could produce
|
|
345
|
+
* function add(v1) { return main_a(v1) + main_b(v2); }
|
|
346
|
+
* It can't replace the arg _expression_ in the from shaders, because
|
|
347
|
+
* the expression isn't available there.
|
|
348
|
+
*/
|
|
349
|
+
// TODO: This is a hard coded hack for vUv backfilling. It works in
|
|
350
|
+
// the simple case. Doesn't work for hell (based on world position).
|
|
351
|
+
if (filler.backfillArgs &&
|
|
352
|
+
!Array.isArray(fillerAst) &&
|
|
353
|
+
fillerAst.type === 'function_call') {
|
|
354
|
+
// Object.values(filterGraphFromNode(graph, node, {
|
|
355
|
+
// node: (n) => n.type === 'source'
|
|
356
|
+
// }).nodes).forEach(sourceNode => {
|
|
357
|
+
if (fromNode.type === 'source') {
|
|
358
|
+
// @ts-ignore
|
|
359
|
+
fillerAst.args = filler.backfillArgs;
|
|
360
|
+
// const fc = engineContext.nodes[sourceNode.id];
|
|
361
|
+
var fc = engineContext.nodes[fromNode.id];
|
|
362
|
+
var main = Object.values(fc.ast.scopes[0].functions.main)[0].declaration;
|
|
363
|
+
main.prototype.parameters = [
|
|
364
|
+
'vec2 vv',
|
|
365
|
+
];
|
|
366
|
+
// @ts-ignore
|
|
367
|
+
var scope = fc.ast.scopes[0];
|
|
368
|
+
renameBindings(scope, function (name, node) {
|
|
369
|
+
return node.type !== 'declaration' && name === 'vUv'
|
|
370
|
+
? 'vv'
|
|
371
|
+
: name;
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
// })
|
|
375
|
+
}
|
|
376
|
+
// Fill in the input! The return value is the new AST of the filled in
|
|
377
|
+
// fromNode.
|
|
378
|
+
nodeContext.ast = filler.filler(fillerAst);
|
|
379
|
+
}
|
|
380
|
+
// log(generate(ast.program));
|
|
381
|
+
});
|
|
382
|
+
// Order matters here! *Prepend* the input nodes to this one, because
|
|
383
|
+
// you have to declare functions in order of use in GLSL
|
|
384
|
+
var sections = mergeShaderSections(continuation_1, isDataNode(node) ||
|
|
385
|
+
node.sourceType === SourceType.EXPRESSION ||
|
|
386
|
+
node.sourceType === SourceType.FN_BODY_FRAGMENT
|
|
387
|
+
? emptyShaderSections()
|
|
388
|
+
: findShaderSections(ast));
|
|
389
|
+
var filler = isDataNode(node)
|
|
390
|
+
? makeExpression(toGlsl(node))
|
|
391
|
+
: parser.produceFiller(node, ast);
|
|
392
|
+
return [sections, filler, __assign(__assign({}, compiledIds), (_a = {}, _a[node.id] = node, _a))];
|
|
393
|
+
}
|
|
394
|
+
else {
|
|
395
|
+
// TODO: This duplicates the above branch, and also does this mean we
|
|
396
|
+
// recalculate the shader sections and filler for every edge? Can I move
|
|
397
|
+
// these lines above the loop?
|
|
398
|
+
var sections = isDataNode(node) ||
|
|
399
|
+
node.sourceType === SourceType.EXPRESSION ||
|
|
400
|
+
node.sourceType === SourceType.FN_BODY_FRAGMENT
|
|
401
|
+
? emptyShaderSections()
|
|
402
|
+
: findShaderSections(ast);
|
|
403
|
+
var filler = isDataNode(node)
|
|
404
|
+
? makeExpression(toGlsl(node))
|
|
405
|
+
: parser.produceFiller(node, ast);
|
|
406
|
+
return [sections, filler, __assign(__assign({}, compiledIds), (_b = {}, _b[node.id] = node, _b))];
|
|
407
|
+
}
|
|
408
|
+
};
|
|
409
|
+
export var compileGraph = function (engineContext, engine, graph) {
|
|
410
|
+
// computeGraphContext(engineContext, engine, graph);
|
|
411
|
+
var outputFrag = graph.nodes.find(function (node) { return node.type === 'output' && node.stage === 'fragment'; });
|
|
412
|
+
if (!outputFrag) {
|
|
413
|
+
throw new Error('No fragment output in graph');
|
|
414
|
+
}
|
|
415
|
+
var _a = __read(compileNode(engine, graph, graph.edges, engineContext, outputFrag), 3), fragment = _a[0], fragmentIds = _a[2];
|
|
416
|
+
var outputVert = graph.nodes.find(function (node) { return node.type === 'output' && node.stage === 'vertex'; });
|
|
417
|
+
if (!outputVert) {
|
|
418
|
+
throw new Error('No vertex output in graph');
|
|
419
|
+
}
|
|
420
|
+
var vertexIds = collectConnectedNodes(graph, outputVert);
|
|
421
|
+
// Some fragment shaders reference vertex shaders which may not have been
|
|
422
|
+
// given edges in the graph. Build invisible edges from these vertex nodes to
|
|
423
|
+
// the hidden "mainStmts" input on the output node, which inlines the function
|
|
424
|
+
// calls to those vertex main() statements and includes them in the output
|
|
425
|
+
var orphanNodes = findLinkedVertexNodes(graph, vertexIds);
|
|
426
|
+
var orphanEdges = orphanNodes.map(function (node) { return ({
|
|
427
|
+
id: makeId(),
|
|
428
|
+
from: node.id,
|
|
429
|
+
to: outputVert.id,
|
|
430
|
+
output: 'main',
|
|
431
|
+
input: "filler_".concat(MAGIC_OUTPUT_STMTS),
|
|
432
|
+
stage: 'vertex',
|
|
433
|
+
category: 'code',
|
|
434
|
+
}); });
|
|
435
|
+
var _b = __read(compileNode(engine, graph, __spreadArray(__spreadArray([], __read(graph.edges), false), __read(orphanEdges), false), engineContext, outputVert), 2), vertex = _b[0];
|
|
436
|
+
// Every compileNode returns the AST so far, as well as the filler for the
|
|
437
|
+
// next node with inputs. On the final step, we discard the filler
|
|
438
|
+
return {
|
|
439
|
+
fragment: fragment,
|
|
440
|
+
vertex: vertex,
|
|
441
|
+
outputFrag: outputFrag,
|
|
442
|
+
outputVert: outputVert,
|
|
443
|
+
orphanNodes: orphanNodes,
|
|
444
|
+
activeNodeIds: new Set(__spreadArray(__spreadArray(__spreadArray([], __read(Object.keys(vertexIds)), false), __read(Object.keys(fragmentIds)), false), __read(orphanNodes.map(function (node) { return node.id; })), false)),
|
|
445
|
+
};
|
|
446
|
+
};
|
|
447
|
+
/**
|
|
448
|
+
* Find engine nodes to set properties on, like find a Physical node so
|
|
449
|
+
* consumers can set physicalNode.myProperty = 123.
|
|
450
|
+
*
|
|
451
|
+
* Finds all active nodes in the graph that have inputs that are properties,
|
|
452
|
+
* which currently means it will find all active engine nodes.
|
|
453
|
+
*/
|
|
454
|
+
export var collectNodeProperties = function (graph) {
|
|
455
|
+
var nodesWithProperties = {
|
|
456
|
+
node: function (node) {
|
|
457
|
+
var _a;
|
|
458
|
+
return 'config' in node &&
|
|
459
|
+
'properties' in node.config &&
|
|
460
|
+
!!((_a = node.config.properties) === null || _a === void 0 ? void 0 : _a.length);
|
|
461
|
+
},
|
|
462
|
+
input: function (input) { return !!input.property; },
|
|
463
|
+
};
|
|
464
|
+
var outputFrag = graph.nodes.find(function (node) { return node.type === 'output' && node.stage === 'fragment'; });
|
|
465
|
+
var outputVert = graph.nodes.find(function (node) { return node.type === 'output' && node.stage === 'vertex'; });
|
|
466
|
+
var fragProperties = filterGraphFromNode(graph, outputFrag, nodesWithProperties);
|
|
467
|
+
var vertProperties = filterGraphFromNode(graph, outputVert, nodesWithProperties);
|
|
468
|
+
return {
|
|
469
|
+
nodes: __assign(__assign({}, fragProperties.nodes), vertProperties.nodes),
|
|
470
|
+
inputs: __assign(__assign({}, fragProperties.inputs), vertProperties.inputs),
|
|
471
|
+
edges: __assign(__assign({}, fragProperties.edges), vertProperties.edges),
|
|
472
|
+
};
|
|
473
|
+
};
|
|
474
|
+
export var compileSource = function (graph, engine, ctx) { return __awaiter(void 0, void 0, void 0, function () {
|
|
475
|
+
var result, compileResult, fragmentResult, vertexResult, dataInputs, dataNodes;
|
|
476
|
+
return __generator(this, function (_a) {
|
|
477
|
+
switch (_a.label) {
|
|
478
|
+
case 0: return [4 /*yield*/, computeGraphContext(ctx, engine, graph)];
|
|
479
|
+
case 1:
|
|
480
|
+
result = _a.sent();
|
|
481
|
+
if (isError(result)) {
|
|
482
|
+
return [2 /*return*/, result];
|
|
483
|
+
}
|
|
484
|
+
compileResult = compileGraph(ctx, engine, graph);
|
|
485
|
+
fragmentResult = generate(shaderSectionsToProgram(compileResult.fragment, engine.mergeOptions).program);
|
|
486
|
+
vertexResult = generate(shaderSectionsToProgram(compileResult.vertex, engine.mergeOptions).program);
|
|
487
|
+
dataInputs = filterGraphNodes(graph, [compileResult.outputFrag, compileResult.outputVert], { input: isDataInput }).inputs;
|
|
488
|
+
dataNodes = Object.entries(dataInputs).reduce(function (acc, _a) {
|
|
489
|
+
var _b = __read(_a, 2), nodeId = _b[0], inputs = _b[1];
|
|
490
|
+
return inputs.reduce(function (iAcc, input) {
|
|
491
|
+
var fromEdge = graph.edges.find(function (edge) { return edge.to === nodeId && edge.input === input.id; });
|
|
492
|
+
var fromNode = fromEdge && graph.nodes.find(function (node) { return node.id === fromEdge.from; });
|
|
493
|
+
return fromNode
|
|
494
|
+
? __assign(__assign({}, iAcc), collectConnectedNodes(graph, fromNode)) : iAcc;
|
|
495
|
+
}, acc);
|
|
496
|
+
}, {});
|
|
497
|
+
return [2 /*return*/, {
|
|
498
|
+
compileResult: compileResult,
|
|
499
|
+
fragmentResult: fragmentResult,
|
|
500
|
+
vertexResult: vertexResult,
|
|
501
|
+
dataNodes: dataNodes,
|
|
502
|
+
dataInputs: dataInputs,
|
|
503
|
+
}];
|
|
504
|
+
}
|
|
505
|
+
});
|
|
506
|
+
}); };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import util from 'util';
|
|
2
|
+
import { parser } from '@shaderfrog/glsl-parser';
|
|
3
|
+
import { generate } from '@shaderfrog/glsl-parser';
|
|
4
|
+
import { addNode } from './graph-node';
|
|
5
|
+
import { shaderSectionsToProgram, mergeShaderSections, findShaderSections, } from './shader-sections';
|
|
6
|
+
import { numberNode } from './data-nodes';
|
|
7
|
+
import { makeEdge } from './edge';
|
|
8
|
+
import { evaluateNode } from './evaluate';
|
|
9
|
+
var inspect = function (thing) {
|
|
10
|
+
return console.log(util.inspect(thing, false, null, true));
|
|
11
|
+
};
|
|
12
|
+
var mergeBlocks = function (ast1, ast2) {
|
|
13
|
+
var s1 = findShaderSections(ast1);
|
|
14
|
+
var s2 = findShaderSections(ast2);
|
|
15
|
+
var merged = mergeShaderSections(s1, s2);
|
|
16
|
+
return generate(shaderSectionsToProgram(merged, {
|
|
17
|
+
includePrecisions: true,
|
|
18
|
+
includeVersion: true,
|
|
19
|
+
}));
|
|
20
|
+
};
|
|
21
|
+
var dedupe = function (code) {
|
|
22
|
+
return generate(shaderSectionsToProgram(findShaderSections(parser.parse(code)), {
|
|
23
|
+
includePrecisions: true,
|
|
24
|
+
includeVersion: true,
|
|
25
|
+
}));
|
|
26
|
+
};
|
|
27
|
+
var counter = 0;
|
|
28
|
+
var p = { x: 0, y: 0 };
|
|
29
|
+
var id = function () { return '' + counter++; };
|
|
30
|
+
var constructor = function () { return ({
|
|
31
|
+
config: {
|
|
32
|
+
version: 3,
|
|
33
|
+
preprocess: false,
|
|
34
|
+
strategies: [],
|
|
35
|
+
uniforms: [],
|
|
36
|
+
},
|
|
37
|
+
id: '1',
|
|
38
|
+
name: '1',
|
|
39
|
+
engine: true,
|
|
40
|
+
type: '',
|
|
41
|
+
inputs: [],
|
|
42
|
+
outputs: [],
|
|
43
|
+
position: { x: 0, y: 0 },
|
|
44
|
+
source: '',
|
|
45
|
+
stage: undefined,
|
|
46
|
+
}); };
|
|
47
|
+
var engine = {
|
|
48
|
+
name: 'three',
|
|
49
|
+
displayName: 'Three.js',
|
|
50
|
+
evaluateNode: function (node) {
|
|
51
|
+
if (node.type === 'number') {
|
|
52
|
+
return parseFloat(node.value);
|
|
53
|
+
}
|
|
54
|
+
return node.value;
|
|
55
|
+
},
|
|
56
|
+
constructors: {
|
|
57
|
+
physical: constructor,
|
|
58
|
+
toon: constructor,
|
|
59
|
+
},
|
|
60
|
+
mergeOptions: {
|
|
61
|
+
includePrecisions: true,
|
|
62
|
+
includeVersion: true,
|
|
63
|
+
},
|
|
64
|
+
importers: {},
|
|
65
|
+
preserve: new Set(),
|
|
66
|
+
parsers: {},
|
|
67
|
+
};
|
|
68
|
+
// it('graph compiler arbitrary helper test', () => {
|
|
69
|
+
// const graph: Graph = {
|
|
70
|
+
// nodes: [
|
|
71
|
+
// outputNode('0', 'Output v', p, 'vertex'),
|
|
72
|
+
// outputNode('1', 'Output f', p, 'fragment'),
|
|
73
|
+
// makeSourceNode(
|
|
74
|
+
// '2',
|
|
75
|
+
// `uniform sampler2D image1;
|
|
76
|
+
// uniform sampler2D image2;
|
|
77
|
+
// void main() {
|
|
78
|
+
// vec3 col = texture2D(image1, posTurn - 0.4 * time).rgb + 1.0;
|
|
79
|
+
// vec3 col = texture2D(image2, negTurn - 0.4 * time).rgb + 2.0;
|
|
80
|
+
// }
|
|
81
|
+
// `,
|
|
82
|
+
// 'fragment'
|
|
83
|
+
// ),
|
|
84
|
+
// makeSourceNode(
|
|
85
|
+
// '3',
|
|
86
|
+
// `void main() {
|
|
87
|
+
// return vec4(0.0);
|
|
88
|
+
// }
|
|
89
|
+
// `,
|
|
90
|
+
// 'fragment'
|
|
91
|
+
// ),
|
|
92
|
+
// makeSourceNode(
|
|
93
|
+
// '4',
|
|
94
|
+
// `void main() {
|
|
95
|
+
// return vec4(1.0);
|
|
96
|
+
// }
|
|
97
|
+
// `,
|
|
98
|
+
// 'fragment'
|
|
99
|
+
// ),
|
|
100
|
+
// ],
|
|
101
|
+
// edges: [
|
|
102
|
+
// makeEdge(id(), '2', '1', 'out', 'filler_frogFragOut', 'fragment'),
|
|
103
|
+
// makeEdge(id(), '3', '2', 'out', 'filler_image1', 'fragment'),
|
|
104
|
+
// makeEdge(id(), '4', '2', 'out', 'filler_image2', 'fragment'),
|
|
105
|
+
// ],
|
|
106
|
+
// };
|
|
107
|
+
// const engineContext: EngineContext = {
|
|
108
|
+
// engine: 'three',
|
|
109
|
+
// nodes: {},
|
|
110
|
+
// runtime: {},
|
|
111
|
+
// debuggingNonsense: {},
|
|
112
|
+
// };
|
|
113
|
+
// const result = compileGraph(engineContext, engine, graph);
|
|
114
|
+
// const built = generate(
|
|
115
|
+
// shaderSectionsToProgram(result.fragment, {
|
|
116
|
+
// includePrecisions: true,
|
|
117
|
+
// includeVersion: true,
|
|
118
|
+
// }).program
|
|
119
|
+
// );
|
|
120
|
+
// expect(built).toBe('hi');
|
|
121
|
+
// });
|
|
122
|
+
describe('evaluateNode()', function () {
|
|
123
|
+
it('evaluates binary nodes', function () {
|
|
124
|
+
var finalAdd = addNode(id(), p);
|
|
125
|
+
var add2 = addNode(id(), p);
|
|
126
|
+
var num1 = numberNode(id(), 'number', p, '3');
|
|
127
|
+
var num2 = numberNode(id(), 'number', p, '5');
|
|
128
|
+
var num3 = numberNode(id(), 'number', p, '7');
|
|
129
|
+
var graph = {
|
|
130
|
+
nodes: [num1, num2, num3, finalAdd, add2],
|
|
131
|
+
edges: [
|
|
132
|
+
makeEdge(id(), num1.id, finalAdd.id, 'out', 'a'),
|
|
133
|
+
makeEdge(id(), add2.id, finalAdd.id, 'out', 'b'),
|
|
134
|
+
makeEdge(id(), num2.id, add2.id, 'out', 'a'),
|
|
135
|
+
makeEdge(id(), num3.id, add2.id, 'out', 'b'),
|
|
136
|
+
],
|
|
137
|
+
};
|
|
138
|
+
expect(evaluateNode(engine, graph, finalAdd)).toBe(15);
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
it('should merge uniforms with interface blocks', function () {
|
|
142
|
+
var astX = parser.parse("uniform vec2 x;");
|
|
143
|
+
var astY = parser.parse("uniform vec2 y, z;\nuniform vec3 a;");
|
|
144
|
+
expect(mergeBlocks(astX, astY)).toEqual("uniform vec2 x, y, z;\nuniform vec3 a;\n");
|
|
145
|
+
var astL01 = parser.parse("uniform Light0 { vec4 y; } x;", { quiet: true });
|
|
146
|
+
var astL02 = parser.parse("uniform Light0 { vec4 y; } x;", { quiet: true });
|
|
147
|
+
expect(mergeBlocks(astL01, astL02)).toEqual("uniform Light0 { vec4 y; } x;\n");
|
|
148
|
+
var astL001 = parser.parse("uniform Light0 { vec4 y; } x;", {
|
|
149
|
+
quiet: true,
|
|
150
|
+
});
|
|
151
|
+
var astL002 = parser.parse("uniform Light0 x;", { quiet: true });
|
|
152
|
+
expect(mergeBlocks(astL001, astL002)).toEqual("uniform Light0 { vec4 y; } x;\n");
|
|
153
|
+
var astLo01 = parser.parse("uniform Light0 x;", { quiet: true });
|
|
154
|
+
var astLo02 = parser.parse("uniform Light0 { vec4 y; } x;", {
|
|
155
|
+
quiet: true,
|
|
156
|
+
});
|
|
157
|
+
expect(mergeBlocks(astLo01, astLo02)).toEqual("uniform Light0 { vec4 y; } x;\n");
|
|
158
|
+
// This may be a bug, look at how the uniforms are merged. I at least want to
|
|
159
|
+
// note its current behavior in this test
|
|
160
|
+
var vec2Arr1 = parser.parse("uniform vec2 y[5];");
|
|
161
|
+
var vec2Arr2 = parser.parse("uniform vec2 y[10];");
|
|
162
|
+
expect(mergeBlocks(vec2Arr1, vec2Arr2)).toEqual("uniform vec2 y[10];\n");
|
|
163
|
+
var block1 = parser.parse("uniform Scene { mat4 view; };");
|
|
164
|
+
var block2 = parser.parse("uniform Scene { mat4 view; };");
|
|
165
|
+
expect(mergeBlocks(block1, block2)).toEqual("uniform Scene { mat4 view; };\n");
|
|
166
|
+
// Verify these lines are preserved (they go through dedupeUniforms)
|
|
167
|
+
expect(dedupe("layout(std140,column_major) uniform;")).toEqual("layout(std140,column_major) uniform;");
|
|
168
|
+
});
|