@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.
Files changed (155) hide show
  1. package/cjs/package.json +1 -0
  2. package/esm/engine.d.ts +69 -0
  3. package/esm/engine.js +209 -0
  4. package/esm/graph/base-node.d.ts +36 -0
  5. package/esm/graph/base-node.js +9 -0
  6. package/esm/graph/code-nodes.d.ts +44 -0
  7. package/esm/graph/code-nodes.js +18 -0
  8. package/esm/graph/context.d.ts +37 -0
  9. package/esm/graph/context.js +243 -0
  10. package/esm/graph/data-nodes.d.ts +83 -0
  11. package/esm/graph/data-nodes.js +131 -0
  12. package/esm/graph/edge.d.ts +13 -0
  13. package/esm/graph/edge.js +7 -0
  14. package/esm/graph/evaluate.d.ts +9 -0
  15. package/esm/graph/evaluate.js +27 -0
  16. package/esm/graph/graph-node.d.ts +8 -0
  17. package/esm/graph/graph-node.js +135 -0
  18. package/esm/graph/graph-types.d.ts +38 -0
  19. package/esm/graph/graph-types.js +22 -0
  20. package/esm/graph/graph.d.ts +89 -0
  21. package/esm/graph/graph.js +506 -0
  22. package/esm/graph/graph.test.d.ts +1 -0
  23. package/esm/graph/graph.test.js +168 -0
  24. package/esm/graph/index.d.ts +11 -0
  25. package/esm/graph/index.js +11 -0
  26. package/esm/graph/parsers.d.ts +39 -0
  27. package/esm/graph/parsers.js +213 -0
  28. package/esm/graph/shader-sections.d.ts +47 -0
  29. package/esm/graph/shader-sections.js +256 -0
  30. package/esm/index.d.ts +3 -0
  31. package/esm/index.js +3 -0
  32. package/esm/package.json +1 -0
  33. package/esm/plugins/babylon/bablyengine.d.ts +28 -0
  34. package/esm/plugins/babylon/bablyengine.js +589 -0
  35. package/esm/plugins/babylon/importers.d.ts +3 -0
  36. package/esm/plugins/babylon/importers.js +64 -0
  37. package/esm/plugins/babylon/index.d.ts +2 -0
  38. package/esm/plugins/babylon/index.js +2 -0
  39. package/esm/plugins/playcanvas/importers.d.ts +3 -0
  40. package/esm/plugins/playcanvas/importers.js +28 -0
  41. package/esm/plugins/playcanvas/index.d.ts +2 -0
  42. package/esm/plugins/playcanvas/index.js +2 -0
  43. package/esm/plugins/playcanvas/playengine.d.ts +39 -0
  44. package/esm/plugins/playcanvas/playengine.js +517 -0
  45. package/esm/plugins/three/importers.d.ts +3 -0
  46. package/esm/plugins/three/importers.js +15 -0
  47. package/esm/plugins/three/index.d.ts +2 -0
  48. package/esm/plugins/three/index.js +2 -0
  49. package/esm/plugins/three/threngine.d.ts +34 -0
  50. package/esm/plugins/three/threngine.js +608 -0
  51. package/esm/strategy/assignemntTo.d.ts +9 -0
  52. package/esm/strategy/assignemntTo.js +26 -0
  53. package/esm/strategy/declarationOf.d.ts +9 -0
  54. package/esm/strategy/declarationOf.js +23 -0
  55. package/esm/strategy/hardCode.d.ts +15 -0
  56. package/esm/strategy/hardCode.js +23 -0
  57. package/esm/strategy/index.d.ts +9 -0
  58. package/esm/strategy/index.js +9 -0
  59. package/esm/strategy/inject.d.ts +15 -0
  60. package/esm/strategy/inject.js +122 -0
  61. package/esm/strategy/namedAttribute.d.ts +9 -0
  62. package/esm/strategy/namedAttribute.js +48 -0
  63. package/esm/strategy/strategy.d.ts +28 -0
  64. package/esm/strategy/strategy.js +31 -0
  65. package/esm/strategy/stratgies.test.d.ts +1 -0
  66. package/esm/strategy/stratgies.test.js +164 -0
  67. package/esm/strategy/texture2D.d.ts +6 -0
  68. package/esm/strategy/texture2D.js +83 -0
  69. package/esm/strategy/uniform.d.ts +6 -0
  70. package/esm/strategy/uniform.js +190 -0
  71. package/esm/strategy/variable.d.ts +6 -0
  72. package/esm/strategy/variable.js +80 -0
  73. package/esm/util/ast.d.ts +30 -0
  74. package/esm/util/ast.js +332 -0
  75. package/esm/util/ensure.d.ts +1 -0
  76. package/esm/util/ensure.js +7 -0
  77. package/esm/util/id.d.ts +1 -0
  78. package/esm/util/id.js +2 -0
  79. package/package.json +9 -11
  80. /package/{engine.d.ts → cjs/engine.d.ts} +0 -0
  81. /package/{engine.js → cjs/engine.js} +0 -0
  82. /package/{graph → cjs/graph}/base-node.d.ts +0 -0
  83. /package/{graph → cjs/graph}/base-node.js +0 -0
  84. /package/{graph → cjs/graph}/code-nodes.d.ts +0 -0
  85. /package/{graph → cjs/graph}/code-nodes.js +0 -0
  86. /package/{graph → cjs/graph}/context.d.ts +0 -0
  87. /package/{graph → cjs/graph}/context.js +0 -0
  88. /package/{graph → cjs/graph}/data-nodes.d.ts +0 -0
  89. /package/{graph → cjs/graph}/data-nodes.js +0 -0
  90. /package/{graph → cjs/graph}/edge.d.ts +0 -0
  91. /package/{graph → cjs/graph}/edge.js +0 -0
  92. /package/{graph → cjs/graph}/evaluate.d.ts +0 -0
  93. /package/{graph → cjs/graph}/evaluate.js +0 -0
  94. /package/{graph → cjs/graph}/graph-node.d.ts +0 -0
  95. /package/{graph → cjs/graph}/graph-node.js +0 -0
  96. /package/{graph → cjs/graph}/graph-types.d.ts +0 -0
  97. /package/{graph → cjs/graph}/graph-types.js +0 -0
  98. /package/{graph → cjs/graph}/graph.d.ts +0 -0
  99. /package/{graph → cjs/graph}/graph.js +0 -0
  100. /package/{graph → cjs/graph}/graph.test.d.ts +0 -0
  101. /package/{graph → cjs/graph}/graph.test.js +0 -0
  102. /package/{graph → cjs/graph}/index.d.ts +0 -0
  103. /package/{graph → cjs/graph}/index.js +0 -0
  104. /package/{graph → cjs/graph}/parsers.d.ts +0 -0
  105. /package/{graph → cjs/graph}/parsers.js +0 -0
  106. /package/{graph → cjs/graph}/shader-sections.d.ts +0 -0
  107. /package/{graph → cjs/graph}/shader-sections.js +0 -0
  108. /package/{index.d.ts → cjs/index.d.ts} +0 -0
  109. /package/{index.js → cjs/index.js} +0 -0
  110. /package/{plugins → cjs/plugins}/babylon/bablyengine.d.ts +0 -0
  111. /package/{plugins → cjs/plugins}/babylon/bablyengine.js +0 -0
  112. /package/{plugins → cjs/plugins}/babylon/importers.d.ts +0 -0
  113. /package/{plugins → cjs/plugins}/babylon/importers.js +0 -0
  114. /package/{plugins → cjs/plugins}/babylon/index.d.ts +0 -0
  115. /package/{plugins → cjs/plugins}/babylon/index.js +0 -0
  116. /package/{plugins → cjs/plugins}/playcanvas/importers.d.ts +0 -0
  117. /package/{plugins → cjs/plugins}/playcanvas/importers.js +0 -0
  118. /package/{plugins → cjs/plugins}/playcanvas/index.d.ts +0 -0
  119. /package/{plugins → cjs/plugins}/playcanvas/index.js +0 -0
  120. /package/{plugins → cjs/plugins}/playcanvas/playengine.d.ts +0 -0
  121. /package/{plugins → cjs/plugins}/playcanvas/playengine.js +0 -0
  122. /package/{plugins → cjs/plugins}/three/importers.d.ts +0 -0
  123. /package/{plugins → cjs/plugins}/three/importers.js +0 -0
  124. /package/{plugins → cjs/plugins}/three/index.d.ts +0 -0
  125. /package/{plugins → cjs/plugins}/three/index.js +0 -0
  126. /package/{plugins → cjs/plugins}/three/threngine.d.ts +0 -0
  127. /package/{plugins → cjs/plugins}/three/threngine.js +0 -0
  128. /package/{strategy → cjs/strategy}/assignemntTo.d.ts +0 -0
  129. /package/{strategy → cjs/strategy}/assignemntTo.js +0 -0
  130. /package/{strategy → cjs/strategy}/declarationOf.d.ts +0 -0
  131. /package/{strategy → cjs/strategy}/declarationOf.js +0 -0
  132. /package/{strategy → cjs/strategy}/hardCode.d.ts +0 -0
  133. /package/{strategy → cjs/strategy}/hardCode.js +0 -0
  134. /package/{strategy → cjs/strategy}/index.d.ts +0 -0
  135. /package/{strategy → cjs/strategy}/index.js +0 -0
  136. /package/{strategy → cjs/strategy}/inject.d.ts +0 -0
  137. /package/{strategy → cjs/strategy}/inject.js +0 -0
  138. /package/{strategy → cjs/strategy}/namedAttribute.d.ts +0 -0
  139. /package/{strategy → cjs/strategy}/namedAttribute.js +0 -0
  140. /package/{strategy → cjs/strategy}/strategy.d.ts +0 -0
  141. /package/{strategy → cjs/strategy}/strategy.js +0 -0
  142. /package/{strategy → cjs/strategy}/stratgies.test.d.ts +0 -0
  143. /package/{strategy → cjs/strategy}/stratgies.test.js +0 -0
  144. /package/{strategy → cjs/strategy}/texture2D.d.ts +0 -0
  145. /package/{strategy → cjs/strategy}/texture2D.js +0 -0
  146. /package/{strategy → cjs/strategy}/uniform.d.ts +0 -0
  147. /package/{strategy → cjs/strategy}/uniform.js +0 -0
  148. /package/{strategy → cjs/strategy}/variable.d.ts +0 -0
  149. /package/{strategy → cjs/strategy}/variable.js +0 -0
  150. /package/{util → cjs/util}/ast.d.ts +0 -0
  151. /package/{util → cjs/util}/ast.js +0 -0
  152. /package/{util → cjs/util}/ensure.d.ts +0 -0
  153. /package/{util → cjs/util}/ensure.js +0 -0
  154. /package/{util → cjs/util}/id.d.ts +0 -0
  155. /package/{util → cjs/util}/id.js +0 -0
@@ -0,0 +1,608 @@
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
+ var _a, _b;
74
+ import { ShaderLib, RawShaderMaterial, Vector2, Vector3, Vector4, Color, GLSL3, Light, Texture, MeshPhongMaterial, MeshPhysicalMaterial, MeshToonMaterial, } from 'three';
75
+ import { NodeType } from '../../graph/graph-types';
76
+ import { prepopulatePropertyInputs, mangleMainFn } from '../../graph/graph';
77
+ import importers from './importers';
78
+ import { EngineNodeType } from '../../engine';
79
+ import { doesLinkThruShader, nodeName } from '../../graph/graph';
80
+ import { returnGlPosition, returnGlPositionHardCoded, returnGlPositionVec3Right, } from '../../util/ast';
81
+ import { property, } from '../../graph/code-nodes';
82
+ import { namedAttributeStrategy, texture2DStrategy, uniformStrategy, } from '../../strategy';
83
+ var log = function () {
84
+ var _a;
85
+ var args = [];
86
+ for (var _i = 0; _i < arguments.length; _i++) {
87
+ args[_i] = arguments[_i];
88
+ }
89
+ return (_a = console.log).call.apply(_a, __spreadArray([console, '\x1b[35m(three)\x1b[0m'], __read(args), false));
90
+ };
91
+ export var phongNode = function (id, name, position, uniforms, stage) {
92
+ return prepopulatePropertyInputs({
93
+ id: id,
94
+ name: 'MeshPhongMaterial',
95
+ position: position,
96
+ engine: true,
97
+ type: EngineNodeType.phong,
98
+ config: {
99
+ version: 3,
100
+ uniforms: uniforms,
101
+ preprocess: true,
102
+ mangle: false,
103
+ properties: [
104
+ property('Color', 'color', 'rgb', 'uniform_diffuse'),
105
+ property('Emissive', 'emissive', 'rgb', 'uniform_emissive'),
106
+ property('Emissive Map', 'emissiveMap', 'texture', 'filler_emissiveMap'),
107
+ property('Emissive Intensity', 'emissiveIntensity', 'number', 'uniform_emissive'),
108
+ property('Texture', 'map', 'texture', 'filler_map'),
109
+ property('Normal Map', 'normalMap', 'texture', 'filler_normalMap'),
110
+ property('Normal Scale', 'normalScale', 'vector2'),
111
+ property('AO Map', 'aoMap', 'texture', 'filler_aoMap'),
112
+ property('AO Intensity', 'aoMapIntensity', 'number', 'filler_aoMapIntensity'),
113
+ property('Shininess', 'shininess', 'number'),
114
+ property('Reflectivity', 'reflectivity', 'number'),
115
+ property('Refraction Ratio', 'refractionRatio', 'number'),
116
+ property('Specular', 'specular', 'rgb', 'uniform_specular'),
117
+ property('Specular Map', 'specularMap', 'texture', 'filler_specularMap'),
118
+ property('Displacement Map', 'displacementMap', 'texture', 'filler_displacementMap'),
119
+ property('Displacement Scale', 'displacementScale', 'number'),
120
+ property('Env Map', 'envMap', 'samplerCube'),
121
+ ],
122
+ strategies: [
123
+ uniformStrategy(),
124
+ stage === 'fragment'
125
+ ? texture2DStrategy()
126
+ : namedAttributeStrategy('position'),
127
+ ],
128
+ },
129
+ inputs: [],
130
+ outputs: [
131
+ {
132
+ name: 'vector4',
133
+ dataType: 'vector4',
134
+ category: 'data',
135
+ id: '1',
136
+ },
137
+ ],
138
+ source: '',
139
+ stage: stage,
140
+ });
141
+ };
142
+ export var physicalNode = function (id, name, position, uniforms, stage) {
143
+ return prepopulatePropertyInputs({
144
+ id: id,
145
+ name: 'MeshPhysicalMaterial',
146
+ position: position,
147
+ engine: true,
148
+ type: EngineNodeType.physical,
149
+ config: {
150
+ uniforms: uniforms,
151
+ version: 3,
152
+ mangle: false,
153
+ preprocess: true,
154
+ properties: [
155
+ property('Color', 'color', 'rgb', 'uniform_diffuse'),
156
+ property('Texture', 'map', 'texture', 'filler_map'),
157
+ property('Opacity', 'opacity', 'number'),
158
+ property('Normal Map', 'normalMap', 'texture', 'filler_normalMap'),
159
+ property('Normal Scale', 'normalScale', 'vector2'),
160
+ property('AO Map', 'aoMap', 'texture', 'filler_aoMap'),
161
+ property('AO Intensity', 'aoMapIntensity', 'number', 'filler_aoMapIntensity'),
162
+ property('Metalness', 'metalness', 'number', 'uniform_metalness'),
163
+ property('Roughness', 'roughness', 'number', 'uniform_roughness'),
164
+ property('Roughness Map', 'roughnessMap', 'texture', 'filler_roughnessMap'),
165
+ property('Displacement Map', 'displacementMap', 'texture', 'filler_displacementMap'),
166
+ property('Displacement Scale', 'displacementScale', 'number'),
167
+ // MeshPhysicalMaterial gets envMap from the scene. MeshStandardMaterial
168
+ // gets it from the material
169
+ // property('Env Map', 'envMap', 'samplerCube'),
170
+ property('Transmission', 'transmission', 'number'),
171
+ property('Transmission Map', 'transmissionMap', 'texture', 'filler_transmissionMap'),
172
+ property('Thickness', 'thickness', 'number'),
173
+ property('Index of Refraction', 'ior', 'number'),
174
+ // Sheen only works with directional lights?
175
+ // https://discourse.threejs.org/t/meshphysicalmaterial-s-sheen/31901/6
176
+ // property('Sheen', 'sheen', 'number'),
177
+ property('Reflectivity', 'reflectivity', 'number'),
178
+ property('Clearcoat', 'clearcoat', 'number'),
179
+ property('Iridescence', 'iridescence', 'number'),
180
+ property('Iridescence IOR', 'iridescenceIOR', 'number'),
181
+ property('Iridescence Thickness Range', 'iridescenceThicknessRange', 'array', undefined, ['100', '400']),
182
+ ],
183
+ hardCodedProperties: {
184
+ isMeshPhysicalMaterial: true,
185
+ isMeshStandardMaterial: true,
186
+ },
187
+ strategies: [
188
+ uniformStrategy(),
189
+ stage === 'fragment'
190
+ ? texture2DStrategy()
191
+ : namedAttributeStrategy('position'),
192
+ ],
193
+ },
194
+ inputs: [],
195
+ outputs: [
196
+ {
197
+ name: 'vector4',
198
+ dataType: 'vector4',
199
+ category: 'data',
200
+ id: '1',
201
+ },
202
+ ],
203
+ source: '',
204
+ stage: stage,
205
+ });
206
+ };
207
+ var cacher = function (engineContext, graph, node, sibling, newValue) {
208
+ var cacheKey = programCacheKey(engineContext, graph, node, sibling);
209
+ if (engineContext.runtime.cache.data[cacheKey]) {
210
+ log('Cache hit', cacheKey);
211
+ }
212
+ else {
213
+ log('Cache miss', cacheKey);
214
+ }
215
+ var materialData = engineContext.runtime.cache.data[cacheKey] || newValue();
216
+ engineContext.runtime.cache.data[cacheKey] = materialData;
217
+ engineContext.runtime.engineMaterial = materialData.material;
218
+ // TODO: We mutate the nodes here, can we avoid that later?
219
+ node.source =
220
+ node.stage === 'fragment' ? materialData.fragment : materialData.vertex;
221
+ if (sibling) {
222
+ sibling.source =
223
+ sibling.stage === 'fragment'
224
+ ? materialData.fragment
225
+ : materialData.vertex;
226
+ }
227
+ };
228
+ var onBeforeCompileMegaShader = function (engineContext, newMat) {
229
+ log('compiling three megashader!');
230
+ var _a = engineContext.runtime, renderer = _a.renderer, sceneData = _a.sceneData, scene = _a.scene, camera = _a.camera;
231
+ var mesh = sceneData.mesh;
232
+ // Temporarily swap the mesh material to the new one, since materials can
233
+ // be mesh specific, render, then get its source code
234
+ var originalMaterial = mesh.material;
235
+ mesh.material = newMat;
236
+ renderer.compile(scene, camera);
237
+ // The references to the compiled shaders in WebGL
238
+ var fragmentRef = renderer.properties
239
+ .get(mesh.material)
240
+ .programs.values()
241
+ .next().value.fragmentShader;
242
+ var vertexRef = renderer.properties
243
+ .get(mesh.material)
244
+ .programs.values()
245
+ .next().value.vertexShader;
246
+ var gl = renderer.getContext();
247
+ var fragment = gl.getShaderSource(fragmentRef);
248
+ var vertex = gl.getShaderSource(vertexRef);
249
+ // Reset the material on the mesh, since the shader we're computing context
250
+ // for might not be the one actually want on the mesh - like if a toon node
251
+ // was added to the graph but not connected
252
+ mesh.material = originalMaterial;
253
+ // Do we even need to do this? This is just for debugging right? Using the
254
+ // source on the node is the important thing.
255
+ return {
256
+ material: newMat,
257
+ fragmentRef: fragmentRef,
258
+ vertexRef: vertexRef,
259
+ fragment: fragment,
260
+ vertex: vertex,
261
+ };
262
+ };
263
+ var megaShaderMainpulateAst = function (engineContext, engine, graph, ast, inputEdges, node, sibling) {
264
+ var programAst = ast;
265
+ var mainName = 'main' || nodeName(node);
266
+ if (node.stage === 'vertex') {
267
+ if (doesLinkThruShader(graph, node)) {
268
+ returnGlPositionHardCoded(mainName, programAst, 'vec3', 'transformed');
269
+ }
270
+ else {
271
+ returnGlPosition(mainName, programAst);
272
+ }
273
+ }
274
+ // We specify engine nodes are mangle: false, which is the graph step that
275
+ // handles renaming the main fn, so we have to do it ourselves
276
+ mangleMainFn(programAst, node, sibling);
277
+ return programAst;
278
+ };
279
+ var nodeCacheKey = function (graph, node) {
280
+ return ('[ID:' +
281
+ node.id +
282
+ 'Edges:' +
283
+ graph.edges
284
+ .filter(function (edge) { return edge.to === node.id; })
285
+ .map(function (edge) { return "(".concat(edge.to, "->").concat(edge.input, ")"); })
286
+ .sort()
287
+ .join(',') +
288
+ ']'
289
+ // Currently excluding node inputs because these are calculated *after*
290
+ // the onbeforecompile, so the next compile, they'll all change!
291
+ // node.inputs.map((i) => `${i.id}${i.bakeable}`)
292
+ );
293
+ };
294
+ var programCacheKey = function (engineContext, graph, node, sibling) {
295
+ // The megashader source is dependent on scene information, like the number
296
+ // and type of lights in the scene. This kinda sucks - it's duplicating
297
+ // three's material cache key, and is coupled to how three builds shaders
298
+ var scene = engineContext.runtime.scene;
299
+ var lights = [];
300
+ scene.traverse(function (obj) {
301
+ if (obj instanceof Light) {
302
+ lights.push(obj.type);
303
+ }
304
+ });
305
+ return ([node, sibling]
306
+ .filter(function (n) { return !!n; })
307
+ .sort(function (a, b) { return a.id.localeCompare(b.id); })
308
+ .map(function (n) { return nodeCacheKey(graph, n); })
309
+ .join('-') +
310
+ '|Lights:' +
311
+ lights.join(',') +
312
+ '|Envtex:' +
313
+ scene.environmentTexture);
314
+ };
315
+ export var defaultPropertySetting = function (property) {
316
+ if (property.type === 'texture') {
317
+ return new Texture();
318
+ }
319
+ else if (property.type === 'number') {
320
+ return 0.5;
321
+ }
322
+ else if (property.type === 'rgb') {
323
+ return new Color(1, 1, 1);
324
+ }
325
+ else if (property.type === 'rgba') {
326
+ return new Vector4(1, 1, 1, 1);
327
+ }
328
+ };
329
+ var threeMaterialProperties = function (graph, node, sibling) {
330
+ // 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
+ }, {});
337
+ // Then look for any edges into those inputs and set the material property
338
+ return graph.edges
339
+ .filter(function (edge) { return edge.to === node.id || edge.to === (sibling === null || sibling === void 0 ? void 0 : sibling.id); })
340
+ .reduce(function (acc, edge) {
341
+ // Check if we've plugged into an input for a property
342
+ var propertyInput = propertyInputs[edge.input];
343
+ if (propertyInput) {
344
+ // Find the property itself
345
+ var property_1 = (node.config.properties || []).find(function (p) { return p.property === propertyInput.property; });
346
+ // Initialize the property on the material
347
+ acc[property_1.property] = defaultPropertySetting(property_1);
348
+ }
349
+ return acc;
350
+ }, {});
351
+ };
352
+ var evaluateNode = function (node) {
353
+ if (node.type === 'number') {
354
+ return parseFloat(node.value);
355
+ }
356
+ if (node.type === 'vector2') {
357
+ return new Vector2(parseFloat(node.value[0]), parseFloat(node.value[1]));
358
+ }
359
+ else if (node.type === 'vector3') {
360
+ return new Vector3(parseFloat(node.value[0]), parseFloat(node.value[1]), parseFloat(node.value[2]));
361
+ }
362
+ else if (node.type === 'vector4') {
363
+ return new Vector4(parseFloat(node.value[0]), parseFloat(node.value[1]), parseFloat(node.value[2]), parseFloat(node.value[3]));
364
+ }
365
+ else if (node.type === 'rgb') {
366
+ return new Color(parseFloat(node.value[0]), parseFloat(node.value[1]), parseFloat(node.value[2]));
367
+ }
368
+ else if (node.type === 'rgba') {
369
+ return new Vector4(parseFloat(node.value[0]), parseFloat(node.value[1]), parseFloat(node.value[2]), parseFloat(node.value[3]));
370
+ }
371
+ else {
372
+ return node.value;
373
+ }
374
+ };
375
+ export var toonNode = function (id, name, position, uniforms, stage) {
376
+ return prepopulatePropertyInputs({
377
+ id: id,
378
+ name: 'MeshToonMaterial',
379
+ position: position,
380
+ engine: true,
381
+ type: EngineNodeType.toon,
382
+ config: {
383
+ uniforms: uniforms,
384
+ version: 3,
385
+ preprocess: true,
386
+ mangle: false,
387
+ properties: [
388
+ property('Color', 'color', 'rgb', 'uniform_diffuse'),
389
+ property('Texture', 'map', 'texture', 'filler_map'),
390
+ property('Gradient Map', 'gradientMap', 'texture', 'filler_gradientMap'),
391
+ property('Normal Map', 'normalMap', 'texture', 'filler_normalMap'),
392
+ property('Normal Scale', 'normalScale', 'vector2'),
393
+ property('AO Map', 'aoMap', 'texture', 'filler_aoMap'),
394
+ property('AO Intensity', 'aoMapIntensity', 'number', 'filler_aoMapIntensity'),
395
+ property('Displacement Map', 'displacementMap', 'texture', 'filler_displacementMap'),
396
+ property('Displacement Scale', 'displacementScale', 'number'),
397
+ property('Env Map', 'envMap', 'samplerCube'),
398
+ ],
399
+ strategies: [
400
+ uniformStrategy(),
401
+ stage === 'fragment'
402
+ ? texture2DStrategy()
403
+ : namedAttributeStrategy('position'),
404
+ ],
405
+ },
406
+ inputs: [],
407
+ outputs: [
408
+ {
409
+ name: 'vector4',
410
+ dataType: 'vector4',
411
+ category: 'data',
412
+ id: '1',
413
+ },
414
+ ],
415
+ source: '',
416
+ stage: stage,
417
+ });
418
+ };
419
+ export var threngine = {
420
+ name: 'three',
421
+ displayName: 'Three.js',
422
+ importers: importers,
423
+ mergeOptions: {
424
+ includePrecisions: true,
425
+ includeVersion: true,
426
+ },
427
+ evaluateNode: evaluateNode,
428
+ constructors: (_a = {},
429
+ _a[EngineNodeType.phong] = phongNode,
430
+ _a[EngineNodeType.physical] = physicalNode,
431
+ _a[EngineNodeType.toon] = toonNode,
432
+ _a),
433
+ // TODO: Get from uniform lib?
434
+ preserve: new Set([
435
+ 'viewMatrix',
436
+ 'modelMatrix',
437
+ 'modelViewMatrix',
438
+ 'projectionMatrix',
439
+ 'normalMatrix',
440
+ 'uvTransform',
441
+ // Attributes
442
+ 'position',
443
+ 'normal',
444
+ 'uv',
445
+ 'uv2',
446
+ 'tangent',
447
+ // Varyings
448
+ 'vUv',
449
+ 'vUv2',
450
+ 'vViewPosition',
451
+ 'vNormal',
452
+ 'vPosition',
453
+ // Uniforms
454
+ 'cameraPosition',
455
+ 'isOrthographic',
456
+ 'diffuse',
457
+ 'emissive',
458
+ 'specular',
459
+ 'shininess',
460
+ 'opacity',
461
+ 'map',
462
+ 'specularTint',
463
+ 'time',
464
+ 'normalScale',
465
+ 'normalMap',
466
+ 'envMap',
467
+ 'envMapIntensity',
468
+ 'flipEnvMap',
469
+ 'maxMipLevel',
470
+ 'roughnessMap',
471
+ // Uniforms for lighting
472
+ 'receiveShadow',
473
+ 'ambientLightColor',
474
+ 'lightProbe',
475
+ // Light uniform arrays
476
+ 'spotLights',
477
+ 'pointLights',
478
+ // This isn't three wtf
479
+ 'resolution',
480
+ 'color',
481
+ 'image',
482
+ 'gradientMap',
483
+ // TODO: This isn't specific to threejs as an engine, it's specific to the
484
+ // phong shader. If a *shader* node has brightness, it should be unique, not
485
+ // use the threejs one!
486
+ 'brightness',
487
+ // TODO: These depend on the shaderlib, this might need to be a runtime
488
+ // concern
489
+ // Metalness
490
+ 'roughness',
491
+ 'metalness',
492
+ 'ior',
493
+ 'specularIntensity',
494
+ 'clearcoat',
495
+ 'clearcoatRoughness',
496
+ 'transmission',
497
+ 'thickness',
498
+ 'attenuationDistance',
499
+ 'attenuationTint',
500
+ 'transmissionSamplerMap',
501
+ 'transmissionSamplerSize',
502
+ 'displacementMap',
503
+ 'displacementScale',
504
+ 'displacementBias',
505
+ ]),
506
+ parsers: (_b = {},
507
+ _b[NodeType.SOURCE] = {
508
+ manipulateAst: function (engineContext, engine, graph, ast, inputEdges, node, sibling) {
509
+ var programAst = ast;
510
+ var mainName = 'main' || nodeName(node);
511
+ // This hinges on the vertex shader calling vec3(p)
512
+ if (node.stage === 'vertex') {
513
+ if (doesLinkThruShader(graph, node)) {
514
+ returnGlPositionVec3Right(mainName, programAst);
515
+ }
516
+ else {
517
+ returnGlPosition(mainName, programAst);
518
+ }
519
+ }
520
+ return ast;
521
+ },
522
+ },
523
+ _b[EngineNodeType.phong] = {
524
+ onBeforeCompile: function (graph, engineContext, node, sibling) { return __awaiter(void 0, void 0, void 0, function () {
525
+ return __generator(this, function (_a) {
526
+ cacher(engineContext, graph, node, sibling, function () {
527
+ return onBeforeCompileMegaShader(engineContext, new MeshPhongMaterial(__assign({
528
+ // @ts-ignore
529
+ isMeshPhongMaterial: true }, threeMaterialProperties(graph, node, sibling))));
530
+ });
531
+ return [2 /*return*/];
532
+ });
533
+ }); },
534
+ manipulateAst: megaShaderMainpulateAst,
535
+ },
536
+ _b[EngineNodeType.physical] = {
537
+ onBeforeCompile: function (graph, engineContext, node, sibling) { return __awaiter(void 0, void 0, void 0, function () {
538
+ return __generator(this, function (_a) {
539
+ cacher(engineContext, graph, node, sibling, function () {
540
+ return onBeforeCompileMegaShader(engineContext, new MeshPhysicalMaterial(__assign(__assign({}, node.config.hardCodedProperties), threeMaterialProperties(graph, node, sibling))));
541
+ });
542
+ return [2 /*return*/];
543
+ });
544
+ }); },
545
+ manipulateAst: megaShaderMainpulateAst,
546
+ },
547
+ _b[EngineNodeType.toon] = {
548
+ onBeforeCompile: function (graph, engineContext, node, sibling) { return __awaiter(void 0, void 0, void 0, function () {
549
+ return __generator(this, function (_a) {
550
+ cacher(engineContext, graph, node, sibling, function () {
551
+ return onBeforeCompileMegaShader(engineContext, new MeshToonMaterial(__assign({ gradientMap: new Texture(),
552
+ // @ts-ignore
553
+ isMeshToonMaterial: true }, threeMaterialProperties(graph, node, sibling))));
554
+ });
555
+ return [2 /*return*/];
556
+ });
557
+ }); },
558
+ manipulateAst: megaShaderMainpulateAst,
559
+ },
560
+ _b),
561
+ };
562
+ export var createMaterial = function (compileResult, ctx) {
563
+ 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) } });
565
+ // Also the ThreeComponent's sceneConfig properties modify the material
566
+ var initialProperties = {
567
+ name: 'ShaderFrog Material',
568
+ lights: true,
569
+ uniforms: __assign({}, finalUniforms),
570
+ // See https://github.com/mrdoob/three.js/pull/26809
571
+ glslVersion: GLSL3,
572
+ vertexShader: compileResult === null || compileResult === void 0 ? void 0 : compileResult.vertexResult.replace('#version 300 es', ''),
573
+ fragmentShader: compileResult === null || compileResult === void 0 ? void 0 : compileResult.fragmentResult.replace('#version 300 es', ''),
574
+ };
575
+ var additionalProperties = Object.entries(__assign({}, engineMaterial))
576
+ .filter(function (_a) {
577
+ var _b = __read(_a, 1), property = _b[0];
578
+ // Ignore three material "hidden" properties
579
+ return property.charAt(0) !== '_' &&
580
+ // Ignore uuid since it should probably be unique?
581
+ property !== 'uuid' &&
582
+ // I'm not sure what three does with type under the hood, ignore it
583
+ property !== 'type' &&
584
+ // "precision" adds a precision preprocessor line
585
+ property !== 'precision' &&
586
+ // Ignore existing properties
587
+ !(property in initialProperties) &&
588
+ // Ignore STANDARD and PHYSICAL defines to the top of the shader in
589
+ // WebGLProgram
590
+ // https://github.com/mrdoob/three.js/blob/e7042de7c1a2c70e38654a04b6fd97d9c978e781/src/renderers/webgl/WebGLProgram.js#L392
591
+ // which occurs if we set isMeshPhysicalMaterial/isMeshStandardMaterial
592
+ property !== 'defines';
593
+ })
594
+ .reduce(function (acc, _a) {
595
+ var _b;
596
+ var _c = __read(_a, 2), key = _c[0], value = _c[1];
597
+ return (__assign(__assign({}, acc), (_b = {}, _b[key] = value, _b)));
598
+ }, {});
599
+ var material = new RawShaderMaterial(initialProperties);
600
+ // This prevents a deluge of warnings from three on the constructor saying
601
+ // that each of these properties is not a property of the material
602
+ Object.entries(additionalProperties).forEach(function (_a) {
603
+ var _b = __read(_a, 2), key = _b[0], value = _b[1];
604
+ // @ts-ignore
605
+ material[key] = value;
606
+ });
607
+ return material;
608
+ };
@@ -0,0 +1,9 @@
1
+ import { BaseStrategy, ApplyStrategy, StrategyType } from '.';
2
+ export interface AssignemntToStrategy extends BaseStrategy {
3
+ type: StrategyType.ASSIGNMENT_TO;
4
+ config: {
5
+ assignTo: string;
6
+ };
7
+ }
8
+ export declare const assignemntToStrategy: (assignTo: string) => AssignemntToStrategy;
9
+ export declare const applyAssignmentToStrategy: ApplyStrategy<AssignemntToStrategy>;
@@ -0,0 +1,26 @@
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) { return ({
6
+ type: StrategyType.ASSIGNMENT_TO,
7
+ config: { assignTo: assignTo },
8
+ }); };
9
+ // Apply the strategy
10
+ export var applyAssignmentToStrategy = function (strategy, ast, graphNode, siblingNode) {
11
+ var assignNode = findAssignmentTo(ast, strategy.config.assignTo);
12
+ var name = strategy.config.assignTo;
13
+ return assignNode
14
+ ? [
15
+ [
16
+ nodeInput(name, "filler_".concat(name), 'filler', undefined, // Data type for what plugs into this filler
17
+ ['code', 'data'], false),
18
+ function (fillerAst) {
19
+ assignNode.expression.right =
20
+ fillerAst;
21
+ return ast;
22
+ },
23
+ ],
24
+ ]
25
+ : [];
26
+ };
@@ -0,0 +1,9 @@
1
+ import { BaseStrategy, ApplyStrategy, StrategyType } from '.';
2
+ export declare const declarationOfStrategy: (declarationOf: string) => DeclarationOfStrategy;
3
+ export interface DeclarationOfStrategy extends BaseStrategy {
4
+ type: StrategyType.DECLARATION_OF;
5
+ config: {
6
+ declarationOf: string;
7
+ };
8
+ }
9
+ export declare const constApplyDeclarationOf: ApplyStrategy<DeclarationOfStrategy>;
@@ -0,0 +1,23 @@
1
+ import { findDeclarationOf } from '../util/ast';
2
+ import { nodeInput } from '../graph/base-node';
3
+ import { StrategyType } from '.';
4
+ export var declarationOfStrategy = function (declarationOf) { return ({
5
+ type: StrategyType.DECLARATION_OF,
6
+ config: { declarationOf: declarationOf },
7
+ }); };
8
+ export var constApplyDeclarationOf = function (strategy, ast, graphNode, siblingNode) {
9
+ var declaration = findDeclarationOf(ast, strategy.config.declarationOf);
10
+ var name = strategy.config.declarationOf;
11
+ return declaration
12
+ ? [
13
+ [
14
+ nodeInput(name, "filler_".concat(name), 'filler', undefined, // Data type for what plugs into this filler
15
+ ['code', 'data'], false),
16
+ function (fillerAst) {
17
+ declaration.initializer = fillerAst;
18
+ return ast;
19
+ },
20
+ ],
21
+ ]
22
+ : [];
23
+ };