@shaderfrog/core 0.0.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.
@@ -0,0 +1,512 @@
1
+ import { Graph } from '../../core/graph';
2
+ import {
3
+ colorNode,
4
+ DataNode,
5
+ numberNode,
6
+ numberUniformData,
7
+ textureNode,
8
+ vectorUniformData,
9
+ } from '../../core/nodes/data-nodes';
10
+ import { EdgeType, makeEdge } from '../../core/nodes/edge';
11
+ import { outputNode } from '../../core/nodes/engine-node';
12
+ import { fireFrag, fireVert } from '../../shaders/fireNode';
13
+ import {
14
+ heatShaderFragmentNode,
15
+ heatShaderVertexNode,
16
+ variation1 as heatmapV1,
17
+ } from '../../shaders/heatmapShaderNode';
18
+ import purpleNoiseNode from '../../shaders/purpleNoiseNode';
19
+ import staticShaderNode, { variation1 } from '../../shaders/staticShaderNode';
20
+ import { makeId } from '../../util/id';
21
+ import { checkerboardF, checkerboardV } from '../../shaders/checkboardNode';
22
+ import normalMapify from '../../shaders/normalmapifyNode';
23
+ import { convertNode, convertToEngine, Engine } from '../../core/engine';
24
+ import { babylengine } from '../../plugins/babylon/bablyengine';
25
+ import { CoreNode } from '../../core/nodes/core-node';
26
+ import { SourceNode } from '../../core/nodes/code-nodes';
27
+
28
+ export enum Example {
29
+ GLASS_FIREBALL = 'Glass Fireball',
30
+ // GEMSTONE = 'Gemstone',
31
+ LIVING_DIAMOND = 'Living Diamond',
32
+ // TOON = 'Toon',
33
+ DEFAULT = 'Mesh Physical Material',
34
+ }
35
+
36
+ const edgeFrom = (
37
+ fromNode: CoreNode,
38
+ toId: string,
39
+ input: string,
40
+ type?: EdgeType
41
+ ) => makeEdge(makeId(), fromNode.id, toId, outFrom(fromNode), input, type);
42
+
43
+ const outFrom = (node: CoreNode) => node.outputs[0].name;
44
+
45
+ const konvert = (node: SourceNode) =>
46
+ convertNode(node, babylengine.importers.three);
47
+
48
+ export const makeExampleGraph = (example: Example): [Graph, string, string] => {
49
+ console.log('🌈 Making new graph!!');
50
+ let newGraph: Graph;
51
+ let previewObject: string;
52
+ let bg: string = '';
53
+
54
+ // @ts-ignore
55
+ if (example === Example.GEMSTONE) {
56
+ const outputF = outputNode(
57
+ makeId(),
58
+ 'Output',
59
+ { x: 434, y: -97 },
60
+ 'fragment'
61
+ );
62
+ const outputV = outputNode(makeId(), 'Output', { x: 434, y: 20 }, 'vertex');
63
+
64
+ const physicalGroupId = makeId();
65
+ const physicalF = babylengine.constructors.physical(
66
+ makeId(),
67
+ 'Physical',
68
+ physicalGroupId,
69
+ { x: 178, y: -103 },
70
+ [],
71
+ 'fragment'
72
+ );
73
+ const physicalV = babylengine.constructors.physical(
74
+ makeId(),
75
+ 'Physical',
76
+ physicalGroupId,
77
+ { x: 434, y: 130 },
78
+ [],
79
+ 'vertex',
80
+ physicalF.id
81
+ );
82
+ const staticF = konvert(
83
+ staticShaderNode(makeId(), { x: -196, y: -303 }, variation1)
84
+ );
85
+ const heatmap = konvert(
86
+ heatShaderFragmentNode(makeId(), { x: -478, y: 12 }, heatmapV1)
87
+ );
88
+ const heatmapV = konvert(
89
+ heatShaderVertexNode(makeId(), heatmap.id, {
90
+ x: -478,
91
+ y: -194,
92
+ })
93
+ );
94
+
95
+ const normaled = normalMapify(makeId(), { x: -178, y: -149 });
96
+ const normalStrength = numberNode(
97
+ makeId(),
98
+ 'Normal Strength',
99
+ { x: -482, y: -105 },
100
+ '1..0'
101
+ );
102
+
103
+ const color = colorNode(makeId(), 'Color', { x: -187, y: -413 }, [
104
+ '1.0',
105
+ '0.75',
106
+ '1.0',
107
+ ]);
108
+ const roughness = numberNode(
109
+ makeId(),
110
+ 'Roughness',
111
+ { x: -187, y: 54 },
112
+ '0.37'
113
+ );
114
+ // const transmission = numberNode(
115
+ // makeId(),
116
+ // 'Transmission',
117
+ // { x: -187, y: 153 },
118
+ // '0.5'
119
+ // );
120
+ // const thickness = numberNode(
121
+ // makeId(),
122
+ // 'Thickness',
123
+ // { x: -187, y: 240 },
124
+ // '1.0'
125
+ // );
126
+ // const ior = numberNode(makeId(), 'Ior', { x: -187, y: 328 }, '2.0');
127
+
128
+ newGraph = {
129
+ nodes: [
130
+ color,
131
+ normaled,
132
+ normalStrength,
133
+ roughness,
134
+ // transmission,
135
+ // thickness,
136
+ // ior,
137
+ staticF,
138
+ heatmap,
139
+ heatmapV,
140
+ outputF,
141
+ outputV,
142
+ physicalF,
143
+ physicalV,
144
+ ],
145
+ edges: [
146
+ edgeFrom(physicalF, outputF.id, 'filler_frogFragOut', 'fragment'),
147
+ edgeFrom(physicalV, outputV.id, 'filler_gl_Position', 'vertex'),
148
+ edgeFrom(staticF, physicalF.id, 'property_albedoTexture', 'fragment'),
149
+ edgeFrom(color, physicalF.id, 'property_albedoColor', 'fragment'),
150
+ edgeFrom(roughness, physicalF.id, 'property_roughness', 'fragment'),
151
+
152
+ // edgeFrom(
153
+ // transmission,
154
+ // physicalF.id,
155
+ // 'property_transmission',
156
+ // 'fragment'
157
+ // ),
158
+ // edgeFrom(thickness, physicalF.id, 'property_thickness', 'fragment'),
159
+ // edgeFrom(ior, physicalF.id, 'property_ior', 'fragment'),
160
+ edgeFrom(
161
+ normalStrength,
162
+ normaled.id,
163
+ 'uniform_normal_strength',
164
+ 'fragment'
165
+ ),
166
+ edgeFrom(heatmap, normaled.id, 'filler_normal_map', 'fragment'),
167
+ edgeFrom(normaled, physicalF.id, 'property_bumpTexture', 'fragment'),
168
+ ],
169
+ };
170
+ previewObject = 'icosahedron';
171
+ bg = 'cityCourtYard';
172
+ // @ts-ignore
173
+ } else if (example === Example.TOON) {
174
+ const outputF = outputNode(
175
+ makeId(),
176
+ 'Output',
177
+ { x: 434, y: -97 },
178
+ 'fragment'
179
+ );
180
+ const outputV = outputNode(makeId(), 'Output', { x: 434, y: 16 }, 'vertex');
181
+
182
+ const toonGroupId = makeId();
183
+ const toonF = babylengine.constructors.toon(
184
+ makeId(),
185
+ 'Toon',
186
+ toonGroupId,
187
+ { x: 178, y: -103 },
188
+ [],
189
+ 'fragment'
190
+ );
191
+ const toonV = babylengine.constructors.toon(
192
+ makeId(),
193
+ 'Toon',
194
+ toonGroupId,
195
+ { x: 434, y: 130 },
196
+ [],
197
+ 'vertex',
198
+ toonF.id
199
+ );
200
+ const properties: [string, DataNode][] = [
201
+ [
202
+ 'albedoColor',
203
+ colorNode(makeId(), 'Color', { x: -153, y: -268 }, ['0', '0.7', '0']),
204
+ ],
205
+ // [
206
+ // 'gradientMap',
207
+ // textureNode(
208
+ // makeId(),
209
+ // 'Gradient Map',
210
+ // { x: -153, y: -160 },
211
+ // 'threeTone'
212
+ // ),
213
+ // ],
214
+ [
215
+ 'bumpTexture',
216
+ textureNode(
217
+ makeId(),
218
+ 'Bump Texture',
219
+ { x: -153, y: -50 },
220
+ 'brickNormal'
221
+ ),
222
+ ],
223
+ ];
224
+
225
+ newGraph = {
226
+ nodes: [outputF, outputV, toonF, toonV, ...properties.map(([, p]) => p)],
227
+ edges: [
228
+ edgeFrom(toonF, outputF.id, 'filler_frogFragOut', 'fragment'),
229
+ edgeFrom(toonV, outputV.id, 'filler_gl_Position', 'vertex'),
230
+ ...properties.map(([name, prop]) =>
231
+ edgeFrom(prop, toonF.id, `property_${name}`, prop.type)
232
+ ),
233
+ ],
234
+ };
235
+ previewObject = 'torusknot';
236
+ bg = '';
237
+ } else if (example === Example.DEFAULT) {
238
+ const outputF = outputNode(
239
+ makeId(),
240
+ 'Output',
241
+ { x: 434, y: -97 },
242
+ 'fragment'
243
+ );
244
+ const outputV = outputNode(makeId(), 'Output', { x: 434, y: 16 }, 'vertex');
245
+
246
+ const physicalGroupId = makeId();
247
+ const physicalF = babylengine.constructors.physical(
248
+ makeId(),
249
+ 'Physical',
250
+ physicalGroupId,
251
+ { x: 178, y: -103 },
252
+ [],
253
+ 'fragment'
254
+ );
255
+ const physicalV = babylengine.constructors.physical(
256
+ makeId(),
257
+ 'Physical',
258
+ physicalGroupId,
259
+ { x: 434, y: 130 },
260
+ [],
261
+ 'vertex',
262
+ physicalF.id
263
+ );
264
+
265
+ const checkerboardf = checkerboardF(makeId(), { x: -162, y: -105 });
266
+ const checkerboardv = checkerboardV(makeId(), checkerboardf.id, {
267
+ x: -162,
268
+ y: 43,
269
+ });
270
+ newGraph = {
271
+ nodes: [
272
+ outputF,
273
+ outputV,
274
+ physicalF,
275
+ physicalV,
276
+ checkerboardf,
277
+ checkerboardv,
278
+ ],
279
+ edges: [
280
+ edgeFrom(physicalF, outputF.id, 'filler_frogFragOut', 'fragment'),
281
+ edgeFrom(physicalV, outputV.id, 'filler_gl_Position', 'vertex'),
282
+ edgeFrom(
283
+ checkerboardf,
284
+ physicalF.id,
285
+ 'property_albedoTexture',
286
+ 'fragment'
287
+ ),
288
+ ],
289
+ };
290
+ previewObject = 'sphere';
291
+ bg = '';
292
+ } else if (example === Example.LIVING_DIAMOND) {
293
+ const outputF = outputNode(
294
+ makeId(),
295
+ 'Output',
296
+ { x: 434, y: -97 },
297
+ 'fragment'
298
+ );
299
+ const outputV = outputNode(makeId(), 'Output', { x: 434, y: 16 }, 'vertex');
300
+
301
+ const nMap = konvert(normalMapify(makeId(), { x: -185, y: 507 }));
302
+
303
+ const purpleNoise = konvert(
304
+ purpleNoiseNode(makeId(), { x: -512, y: 434 }, [
305
+ numberUniformData(
306
+ 'speed',
307
+ babylengine.name === 'babylon' ? '1.0' : '0.2'
308
+ ),
309
+ numberUniformData('brightnessX', '1.0'),
310
+ numberUniformData('permutations', '10'),
311
+ numberUniformData('iterations', '2'),
312
+ vectorUniformData(
313
+ 'uvScale',
314
+ babylengine.name === 'babylon' ? ['0.1', '0.1'] : ['0.9', '0.9']
315
+ ),
316
+ vectorUniformData('color1', ['0', '1', '1']),
317
+ vectorUniformData('color2', ['1', '0', '1']),
318
+ vectorUniformData('color3', ['1', '1', '0']),
319
+ ])
320
+ );
321
+
322
+ const properties = [
323
+ numberNode(makeId(), 'Metallic', { x: -185, y: -110 }, '0.1'),
324
+ numberNode(makeId(), 'Roughness', { x: -185, y: 0 }, '0.055'),
325
+ numberNode(makeId(), 'Alpha', { x: -185, y: 110 }, '0.2'),
326
+ ];
327
+ const ior = numberNode(
328
+ makeId(),
329
+ 'Index Of Refraction',
330
+ { x: -110, y: 62 },
331
+ '1.05'
332
+ );
333
+
334
+ const physicalGroupId = makeId();
335
+ const physicalF = babylengine.constructors.physical(
336
+ makeId(),
337
+ 'Physical',
338
+ physicalGroupId,
339
+ { x: 178, y: -103 },
340
+ [],
341
+ 'fragment'
342
+ );
343
+ const physicalV = babylengine.constructors.physical(
344
+ makeId(),
345
+ 'Physical',
346
+ physicalGroupId,
347
+ { x: 434, y: 130 },
348
+ [],
349
+ 'vertex',
350
+ physicalF.id
351
+ );
352
+
353
+ newGraph = {
354
+ nodes: [
355
+ outputF,
356
+ outputV,
357
+ physicalF,
358
+ physicalV,
359
+ purpleNoise,
360
+ nMap,
361
+ ior,
362
+ ...properties,
363
+ ],
364
+ edges: [
365
+ edgeFrom(physicalF, outputF.id, 'filler_frogFragOut', 'fragment'),
366
+ edgeFrom(physicalV, outputV.id, 'filler_gl_Position', 'vertex'),
367
+ edgeFrom(purpleNoise, nMap.id, 'filler_normal_map', 'fragment'),
368
+ edgeFrom(nMap, physicalF.id, 'property_bumpTexture', 'fragment'),
369
+ edgeFrom(ior, physicalF.id, `property_indexOfRefraction`, 'number'),
370
+ ...properties.map((prop) =>
371
+ edgeFrom(
372
+ prop,
373
+ physicalF.id,
374
+ `property_${prop.name.toLowerCase()}`,
375
+ prop.type
376
+ )
377
+ ),
378
+ ],
379
+ };
380
+ previewObject = 'icosahedron';
381
+ bg = 'cityCourtYard';
382
+ } else if (example === Example.GLASS_FIREBALL) {
383
+ const outputF = outputNode(
384
+ makeId(),
385
+ 'Output',
386
+ { x: 434, y: -97 },
387
+ 'fragment'
388
+ );
389
+ const outputV = outputNode(makeId(), 'Output', { x: 434, y: 20 }, 'vertex');
390
+
391
+ const physicalGroupId = makeId();
392
+ const physicalF = babylengine.constructors.physical(
393
+ makeId(),
394
+ 'Physical',
395
+ physicalGroupId,
396
+ { x: 178, y: -103 },
397
+ [],
398
+ 'fragment'
399
+ );
400
+ const physicalV = babylengine.constructors.physical(
401
+ makeId(),
402
+ 'Physical',
403
+ physicalGroupId,
404
+ { x: 434, y: 130 },
405
+ [],
406
+ 'vertex',
407
+ physicalF.id
408
+ );
409
+ const fireF = konvert(fireFrag(makeId(), { x: -88, y: -120 }));
410
+ const fireV = konvert(
411
+ fireVert(makeId(), fireF.id, { x: -88, y: 610 }, [
412
+ numberUniformData('fireSpeed', '0.768'),
413
+ numberUniformData('pulseHeight', '0.0'),
414
+ numberUniformData('displacementHeight', '0.481'),
415
+ numberUniformData('turbulenceDetail', '0.907'),
416
+ ])
417
+ );
418
+
419
+ const roughness = numberNode(
420
+ makeId(),
421
+ 'Roughness',
422
+ { x: -103, y: -16 },
423
+ '0.1'
424
+ );
425
+ const metalness = numberNode(
426
+ makeId(),
427
+ 'Metalness',
428
+ { x: -103, y: 62 },
429
+ '0.09'
430
+ );
431
+ const alpha = numberNode(makeId(), 'Alpha', { x: -103, y: 62 }, '0.0');
432
+ const ior = numberNode(
433
+ makeId(),
434
+ 'Index Of Refraction',
435
+ { x: -110, y: 62 },
436
+ '1.05'
437
+ );
438
+
439
+ newGraph = {
440
+ nodes: [
441
+ alpha,
442
+ ior,
443
+ roughness,
444
+ metalness,
445
+ fireF,
446
+ fireV,
447
+ outputF,
448
+ outputV,
449
+ physicalF,
450
+ physicalV,
451
+ ],
452
+ edges: [
453
+ edgeFrom(physicalF, outputF.id, 'filler_frogFragOut', 'fragment'),
454
+ edgeFrom(physicalV, outputV.id, 'filler_gl_Position', 'vertex'),
455
+ edgeFrom(fireF, physicalF.id, 'property_albedoTexture', 'fragment'),
456
+ edgeFrom(roughness, physicalF.id, 'property_roughness', 'fragment'),
457
+ edgeFrom(metalness, physicalF.id, 'property_metallic', 'fragment'),
458
+ edgeFrom(alpha, physicalF.id, 'property_alpha', 'fragment'),
459
+ edgeFrom(ior, physicalF.id, 'property_indexOfRefraction', 'fragment'),
460
+ edgeFrom(fireV, physicalV.id, 'filler_position', 'vertex'),
461
+ ],
462
+ };
463
+ previewObject = 'sphere';
464
+ bg = 'cityCourtYard';
465
+ } else {
466
+ const outputF = outputNode(
467
+ makeId(),
468
+ 'Output',
469
+ { x: 434, y: -97 },
470
+ 'fragment'
471
+ );
472
+ const outputV = outputNode(makeId(), 'Output', { x: 434, y: 20 }, 'vertex');
473
+
474
+ const physicalGroupId = makeId();
475
+ const physicalF = babylengine.constructors.physical(
476
+ makeId(),
477
+ 'Physical',
478
+ physicalGroupId,
479
+ { x: 178, y: -103 },
480
+ [],
481
+ 'fragment'
482
+ );
483
+ const physicalV = babylengine.constructors.physical(
484
+ makeId(),
485
+ 'Physical',
486
+ physicalGroupId,
487
+ { x: 434, y: 130 },
488
+ [],
489
+ 'vertex',
490
+ physicalF.id
491
+ );
492
+
493
+ const purpleNoise = konvert(purpleNoiseNode(makeId(), { x: -100, y: 0 }));
494
+
495
+ newGraph = {
496
+ nodes: [purpleNoise, outputF, outputV, physicalF, physicalV],
497
+ edges: [
498
+ edgeFrom(physicalF, outputF.id, 'filler_frogFragOut', 'fragment'),
499
+ edgeFrom(physicalV, outputV.id, 'filler_gl_Position', 'vertex'),
500
+ edgeFrom(
501
+ purpleNoise,
502
+ physicalF.id,
503
+ 'property_albedoTexture',
504
+ 'fragment'
505
+ ),
506
+ ],
507
+ };
508
+ previewObject = 'torusknot';
509
+ }
510
+
511
+ return [newGraph, previewObject, bg];
512
+ };
@@ -0,0 +1,69 @@
1
+ import { renameBindings } from '@shaderfrog/glsl-parser/parser/utils';
2
+ import { EngineImporters, EngineNodeType } from '../../core/engine';
3
+
4
+ const nodeInputMap = {
5
+ normalMap: 'bumpSampler',
6
+ property_map: 'property_albedoTexture',
7
+ property_normalMap: 'property_bumpTexture',
8
+ property_color: 'property_albedoColor',
9
+ property_metalness: 'property_metallic',
10
+ filler_position: 'filler_position',
11
+ };
12
+
13
+ const importers: EngineImporters = {
14
+ three: {
15
+ // TODO: For hell:
16
+ // the renames below don't really work, the "seen" thing is confusing - I
17
+ // don't remember why I did that - is that to avoid renaming the original
18
+ // declaration? the original declaraitons need to be renamed or stripped
19
+ // from the original shader and the right imports added
20
+ //
21
+ // Also need to show babylon compile errors in the UI
22
+ convertAst(ast, type) {
23
+ // Babylon has no normalmatrix. They do have a normal attribute. So undo any
24
+ // multiplication by normalMatrix?
25
+ const seen: Record<string, boolean> = {};
26
+ renameBindings(ast.scopes[0], (name) => {
27
+ // console.log({ name }, 'seen:', seen[name]);
28
+ const renamed =
29
+ name === 'vUv'
30
+ ? 'vMainUV1'
31
+ : name === 'vNormal'
32
+ ? 'vNormalW'
33
+ : name === 'projectionMatrix'
34
+ ? seen[name]
35
+ ? 'viewProjection'
36
+ : 'hobgoblin'
37
+ : name === 'modelMatrix'
38
+ ? seen[name]
39
+ ? 'world'
40
+ : name
41
+ : name === 'modelViewMatrix'
42
+ ? seen[name]
43
+ ? '(world * viewProjection)'
44
+ : name
45
+ : name === 'vPosition'
46
+ ? seen[name]
47
+ ? 'vPositionW'
48
+ : name
49
+ : name;
50
+
51
+ seen[name] = true;
52
+
53
+ return renamed;
54
+ });
55
+ },
56
+ nodeInputMap: {
57
+ [EngineNodeType.physical]: nodeInputMap,
58
+ },
59
+ edgeMap: {
60
+ normalMap: 'bumpSampler',
61
+ property_map: 'property_albedoTexture',
62
+ property_normalMap: 'property_bumpTexture',
63
+ property_color: 'property_albedoColor',
64
+ property_metalness: 'property_metallic',
65
+ },
66
+ },
67
+ };
68
+
69
+ export default importers;
@@ -0,0 +1,6 @@
1
+ import { babylengine } from './bablyengine';
2
+ import BabylonComponent from './BabylonComponent';
3
+
4
+ export { BabylonComponent as Editor, babylengine as engine };
5
+
6
+ export * from './examples';