@shaderfrog/core 3.0.0 → 3.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/engine.d.ts +3 -1
- package/engine.js +3 -3
- package/graph/context.d.ts +1 -1
- package/graph/graph.test.js +16 -21
- package/graph/parsers.js +3 -3
- package/package.json +3 -3
- package/plugins/babylon/importers.js +1 -1
- package/plugins/playcanvas/importers.js +1 -1
- package/plugins/three/importers.d.ts +1 -1
- package/plugins/three/importers.js +35 -12
- package/plugins/three/threngine.test.js +4 -4
- package/strategy/stratgies.test.js +9 -9
- package/util/ast.js +7 -7
- package/util/ast.test.js +3 -3
- package/util/math.d.ts +2 -0
- package/util/math.js +6 -0
- package/util/whitespace.test.js +2 -3
package/engine.d.ts
CHANGED
|
@@ -77,7 +77,9 @@ export declare const extendNodesContext: (context: EngineContext, nodesContext:
|
|
|
77
77
|
};
|
|
78
78
|
};
|
|
79
79
|
export type EngineImporter = {
|
|
80
|
-
convertAst(ast: Program,
|
|
80
|
+
convertAst(ast: Program, options?: Record<string, unknown> & {
|
|
81
|
+
type?: ShaderStage;
|
|
82
|
+
}): void;
|
|
81
83
|
nodeInputMap: Partial<Record<EngineNodeType, Record<string, string | null>>>;
|
|
82
84
|
edgeMap: {
|
|
83
85
|
[oldInput: string]: string;
|
package/engine.js
CHANGED
|
@@ -35,7 +35,7 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
|
35
35
|
return to.concat(ar || Array.prototype.slice.call(from));
|
|
36
36
|
};
|
|
37
37
|
import preprocess from '@shaderfrog/glsl-parser/preprocessor';
|
|
38
|
-
import { generate,
|
|
38
|
+
import { generate, parse } from '@shaderfrog/glsl-parser';
|
|
39
39
|
import { NodeType } from './graph/graph-types';
|
|
40
40
|
import groupBy from 'lodash.groupby';
|
|
41
41
|
import { collectNodeProperties } from './graph/graph';
|
|
@@ -71,8 +71,8 @@ export var convertNode = function (node, converter) {
|
|
|
71
71
|
define: function () { return true; },
|
|
72
72
|
},
|
|
73
73
|
});
|
|
74
|
-
var ast =
|
|
75
|
-
converter.convertAst(ast, node.stage);
|
|
74
|
+
var ast = parse(preprocessed, { stage: node.stage });
|
|
75
|
+
converter.convertAst(ast, { type: node.stage });
|
|
76
76
|
var source = generate(ast);
|
|
77
77
|
return __assign(__assign({}, node), { source: source });
|
|
78
78
|
};
|
package/graph/context.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { GlslSyntaxError } from '@shaderfrog/glsl-parser';
|
|
2
2
|
import { AstNode, FunctionNode, Program } from '@shaderfrog/glsl-parser/ast';
|
|
3
3
|
import { Engine, EngineContext } from '../engine';
|
|
4
4
|
import { NodeInput } from './base-node';
|
package/graph/graph.test.js
CHANGED
|
@@ -47,8 +47,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
47
47
|
};
|
|
48
48
|
import { expect, describe, it } from 'vitest';
|
|
49
49
|
import util from 'util';
|
|
50
|
-
import {
|
|
51
|
-
import { generate } from '@shaderfrog/glsl-parser';
|
|
50
|
+
import { generate, parse } from '@shaderfrog/glsl-parser';
|
|
52
51
|
import { addNode, outputNode, sourceNode } from './graph-node';
|
|
53
52
|
import { shaderSectionsToProgram, mergeShaderSections, findShaderSections, extractSource, filterUniformNames, filterQualifiedStatements, } from './shader-sections';
|
|
54
53
|
import { numberNode } from './data-nodes';
|
|
@@ -73,7 +72,7 @@ var mergeBlocks = function (ast1, ast2) {
|
|
|
73
72
|
}));
|
|
74
73
|
};
|
|
75
74
|
var dedupe = function (code) {
|
|
76
|
-
return generate(shaderSectionsToProgram(findShaderSections('',
|
|
75
|
+
return generate(shaderSectionsToProgram(findShaderSections('', parse(code)), {
|
|
77
76
|
includePrecisions: true,
|
|
78
77
|
includeVersion: true,
|
|
79
78
|
}));
|
|
@@ -408,44 +407,40 @@ describe('evaluateNode()', function () {
|
|
|
408
407
|
});
|
|
409
408
|
});
|
|
410
409
|
it('should merge uniforms with interface blocks', function () {
|
|
411
|
-
var astX =
|
|
412
|
-
var astY =
|
|
410
|
+
var astX = parse("uniform vec2 x;");
|
|
411
|
+
var astY = parse("uniform vec2 y, z;\nuniform vec3 a;");
|
|
413
412
|
expect(mergeBlocks(astX, astY)).toEqual("uniform vec2 x, y, z;\nuniform vec3 a;\n");
|
|
414
|
-
var astL01 =
|
|
415
|
-
var astL02 =
|
|
413
|
+
var astL01 = parse("uniform Light0 { vec4 y; } x;", { quiet: true });
|
|
414
|
+
var astL02 = parse("uniform Light0 { vec4 y; } x;", { quiet: true });
|
|
416
415
|
expect(mergeBlocks(astL01, astL02)).toEqual("uniform Light0 { vec4 y; } x;\n");
|
|
417
|
-
var astL001 =
|
|
416
|
+
var astL001 = parse("uniform Light0 { vec4 y; } x;", {
|
|
418
417
|
quiet: true,
|
|
419
418
|
});
|
|
420
|
-
var astL002 =
|
|
419
|
+
var astL002 = parse("uniform Light0 x;", { quiet: true });
|
|
421
420
|
expect(mergeBlocks(astL001, astL002)).toEqual("uniform Light0 { vec4 y; } x;\n");
|
|
422
|
-
var astLo01 =
|
|
423
|
-
var astLo02 =
|
|
421
|
+
var astLo01 = parse("uniform Light0 x;", { quiet: true });
|
|
422
|
+
var astLo02 = parse("uniform Light0 { vec4 y; } x;", {
|
|
424
423
|
quiet: true,
|
|
425
424
|
});
|
|
426
425
|
expect(mergeBlocks(astLo01, astLo02)).toEqual("uniform Light0 { vec4 y; } x;\n");
|
|
427
426
|
// This may be a bug, look at how the uniforms are merged. I at least want to
|
|
428
427
|
// note its current behavior in this test
|
|
429
|
-
var vec2Arr1 =
|
|
430
|
-
var vec2Arr2 =
|
|
428
|
+
var vec2Arr1 = parse("uniform vec2 y[5];");
|
|
429
|
+
var vec2Arr2 = parse("uniform vec2 y[10];");
|
|
431
430
|
expect(mergeBlocks(vec2Arr1, vec2Arr2)).toEqual("uniform vec2 y[10];\n");
|
|
432
|
-
var block1 =
|
|
433
|
-
var block2 =
|
|
431
|
+
var block1 = parse("uniform Scene { mat4 view; };");
|
|
432
|
+
var block2 = parse("uniform Scene { mat4 view; };");
|
|
434
433
|
expect(mergeBlocks(block1, block2)).toEqual("uniform Scene { mat4 view; };\n");
|
|
435
434
|
// Verify these lines are preserved (they go through dedupeUniforms)
|
|
436
435
|
expect(dedupe("layout(std140,column_major) uniform;")).toEqual("layout(std140,column_major) uniform;");
|
|
437
436
|
});
|
|
438
437
|
it('filterUniformNames', function () {
|
|
439
|
-
var stmts =
|
|
440
|
-
.parse("uniform vec4 x,y;\nuniform vec2 x, y[5];\nuniform Light0 { vec4 y; } x;\nuniform Light0 { vec4 x; } y;\n")
|
|
441
|
-
.program.filter(function (s) { return s.type === 'declaration_statement'; });
|
|
438
|
+
var stmts = parse("uniform vec4 x,y;\nuniform vec2 x, y[5];\nuniform Light0 { vec4 y; } x;\nuniform Light0 { vec4 x; } y;\n").program.filter(function (s) { return s.type === 'declaration_statement'; });
|
|
442
439
|
var filtered = filterUniformNames(stmts.map(function (x) { return ({ nodeId: '', source: x }); }), function (name) { return name !== 'x'; });
|
|
443
440
|
expect(generate(extractSource(filtered))).toEqual("uniform vec4 y;\nuniform vec2 y[5];\nuniform Light0 { vec4 x; } y;\n");
|
|
444
441
|
});
|
|
445
442
|
it('filterQualifiedStatements', function () {
|
|
446
|
-
var stmts =
|
|
447
|
-
.parse("in vec2 x, y;\nout vec2 x;\n")
|
|
448
|
-
.program.filter(function (s) { return s.type === 'declaration_statement'; });
|
|
443
|
+
var stmts = parse("in vec2 x, y;\nout vec2 x;\n").program.filter(function (s) { return s.type === 'declaration_statement'; });
|
|
449
444
|
var filtered = filterQualifiedStatements(stmts.map(function (x) { return ({ nodeId: '', source: x }); }), function (name) { return name !== 'x'; });
|
|
450
445
|
expect(generate(extractSource(filtered))).toEqual("in vec2 y;\n");
|
|
451
446
|
});
|
package/graph/parsers.js
CHANGED
|
@@ -24,7 +24,7 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
|
24
24
|
return to.concat(ar || Array.prototype.slice.call(from));
|
|
25
25
|
};
|
|
26
26
|
var _a;
|
|
27
|
-
import {
|
|
27
|
+
import { parse } from '@shaderfrog/glsl-parser';
|
|
28
28
|
import { visit, } from '@shaderfrog/glsl-parser/ast';
|
|
29
29
|
import preprocess from '@shaderfrog/glsl-parser/preprocessor';
|
|
30
30
|
import { convert300MainToReturn, findMainOrThrow, from2To3, makeExpression, makeExpressionWithScopes, makeFnBodyStatementWithScopes, } from '../util/ast';
|
|
@@ -88,7 +88,7 @@ export var coreParsers = (_a = {},
|
|
|
88
88
|
version: function () { return true; },
|
|
89
89
|
},
|
|
90
90
|
});
|
|
91
|
-
ast =
|
|
91
|
+
ast = parse(preprocessed, { stage: node.stage });
|
|
92
92
|
if (node.config.version === 2 && node.stage) {
|
|
93
93
|
from2To3(ast, node.stage);
|
|
94
94
|
}
|
|
@@ -134,7 +134,7 @@ export var coreParsers = (_a = {},
|
|
|
134
134
|
// which might be a little awkward for graph creators?
|
|
135
135
|
_a[NodeType.OUTPUT] = {
|
|
136
136
|
produceAst: function (engineContext, engine, graph, node, inputEdges) {
|
|
137
|
-
return
|
|
137
|
+
return parse(node.source);
|
|
138
138
|
},
|
|
139
139
|
findInputs: function (engineContext, ast, edges, node, sibling) {
|
|
140
140
|
return __spreadArray(__spreadArray([], __read(node.config.strategies.flatMap(function (strategy) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shaderfrog/core",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.2",
|
|
4
4
|
"description": "Shaderfrog core",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"@babel/core": "^7.21.8",
|
|
35
35
|
"@babel/preset-env": "^7.21.5",
|
|
36
36
|
"@babel/preset-typescript": "^7.21.5",
|
|
37
|
-
"@shaderfrog/glsl-parser": "^
|
|
37
|
+
"@shaderfrog/glsl-parser": "^6.0.0-beta.9",
|
|
38
38
|
"@swc/core": "^1.6.7",
|
|
39
39
|
"@types/lodash.groupby": "^4.6.7",
|
|
40
40
|
"@types/three": "^0.169.0",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"lodash.groupby": "^4.6.0"
|
|
49
49
|
},
|
|
50
50
|
"peerDependencies": {
|
|
51
|
-
"@shaderfrog/glsl-parser": "^
|
|
51
|
+
"@shaderfrog/glsl-parser": "^6.0.0-beta.7",
|
|
52
52
|
"babylonjs": ">=4",
|
|
53
53
|
"playcanvas": "^1.65.3",
|
|
54
54
|
"three": ">=0.50"
|
|
@@ -18,7 +18,7 @@ var importers = {
|
|
|
18
18
|
// from the original shader and the right imports added
|
|
19
19
|
//
|
|
20
20
|
// Also need to show babylon compile errors in the UI
|
|
21
|
-
convertAst: function (ast,
|
|
21
|
+
convertAst: function (ast, options) {
|
|
22
22
|
// Babylon has no normalmatrix. They do have a normal attribute. So undo any
|
|
23
23
|
// multiplication by normalMatrix?
|
|
24
24
|
var seen = {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { EngineImporters } from '../../engine';
|
|
2
|
-
export declare const defaultShadertoyVertex = "\nprecision highp float;\nprecision highp int;\n\nattribute vec3 position;\nattribute vec2 uv;\nvarying vec2 vUv;\n\nvoid main() {\n vUv = uv;\n gl_Position = vec4(position
|
|
2
|
+
export declare const defaultShadertoyVertex = "\nprecision highp float;\nprecision highp int;\n\nuniform mat4 modelMatrix;\nuniform mat4 modelViewMatrix;\nuniform mat4 projectionMatrix;\nuniform mat4 viewMatrix;\nuniform mat3 normalMatrix;\n\nattribute vec3 position;\nattribute vec3 normal;\nattribute vec2 uv;\nattribute vec2 uv2;\n\nvarying vec2 vUv;\nvarying vec3 vPosition;\nvarying vec3 vNormal;\n\nvoid main() {\n vUv = uv;\n vPosition = position;\n vNormal = normal;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}\n";
|
|
3
3
|
declare const importers: EngineImporters;
|
|
4
4
|
export default importers;
|
|
@@ -1,20 +1,33 @@
|
|
|
1
1
|
import { renameBindings, renameFunction, } from '@shaderfrog/glsl-parser/parser/utils';
|
|
2
2
|
import { findMainOrThrow, makeStatement } from '../../util/ast';
|
|
3
|
-
|
|
3
|
+
import { range } from '../../util/math';
|
|
4
|
+
export var defaultShadertoyVertex = "\nprecision highp float;\nprecision highp int;\n\nuniform mat4 modelMatrix;\nuniform mat4 modelViewMatrix;\nuniform mat4 projectionMatrix;\nuniform mat4 viewMatrix;\nuniform mat3 normalMatrix;\n\nattribute vec3 position;\nattribute vec3 normal;\nattribute vec2 uv;\nattribute vec2 uv2;\n\nvarying vec2 vUv;\nvarying vec3 vPosition;\nvarying vec3 vNormal;\n\nvoid main() {\n vUv = uv;\n vPosition = position;\n vNormal = normal;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}\n";
|
|
4
5
|
var importers = {
|
|
5
6
|
shadertoy: {
|
|
6
7
|
code: {
|
|
7
8
|
defaultShadertoyVertex: defaultShadertoyVertex,
|
|
8
9
|
},
|
|
9
|
-
convertAst: function (ast,
|
|
10
|
-
|
|
10
|
+
convertAst: function (ast, options) {
|
|
11
|
+
var isUv = (options === null || options === void 0 ? void 0 : options.importType) === 'uv';
|
|
12
|
+
var isScreen = !isUv;
|
|
13
|
+
if (isScreen) {
|
|
14
|
+
ast.program.unshift(makeStatement('uniform vec2 renderResolution', '\n')[0]);
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
ast.program.unshift(makeStatement('varying vec2 vUv', '\n')[0]);
|
|
18
|
+
}
|
|
11
19
|
// These do not catch variables in preprocessor definitions! See "SAD HACK"
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
20
|
+
if (ast.scopes.some(function (s) { return 'iTime' in s.bindings; })) {
|
|
21
|
+
ast.program.unshift(makeStatement('uniform float time')[0]);
|
|
22
|
+
}
|
|
23
|
+
if (ast.scopes.some(function (s) { return 'iMouse' in s.bindings; })) {
|
|
24
|
+
ast.program.unshift(makeStatement('uniform vec2 mouse')[0]);
|
|
25
|
+
}
|
|
26
|
+
range(0, 9).forEach(function (i) {
|
|
27
|
+
if (ast.scopes.some(function (s) { return "iChannel".concat(i) in s.bindings; })) {
|
|
28
|
+
ast.program.unshift(makeStatement("uniform sampler2D iChannel".concat(i))[0]);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
18
31
|
ast.program.unshift(makeStatement('precision highp int', '\n')[0]);
|
|
19
32
|
ast.program.unshift(makeStatement('precision highp float')[0]);
|
|
20
33
|
ast.scopes[0].functions.main = renameFunction(ast.scopes[0].functions.mainImage, 'main');
|
|
@@ -33,13 +46,23 @@ var importers = {
|
|
|
33
46
|
return 'mouse';
|
|
34
47
|
}
|
|
35
48
|
if (name === 'iResolution') {
|
|
36
|
-
|
|
49
|
+
if (isUv) {
|
|
50
|
+
return 'vec2(1.0)';
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
return 'renderResolution';
|
|
54
|
+
}
|
|
37
55
|
}
|
|
38
56
|
if (name === 'fragColor') {
|
|
39
57
|
return 'gl_FragColor';
|
|
40
58
|
}
|
|
41
59
|
if (name === 'fragCoord') {
|
|
42
|
-
|
|
60
|
+
if (isUv) {
|
|
61
|
+
return 'vUv';
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
return 'gl_FragCoord.xy';
|
|
65
|
+
}
|
|
43
66
|
}
|
|
44
67
|
return name;
|
|
45
68
|
});
|
|
@@ -49,7 +72,7 @@ var importers = {
|
|
|
49
72
|
edgeMap: {},
|
|
50
73
|
},
|
|
51
74
|
babylon: {
|
|
52
|
-
convertAst: function (ast,
|
|
75
|
+
convertAst: function (ast, options) {
|
|
53
76
|
ast.scopes[0].bindings = renameBindings(ast.scopes[0].bindings, function (name) {
|
|
54
77
|
return name === 'vMainUV1' ? 'vUv' : name === 'vNormalW' ? 'vNormal' : name;
|
|
55
78
|
});
|
|
@@ -44,7 +44,7 @@ import { threngine } from './threngine';
|
|
|
44
44
|
import { makeId } from '../../util/id';
|
|
45
45
|
import { fail } from '../../test-util';
|
|
46
46
|
import importers from './importers';
|
|
47
|
-
import { generate,
|
|
47
|
+
import { generate, parse } from '@shaderfrog/glsl-parser';
|
|
48
48
|
var p = { x: 0, y: 0 };
|
|
49
49
|
var makeSourceNode = function (id, source, stage, strategies) {
|
|
50
50
|
if (strategies === void 0) { strategies = [texture2DStrategy(), namedAttributeStrategy('position')]; }
|
|
@@ -128,9 +128,9 @@ it('threngine shadertoy import', function () { return __awaiter(void 0, void 0,
|
|
|
128
128
|
var testImport, p;
|
|
129
129
|
return __generator(this, function (_a) {
|
|
130
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 =
|
|
132
|
-
importers.shadertoy.convertAst(p, 'fragment');
|
|
133
|
-
expect(generate(p)).toContain("\nprecision highp float;\nprecision highp int;\n\nuniform
|
|
131
|
+
p = parse(testImport);
|
|
132
|
+
importers.shadertoy.convertAst(p, { type: 'fragment' });
|
|
133
|
+
expect(generate(p)).toContain("\nprecision highp float;\nprecision highp int;\n\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
134
|
return [2 /*return*/];
|
|
135
135
|
});
|
|
136
136
|
}); });
|
|
@@ -15,7 +15,7 @@ var __read = (this && this.__read) || function (o, n) {
|
|
|
15
15
|
return ar;
|
|
16
16
|
};
|
|
17
17
|
import { expect, it } from 'vitest';
|
|
18
|
-
import {
|
|
18
|
+
import { parse } from '@shaderfrog/glsl-parser';
|
|
19
19
|
import { generate } from '@shaderfrog/glsl-parser';
|
|
20
20
|
import { applyStrategy, StrategyType } from '.';
|
|
21
21
|
import { makeExpression } from '../util/ast';
|
|
@@ -24,7 +24,7 @@ import { NodeType } from '../graph/graph-types';
|
|
|
24
24
|
import { mangleEntireProgram } from '../graph';
|
|
25
25
|
it('named attribute strategy`', function () {
|
|
26
26
|
var source = "\nin vec3 replaceThisAtrribute;\nvoid main() {\n vec2 y = replaceThisAtrribute;\n}\n";
|
|
27
|
-
var ast =
|
|
27
|
+
var ast = parse(source, { quiet: true });
|
|
28
28
|
var fillers = applyStrategy({
|
|
29
29
|
type: StrategyType.NAMED_ATTRIBUTE,
|
|
30
30
|
config: {
|
|
@@ -43,7 +43,7 @@ it('named attribute strategy`', function () {
|
|
|
43
43
|
});
|
|
44
44
|
it('inject strategy after', function () {
|
|
45
45
|
var source = "\nuniform float x;\n// Some comment\nvoid main() {\n/* some comment */\nre(x, y, z);\n// Middle comment\nre(x, y, z);\n// Final comment\n}";
|
|
46
|
-
var ast =
|
|
46
|
+
var ast = parse(source, { quiet: true });
|
|
47
47
|
var fillers = applyStrategy({
|
|
48
48
|
type: StrategyType.INJECT,
|
|
49
49
|
config: {
|
|
@@ -64,7 +64,7 @@ it('inject strategy after', function () {
|
|
|
64
64
|
});
|
|
65
65
|
it('inject strategy before', function () {
|
|
66
66
|
var source = "\nuniform float x;\n// Some comment\nvoid main() {\n/* some comment */\nre(x, y, z);\n// Middle comment\nre(x, y, z);\n// Final comment\n}";
|
|
67
|
-
var ast =
|
|
67
|
+
var ast = parse(source, { quiet: true });
|
|
68
68
|
var fillers = applyStrategy({
|
|
69
69
|
type: StrategyType.INJECT,
|
|
70
70
|
config: {
|
|
@@ -123,7 +123,7 @@ var engine = {
|
|
|
123
123
|
};
|
|
124
124
|
it('correctly fills with uniform strategy', function () {
|
|
125
125
|
var _a, _b, _c;
|
|
126
|
-
var ast =
|
|
126
|
+
var ast = parse("\nlayout(std140,column_major) uniform;\nuniform sampler2D image;\nuniform vec4 input, output, other;\nuniform vec4 zenput;\nuniform Light0 { vec4 y; } x;\nvec3 topLevel = vec3(0.0);\nvoid other(in vec3 param) {}\nvoid main() {\n vec4 computed = texture2D(image, uvPow * 1.0);\n vec4 x = input;\n vec4 y = output;\n vec4 z = zenput;\n}", { quiet: true });
|
|
127
127
|
var fillers = applyStrategy({ type: StrategyType.UNIFORM, config: {} }, ast, {});
|
|
128
128
|
// It should find uniforms with simple types, excluding sampler2D
|
|
129
129
|
expect(fillers.map(function (_a) {
|
|
@@ -170,7 +170,7 @@ it('correctly fills with uniform strategy', function () {
|
|
|
170
170
|
});
|
|
171
171
|
it('correctly fills with uniform strategy through mangling', function () {
|
|
172
172
|
var _a, _b, _c;
|
|
173
|
-
var ast =
|
|
173
|
+
var ast = parse("\nuniform sampler2D image;\nuniform vec4 input, output;\nvoid main() {\n vec4 computed = texture2D(image, uvPow * 1.0);\n vec4 x = input;\n vec4 y = output;\n}", { quiet: true });
|
|
174
174
|
var node = { id: '1', name: 'fake' };
|
|
175
175
|
var fillers = applyStrategy({ type: StrategyType.UNIFORM, config: {} }, ast, node);
|
|
176
176
|
mangleEntireProgram(engine, ast, node);
|
|
@@ -207,14 +207,14 @@ it('correctly fills with uniform strategy through mangling', function () {
|
|
|
207
207
|
expect(result).toContain("uniform sampler2D image_".concat(node.id, ";"));
|
|
208
208
|
});
|
|
209
209
|
it('uses name without suffix for single call', function () {
|
|
210
|
-
var ast =
|
|
210
|
+
var ast = parse("\nvoid main() {\n vec4 computed = texture2D(noiseImage, uvPow * 1.0);\n}", { quiet: true });
|
|
211
211
|
expect(applyStrategy({ type: StrategyType.TEXTURE_2D, config: {} }, ast, {}, {}).map(function (_a) {
|
|
212
212
|
var _b = __read(_a, 1), name = _b[0].displayName;
|
|
213
213
|
return name;
|
|
214
214
|
})).toEqual(['noiseImage']);
|
|
215
215
|
});
|
|
216
216
|
it('finds one texture2D input for one texture2D() call', function () {
|
|
217
|
-
var ast =
|
|
217
|
+
var ast = parse("\nvoid main() {\n vec4 computed = texture2D(noiseImage, uvPow * 1.0);\n computed += texture2D(noiseImage, uvPow * 2.0);\n}", { quiet: true });
|
|
218
218
|
expect(applyStrategy({ type: StrategyType.TEXTURE_2D, config: {} }, ast, {}, {}).map(function (_a) {
|
|
219
219
|
var _b = __read(_a, 1), name = _b[0].displayName;
|
|
220
220
|
return name;
|
|
@@ -229,7 +229,7 @@ it('Make sure texture2D finds preprocessed texture() call', function () {
|
|
|
229
229
|
version: function () { return true; },
|
|
230
230
|
},
|
|
231
231
|
});
|
|
232
|
-
var ast =
|
|
232
|
+
var ast = parse(pp, { quiet: true });
|
|
233
233
|
expect(applyStrategy({ type: StrategyType.TEXTURE_2D, config: {} }, ast, {}, {}).map(function (_a) {
|
|
234
234
|
var _b = __read(_a, 1), name = _b[0].displayName;
|
|
235
235
|
return name;
|
package/util/ast.js
CHANGED
|
@@ -37,7 +37,7 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
|
37
37
|
}
|
|
38
38
|
return to.concat(ar || Array.prototype.slice.call(from));
|
|
39
39
|
};
|
|
40
|
-
import {
|
|
40
|
+
import { parse, generate } from '@shaderfrog/glsl-parser';
|
|
41
41
|
import { visit, } from '@shaderfrog/glsl-parser/ast';
|
|
42
42
|
import { addFnStmtWithIndent } from './whitespace';
|
|
43
43
|
import { renameBinding } from '@shaderfrog/glsl-parser/parser/utils';
|
|
@@ -175,7 +175,7 @@ export var makeStatement = function (stmt, ws) {
|
|
|
175
175
|
// log(`Parsing "${stmt}"`);
|
|
176
176
|
var ast;
|
|
177
177
|
try {
|
|
178
|
-
ast =
|
|
178
|
+
ast = parse("".concat(stmt, ";").concat(ws, "\n"), { quiet: true });
|
|
179
179
|
}
|
|
180
180
|
catch (error) {
|
|
181
181
|
console.error({ stmt: stmt, error: error });
|
|
@@ -188,7 +188,7 @@ export var makeFnStatement = function (fnStmt) {
|
|
|
188
188
|
var ast;
|
|
189
189
|
try {
|
|
190
190
|
// Create a statement with no trailing nor leading whitespace
|
|
191
|
-
ast =
|
|
191
|
+
ast = parse("void main() {".concat(fnStmt, ";}"), { quiet: true });
|
|
192
192
|
}
|
|
193
193
|
catch (error) {
|
|
194
194
|
console.error({ fnStmt: fnStmt, error: error });
|
|
@@ -217,7 +217,7 @@ export var addNewScope = function (left, right) { return (__assign(__assign({},
|
|
|
217
217
|
export var makeExpression = function (expr) {
|
|
218
218
|
var ast;
|
|
219
219
|
try {
|
|
220
|
-
ast =
|
|
220
|
+
ast = parse("void main() {\n a = ".concat(expr, ";\n }"), { quiet: true });
|
|
221
221
|
}
|
|
222
222
|
catch (error) {
|
|
223
223
|
console.error({ expr: expr, error: error });
|
|
@@ -229,7 +229,7 @@ export var makeExpression = function (expr) {
|
|
|
229
229
|
export var makeExpressionWithScopes = function (expr) {
|
|
230
230
|
var ast;
|
|
231
231
|
try {
|
|
232
|
-
ast =
|
|
232
|
+
ast = parse("void main() {\n ".concat(expr, ";\n }"), { quiet: true });
|
|
233
233
|
}
|
|
234
234
|
catch (error) {
|
|
235
235
|
console.error({ expr: expr, error: error });
|
|
@@ -245,7 +245,7 @@ export var makeExpressionWithScopes = function (expr) {
|
|
|
245
245
|
export var makeFnBodyStatementWithScopes = function (body) {
|
|
246
246
|
var ast;
|
|
247
247
|
try {
|
|
248
|
-
ast =
|
|
248
|
+
ast = parse("void main() {\n".concat(body, "\n }"), { quiet: true });
|
|
249
249
|
}
|
|
250
250
|
catch (error) {
|
|
251
251
|
console.error({ body: body, error: error });
|
|
@@ -398,7 +398,7 @@ export var backfillAst = function (ast, fromType, targetVariable, mainFn) {
|
|
|
398
398
|
.filter(
|
|
399
399
|
// Watch out for the main(void){} case!
|
|
400
400
|
function (arg) { return arg.specifier.specifier.token !== 'void'; })
|
|
401
|
-
.concat(
|
|
401
|
+
.concat(parse("void x(".concat(fromType, " ").concat(targetVariable, ") {}"))
|
|
402
402
|
.program[0].prototype.parameters);
|
|
403
403
|
}
|
|
404
404
|
return ast;
|
package/util/ast.test.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { expect, it } from 'vitest';
|
|
2
|
-
import {
|
|
2
|
+
import { parse } from '@shaderfrog/glsl-parser';
|
|
3
3
|
import { generate } from '@shaderfrog/glsl-parser';
|
|
4
4
|
import { backfillAst, findMain } from '../util/ast';
|
|
5
5
|
it('backfillAst', function () {
|
|
6
|
-
var source =
|
|
6
|
+
var source = parse("\nattribute vec2 vUv, xx;\nvoid main() {\n gl_FragColor = vec4(vUv, xx);\n}");
|
|
7
7
|
var result = backfillAst(source, 'vec2', 'vUv', findMain(source));
|
|
8
8
|
expect(generate(result)).toBe("\nattribute vec2 vUv, xx;\nvoid main(vec2 vUv) {\n gl_FragColor = vec4(vUv, xx);\n}");
|
|
9
9
|
});
|
|
10
10
|
it('backfillAst with void main fn', function () {
|
|
11
|
-
var source =
|
|
11
|
+
var source = parse("\nattribute vec2 vUv;\nvoid main(void) {\n gl_FragColor = vec4(vUv, 1.0, 1.0);\n}");
|
|
12
12
|
var result = backfillAst(source, 'vec2', 'vUv', findMain(source));
|
|
13
13
|
expect(generate(result)).toBe("\nattribute vec2 vUv;\nvoid main(vec2 vUv) {\n gl_FragColor = vec4(vUv, 1.0, 1.0);\n}");
|
|
14
14
|
});
|
package/util/math.d.ts
ADDED
package/util/math.js
ADDED
package/util/whitespace.test.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { expect, it } from 'vitest';
|
|
2
|
-
import {
|
|
3
|
-
import { generate } from '@shaderfrog/glsl-parser';
|
|
2
|
+
import { parse, generate } from '@shaderfrog/glsl-parser';
|
|
4
3
|
import { addFnStmtWithIndent } from './whitespace';
|
|
5
4
|
import { findMainOrThrow } from './ast';
|
|
6
5
|
it("addFnStmtWithIndent", function () {
|
|
7
6
|
var source = "void main() {\n vec2 y;\n}\n";
|
|
8
|
-
var ast =
|
|
7
|
+
var ast = parse(source, { quiet: true });
|
|
9
8
|
var m = findMainOrThrow(ast);
|
|
10
9
|
m.body.statements = addFnStmtWithIndent(m, "return x");
|
|
11
10
|
// Should line up the whitespace properly!
|