From 8686a4ece74bf4c1bf0613481a268e33ecd35cfa Mon Sep 17 00:00:00 2001 From: Stalgia Grigg Date: Mon, 4 Nov 2019 15:45:29 -0800 Subject: [PATCH 01/11] Only update modified uniforms --- src/webgl/p5.Shader.js | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/src/webgl/p5.Shader.js b/src/webgl/p5.Shader.js index e4ea4a4b49..cdf92cdf7b 100644 --- a/src/webgl/p5.Shader.js +++ b/src/webgl/p5.Shader.js @@ -171,11 +171,19 @@ p5.Shader.prototype._loadUniforms = function() { } uniform.name = uniformName; uniform.type = uniformInfo.type; + uniform._cachedData = undefined; if (uniform.type === gl.SAMPLER_2D) { uniform.samplerIndex = samplerIndex; samplerIndex++; this.samplers.push(uniform); } + uniform.isArray = + uniform.type === gl.FLOAT_MAT3 || + uniform.type === gl.FLOAT_MAT4 || + uniform.type === gl.INT_VEC2 || + uniform.type === gl.INT_VEC3 || + uniform.type === gl.INT_VEC4; + this.uniforms[uniformName] = uniform; } this._loadedUniforms = true; @@ -193,6 +201,7 @@ p5.Shader.prototype.compile = () => { p5.Shader.prototype.bindShader = function() { this.init(); if (!this._bound) { + // NEED TO MINIMIZE CALLS TO useProgram(); this.useProgram(); this._bound = true; @@ -341,16 +350,29 @@ p5.Shader.prototype.useProgram = function() { * canvas toggles between a circular gradient of orange and blue vertically. and a circular gradient of red and green moving horizontally when mouse is clicked/pressed. */ p5.Shader.prototype.setUniform = function(uniformName, data) { - //@todo update all current gl.uniformXX calls - const uniform = this.uniforms[uniformName]; if (!uniform) { return; } + const gl = this._renderer.GL; + + if (uniform.isArray) { + if ( + uniform._cachedData && + this._renderer._arraysEqual(uniform._cachedData, data) + ) { + return; + } else { + uniform._cachedData = data.slice(0); + } + } else if (uniform._cachedData && uniform._cachedData === data) { + return; + } else { + uniform._cachedData = data; + } const location = uniform.location; - const gl = this._renderer.GL; this.useProgram(); switch (uniform.type) { @@ -521,4 +543,8 @@ p5.Shader.prototype.enableAttrib = function( return this; }; +p5.Shader.prototype._isArray = function(uniform) { + return uniform; +}; + export default p5.Shader; From 8debb51ee472f49d7453eb8f725199215e6e7497 Mon Sep 17 00:00:00 2001 From: Stalgia Grigg Date: Mon, 4 Nov 2019 16:37:24 -0800 Subject: [PATCH 02/11] Background caching --- src/webgl/p5.RendererGL.js | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/src/webgl/p5.RendererGL.js b/src/webgl/p5.RendererGL.js index dd8b73b63f..8a7f496ed3 100755 --- a/src/webgl/p5.RendererGL.js +++ b/src/webgl/p5.RendererGL.js @@ -169,6 +169,8 @@ p5.RendererGL = function(elt, pInst, isMainCanvas, attr) { this.fontInfos = {}; + this._cachedBackground = undefined; + return this; }; @@ -533,12 +535,19 @@ p5.RendererGL.prototype._update = function() { */ p5.RendererGL.prototype.background = function(...args) { const _col = this._pInst.color(...args); - const _r = _col.levels[0] / 255; - const _g = _col.levels[1] / 255; - const _b = _col.levels[2] / 255; - const _a = _col.levels[3] / 255; - this.GL.clearColor(_r, _g, _b, _a); - this.GL.depthMask(true); + if (this._cachedBackground) { + if (!this._arraysEqual(_col._array, this._cachedBackground)) { + const _r = _col.levels[0] / 255; + const _g = _col.levels[1] / 255; + const _b = _col.levels[2] / 255; + const _a = _col.levels[3] / 255; + this.GL.clearColor(_r, _g, _b, _a); + this.GL.depthMask(true); + this._cachedBackground = _col._array.slice(0); + } + } else { + this._cachedBackground = _col._array.slice(0); + } this.GL.clear(this.GL.COLOR_BUFFER_BIT | this.GL.DEPTH_BUFFER_BIT); }; @@ -1293,6 +1302,23 @@ p5.RendererGL.prototype._bindBuffer = function( /////////////////////////////// //// UTILITY FUNCTIONS ////////////////////////////// +p5.RendererGL.prototype._arraysEqual = function(a, b) { + if (a.length !== b.length) return false; + for (var i = 0; i < a.length; i++) { + if (a[i] !== b[i]) return false; + } + return true; +}; + +p5.RendererGL.prototype._isTypedArray = function(arr) { + let res = false; + res = arr instanceof Float32Array; + res = arr instanceof Float64Array; + res = arr instanceof Int16Array; + res = arr instanceof Uint16Array; + res = arr instanceof Uint32Array; + return res; +}; /** * turn a two dimensional array into one dimensional array * @private From e36fc18750cf3acc5b62c7e021f95ee3daa67d4c Mon Sep 17 00:00:00 2001 From: Stalgia Grigg Date: Mon, 4 Nov 2019 17:04:04 -0800 Subject: [PATCH 03/11] Reduce use of useProgram --- src/webgl/p5.RendererGL.js | 1 + src/webgl/p5.Shader.js | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/webgl/p5.RendererGL.js b/src/webgl/p5.RendererGL.js index 8a7f496ed3..e8e093ba7d 100755 --- a/src/webgl/p5.RendererGL.js +++ b/src/webgl/p5.RendererGL.js @@ -170,6 +170,7 @@ p5.RendererGL = function(elt, pInst, isMainCanvas, attr) { this.fontInfos = {}; this._cachedBackground = undefined; + this._curShader = undefined; return this; }; diff --git a/src/webgl/p5.Shader.js b/src/webgl/p5.Shader.js index cdf92cdf7b..820ae4539f 100644 --- a/src/webgl/p5.Shader.js +++ b/src/webgl/p5.Shader.js @@ -283,7 +283,10 @@ p5.Shader.prototype._setMatrixUniforms = function() { */ p5.Shader.prototype.useProgram = function() { const gl = this._renderer.GL; - gl.useProgram(this._glProgram); + if (this._renderer._curShader !== this) { + gl.useProgram(this._glProgram); + this._renderer._curShader = this; + } return this; }; From 06e833e44285cd079e7691fea09cb54e22652437 Mon Sep 17 00:00:00 2001 From: Stalgia Grigg Date: Mon, 4 Nov 2019 17:15:56 -0800 Subject: [PATCH 04/11] Better background caching --- src/webgl/p5.RendererGL.js | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/webgl/p5.RendererGL.js b/src/webgl/p5.RendererGL.js index e8e093ba7d..56acd95158 100755 --- a/src/webgl/p5.RendererGL.js +++ b/src/webgl/p5.RendererGL.js @@ -536,20 +536,19 @@ p5.RendererGL.prototype._update = function() { */ p5.RendererGL.prototype.background = function(...args) { const _col = this._pInst.color(...args); - if (this._cachedBackground) { - if (!this._arraysEqual(_col._array, this._cachedBackground)) { - const _r = _col.levels[0] / 255; - const _g = _col.levels[1] / 255; - const _b = _col.levels[2] / 255; - const _a = _col.levels[3] / 255; - this.GL.clearColor(_r, _g, _b, _a); - this.GL.depthMask(true); - this._cachedBackground = _col._array.slice(0); - } - } else { + const needsUpdate = + this._cachedBackground === undefined || + !this._arraysEqual(_col._array, this._cachedBackground); + if (needsUpdate) { + const _r = _col.levels[0] / 255; + const _g = _col.levels[1] / 255; + const _b = _col.levels[2] / 255; + const _a = _col.levels[3] / 255; + this.GL.clearColor(_r, _g, _b, _a); + this.GL.depthMask(true); this._cachedBackground = _col._array.slice(0); } - this.GL.clear(this.GL.COLOR_BUFFER_BIT | this.GL.DEPTH_BUFFER_BIT); + this.GL.clear(this.GL.COLOR_BUFFER_BIT); }; ////////////////////////////////////////////// From ae017cd3414bcffaa67b1097b6a9fa92f2c9ada6 Mon Sep 17 00:00:00 2001 From: Stalgia Grigg Date: Mon, 4 Nov 2019 18:21:02 -0800 Subject: [PATCH 05/11] Only change blend state in GL when necessary --- src/webgl/material.js | 23 ++++++++++++++++------- src/webgl/p5.RendererGL.js | 1 + 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/webgl/material.js b/src/webgl/material.js index 4435fc741e..2a861630f3 100644 --- a/src/webgl/material.js +++ b/src/webgl/material.js @@ -782,14 +782,19 @@ p5.RendererGL.prototype._applyColorBlend = function(colors) { const gl = this.GL; const isTexture = this.drawMode === constants.TEXTURE; - if (isTexture || colors[colors.length - 1] < 1.0 || this._isErasing) { - gl.depthMask(isTexture); - gl.enable(gl.BLEND); - this._applyBlendMode(); - } else { - gl.depthMask(true); - gl.disable(gl.BLEND); + const doBlend = + isTexture || colors[colors.length - 1] < 1.0 || this._isErasing; + if (doBlend !== this._isBlending) { + if (doBlend) { + gl.depthMask(isTexture); + gl.enable(gl.BLEND); + } else { + gl.depthMask(true); + gl.disable(gl.BLEND); + } + this._isBlending = doBlend; } + this._applyBlendMode(); return colors; }; @@ -799,6 +804,9 @@ p5.RendererGL.prototype._applyColorBlend = function(colors) { * @return {Number[]]} Normalized numbers array */ p5.RendererGL.prototype._applyBlendMode = function() { + if (this._cachedBlendMode === this._curBlendMode) { + return; + } const gl = this.GL; switch (this.curBlendMode) { case constants.BLEND: @@ -861,6 +869,7 @@ p5.RendererGL.prototype._applyBlendMode = function() { ); break; } + this._cachedBlendMode = this.curBlendMode; }; export default p5; diff --git a/src/webgl/p5.RendererGL.js b/src/webgl/p5.RendererGL.js index 56acd95158..282612e6a2 100755 --- a/src/webgl/p5.RendererGL.js +++ b/src/webgl/p5.RendererGL.js @@ -96,6 +96,7 @@ p5.RendererGL = function(elt, pInst, isMainCanvas, attr) { this.curBlendMode = this._cachedBlendMode = constants.BLEND; this.blendExt = this.GL.getExtension('EXT_blend_minmax'); + this._isBlending = false; this._useSpecularMaterial = false; this._useEmissiveMaterial = false; From cec95e733cf4d1aa304b69a340927a2c908e547e Mon Sep 17 00:00:00 2001 From: Stalgia Grigg Date: Mon, 4 Nov 2019 19:08:12 -0800 Subject: [PATCH 06/11] Typo fix --- src/webgl/material.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/webgl/material.js b/src/webgl/material.js index 2a861630f3..8048c7d315 100644 --- a/src/webgl/material.js +++ b/src/webgl/material.js @@ -804,7 +804,7 @@ p5.RendererGL.prototype._applyColorBlend = function(colors) { * @return {Number[]]} Normalized numbers array */ p5.RendererGL.prototype._applyBlendMode = function() { - if (this._cachedBlendMode === this._curBlendMode) { + if (this._cachedBlendMode === this.curBlendMode) { return; } const gl = this.GL; From 73a2d2bb2487c8e7cd92318ff87458514105cd37 Mon Sep 17 00:00:00 2001 From: Stalgia Grigg Date: Tue, 5 Nov 2019 09:16:56 -0800 Subject: [PATCH 07/11] Cleanup --- src/webgl/p5.Shader.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/webgl/p5.Shader.js b/src/webgl/p5.Shader.js index 820ae4539f..29f3e406ec 100644 --- a/src/webgl/p5.Shader.js +++ b/src/webgl/p5.Shader.js @@ -201,7 +201,6 @@ p5.Shader.prototype.compile = () => { p5.Shader.prototype.bindShader = function() { this.init(); if (!this._bound) { - // NEED TO MINIMIZE CALLS TO useProgram(); this.useProgram(); this._bound = true; @@ -546,8 +545,4 @@ p5.Shader.prototype.enableAttrib = function( return this; }; -p5.Shader.prototype._isArray = function(uniform) { - return uniform; -}; - export default p5.Shader; From 0f76e289a4eb494494146902e68e33e08ae8bffa Mon Sep 17 00:00:00 2001 From: Stalgia Grigg Date: Tue, 5 Nov 2019 09:33:23 -0800 Subject: [PATCH 08/11] Better array equal --- src/webgl/p5.RendererGL.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/webgl/p5.RendererGL.js b/src/webgl/p5.RendererGL.js index 282612e6a2..f1e068f33a 100755 --- a/src/webgl/p5.RendererGL.js +++ b/src/webgl/p5.RendererGL.js @@ -1304,8 +1304,9 @@ p5.RendererGL.prototype._bindBuffer = function( //// UTILITY FUNCTIONS ////////////////////////////// p5.RendererGL.prototype._arraysEqual = function(a, b) { - if (a.length !== b.length) return false; - for (var i = 0; i < a.length; i++) { + const aLength = a.length; + if (aLength !== b.length) return false; + for (let i = 0; i < aLength; i++) { if (a[i] !== b[i]) return false; } return true; From b56eaa59a2dcc85c91203729f75b6cef2aae681c Mon Sep 17 00:00:00 2001 From: Stalgia Grigg Date: Tue, 5 Nov 2019 11:04:46 -0800 Subject: [PATCH 09/11] Only enable vertexAttribute once, and blending fix --- src/webgl/p5.RendererGL.Retained.js | 4 ++-- src/webgl/p5.RendererGL.js | 3 ++- src/webgl/p5.Shader.js | 7 +++++-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/webgl/p5.RendererGL.Retained.js b/src/webgl/p5.RendererGL.Retained.js index cb499821c6..4daa99c307 100644 --- a/src/webgl/p5.RendererGL.Retained.js +++ b/src/webgl/p5.RendererGL.Retained.js @@ -130,8 +130,8 @@ p5.RendererGL.prototype._prepareBuffers = function(buffers, shader, defs) { gl.deleteBuffer(buffer); buffers[def.dst] = null; } - // disable the vertex - gl.disableVertexAttribArray(attr.index); + // no need to disable + // gl.disableVertexAttribArray(attr.index); } } }; diff --git a/src/webgl/p5.RendererGL.js b/src/webgl/p5.RendererGL.js index f1e068f33a..6e449d0370 100755 --- a/src/webgl/p5.RendererGL.js +++ b/src/webgl/p5.RendererGL.js @@ -94,7 +94,8 @@ p5.RendererGL = function(elt, pInst, isMainCanvas, attr) { this.curFillColor = this._cachedFillStyle = [1, 1, 1, 1]; this.curStrokeColor = this._cachedStrokeStyle = [0, 0, 0, 1]; - this.curBlendMode = this._cachedBlendMode = constants.BLEND; + this.curBlendMode = constants.BLEND; + this._cachedBlendMode = undefined; this.blendExt = this.GL.getExtension('EXT_blend_minmax'); this._isBlending = false; diff --git a/src/webgl/p5.Shader.js b/src/webgl/p5.Shader.js index 29f3e406ec..53f79e5f42 100644 --- a/src/webgl/p5.Shader.js +++ b/src/webgl/p5.Shader.js @@ -531,8 +531,11 @@ p5.Shader.prototype.enableAttrib = function( const loc = attr.location; if (loc !== -1) { const gl = this._renderer.GL; - gl.enableVertexAttribArray(loc); - gl.vertexAttribPointer( + if (!attr.enabled) { + gl.enableVertexAttribArray(loc); + attr.enabled = true; + } + this._renderer.GL.vertexAttribPointer( loc, size, type || gl.FLOAT, From 5f08b31217b1109d0427502ae9b65e8785eb5d41 Mon Sep 17 00:00:00 2001 From: Stalgia Grigg Date: Tue, 5 Nov 2019 11:05:59 -0800 Subject: [PATCH 10/11] Get rid of old manual tests leftover from merge --- .../webgl/interaction/orbitControl/sketch.js | 33 ------------------- .../webgl/lights/noLights/index.html | 17 ---------- .../webgl/lights/noLights/sketch.js | 18 ---------- .../webgl/lights/spotLight/index.html | 17 ---------- .../webgl/lights/spotLight/sketch.js | 15 --------- 5 files changed, 100 deletions(-) delete mode 100644 test/manual-test-examples/webgl/interaction/orbitControl/sketch.js delete mode 100644 test/manual-test-examples/webgl/lights/noLights/index.html delete mode 100644 test/manual-test-examples/webgl/lights/noLights/sketch.js delete mode 100644 test/manual-test-examples/webgl/lights/spotLight/index.html delete mode 100644 test/manual-test-examples/webgl/lights/spotLight/sketch.js diff --git a/test/manual-test-examples/webgl/interaction/orbitControl/sketch.js b/test/manual-test-examples/webgl/interaction/orbitControl/sketch.js deleted file mode 100644 index e24677cfab..0000000000 --- a/test/manual-test-examples/webgl/interaction/orbitControl/sketch.js +++ /dev/null @@ -1,33 +0,0 @@ -function setup() { - createCanvas(windowWidth, windowHeight, WEBGL); - - // controls should work whether or not camera center is set to (0,0,0) - // camera(0, 0, 500, 300, 0, 0, 0, 1, 0); -} - -function draw() { - background(250); - var radius = width; - - orbitControl(1, 1, 0.1); - - normalMaterial(); - - let scale = 200; - for (let px = -5; px < 5; px++) { - for (let pz = -5; pz < 5; pz++) { - push(); - rotateX(PI); - translate(px * scale, 0, pz * scale); - if (px > 0) { - fill(255, 0, 0); - } - if (px === 0 && pz === 0) { - cone(50, 100); - } else { - cone(20, 50); - } - pop(); - } - } -} diff --git a/test/manual-test-examples/webgl/lights/noLights/index.html b/test/manual-test-examples/webgl/lights/noLights/index.html deleted file mode 100644 index ef2cf9f556..0000000000 --- a/test/manual-test-examples/webgl/lights/noLights/index.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/test/manual-test-examples/webgl/lights/noLights/sketch.js b/test/manual-test-examples/webgl/lights/noLights/sketch.js deleted file mode 100644 index ab8523f924..0000000000 --- a/test/manual-test-examples/webgl/lights/noLights/sketch.js +++ /dev/null @@ -1,18 +0,0 @@ -function setup() { - createCanvas(windowWidth, windowHeight, WEBGL); -} - -function draw() { - background(0); - - ambientLight(150, 0, 0); - translate(-200, 0, 0); - ambientMaterial(250); - sphere(50, 64); - - noLights(); - ambientLight(0, 150, 0); - translate(400, 0, 0); - ambientMaterial(250); - sphere(50, 64); -} diff --git a/test/manual-test-examples/webgl/lights/spotLight/index.html b/test/manual-test-examples/webgl/lights/spotLight/index.html deleted file mode 100644 index ef2cf9f556..0000000000 --- a/test/manual-test-examples/webgl/lights/spotLight/index.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/test/manual-test-examples/webgl/lights/spotLight/sketch.js b/test/manual-test-examples/webgl/lights/spotLight/sketch.js deleted file mode 100644 index e29589ea0a..0000000000 --- a/test/manual-test-examples/webgl/lights/spotLight/sketch.js +++ /dev/null @@ -1,15 +0,0 @@ -function setup() { - createCanvas(windowWidth, windowHeight, WEBGL); - setAttributes('perPixelLighting', true); -} - -function draw() { - background(0); - - ambientLight(50); - spotLight(0, 250, 0, 0, 0, 200, 0, 0, -1, -Math.PI / 16, 5); - spotLight(250, 0, 0, 0, 200, 200, 0, -1, -1, Math.PI / 16, 5); - - ambientMaterial(250); - sphere(70, 64); -} From f2f217881f38d85d7dbb1942a4851c164fdc1573 Mon Sep 17 00:00:00 2001 From: Stalgia Grigg Date: Tue, 5 Nov 2019 13:06:35 -0800 Subject: [PATCH 11/11] Add comment about RendererGL.GL --- src/webgl/p5.RendererGL.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/webgl/p5.RendererGL.js b/src/webgl/p5.RendererGL.js index 6e449d0370..c49deb6eed 100755 --- a/src/webgl/p5.RendererGL.js +++ b/src/webgl/p5.RendererGL.js @@ -63,6 +63,9 @@ p5.RendererGL = function(elt, pInst, isMainCanvas, attr) { this._setAttributeDefaults(pInst); this._initContext(); this.isP3D = true; //lets us know we're in 3d mode + + // This redundant property is useful in reminding you that you are + // interacting with WebGLRenderingContext, still worth considering future removal this.GL = this.drawingContext; // erasing