Skip to content

Commit

Permalink
Start work fixing how transforms work with effects that are not "in p…
Browse files Browse the repository at this point in the history
…lace"

- instead of rendering transform nodes, transform texture lookup in effect nodes
- should be faster, use less GPU memory and make compositing more consistent
- should fix #54 because transform nodes won't need frame buffers
  • Loading branch information
brianchirls committed Jun 14, 2015
1 parent fdb522e commit b521a77
Showing 1 changed file with 111 additions and 14 deletions.
125 changes: 111 additions & 14 deletions seriously.js
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,50 @@

return dest;
},
inverse: function (mat, dest) {
if(!dest) { dest = mat; }

// Cache the matrix values (makes for huge speed increases!)
var a00 = mat[0], a01 = mat[1], a02 = mat[2], a03 = mat[3];
var a10 = mat[4], a11 = mat[5], a12 = mat[6], a13 = mat[7];
var a20 = mat[8], a21 = mat[9], a22 = mat[10], a23 = mat[11];
var a30 = mat[12], a31 = mat[13], a32 = mat[14], a33 = mat[15];

var b00 = a00*a11 - a01*a10;
var b01 = a00*a12 - a02*a10;
var b02 = a00*a13 - a03*a10;
var b03 = a01*a12 - a02*a11;
var b04 = a01*a13 - a03*a11;
var b05 = a02*a13 - a03*a12;
var b06 = a20*a31 - a21*a30;
var b07 = a20*a32 - a22*a30;
var b08 = a20*a33 - a23*a30;
var b09 = a21*a32 - a22*a31;
var b10 = a21*a33 - a23*a31;
var b11 = a22*a33 - a23*a32;

// Calculate the determinant (inlined to avoid double-caching)
var invDet = 1/(b00*b11 - b01*b10 + b02*b09 + b03*b08 - b04*b07 + b05*b06);

dest[0] = (a11*b11 - a12*b10 + a13*b09)*invDet;
dest[1] = (-a01*b11 + a02*b10 - a03*b09)*invDet;
dest[2] = (a31*b05 - a32*b04 + a33*b03)*invDet;
dest[3] = (-a21*b05 + a22*b04 - a23*b03)*invDet;
dest[4] = (-a10*b11 + a12*b08 - a13*b07)*invDet;
dest[5] = (a00*b11 - a02*b08 + a03*b07)*invDet;
dest[6] = (-a30*b05 + a32*b02 - a33*b01)*invDet;
dest[7] = (a20*b05 - a22*b02 + a23*b01)*invDet;
dest[8] = (a10*b10 - a11*b08 + a13*b06)*invDet;
dest[9] = (-a00*b10 + a01*b08 - a03*b06)*invDet;
dest[10] = (a30*b04 - a31*b02 + a33*b00)*invDet;
dest[11] = (-a20*b04 + a21*b02 - a23*b00)*invDet;
dest[12] = (-a10*b09 + a11*b07 - a12*b06)*invDet;
dest[13] = (a00*b09 - a01*b07 + a02*b06)*invDet;
dest[14] = (-a30*b03 + a31*b01 - a32*b00)*invDet;
dest[15] = (a20*b03 - a21*b01 + a22*b00)*invDet;

return dest;
},
identity: function (dest) {
dest[0] = 1;
dest[1] = 0;
Expand Down Expand Up @@ -2111,7 +2155,9 @@
var key, name, input,
defaultValue,
defaults,
defaultSources = {};
defaultSources = {},
sourceNames = [],
me = this;

Node.call(this, options);
this.gl = gl;
Expand All @@ -2124,7 +2170,9 @@
this.shaderDirty = true;
this.hook = hook;
this.options = options;
this.transform = null;

this.sourceTransforms = {};
this.sourceResolutions = {};

this.effect = extend({}, this.effectRef);
if (this.effectRef.definition) {
Expand All @@ -2137,6 +2185,7 @@
validateInputSpecs(this.effect);

this.uniforms.transform = identity;

this.inputs = {};
defaults = defaultInputs[hook];
for (name in this.effect.inputs) {
Expand All @@ -2154,6 +2203,8 @@
input.defaultValue = '';
} else if (input.type === 'enum') {
input.defaultValue = input.firstValue;
} else if (input.type === 'image') {
sourceNames.push(name);
}
}

Expand All @@ -2173,6 +2224,20 @@
}
}

//set up transforms for source nodes
this.uniforms.sourceResolution = new Float32Array(2 * sourceNames.length);
this.uniforms.sourceTransform = new Float32Array(16 * sourceNames.length);
sourceNames.forEach(function (name, i) {
//2 elements x 4 bytes per element
me.sourceResolutions[name] = new Float32Array(me.uniforms.sourceResolution.buffer, i * 2 * 4, 2);
me.sourceResolutions[name][0] = 1;
me.sourceResolutions[name][1] = 1;

//16 elements x 4 bytes per element
me.sourceTransforms[name] = new Float32Array(me.uniforms.sourceTransform.buffer, i * 16 * 4, 16);
mat4.identity(me.sourceTransforms[name]);
});

if (gl) {
this.initialize();
if (this.effect.commonShader) {
Expand Down Expand Up @@ -2234,10 +2299,17 @@
};

EffectNode.prototype.resize = function () {
var i;
var i, key;

Node.prototype.resize.call(this);

for (key in this.sources) {
if (this.sources.hasOwnProperty(key)) {
this.sourceResolutions[key][0] = this.sources[key].width;
this.sourceResolutions[key][1] = this.sources[key].height;
}
}

if (this.effect.resize) {
this.effect.resize.call(this);
}
Expand Down Expand Up @@ -2394,6 +2466,10 @@

inPlace = typeof this.inPlace === 'function' ? this.inPlace(key) : this.inPlace;
this.sources[key].render(!inPlace);

if (this.sources[key].cumulativeMatrix) {
mat4.inverse(this.sources[key].cumulativeMatrix, this.sourceTransforms[key]);
}
}
}

Expand Down Expand Up @@ -2458,6 +2534,7 @@
}

this.sources[name] = value;
mat4.identity(this.sourceTransforms[name]);
value.addTarget(this);
}
} else {
Expand Down Expand Up @@ -3788,7 +3865,6 @@
}

this.target = target;
this.transform = null;
this.transformDirty = true;
this.flip = flip;
if (width) {
Expand All @@ -3800,6 +3876,9 @@

this.uniforms.resolution[0] = this.width;
this.uniforms.resolution[1] = this.height;
this.uniforms.sourceResolution = [1, 1];
this.uniforms.sourceTransform = new Float32Array(identity);
this.uniforms.transform = new Float32Array(identity);

if (opts.auto !== undefined) {
this.auto = opts.auto;
Expand Down Expand Up @@ -3870,11 +3949,12 @@
this.plugin.resize.call(this);
}

if (this.source &&
(this.source.width !== this.width || this.source.height !== this.height)) {
if (!this.transform) {
this.transform = new Float32Array(16);
}
if (this.source) {
this.uniforms.sourceResolution[0] = this.source.width;
this.uniforms.sourceResolution[1] = this.source.height;
} else {
this.uniforms.sourceResolution[0] = 1;
this.uniforms.sourceResolution[1] = 1;
}
};

Expand Down Expand Up @@ -3912,6 +3992,7 @@

this.uniforms.source = this.source.texture;

/*
if (this.source.width === this.width && this.source.height === this.height) {
this.uniforms.transform = this.source.cumulativeMatrix || identity;
} else if (this.transformDirty) {
Expand All @@ -3930,6 +4011,10 @@
this.uniforms.transform = matrix;
this.transformDirty = false;
}
*/

//todo: bring back transformDirty
mat4.inverse(this.source.cumulativeMatrix || identity, this.uniforms.sourceTransform);

draw(baseShader, rectangleModel, this.uniforms, this.frameBuffer.frameBuffer, this, outputRenderOptions);

Expand Down Expand Up @@ -4598,7 +4683,7 @@
this.transformDirty = false;
}

if (renderTransform && gl) {
if (false && renderTransform && gl) {
if (this.renderDirty) {
if (!this.frameBuffer) {
this.uniforms = {
Expand Down Expand Up @@ -6417,11 +6502,24 @@
'attribute vec4 position;',
'attribute vec2 texCoord;',

//transform output of this node
'uniform vec2 resolution;',
'uniform mat4 transform;',

//transform sources
'uniform mat4 sourceTransform[1];',
'uniform vec2 sourceResolution[1];',

'varying vec2 vTexCoord;',

'const vec2 HALF = vec2(0.5);',
'vec2 adjustedCoords(vec2 coords, vec2 res, mat4 inv) {',
' vec4 c4 = vec4((coords - HALF) * 2.0 * resolution, 0.0, 1.0);',
' c4 = inv * c4;',
' vec2 adjusted = c4.xy / c4.w;',
' return adjusted / res / 2.0 + HALF;',
'}',

'void main(void) {',
// first convert to screen space
' vec4 screenPosition = vec4(position.xy * resolution / 2.0, position.z, position.w);',
Expand All @@ -6431,7 +6529,8 @@
' gl_Position.xy = screenPosition.xy * 2.0 / resolution;',
' gl_Position.z = screenPosition.z * 2.0 / (resolution.x / resolution.y);',
' gl_Position.w = screenPosition.w;',
' vTexCoord = texCoord;',

' vTexCoord = adjustedCoords(texCoord, sourceResolution[0], sourceTransform[0]);',
'}\n'
].join('\n');

Expand All @@ -6443,13 +6542,11 @@
'uniform sampler2D source;',

'void main(void) {',
/*
' if (any(lessThan(vTexCoord, vec2(0.0))) || any(greaterThanEqual(vTexCoord, vec2(1.0)))) {',
' gl_FragColor = vec4(0.0);',
' } else {',
*/
' gl_FragColor = texture2D(source, vTexCoord);',
//' }',
' }',
'}'
].join('\n');

Expand Down

0 comments on commit b521a77

Please sign in to comment.