@shaderfrog/core 0.0.2 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/README.md +184 -1
  2. package/dist/ast/manipulate.js +328 -0
  3. package/dist/ast/shader-sections.js +256 -0
  4. package/dist/context.js +230 -0
  5. package/dist/engine.js +209 -0
  6. package/dist/evaluate.js +27 -0
  7. package/dist/graph-types.js +7 -0
  8. package/dist/graph.js +381 -0
  9. package/dist/graph.test.js +168 -0
  10. package/dist/nodes/code-nodes.js +18 -0
  11. package/dist/nodes/core-node.js +9 -0
  12. package/dist/nodes/data-nodes.js +123 -0
  13. package/dist/nodes/edge.js +1 -0
  14. package/dist/nodes/engine-node.js +189 -0
  15. package/dist/parsers.js +213 -0
  16. package/dist/plugins/babylon/bablyengine.js +582 -0
  17. package/dist/plugins/babylon/importers.js +64 -0
  18. package/{src/plugins/babylon/index.ts → dist/plugins/babylon/index.js} +0 -1
  19. package/dist/plugins/playcanvas/importers.js +28 -0
  20. package/dist/plugins/playcanvas/index.js +2 -0
  21. package/dist/plugins/playcanvas/playengine.js +510 -0
  22. package/dist/plugins/three/importers.js +15 -0
  23. package/{src/plugins/three/index.ts → dist/plugins/three/index.js} +0 -1
  24. package/dist/plugins/three/threngine.js +495 -0
  25. package/dist/strategy/assignemntTo.js +26 -0
  26. package/dist/strategy/declarationOf.js +23 -0
  27. package/dist/strategy/hardCode.js +23 -0
  28. package/dist/strategy/index.js +38 -0
  29. package/dist/strategy/inject.js +122 -0
  30. package/dist/strategy/namedAttribute.js +48 -0
  31. package/dist/strategy/texture2D.js +83 -0
  32. package/dist/strategy/uniform.js +190 -0
  33. package/dist/strategy/variable.js +80 -0
  34. package/dist/stratgies.test.js +164 -0
  35. package/dist/util/ast.js +9 -0
  36. package/dist/util/ensure.js +7 -0
  37. package/dist/util/id.js +2 -0
  38. package/package.json +12 -4
  39. package/src/ast/manipulate.ts +0 -392
  40. package/src/ast/shader-sections.ts +0 -323
  41. package/src/core/engine.ts +0 -214
  42. package/src/core/file.js +0 -53
  43. package/src/core/graph.ts +0 -1007
  44. package/src/core/nodes/code-nodes.ts +0 -66
  45. package/src/core/nodes/core-node.ts +0 -48
  46. package/src/core/nodes/data-nodes.ts +0 -344
  47. package/src/core/nodes/edge.ts +0 -23
  48. package/src/core/nodes/engine-node.ts +0 -266
  49. package/src/core/strategy.ts +0 -520
  50. package/src/core.test.ts +0 -312
  51. package/src/plugins/babylon/bablyengine.ts +0 -670
  52. package/src/plugins/babylon/importers.ts +0 -69
  53. package/src/plugins/three/importers.ts +0 -18
  54. package/src/plugins/three/threngine.tsx +0 -571
  55. package/src/util/ensure.ts +0 -10
  56. package/src/util/id.ts +0 -2
@@ -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 { shaderSectionsToProgram } from './ast/shader-sections';
5
+ import { addNode } from './nodes/engine-node';
6
+ import { mergeShaderSections, findShaderSections } from './ast/shader-sections';
7
+ import { numberNode } from './nodes/data-nodes';
8
+ import { makeEdge } from './nodes/edge';
9
+ import { evaluateNode } from './evaluate';
10
+ var inspect = function (thing) {
11
+ return console.log(util.inspect(thing, false, null, true));
12
+ };
13
+ var mergeBlocks = function (ast1, ast2) {
14
+ var s1 = findShaderSections(ast1);
15
+ var s2 = findShaderSections(ast2);
16
+ var merged = mergeShaderSections(s1, s2);
17
+ return generate(shaderSectionsToProgram(merged, {
18
+ includePrecisions: true,
19
+ includeVersion: true,
20
+ }));
21
+ };
22
+ var dedupe = function (code) {
23
+ return generate(shaderSectionsToProgram(findShaderSections(parser.parse(code)), {
24
+ includePrecisions: true,
25
+ includeVersion: true,
26
+ }));
27
+ };
28
+ var counter = 0;
29
+ var p = { x: 0, y: 0 };
30
+ var id = function () { return '' + counter++; };
31
+ var constructor = function () { return ({
32
+ config: {
33
+ version: 3,
34
+ preprocess: false,
35
+ strategies: [],
36
+ uniforms: [],
37
+ },
38
+ id: '1',
39
+ name: '1',
40
+ type: '',
41
+ inputs: [],
42
+ outputs: [],
43
+ position: { x: 0, y: 0 },
44
+ source: '',
45
+ stage: undefined,
46
+ groupId: null,
47
+ }); };
48
+ var engine = {
49
+ name: 'three',
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
+ });
@@ -0,0 +1,18 @@
1
+ export var mapInputName = function (node, _a) {
2
+ var _b, _c;
3
+ var id = _a.id, displayName = _a.displayName;
4
+ return ((_c = (_b = node.config) === null || _b === void 0 ? void 0 : _b.inputMapping) === null || _c === void 0 ? void 0 : _c[id]) || displayName;
5
+ };
6
+ export var property = function (displayName, property, type, fillerName, defaultValue) { return ({
7
+ displayName: displayName,
8
+ type: type,
9
+ property: property,
10
+ fillerName: fillerName,
11
+ defaultValue: defaultValue,
12
+ }); };
13
+ export var SourceType;
14
+ (function (SourceType) {
15
+ SourceType["EXPRESSION"] = "Expression";
16
+ SourceType["FN_BODY_FRAGMENT"] = "Function Body Fragment";
17
+ SourceType["SHADER_FRAGMENT"] = "Shader Fragment";
18
+ })(SourceType || (SourceType = {}));
@@ -0,0 +1,9 @@
1
+ export var nodeInput = function (displayName, id, type, dataType, accepts, bakeable, property) { return ({
2
+ displayName: displayName,
3
+ id: id,
4
+ type: type,
5
+ dataType: dataType,
6
+ accepts: accepts,
7
+ bakeable: bakeable,
8
+ property: property,
9
+ }); };
@@ -0,0 +1,123 @@
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
+ export var numberNode = function (id, name, position, value, optionals) { return ({
13
+ type: 'number',
14
+ id: id,
15
+ name: name,
16
+ position: position,
17
+ value: value,
18
+ inputs: (optionals === null || optionals === void 0 ? void 0 : optionals.inputs) || [],
19
+ outputs: (optionals === null || optionals === void 0 ? void 0 : optionals.outputs) || [
20
+ {
21
+ name: 'float',
22
+ id: '1',
23
+ category: 'data',
24
+ },
25
+ ],
26
+ range: optionals === null || optionals === void 0 ? void 0 : optionals.range,
27
+ stepper: optionals === null || optionals === void 0 ? void 0 : optionals.stepper,
28
+ }); };
29
+ export var numberUniformData = function (name, value, range, stepper) { return ({
30
+ type: 'number',
31
+ name: name,
32
+ value: value,
33
+ range: range,
34
+ stepper: stepper,
35
+ }); };
36
+ export var textureNode = function (id, name, position, value) { return ({
37
+ type: 'texture',
38
+ id: id,
39
+ name: name,
40
+ position: position,
41
+ value: value,
42
+ inputs: [],
43
+ outputs: [
44
+ {
45
+ name: 'texture',
46
+ id: '1',
47
+ category: 'data',
48
+ },
49
+ ],
50
+ }); };
51
+ export var textureUniformData = function (name, value) { return ({ type: 'texture', name: name, value: value }); };
52
+ export var samplerCubeNode = function (id, name, position, value) { return ({
53
+ type: 'samplerCube',
54
+ id: id,
55
+ name: name,
56
+ position: position,
57
+ value: value,
58
+ inputs: [],
59
+ outputs: [
60
+ {
61
+ name: 'samplerCube',
62
+ id: '1',
63
+ category: 'data',
64
+ },
65
+ ],
66
+ }); };
67
+ export var samplerCubeUniformData = function (name, value) { return ({ type: 'samplerCube', name: name, value: value }); };
68
+ export function arrayNode(id, name, position, value) {
69
+ return {
70
+ id: id,
71
+ name: name,
72
+ position: position,
73
+ inputs: [],
74
+ outputs: [
75
+ {
76
+ name: 'array',
77
+ id: '1',
78
+ category: 'data',
79
+ },
80
+ ],
81
+ value: value,
82
+ dimensions: value.length,
83
+ type: 'array',
84
+ };
85
+ }
86
+ export function vectorNode(id, name, position, value) {
87
+ return __assign({ id: id, name: name, position: position, inputs: [], outputs: [
88
+ {
89
+ name: "vector".concat(value.length),
90
+ id: '1',
91
+ category: 'data',
92
+ },
93
+ ] }, (value.length === 2
94
+ ? { value: value, dimensions: 2, type: 'vector2' }
95
+ : value.length === 3
96
+ ? { value: value, dimensions: 3, type: 'vector3' }
97
+ : { value: value, dimensions: 4, type: 'vector4' }));
98
+ }
99
+ export var arrayUniformData = function (name, value) { return ({
100
+ name: name,
101
+ value: value,
102
+ dimensions: value.length,
103
+ type: 'array',
104
+ }); };
105
+ export var vectorUniformData = function (name, value) { return (__assign({ name: name }, (value.length === 2
106
+ ? { value: value, dimensions: 2, type: 'vector2' }
107
+ : value.length === 3
108
+ ? { value: value, dimensions: 3, type: 'vector3' }
109
+ : { value: value, dimensions: 4, type: 'vector4' }))); };
110
+ export function colorNode(id, name, position, value) {
111
+ return __assign({ id: id, name: name, position: position, inputs: [], outputs: [
112
+ {
113
+ name: value.length === 3 ? 'rgb' : 'rgba',
114
+ id: '1',
115
+ category: 'data',
116
+ },
117
+ ] }, (value.length === 3
118
+ ? { value: value, dimensions: 3, type: 'rgb' }
119
+ : { value: value, dimensions: 4, type: 'rgba' }));
120
+ }
121
+ export var colorUniformData = function (name, value) { return (__assign({ name: name }, (value.length === 3
122
+ ? { value: value, dimensions: 3, type: 'rgb' }
123
+ : { value: value, dimensions: 4, type: 'rgba' }))); };
@@ -0,0 +1 @@
1
+ export var makeEdge = function (id, from, to, output, input, type) { return ({ id: id, from: from, to: to, output: output, input: input, type: type }); };
@@ -0,0 +1,189 @@
1
+ import { EngineNodeType } from '../engine';
2
+ import { prepopulatePropertyInputs } from '../graph';
3
+ import { NodeType } from '../graph-types';
4
+ import { assignemntToStrategy, namedAttributeStrategy, texture2DStrategy, uniformStrategy, variableStrategy, } from '../strategy';
5
+ import { SourceType, property, } from './code-nodes';
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 ({
13
+ id: id,
14
+ name: name,
15
+ groupId: undefined,
16
+ type: NodeType.SOURCE,
17
+ config: config,
18
+ position: position,
19
+ inputs: [],
20
+ outputs: [
21
+ {
22
+ name: 'vector4',
23
+ category: 'data',
24
+ id: '1',
25
+ },
26
+ ],
27
+ source: source,
28
+ stage: stage,
29
+ originalEngine: originalEngine,
30
+ nextStageNodeId: nextStageNodeId,
31
+ }); };
32
+ export var outputNode = function (id, name, position, stage) { return ({
33
+ id: id,
34
+ name: name,
35
+ position: position,
36
+ groupId: undefined,
37
+ type: NodeType.OUTPUT,
38
+ config: {
39
+ version: 3,
40
+ mangle: false,
41
+ preprocess: false,
42
+ uniforms: [],
43
+ inputMapping: stage === 'fragment'
44
+ ? {
45
+ filler_frogFragOut: 'Color',
46
+ }
47
+ : {
48
+ filler_gl_Position: 'Position',
49
+ },
50
+ strategies: [
51
+ assignemntToStrategy(stage === 'fragment' ? 'frogFragOut' : 'gl_Position'),
52
+ ],
53
+ },
54
+ inputs: [],
55
+ outputs: [],
56
+ // Consumed by findVec4Constructo4
57
+ source: stage === 'fragment'
58
+ ? "\n#version 300 es\nprecision highp float;\n\nout vec4 frogFragOut;\nvoid main() {\n frogFragOut = vec4(1.0);\n}\n"
59
+ : // gl_Position isn't "out"-able apparently https://stackoverflow.com/a/24425436/743464
60
+ "\n#version 300 es\nprecision highp float;\n\nvoid main() {\n gl_Position = vec4(1.0);\n}\n",
61
+ stage: stage,
62
+ }); };
63
+ export var expressionNode = function (id, name, position, source) { return ({
64
+ id: id,
65
+ name: name,
66
+ position: position,
67
+ type: NodeType.SOURCE,
68
+ sourceType: SourceType.EXPRESSION,
69
+ groupId: undefined,
70
+ stage: undefined,
71
+ config: {
72
+ uniforms: [],
73
+ version: 3,
74
+ preprocess: false,
75
+ inputMapping: {},
76
+ strategies: [variableStrategy()],
77
+ },
78
+ inputs: [],
79
+ outputs: [
80
+ {
81
+ name: 'expression',
82
+ category: 'data',
83
+ id: '1',
84
+ },
85
+ ],
86
+ source: source,
87
+ }); };
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
+ export var addNode = function (id, position) { return ({
137
+ id: id,
138
+ name: 'add',
139
+ position: position,
140
+ type: NodeType.BINARY,
141
+ groupId: undefined,
142
+ stage: undefined,
143
+ config: {
144
+ mangle: false,
145
+ version: 3,
146
+ preprocess: true,
147
+ strategies: [],
148
+ uniforms: [],
149
+ },
150
+ inputs: [],
151
+ outputs: [
152
+ {
153
+ name: 'sum',
154
+ category: 'data',
155
+ id: '1',
156
+ },
157
+ ],
158
+ source: "a + b",
159
+ operator: '+',
160
+ sourceType: SourceType.EXPRESSION,
161
+ biStage: true,
162
+ }); };
163
+ export var multiplyNode = function (id, position) { return ({
164
+ id: id,
165
+ name: 'multiply',
166
+ type: NodeType.BINARY,
167
+ groupId: undefined,
168
+ stage: undefined,
169
+ position: position,
170
+ config: {
171
+ version: 3,
172
+ uniforms: [],
173
+ mangle: false,
174
+ preprocess: true,
175
+ strategies: [],
176
+ },
177
+ inputs: [],
178
+ outputs: [
179
+ {
180
+ name: 'product',
181
+ category: 'data',
182
+ id: '1',
183
+ },
184
+ ],
185
+ source: "a * b",
186
+ operator: '*',
187
+ sourceType: SourceType.EXPRESSION,
188
+ biStage: true,
189
+ }); };