@shaderfrog/core 2.0.0-beta.3 → 3.0.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 +2 -2
- package/engine.d.ts +39 -3
- package/engine.js +5 -0
- package/graph/code-nodes.d.ts +8 -2
- package/graph/code-nodes.js +5 -1
- package/graph/context.d.ts +8 -6
- package/graph/context.js +53 -50
- package/graph/data-nodes.d.ts +15 -6
- package/graph/data-nodes.js +1 -1
- package/graph/evaluate.js +7 -0
- package/graph/graph-types.d.ts +26 -6
- package/graph/graph-types.js +69 -0
- package/graph/graph.d.ts +35 -4
- package/graph/graph.js +187 -143
- package/graph/graph.test.js +244 -54
- package/graph/parsers.d.ts +4 -12
- package/graph/parsers.js +32 -18
- package/graph/shader-sections.d.ts +31 -14
- package/graph/shader-sections.js +93 -19
- package/package.json +4 -4
- package/plugins/babylon/bablyengine.js +9 -10
- package/plugins/playcanvas/playengine.js +9 -10
- package/plugins/three/importers.d.ts +1 -0
- package/plugins/three/importers.js +49 -1
- package/plugins/three/threngine.d.ts +6 -4
- package/plugins/three/threngine.js +59 -39
- package/plugins/three/threngine.test.js +51 -4
- package/strategy/assignmentTo.d.ts +10 -0
- package/strategy/assignmentTo.js +35 -0
- package/strategy/declarationOf.js +2 -2
- package/strategy/hardCode.js +1 -4
- package/strategy/index.d.ts +1 -1
- package/strategy/index.js +1 -1
- package/strategy/inject.js +3 -4
- package/strategy/namedAttribute.js +2 -2
- package/strategy/strategy.d.ts +30 -5
- package/strategy/strategy.js +1 -1
- package/strategy/stratgies.test.js +59 -31
- package/strategy/texture2D.js +20 -22
- package/strategy/uniform.js +54 -56
- package/strategy/variable.js +5 -5
- package/util/ast.d.ts +9 -4
- package/util/ast.js +37 -8
- package/util/ast.test.d.ts +1 -0
- package/util/ast.test.js +14 -0
- package/util/indexByid.d.ts +4 -0
- package/util/indexByid.js +18 -0
- package/util/whitespace.d.ts +2 -0
- package/util/whitespace.js +22 -3
|
@@ -76,10 +76,11 @@ import { NodeType } from '../../graph/graph-types';
|
|
|
76
76
|
import { prepopulatePropertyInputs, mangleMainFn } from '../../graph/graph';
|
|
77
77
|
import importers from './importers';
|
|
78
78
|
import { EngineNodeType } from '../../engine';
|
|
79
|
-
import { doesLinkThruShader
|
|
79
|
+
import { doesLinkThruShader } from '../../graph/graph';
|
|
80
80
|
import { returnGlPosition, returnGlPositionHardCoded, returnGlPositionVec3Right, } from '../../util/ast';
|
|
81
81
|
import { property, } from '../../graph/code-nodes';
|
|
82
82
|
import { namedAttributeStrategy, texture2DStrategy, uniformStrategy, } from '../../strategy';
|
|
83
|
+
import indexById from '../../util/indexByid';
|
|
83
84
|
var log = function () {
|
|
84
85
|
var _a;
|
|
85
86
|
var args = [];
|
|
@@ -117,6 +118,8 @@ export var phongNode = function (id, name, position, uniforms, stage) {
|
|
|
117
118
|
property('Specular Map', 'specularMap', 'texture', 'filler_specularMap'),
|
|
118
119
|
property('Displacement Map', 'displacementMap', 'texture', 'filler_displacementMap'),
|
|
119
120
|
property('Displacement Scale', 'displacementScale', 'number'),
|
|
121
|
+
property('Bump Map', 'bumpMap', 'texture', 'filler_bumpMap'),
|
|
122
|
+
property('Bump Scale', 'bumpScale', 'number'),
|
|
120
123
|
property('Env Map', 'envMap', 'samplerCube'),
|
|
121
124
|
],
|
|
122
125
|
strategies: [
|
|
@@ -167,6 +170,7 @@ export var physicalNode = function (id, name, position, uniforms, stage) {
|
|
|
167
170
|
// MeshPhysicalMaterial gets envMap from the scene. MeshStandardMaterial
|
|
168
171
|
// gets it from the material
|
|
169
172
|
// property('Env Map', 'envMap', 'samplerCube'),
|
|
173
|
+
property('Env Map Intensity', 'envMapIntensity', 'number', 'uniform_envMapIntensity'),
|
|
170
174
|
property('Transmission', 'transmission', 'number'),
|
|
171
175
|
property('Transmission Map', 'transmissionMap', 'texture', 'filler_transmissionMap'),
|
|
172
176
|
property('Thickness', 'thickness', 'number'),
|
|
@@ -176,6 +180,7 @@ export var physicalNode = function (id, name, position, uniforms, stage) {
|
|
|
176
180
|
// property('Sheen', 'sheen', 'number'),
|
|
177
181
|
property('Reflectivity', 'reflectivity', 'number'),
|
|
178
182
|
property('Clearcoat', 'clearcoat', 'number'),
|
|
183
|
+
property('Clearcoat Roughness', 'clearcoatRoughness', 'number'),
|
|
179
184
|
property('Iridescence', 'iridescence', 'number'),
|
|
180
185
|
property('Iridescence IOR', 'iridescenceIOR', 'number'),
|
|
181
186
|
property('Iridescence Thickness Range', 'iridescenceThicknessRange', 'array', undefined, ['100', '400']),
|
|
@@ -213,17 +218,13 @@ var cacher = function (engineContext, graph, node, sibling, newValue) {
|
|
|
213
218
|
log('Cache miss', cacheKey);
|
|
214
219
|
}
|
|
215
220
|
var materialData = engineContext.runtime.cache.data[cacheKey] || newValue();
|
|
221
|
+
// This is nasty: We mutate the runtime context here, and return the partial
|
|
222
|
+
// nodeContext later. See also the TODO: Refactor in context.ts.
|
|
216
223
|
engineContext.runtime.cache.data[cacheKey] = materialData;
|
|
217
224
|
engineContext.runtime.engineMaterial = materialData.material;
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
if (sibling) {
|
|
222
|
-
sibling.source =
|
|
223
|
-
sibling.stage === 'fragment'
|
|
224
|
-
? materialData.fragment
|
|
225
|
-
: materialData.vertex;
|
|
226
|
-
}
|
|
225
|
+
return {
|
|
226
|
+
computedSource: node.stage === 'fragment' ? materialData.fragment : materialData.vertex,
|
|
227
|
+
};
|
|
227
228
|
};
|
|
228
229
|
var onBeforeCompileMegaShader = function (engineContext, newMat) {
|
|
229
230
|
log('compiling three megashader!');
|
|
@@ -262,7 +263,7 @@ var onBeforeCompileMegaShader = function (engineContext, newMat) {
|
|
|
262
263
|
};
|
|
263
264
|
var megaShaderMainpulateAst = function (engineContext, engine, graph, ast, inputEdges, node, sibling) {
|
|
264
265
|
var programAst = ast;
|
|
265
|
-
var mainName = 'main' || nodeName(node);
|
|
266
|
+
var mainName = 'main'; // || nodeName(node);
|
|
266
267
|
if (node.stage === 'vertex') {
|
|
267
268
|
if (doesLinkThruShader(graph, node)) {
|
|
268
269
|
returnGlPositionHardCoded(mainName, programAst, 'vec3', 'transformed');
|
|
@@ -292,6 +293,7 @@ var nodeCacheKey = function (graph, node) {
|
|
|
292
293
|
);
|
|
293
294
|
};
|
|
294
295
|
var programCacheKey = function (engineContext, graph, node, sibling) {
|
|
296
|
+
var _a, _b;
|
|
295
297
|
// The megashader source is dependent on scene information, like the number
|
|
296
298
|
// and type of lights in the scene. This kinda sucks - it's duplicating
|
|
297
299
|
// three's material cache key, and is coupled to how three builds shaders
|
|
@@ -299,7 +301,7 @@ var programCacheKey = function (engineContext, graph, node, sibling) {
|
|
|
299
301
|
var lights = [];
|
|
300
302
|
scene.traverse(function (obj) {
|
|
301
303
|
if (obj instanceof Light) {
|
|
302
|
-
lights.push(obj.
|
|
304
|
+
lights.push(obj.uuid);
|
|
303
305
|
}
|
|
304
306
|
});
|
|
305
307
|
return ([node, sibling]
|
|
@@ -309,8 +311,10 @@ var programCacheKey = function (engineContext, graph, node, sibling) {
|
|
|
309
311
|
.join('-') +
|
|
310
312
|
'|Lights:' +
|
|
311
313
|
lights.join(',') +
|
|
312
|
-
'|
|
|
313
|
-
scene.
|
|
314
|
+
'|Bg:' +
|
|
315
|
+
((_a = scene.background) === null || _a === void 0 ? void 0 : _a.uuid) +
|
|
316
|
+
'|Env:' +
|
|
317
|
+
((_b = scene.environment) === null || _b === void 0 ? void 0 : _b.uuid));
|
|
314
318
|
};
|
|
315
319
|
export var defaultPropertySetting = function (property) {
|
|
316
320
|
if (property.type === 'texture') {
|
|
@@ -328,12 +332,7 @@ export var defaultPropertySetting = function (property) {
|
|
|
328
332
|
};
|
|
329
333
|
var threeMaterialProperties = function (graph, node, sibling) {
|
|
330
334
|
// Find inputs to this node that are dependent on a property of the material
|
|
331
|
-
var propertyInputs = node.inputs
|
|
332
|
-
.filter(function (i) { return i.property; })
|
|
333
|
-
.reduce(function (acc, input) {
|
|
334
|
-
var _a;
|
|
335
|
-
return (__assign(__assign({}, acc), (_a = {}, _a[input.id] = input, _a)));
|
|
336
|
-
}, {});
|
|
335
|
+
var propertyInputs = indexById(node.inputs.filter(function (i) { return i.property; }));
|
|
337
336
|
// Then look for any edges into those inputs and set the material property
|
|
338
337
|
return graph.edges
|
|
339
338
|
.filter(function (edge) { return edge.to === node.id || edge.to === (sibling === null || sibling === void 0 ? void 0 : sibling.id); })
|
|
@@ -349,6 +348,24 @@ var threeMaterialProperties = function (graph, node, sibling) {
|
|
|
349
348
|
return acc;
|
|
350
349
|
}, {});
|
|
351
350
|
};
|
|
351
|
+
export var stringifyThreeValue = function (input) {
|
|
352
|
+
if (input instanceof Vector2) {
|
|
353
|
+
return "new Vector2(".concat(input.x, ", ").concat(input.y, ")");
|
|
354
|
+
}
|
|
355
|
+
else if (input instanceof Vector3) {
|
|
356
|
+
return "new Vector3(".concat(input.x, ", ").concat(input.y, ", ").concat(input.z, ")");
|
|
357
|
+
}
|
|
358
|
+
else if (input instanceof Vector4) {
|
|
359
|
+
return "new Vector4(".concat(input.x, ", ").concat(input.y, ", ").concat(input.z, ", ").concat(input.w, ")");
|
|
360
|
+
}
|
|
361
|
+
else if (input instanceof Color) {
|
|
362
|
+
return "new Color(".concat(input.r, ", ").concat(input.g, ", ").concat(input.b, ")");
|
|
363
|
+
}
|
|
364
|
+
else if (input instanceof Texture) {
|
|
365
|
+
return "new Texture()";
|
|
366
|
+
}
|
|
367
|
+
return "".concat(input);
|
|
368
|
+
};
|
|
352
369
|
var evaluateNode = function (node) {
|
|
353
370
|
if (node.type === 'number') {
|
|
354
371
|
return parseFloat(node.value);
|
|
@@ -395,6 +412,7 @@ export var toonNode = function (id, name, position, uniforms, stage) {
|
|
|
395
412
|
property('Displacement Map', 'displacementMap', 'texture', 'filler_displacementMap'),
|
|
396
413
|
property('Displacement Scale', 'displacementScale', 'number'),
|
|
397
414
|
property('Env Map', 'envMap', 'samplerCube'),
|
|
415
|
+
property('Env Map Intensity', 'envMapIntensity', 'number'),
|
|
398
416
|
],
|
|
399
417
|
strategies: [
|
|
400
418
|
uniformStrategy(),
|
|
@@ -459,8 +477,9 @@ export var threngine = {
|
|
|
459
477
|
'shininess',
|
|
460
478
|
'opacity',
|
|
461
479
|
'map',
|
|
480
|
+
'IncidentLight',
|
|
481
|
+
'ReflectedLight',
|
|
462
482
|
'specularTint',
|
|
463
|
-
'time',
|
|
464
483
|
'normalScale',
|
|
465
484
|
'normalMap',
|
|
466
485
|
'envMap',
|
|
@@ -502,12 +521,16 @@ export var threngine = {
|
|
|
502
521
|
'displacementMap',
|
|
503
522
|
'displacementScale',
|
|
504
523
|
'displacementBias',
|
|
524
|
+
// passed by shaderfrog. maybe should have separate names? duplicated across
|
|
525
|
+
// all the engines.
|
|
526
|
+
'time',
|
|
527
|
+
'renderResolution',
|
|
505
528
|
]),
|
|
506
529
|
parsers: (_b = {},
|
|
507
530
|
_b[NodeType.SOURCE] = {
|
|
508
531
|
manipulateAst: function (engineContext, engine, graph, ast, inputEdges, node, sibling) {
|
|
509
532
|
var programAst = ast;
|
|
510
|
-
var mainName = 'main' || nodeName(node);
|
|
533
|
+
var mainName = 'main'; // || nodeName(node);
|
|
511
534
|
// This hinges on the vertex shader calling vec3(p)
|
|
512
535
|
if (node.stage === 'vertex') {
|
|
513
536
|
if (doesLinkThruShader(graph, node)) {
|
|
@@ -523,12 +546,11 @@ export var threngine = {
|
|
|
523
546
|
_b[EngineNodeType.phong] = {
|
|
524
547
|
onBeforeCompile: function (graph, engineContext, node, sibling) { return __awaiter(void 0, void 0, void 0, function () {
|
|
525
548
|
return __generator(this, function (_a) {
|
|
526
|
-
cacher(engineContext, graph, node, sibling, function () {
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
return [2 /*return*/];
|
|
549
|
+
return [2 /*return*/, cacher(engineContext, graph, node, sibling, function () {
|
|
550
|
+
return onBeforeCompileMegaShader(engineContext, new MeshPhongMaterial(__assign({
|
|
551
|
+
// @ts-ignore
|
|
552
|
+
isMeshPhongMaterial: true }, threeMaterialProperties(graph, node, sibling))));
|
|
553
|
+
})];
|
|
532
554
|
});
|
|
533
555
|
}); },
|
|
534
556
|
manipulateAst: megaShaderMainpulateAst,
|
|
@@ -536,10 +558,9 @@ export var threngine = {
|
|
|
536
558
|
_b[EngineNodeType.physical] = {
|
|
537
559
|
onBeforeCompile: function (graph, engineContext, node, sibling) { return __awaiter(void 0, void 0, void 0, function () {
|
|
538
560
|
return __generator(this, function (_a) {
|
|
539
|
-
cacher(engineContext, graph, node, sibling, function () {
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
return [2 /*return*/];
|
|
561
|
+
return [2 /*return*/, cacher(engineContext, graph, node, sibling, function () {
|
|
562
|
+
return onBeforeCompileMegaShader(engineContext, new MeshPhysicalMaterial(__assign(__assign({}, node.config.hardCodedProperties), threeMaterialProperties(graph, node, sibling))));
|
|
563
|
+
})];
|
|
543
564
|
});
|
|
544
565
|
}); },
|
|
545
566
|
manipulateAst: megaShaderMainpulateAst,
|
|
@@ -547,12 +568,11 @@ export var threngine = {
|
|
|
547
568
|
_b[EngineNodeType.toon] = {
|
|
548
569
|
onBeforeCompile: function (graph, engineContext, node, sibling) { return __awaiter(void 0, void 0, void 0, function () {
|
|
549
570
|
return __generator(this, function (_a) {
|
|
550
|
-
cacher(engineContext, graph, node, sibling, function () {
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
return [2 /*return*/];
|
|
571
|
+
return [2 /*return*/, cacher(engineContext, graph, node, sibling, function () {
|
|
572
|
+
return onBeforeCompileMegaShader(engineContext, new MeshToonMaterial(__assign({ gradientMap: new Texture(),
|
|
573
|
+
// @ts-ignore
|
|
574
|
+
isMeshToonMaterial: true }, threeMaterialProperties(graph, node, sibling))));
|
|
575
|
+
})];
|
|
556
576
|
});
|
|
557
577
|
}); },
|
|
558
578
|
manipulateAst: megaShaderMainpulateAst,
|
|
@@ -561,7 +581,7 @@ export var threngine = {
|
|
|
561
581
|
};
|
|
562
582
|
export var createMaterial = function (compileResult, ctx) {
|
|
563
583
|
var engineMaterial = ctx.runtime.engineMaterial;
|
|
564
|
-
var finalUniforms = __assign(__assign(__assign(__assign({}, ShaderLib.phong.uniforms), ShaderLib.toon.uniforms), ShaderLib.physical.uniforms), { time: { value: 0 }, cameraPosition: { value: new Vector3(1.0) } });
|
|
584
|
+
var finalUniforms = __assign(__assign(__assign(__assign({}, ShaderLib.phong.uniforms), ShaderLib.toon.uniforms), ShaderLib.physical.uniforms), { time: { value: 0 }, cameraPosition: { value: new Vector3(1.0) }, renderResolution: { value: new Vector2(1.0) } });
|
|
565
585
|
// Also the ThreeComponent's sceneConfig properties modify the material
|
|
566
586
|
var initialProperties = {
|
|
567
587
|
name: 'ShaderFrog Material',
|
|
@@ -37,15 +37,17 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
37
37
|
import { expect, it } from 'vitest';
|
|
38
38
|
import { outputNode, sourceNode } from '../../graph/graph-node';
|
|
39
39
|
import { makeEdge } from '../../graph/edge';
|
|
40
|
-
import { compileSource } from '../../graph/graph';
|
|
41
|
-
import { texture2DStrategy } from '../../strategy';
|
|
40
|
+
import { compileSource, nodeName } from '../../graph/graph';
|
|
41
|
+
import { namedAttributeStrategy, texture2DStrategy } from '../../strategy';
|
|
42
42
|
import { isError } from '../../graph/context';
|
|
43
43
|
import { threngine } from './threngine';
|
|
44
44
|
import { makeId } from '../../util/id';
|
|
45
45
|
import { fail } from '../../test-util';
|
|
46
|
+
import importers from './importers';
|
|
47
|
+
import { generate, parser } from '@shaderfrog/glsl-parser';
|
|
46
48
|
var p = { x: 0, y: 0 };
|
|
47
49
|
var makeSourceNode = function (id, source, stage, strategies) {
|
|
48
|
-
if (strategies === void 0) { strategies = [texture2DStrategy()]; }
|
|
50
|
+
if (strategies === void 0) { strategies = [texture2DStrategy(), namedAttributeStrategy('position')]; }
|
|
49
51
|
return sourceNode(id, "Shader ".concat(id), p, {
|
|
50
52
|
version: 2,
|
|
51
53
|
preprocess: false,
|
|
@@ -82,8 +84,53 @@ it('threngine compileSource() and manipulateAst()', function () { return __await
|
|
|
82
84
|
// Threngine has parsers for vertex shaders, make sure that is set properly
|
|
83
85
|
expect(result.vertexResult).toContain("vec4 main_Shader_".concat(vertInput.id, "() {\n vec4 frogOut = modelViewMatrix * vec4(position, 1.0);\n return frogOut;\n}"));
|
|
84
86
|
// Check that it inlned. For fun.
|
|
85
|
-
expect(result.vertexResult).toContain("gl_Position =
|
|
87
|
+
expect(result.vertexResult).toContain("gl_Position = ".concat(nodeName(vertInput), "();"));
|
|
86
88
|
return [2 /*return*/];
|
|
87
89
|
}
|
|
88
90
|
});
|
|
89
91
|
}); });
|
|
92
|
+
it('threngine compileSource() linking through vertex', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
93
|
+
var outV, outF, vert1, vert2, graph, engineContext, result;
|
|
94
|
+
return __generator(this, function (_a) {
|
|
95
|
+
switch (_a.label) {
|
|
96
|
+
case 0:
|
|
97
|
+
outV = outputNode(makeId(), 'Output v', p, 'vertex');
|
|
98
|
+
outF = outputNode(makeId(), 'Output f', p, 'fragment');
|
|
99
|
+
vert1 = makeSourceNode(makeId(), "void main() {\n gl_Position = modelViewMatrix * vec4(position, 1.0);\n}\n", 'vertex');
|
|
100
|
+
vert2 = makeSourceNode(makeId(), "void main() {\n gl_Position = modelViewMatrix * vec4(position, 1.0);\n}\n", 'vertex');
|
|
101
|
+
graph = {
|
|
102
|
+
nodes: [outV, outF, vert1, vert2],
|
|
103
|
+
edges: [
|
|
104
|
+
makeEdge(makeId(), vert1.id, outV.id, 'out', 'filler_gl_Position', 'vertex'),
|
|
105
|
+
makeEdge(makeId(), vert2.id, vert1.id, 'out', 'filler_position', 'vertex'),
|
|
106
|
+
],
|
|
107
|
+
};
|
|
108
|
+
engineContext = {
|
|
109
|
+
engine: 'three',
|
|
110
|
+
nodes: {},
|
|
111
|
+
runtime: {},
|
|
112
|
+
debuggingNonsense: {},
|
|
113
|
+
};
|
|
114
|
+
return [4 /*yield*/, compileSource(graph, threngine, engineContext)];
|
|
115
|
+
case 1:
|
|
116
|
+
result = _a.sent();
|
|
117
|
+
if (isError(result)) {
|
|
118
|
+
fail(result);
|
|
119
|
+
}
|
|
120
|
+
// Because vert2 links through vert1, it should be a vec3, not a vec4
|
|
121
|
+
expect(result.vertexResult).toContain("vec3 ".concat(nodeName(vert2), "() {"));
|
|
122
|
+
expect(result.vertexResult).toContain("vec4 ".concat(nodeName(vert1), "() {"));
|
|
123
|
+
return [2 /*return*/];
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
}); });
|
|
127
|
+
it('threngine shadertoy import', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
128
|
+
var testImport, p;
|
|
129
|
+
return __generator(this, function (_a) {
|
|
130
|
+
testImport = "\nvoid mainImage( out vec4 fragColor, in vec2 fragCoord ){\n vec3 rd = normalize(vec3(2.*fragCoord - iResolution.xy, iResolution.y));\n fragColor = vec4(sqrt(clamp(col, 0., 1.)), 1.0 * iTime);\n}\n";
|
|
131
|
+
p = parser.parse(testImport);
|
|
132
|
+
importers.shadertoy.convertAst(p, 'fragment');
|
|
133
|
+
expect(generate(p)).toContain("\nprecision highp float;\nprecision highp int;\n\nuniform vec2 mouse;\nuniform float time;\nuniform vec2 renderResolution;\n\nvoid main() {\n vec3 rd = normalize(vec3(2.*gl_FragCoord.xy - renderResolution.xy, renderResolution.y));\n gl_FragColor = vec4(sqrt(clamp(col, 0., 1.)), 1.0 * time);\n}\n");
|
|
134
|
+
return [2 /*return*/];
|
|
135
|
+
});
|
|
136
|
+
}); });
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { BaseStrategy, ApplyStrategy, StrategyType } from '.';
|
|
2
|
+
export interface AssignmentToStrategy extends BaseStrategy {
|
|
3
|
+
type: StrategyType.ASSIGNMENT_TO;
|
|
4
|
+
config: {
|
|
5
|
+
assignTo: string;
|
|
6
|
+
nth?: number;
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
export declare const assignemntToStrategy: (assignTo: string, nth?: number) => AssignmentToStrategy;
|
|
10
|
+
export declare const applyAssignmentToStrategy: ApplyStrategy<AssignmentToStrategy>;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { findAssignmentTo } from '../util/ast';
|
|
2
|
+
import { nodeInput } from '../graph/base-node';
|
|
3
|
+
import { StrategyType } from '.';
|
|
4
|
+
// Constructor
|
|
5
|
+
export var assignemntToStrategy = function (assignTo, nth) {
|
|
6
|
+
if (nth === void 0) { nth = 1; }
|
|
7
|
+
return ({
|
|
8
|
+
type: StrategyType.ASSIGNMENT_TO,
|
|
9
|
+
config: { assignTo: assignTo, nth: nth },
|
|
10
|
+
});
|
|
11
|
+
};
|
|
12
|
+
// Apply the strategy
|
|
13
|
+
export var applyAssignmentToStrategy = function (strategy, ast, graphNode, siblingNode) {
|
|
14
|
+
var assignNode = findAssignmentTo(ast, strategy.config.assignTo, strategy.config.nth || 1);
|
|
15
|
+
var name = strategy.config.assignTo;
|
|
16
|
+
return assignNode
|
|
17
|
+
? [
|
|
18
|
+
[
|
|
19
|
+
nodeInput(name, "filler_".concat(name), 'filler', undefined, // Data type for what plugs into this filler
|
|
20
|
+
['code', 'data'], false),
|
|
21
|
+
function (filler) {
|
|
22
|
+
var filled = filler();
|
|
23
|
+
if ('expression' in assignNode) {
|
|
24
|
+
assignNode.expression.right =
|
|
25
|
+
filled;
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
assignNode.initializer = filled;
|
|
29
|
+
}
|
|
30
|
+
return ast;
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
]
|
|
34
|
+
: [];
|
|
35
|
+
};
|
|
@@ -13,8 +13,8 @@ export var constApplyDeclarationOf = function (strategy, ast, graphNode, sibling
|
|
|
13
13
|
[
|
|
14
14
|
nodeInput(name, "filler_".concat(name), 'filler', undefined, // Data type for what plugs into this filler
|
|
15
15
|
['code', 'data'], false),
|
|
16
|
-
function (
|
|
17
|
-
declaration.initializer =
|
|
16
|
+
function (filler) {
|
|
17
|
+
declaration.initializer = filler();
|
|
18
18
|
return ast;
|
|
19
19
|
},
|
|
20
20
|
],
|
package/strategy/hardCode.js
CHANGED
|
@@ -12,10 +12,7 @@ export var applyHardCodeStrategy = function (strategy, ast, graphNode, siblingNo
|
|
|
12
12
|
// so this awkward branch is to make types line up. But I don't think
|
|
13
13
|
// this code path would ever get called
|
|
14
14
|
function (filler) {
|
|
15
|
-
|
|
16
|
-
throw new Error('Cannot use void filler');
|
|
17
|
-
}
|
|
18
|
-
return filler;
|
|
15
|
+
return filler();
|
|
19
16
|
},
|
|
20
17
|
];
|
|
21
18
|
return ci;
|
package/strategy/index.d.ts
CHANGED
package/strategy/index.js
CHANGED
package/strategy/inject.js
CHANGED
|
@@ -62,10 +62,9 @@ export var applyInjectStrategy = function (strategy, ast, graphNode, siblingNode
|
|
|
62
62
|
[
|
|
63
63
|
nodeInput(name, "filler_".concat(name), 'filler', undefined, // Data type for what plugs into this filler
|
|
64
64
|
['code', 'data'], false),
|
|
65
|
-
function (
|
|
66
|
-
var
|
|
67
|
-
|
|
68
|
-
: [fillerAst];
|
|
65
|
+
function (filler) {
|
|
66
|
+
var result = filler();
|
|
67
|
+
var toInsert = Array.isArray(result) ? result : [result];
|
|
69
68
|
// Loop backwards through the matches because when we inject code into
|
|
70
69
|
// parent nodes, it modifies the statement list arrays
|
|
71
70
|
for (
|
|
@@ -28,7 +28,7 @@ export var applyNamedAttributeStrategy = function (strategy, ast, graphNode, sib
|
|
|
28
28
|
[
|
|
29
29
|
nodeInput(attributeName, "filler_".concat(attributeName), 'filler', undefined, // Data type for what plugs into this filler
|
|
30
30
|
['code', 'data'], true),
|
|
31
|
-
function (
|
|
31
|
+
function (filler) {
|
|
32
32
|
Object.entries(program.scopes[0].bindings).forEach(function (_a) {
|
|
33
33
|
var _b = __read(_a, 2), name = _b[0], binding = _b[1];
|
|
34
34
|
binding.references.forEach(function (ref) {
|
|
@@ -37,7 +37,7 @@ export var applyNamedAttributeStrategy = function (strategy, ast, graphNode, sib
|
|
|
37
37
|
if (ref.type === 'identifier' &&
|
|
38
38
|
ref !== binding.declaration &&
|
|
39
39
|
ref.identifier === attributeName) {
|
|
40
|
-
ref.identifier = generateFiller(
|
|
40
|
+
ref.identifier = generateFiller(filler());
|
|
41
41
|
}
|
|
42
42
|
});
|
|
43
43
|
});
|
package/strategy/strategy.d.ts
CHANGED
|
@@ -2,13 +2,38 @@ import { AstNode, Program } from '@shaderfrog/glsl-parser/ast';
|
|
|
2
2
|
import { SourceNode } from '../graph/code-nodes';
|
|
3
3
|
import { HardCodeStrategy } from './hardCode';
|
|
4
4
|
import { UniformStrategy } from './uniform';
|
|
5
|
-
import {
|
|
5
|
+
import { AssignmentToStrategy } from './assignmentTo';
|
|
6
6
|
import { DeclarationOfStrategy } from './declarationOf';
|
|
7
7
|
import { Texture2DStrategy } from './texture2D';
|
|
8
8
|
import { NamedAttributeStrategy } from './namedAttribute';
|
|
9
9
|
import { VariableStrategy } from './variable';
|
|
10
10
|
import { InjectStrategy } from './inject';
|
|
11
|
-
import {
|
|
11
|
+
import { NodeInput } from '../graph';
|
|
12
|
+
/**
|
|
13
|
+
* Fillers are generated by *strategies*. Strategies are applied to the AST
|
|
14
|
+
* by applyStrategy() in strategy.ts, which runs strategy functions like
|
|
15
|
+
* applyTexture2DStrategy(), which returns a list of fillers found by each
|
|
16
|
+
* strategy.
|
|
17
|
+
*/
|
|
18
|
+
export type Filler = (...args: string[]) => AstNode | AstNode[] | void;
|
|
19
|
+
export type InputFiller = (filler: Filler) => AstNode | Program;
|
|
20
|
+
export type FillerArguments = AstNode[];
|
|
21
|
+
export type FillerStmt = AstNode;
|
|
22
|
+
export type InputFillerGroup = {
|
|
23
|
+
filler: InputFiller;
|
|
24
|
+
fillerArgs?: FillerArguments;
|
|
25
|
+
fillerStmt?: AstNode;
|
|
26
|
+
};
|
|
27
|
+
export type InputFillers = Record<string, InputFillerGroup>;
|
|
28
|
+
/**
|
|
29
|
+
* A computed input is ultimately what the strategy application process returns
|
|
30
|
+
*/
|
|
31
|
+
export type ComputedInput = [
|
|
32
|
+
NodeInput,
|
|
33
|
+
InputFiller,
|
|
34
|
+
FillerArguments?,
|
|
35
|
+
FillerStmt?
|
|
36
|
+
];
|
|
12
37
|
export declare enum StrategyType {
|
|
13
38
|
VARIABLE = "Variable Names",
|
|
14
39
|
ASSIGNMENT_TO = "Assignment To",
|
|
@@ -23,6 +48,6 @@ export interface BaseStrategy {
|
|
|
23
48
|
type: StrategyType;
|
|
24
49
|
config: Object;
|
|
25
50
|
}
|
|
26
|
-
export type Strategy = UniformStrategy |
|
|
27
|
-
export type ApplyStrategy<T> = (strategy: T, ast: AstNode | Program, node: SourceNode, sibling
|
|
28
|
-
export declare const applyStrategy: (strategy: Strategy, ast: AstNode | Program, node: SourceNode, sibling
|
|
51
|
+
export type Strategy = UniformStrategy | AssignmentToStrategy | Texture2DStrategy | NamedAttributeStrategy | VariableStrategy | HardCodeStrategy | InjectStrategy | DeclarationOfStrategy;
|
|
52
|
+
export type ApplyStrategy<T> = (strategy: T, ast: AstNode | Program, node: SourceNode, sibling?: SourceNode) => ComputedInput[];
|
|
53
|
+
export declare const applyStrategy: (strategy: Strategy, ast: AstNode | Program, node: SourceNode, sibling?: SourceNode) => ComputedInput[];
|
package/strategy/strategy.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
var _a;
|
|
2
2
|
import { applyHardCodeStrategy } from './hardCode';
|
|
3
3
|
import { applyUniformStrategy } from './uniform';
|
|
4
|
-
import { applyAssignmentToStrategy, } from './
|
|
4
|
+
import { applyAssignmentToStrategy, } from './assignmentTo';
|
|
5
5
|
import { constApplyDeclarationOf as constApplyDeclarationOfStrategy, } from './declarationOf';
|
|
6
6
|
import { applyTexture2DStrategy } from './texture2D';
|
|
7
7
|
import { applyNamedAttributeStrategy, } from './namedAttribute';
|