Skip to content

Commit b473ac8

Browse files
committed
got the swizzle assignments working
1 parent d609240 commit b473ac8

File tree

1 file changed

+77
-40
lines changed

1 file changed

+77
-40
lines changed

src/webgl/ShaderGen.js

Lines changed: 77 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ function shadergen(p5, fn) {
3535
generatorFunction = shaderModifier;
3636
}
3737
const generator = new ShaderGenerator(generatorFunction, this, options.srcLocations)
38-
const generatedModifyArgument = generator.hookCallbacks();
38+
const generatedModifyArgument = generator.generate();
3939
console.log("SRC STRING: ", generatorFunction);
4040
console.log("NEW OPTIONS:", generatedModifyArgument['vec4 getFinalColor'])
4141

@@ -113,7 +113,9 @@ function shadergen(p5, fn) {
113113
throw new TypeError("Cannot construct BaseNode instances directly. This is an abstract class.");
114114
}
115115
this.type = type;
116-
116+
this.componentNames = [];
117+
this.swizzleAccessed = false;
118+
this.swizzleChanged = false;
117119
// For tracking recursion depth and creating temporary variables
118120
this.isInternal = isInternal;
119121
this.usedIn = [];
@@ -131,7 +133,36 @@ function shadergen(p5, fn) {
131133
}
132134
}
133135
}
134-
136+
// get type() {
137+
// return this._type;
138+
// }
139+
140+
// set type(value) {
141+
// this._type = value;
142+
// }
143+
144+
addVectorComponents() {
145+
if (this.type.startsWith('vec')) {
146+
const vectorDimensions = +this.type.slice(3);
147+
this.componentNames = ['x', 'y', 'z', 'w'].slice(0, vectorDimensions);
148+
149+
for (let componentName of this.componentNames) {
150+
// let value = new FloatNode()
151+
let value = new ComponentNode(this, componentName, 'float', true);
152+
Object.defineProperty(this, componentName, {
153+
get() {
154+
this.swizzleAccessed = true;
155+
return value;
156+
},
157+
set(newValue) {
158+
this.swizzleChanged = true;
159+
value = newValue;
160+
}
161+
})
162+
}
163+
}
164+
}
165+
135166
// The base node implements a version of toGLSL which determines whether the generated code should be stored in a temporary variable.
136167
toGLSLBase(context){
137168
if (this.shouldUseTemporaryVariable()) {
@@ -143,7 +174,7 @@ function shadergen(p5, fn) {
143174
}
144175

145176
shouldUseTemporaryVariable() {
146-
if (this.temporaryVariable)
177+
if (this.swizzleChanged) { return true; }
147178
if (this.isInternal || isVariableNode(this)) { return false; }
148179
let score = 0;
149180
score += isBinaryOperatorNode(this);
@@ -159,7 +190,18 @@ function shadergen(p5, fn) {
159190
if (this.srcLine) {
160191
line += `\n// From ${this.srcLine}\n`;
161192
}
162-
line += this.type + " " + this.temporaryVariable + " = " + this.toGLSL(context) + ";";
193+
if (this.swizzleChanged) {
194+
const valueArgs = [];
195+
for (let componentName of this.componentNames) {
196+
valueArgs.push(this[componentName])
197+
}
198+
console.log(this, valueArgs)
199+
const replacement = nodeConstructors[this.type](valueArgs)
200+
line += this.type + " " + this.temporaryVariable + " = " + this.toGLSL(context) + ";";
201+
line += `\n` + this.temporaryVariable + " = " + replacement.toGLSL(context) + ";";
202+
} else {
203+
line += this.type + " " + this.temporaryVariable + " = " + this.toGLSL(context) + ";";
204+
}
163205
context.declarations.push(line);
164206
}
165207
return this.temporaryVariable;
@@ -191,22 +233,6 @@ function shadergen(p5, fn) {
191233
return new this.constructor(other);
192234
}
193235
}
194-
195-
addComponent(componentName, type='float') {
196-
this[componentName] = new ComponentNode(this, componentName, type, true);
197-
}
198-
199-
autoAddVectorComponents() {
200-
const options = {
201-
vec2: ['x', 'y'],
202-
vec3: ['x', 'y', 'z'],
203-
vec4: ['x', 'y', 'z', 'w']
204-
};
205-
const componentNames = options[this.type] || [];
206-
for (let componentName of componentNames) {
207-
this.addComponent(componentName);
208-
}
209-
}
210236

211237
toGLSL(context){
212238
throw new TypeError("Not supposed to call this function on BaseNode, which is an abstract class.");
@@ -254,21 +280,20 @@ function shadergen(p5, fn) {
254280
}
255281
}
256282

257-
258283
class VectorNode extends BaseNode {
259284
constructor(values, type, isInternal = false) {
260285
super(isInternal, type);
261-
this.components = ['x', 'y', 'z', 'w'].slice(0, values.length);
262-
this.components.forEach((component, i) => {
286+
this.componentNames = ['x', 'y', 'z', 'w'].slice(0, values.length);
287+
this.componentNames.forEach((component, i) => {
263288
this[component] = new FloatNode(values[i], true);
264289
});
265290
}
266291

267292
toGLSL(context) {
268293
let glslArgs = ``;
269294

270-
this.components.forEach((component, i) => {
271-
const comma = i === this.components.length - 1 ? `` : `, `;
295+
this.componentNames.forEach((component, i) => {
296+
const comma = i === this.componentNames.length - 1 ? `` : `, `;
272297
glslArgs += `${this[component].toGLSLBase(context)}${comma}`;
273298
})
274299

@@ -304,11 +329,10 @@ function shadergen(p5, fn) {
304329
// Variables and member variable nodes
305330
class VariableNode extends BaseNode {
306331
constructor(name, type, isInternal = false) {
307-
super(isInternal, type)
332+
super(isInternal, type);
308333
this.name = name;
309-
this.autoAddVectorComponents();
334+
this.addVectorComponents();
310335
}
311-
312336
toGLSL(context) {
313337
return `${this.name}`;
314338
}
@@ -318,13 +342,13 @@ function shadergen(p5, fn) {
318342
constructor(parent, componentName, type, isInternal = false) {
319343
super(isInternal, type);
320344
this.parent = parent;
321-
this.component = componentName;
322-
this.type = 'float';
345+
this.componentName = componentName;
346+
this.type = type;
323347
}
324348
toGLSL(context) {
325-
// const parentName = this.parent.toGLSLBase(context);
326-
const parentName = this.parent.temporaryVariable ? this.parent.temporaryVariable : this.parent.name;
327-
return `${parentName}.${this.component}`;
349+
const parentName = this.parent.toGLSLBase(context);
350+
// const parentName = this.parent.temporaryVariable ? this.parent.temporaryVariable : this.parent.name;
351+
return `${parentName}.${this.componentName}`;
328352
}
329353
}
330354

@@ -339,6 +363,7 @@ function shadergen(p5, fn) {
339363
operand.usedIn.push(this);
340364
}
341365
this.type = this.determineType();
366+
this.addVectorComponents();
342367
}
343368

344369
// We know that both this.a and this.b are nodes because of BaseNode.enforceType
@@ -476,8 +501,9 @@ function shadergen(p5, fn) {
476501
this.resetGLSLContext();
477502
}
478503

479-
hookCallbacks() {
504+
generate() {
480505
this.modifyFunction();
506+
console.log(this.output);
481507
return this.output;
482508
}
483509

@@ -504,8 +530,6 @@ function shadergen(p5, fn) {
504530
argsArray.push(`, ${parameter.type.typeName} ${parameter.name}`);
505531
}
506532
})
507-
console.log(hookArgs)
508-
509533
const toGLSLResult = userOverride(...hookArgs).toGLSLBase(this.context);
510534
let codeLines = [`(${argsArray.join(', ')}) {`, this.context.declarations.slice()].flat();
511535
codeLines.push(`\n${hookTypes.returnType.typeName} finalReturnValue = ${toGLSLResult};
@@ -565,32 +589,45 @@ function shadergen(p5, fn) {
565589
vec4: 'Vector4',
566590
sampler2D: 'Texture',
567591
};
592+
568593
const nodeConstructors = {
569594
int: (value) => new IntNode(value),
570595
float: (value) => new FloatNode(value),
571596
vec2: (value) => new VectorNode(value, 'vec2'),
572597
vec3: (value) => new VectorNode(value, 'vec3'),
573598
vec4: (value) => new VectorNode(value, 'vec4'),
574599
};
600+
575601
for (const glslType in GLSLTypesToSuffixes) {
576602
// Generate uniform*() Methods for creating uniforms
577603
const typeIdentifier = GLSLTypesToSuffixes[glslType];
578604
const uniformMethodName = `uniform${typeIdentifier}`;
605+
579606
ShaderGenerator.prototype[uniformMethodName] = function(...args) {
580607
let [name, ...defaultValue] = args;
581608
if(glslType.startsWith('vec')) {
582609
defaultValue = conformVectorParameters(defaultValue, +glslType.slice(3));
610+
this.output.uniforms[`${glslType} ${name}`] = defaultValue;
611+
}
612+
else {
613+
console.log("defaultValue: ",defaultValue);
614+
console.log("defaultValue[0]: ",defaultValue[0])
615+
this.output.uniforms[`${glslType} ${name}`] = defaultValue[0];
583616
}
584-
this.output.uniforms[`${glslType} ${name}`] = defaultValue;
617+
585618
let safeType = glslType === 'sampler2D' ? 'vec4' : glslType;
586-
return new VariableNode(name, safeType);
619+
const uniform = new VariableNode(name, safeType, false);
620+
return uniform;
587621
};
622+
588623
fn[uniformMethodName] = function (...args) {
589624
return GLOBAL_SHADER[uniformMethodName](...args);
590625
};
591626

592-
// Generate the create*() Methods for creating variables in shaders
627+
// We don't need a createTexture method.
593628
if (glslType === 'sampler2D') { continue; }
629+
630+
// Generate the create*() Methods for creating variables in shaders
594631
const createMethodName = `create${typeIdentifier}`;
595632
fn[createMethodName] = function (...value) {
596633
if(glslType.startsWith('vec')) {

0 commit comments

Comments
 (0)