@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,66 @@
1
+ import { ShaderStage } from '../graph';
2
+ import { Strategy } from '../strategy';
3
+ import { GraphDataType, UniformDataType } from './data-nodes';
4
+ import { CoreNode, NodeInput } from './core-node';
5
+
6
+ export const mapInputName = (
7
+ node: CodeNode,
8
+ { id, displayName }: NodeInput
9
+ ): string => node.config?.inputMapping?.[id] || displayName;
10
+
11
+ export type InputMapping = { [original: string]: string };
12
+ export type NodeConfig = {
13
+ version: 2 | 3;
14
+ mangle?: boolean;
15
+ preprocess: boolean;
16
+ inputMapping?: InputMapping;
17
+ strategies: Strategy[];
18
+ uniforms: UniformDataType[];
19
+ properties?: NodeProperty[];
20
+ hardCodedProperties?: Record<string, any>;
21
+ };
22
+
23
+ export interface NodeProperty {
24
+ // Display name, like "albedo"
25
+ displayName: string;
26
+ // Type in the engine, like "texture"
27
+ type: GraphDataType;
28
+ // Property name to apply to the material, like "map"
29
+ property: string;
30
+ // The name of the filler this property introduces, aka the GLSL source code
31
+ // to be replaced, if this property is present.
32
+ fillerName?: string;
33
+ defaultValue?: any;
34
+ }
35
+
36
+ export const property = (
37
+ displayName: string,
38
+ property: string,
39
+ type: GraphDataType,
40
+ fillerName?: string,
41
+ defaultValue?: any
42
+ ): NodeProperty => ({
43
+ displayName,
44
+ type,
45
+ property,
46
+ fillerName,
47
+ defaultValue,
48
+ });
49
+
50
+ export interface CodeNode extends CoreNode {
51
+ config: NodeConfig;
52
+ source: string;
53
+ expressionOnly?: boolean;
54
+ stage: ShaderStage | undefined;
55
+ biStage?: boolean;
56
+ groupId: string | null | undefined;
57
+ nextStageNodeId?: string;
58
+ prevStageNodeId?: string;
59
+ originalEngine?: string;
60
+ }
61
+
62
+ export interface BinaryNode extends CodeNode {
63
+ operator: string;
64
+ }
65
+
66
+ export type SourceNode = BinaryNode | CodeNode;
@@ -0,0 +1,48 @@
1
+ import { GraphDataType } from './data-nodes';
2
+
3
+ export type InputCategory = 'data' | 'code';
4
+ export type InputType = 'uniform' | 'property' | 'filler';
5
+
6
+ export interface NodeInput {
7
+ displayName: string;
8
+ id: string;
9
+ type: InputType;
10
+ dataType?: GraphDataType;
11
+ accepts: Set<InputCategory>;
12
+ baked?: boolean;
13
+ bakeable: boolean;
14
+ property?: string;
15
+ }
16
+ export const nodeInput = (
17
+ displayName: string,
18
+ id: string,
19
+ type: InputType,
20
+ dataType: GraphDataType | undefined,
21
+ accepts: Set<InputCategory>,
22
+ bakeable: boolean,
23
+ property?: string
24
+ ): NodeInput => ({
25
+ displayName,
26
+ id,
27
+ type,
28
+ dataType,
29
+ accepts,
30
+ bakeable,
31
+ property,
32
+ });
33
+
34
+ export interface NodeOutput {
35
+ name: string;
36
+ id: string;
37
+ category: InputCategory;
38
+ }
39
+
40
+ export type NodePosition = { x: number; y: number };
41
+ export interface CoreNode {
42
+ id: string;
43
+ name: string;
44
+ type: string;
45
+ inputs: NodeInput[];
46
+ outputs: NodeOutput[];
47
+ position: NodePosition;
48
+ }
@@ -0,0 +1,344 @@
1
+ import { CoreNode, NodeInput, NodeOutput, NodePosition } from './core-node';
2
+
3
+ type ArrayType = 'array';
4
+ type Vector = 'vector2' | 'vector3' | 'vector4';
5
+ type Color = 'rgb' | 'rgba';
6
+ type Mat =
7
+ | 'mat2'
8
+ | 'mat3'
9
+ | 'mat4'
10
+ | 'mat2x2'
11
+ | 'mat2x3'
12
+ | 'mat2x4'
13
+ | 'mat3x2'
14
+ | 'mat3x3'
15
+ | 'mat3x4'
16
+ | 'mat4x2'
17
+ | 'mat4x3'
18
+ | 'mat4x4';
19
+
20
+ export type GraphDataType =
21
+ | Vector
22
+ | Color
23
+ | Mat
24
+ | 'texture'
25
+ | 'samplerCube'
26
+ | 'number'
27
+ | ArrayType;
28
+
29
+ export interface NumberNode extends CoreNode {
30
+ type: 'number';
31
+ value: string;
32
+ range?: [number, number];
33
+ stepper?: number;
34
+ }
35
+ export const numberNode = (
36
+ id: string,
37
+ name: string,
38
+ position: NodePosition,
39
+ value: string,
40
+ optionals?: {
41
+ range?: [number, number];
42
+ stepper?: number;
43
+ inputs?: NodeInput[];
44
+ outputs?: NodeOutput[];
45
+ }
46
+ ): NumberNode => ({
47
+ type: 'number',
48
+ id,
49
+ name,
50
+ position,
51
+ value,
52
+ inputs: optionals?.inputs || [],
53
+ outputs: optionals?.outputs || [
54
+ {
55
+ name: 'float',
56
+ id: '1',
57
+ category: 'data',
58
+ },
59
+ ],
60
+ range: optionals?.range,
61
+ stepper: optionals?.stepper,
62
+ });
63
+
64
+ export type NumberDataUniform = Omit<
65
+ NumberNode,
66
+ 'id' | 'inputs' | 'outputs' | 'position'
67
+ >;
68
+
69
+ export const numberUniformData = (
70
+ name: string,
71
+ value: string,
72
+ range?: [number, number],
73
+ stepper?: number
74
+ ): NumberDataUniform => ({
75
+ type: 'number',
76
+ name,
77
+ value,
78
+ range,
79
+ stepper,
80
+ });
81
+
82
+ export interface TextureNode extends CoreNode {
83
+ type: 'texture';
84
+ value: string;
85
+ }
86
+ export const textureNode = (
87
+ id: string,
88
+ name: string,
89
+ position: NodePosition,
90
+ value: string
91
+ ): TextureNode => ({
92
+ type: 'texture',
93
+ id,
94
+ name,
95
+ position,
96
+ value,
97
+ inputs: [],
98
+ outputs: [
99
+ {
100
+ name: 'texture',
101
+ id: '1',
102
+ category: 'data',
103
+ },
104
+ ],
105
+ });
106
+
107
+ export type TextureDataUniform = Omit<
108
+ TextureNode,
109
+ 'id' | 'inputs' | 'outputs' | 'position'
110
+ >;
111
+
112
+ export const textureUniformData = (
113
+ name: string,
114
+ value: string
115
+ ): TextureDataUniform => ({ type: 'texture', name, value });
116
+
117
+ export interface SamplerCubeNode extends CoreNode {
118
+ type: 'samplerCube';
119
+ value: string;
120
+ }
121
+ export const samplerCubeNode = (
122
+ id: string,
123
+ name: string,
124
+ position: NodePosition,
125
+ value: string
126
+ ): SamplerCubeNode => ({
127
+ type: 'samplerCube',
128
+ id,
129
+ name,
130
+ position,
131
+ value,
132
+ inputs: [],
133
+ outputs: [
134
+ {
135
+ name: 'samplerCube',
136
+ id: '1',
137
+ category: 'data',
138
+ },
139
+ ],
140
+ });
141
+
142
+ export type SamplerCubeDataUniform = Omit<
143
+ SamplerCubeNode,
144
+ 'id' | 'inputs' | 'outputs' | 'position'
145
+ >;
146
+
147
+ export const samplerCubeUniformData = (
148
+ name: string,
149
+ value: string
150
+ ): SamplerCubeDataUniform => ({ type: 'samplerCube', name, value });
151
+
152
+ export type ArrayValue = string[];
153
+
154
+ export interface ArrayNode extends CoreNode {
155
+ type: 'array';
156
+ dimensions: number;
157
+ value: ArrayValue;
158
+ }
159
+
160
+ export function arrayNode(
161
+ id: string,
162
+ name: string,
163
+ position: NodePosition,
164
+ value: ArrayValue
165
+ ): ArrayNode {
166
+ return {
167
+ id,
168
+ name,
169
+ position,
170
+ inputs: [],
171
+ outputs: [
172
+ {
173
+ name: 'array',
174
+ id: '1',
175
+ category: 'data',
176
+ },
177
+ ],
178
+ value,
179
+ dimensions: value.length,
180
+ type: 'array',
181
+ };
182
+ }
183
+
184
+ export type Vector2 = [string, string];
185
+ export type Vector3 = [string, string, string];
186
+ export type Vector4 = [string, string, string, string];
187
+
188
+ export interface Vector2Node extends CoreNode {
189
+ type: 'vector2';
190
+ dimensions: 2;
191
+ value: Vector2;
192
+ }
193
+ export interface Vector3Node extends CoreNode {
194
+ type: 'vector3';
195
+ dimensions: 3;
196
+ value: Vector3;
197
+ }
198
+ export interface Vector4Node extends CoreNode {
199
+ type: 'vector4';
200
+ dimensions: 4;
201
+ value: Vector4;
202
+ }
203
+
204
+ export function vectorNode(
205
+ id: string,
206
+ name: string,
207
+ position: NodePosition,
208
+ value: Vector2 | Vector3 | Vector4
209
+ ): Vector2Node | Vector3Node | Vector4Node {
210
+ return {
211
+ id,
212
+ name,
213
+ position,
214
+ inputs: [],
215
+ outputs: [
216
+ {
217
+ name: `vector${value.length}`,
218
+ id: '1',
219
+ category: 'data',
220
+ },
221
+ ],
222
+ ...(value.length === 2
223
+ ? { value, dimensions: 2, type: 'vector2' }
224
+ : value.length === 3
225
+ ? { value, dimensions: 3, type: 'vector3' }
226
+ : { value, dimensions: 4, type: 'vector4' }),
227
+ };
228
+ }
229
+
230
+ export type ArrayDataUniform = Omit<
231
+ ArrayNode,
232
+ 'id' | 'inputs' | 'outputs' | 'position'
233
+ >;
234
+
235
+ export const arrayUniformData = (
236
+ name: string,
237
+ value: ArrayValue
238
+ ): ArrayDataUniform => ({
239
+ name,
240
+ value,
241
+ dimensions: value.length,
242
+ type: 'array',
243
+ });
244
+
245
+ export type Vector2DataUniform = Omit<
246
+ Vector2Node,
247
+ 'id' | 'inputs' | 'outputs' | 'position'
248
+ >;
249
+ export type Vector3DataUniform = Omit<
250
+ Vector3Node,
251
+ 'id' | 'inputs' | 'outputs' | 'position'
252
+ >;
253
+ export type Vector4DataUniform = Omit<
254
+ Vector4Node,
255
+ 'id' | 'inputs' | 'outputs' | 'position'
256
+ >;
257
+
258
+ export const vectorUniformData = (
259
+ name: string,
260
+ value: Vector2 | Vector3 | Vector4
261
+ ): Vector2DataUniform | Vector3DataUniform | Vector4DataUniform => ({
262
+ name,
263
+ ...(value.length === 2
264
+ ? { value, dimensions: 2, type: 'vector2' }
265
+ : value.length === 3
266
+ ? { value, dimensions: 3, type: 'vector3' }
267
+ : { value, dimensions: 4, type: 'vector4' }),
268
+ });
269
+
270
+ export interface RgbNode extends CoreNode {
271
+ type: 'rgb';
272
+ dimensions: 3;
273
+ value: Vector3;
274
+ }
275
+ export interface RgbaNode extends CoreNode {
276
+ type: 'rgba';
277
+ dimensions: 4;
278
+ value: Vector4;
279
+ }
280
+
281
+ export function colorNode(
282
+ id: string,
283
+ name: string,
284
+ position: NodePosition,
285
+ value: Vector3 | Vector4
286
+ ): RgbNode | RgbaNode {
287
+ return {
288
+ id,
289
+ name,
290
+ position,
291
+ inputs: [],
292
+ outputs: [
293
+ {
294
+ name: value.length === 3 ? 'rgb' : 'rgba',
295
+ id: '1',
296
+ category: 'data',
297
+ },
298
+ ],
299
+ ...(value.length === 3
300
+ ? { value, dimensions: 3, type: 'rgb' }
301
+ : { value, dimensions: 4, type: 'rgba' }),
302
+ };
303
+ }
304
+
305
+ export type RgbDataUniform = Omit<
306
+ RgbNode,
307
+ 'id' | 'inputs' | 'outputs' | 'position'
308
+ >;
309
+ export type RgbaDataUniform = Omit<
310
+ RgbaNode,
311
+ 'id' | 'inputs' | 'outputs' | 'position'
312
+ >;
313
+
314
+ export const colorUniformData = (
315
+ name: string,
316
+ value: Vector3 | Vector4
317
+ ): RgbDataUniform | RgbaDataUniform => ({
318
+ name,
319
+ ...(value.length === 3
320
+ ? { value, dimensions: 3, type: 'rgb' }
321
+ : { value, dimensions: 4, type: 'rgba' }),
322
+ });
323
+
324
+ // When defining nodes, these are the types allowed in uniforms
325
+ export type UniformDataType =
326
+ | TextureDataUniform
327
+ | SamplerCubeDataUniform
328
+ | NumberDataUniform
329
+ | Vector2DataUniform
330
+ | Vector3DataUniform
331
+ | Vector4DataUniform
332
+ | RgbDataUniform
333
+ | RgbaDataUniform;
334
+
335
+ export type DataNode =
336
+ | TextureNode
337
+ | SamplerCubeNode
338
+ | NumberNode
339
+ | Vector2Node
340
+ | Vector3Node
341
+ | Vector4Node
342
+ | ArrayNode
343
+ | RgbNode
344
+ | RgbaNode;
@@ -0,0 +1,23 @@
1
+ import { ShaderStage } from '../graph';
2
+ import { GraphDataType } from './data-nodes';
3
+
4
+ export type EdgeType = ShaderStage | GraphDataType;
5
+ export type Edge = {
6
+ id: string;
7
+ from: string;
8
+ to: string;
9
+ output: string;
10
+ // The ID of the input of the node this edge connects to
11
+ input: string;
12
+ // Fragment, vertex, or any of the data types
13
+ type?: EdgeType;
14
+ };
15
+
16
+ export const makeEdge = (
17
+ id: string,
18
+ from: string,
19
+ to: string,
20
+ output: string,
21
+ input: string,
22
+ type?: EdgeType
23
+ ): Edge => ({ id, from, to, output, input, type });