Skip to content

Commit 5f00840

Browse files
committed
Improved imageLight performance by implementing framebuffer instead of graphics
1 parent 37d3324 commit 5f00840

File tree

2 files changed

+47
-36
lines changed

2 files changed

+47
-36
lines changed

src/webgl/light.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1144,6 +1144,7 @@ p5.prototype.noLights = function(...args) {
11441144
this._assert3d('noLights');
11451145
p5._validateParameters('noLights', args);
11461146

1147+
this._renderer.activeImageLight = null;
11471148
this._renderer._enableLighting = false;
11481149

11491150
this._renderer.ambientLightColors.length = 0;

src/webgl/p5.RendererGL.js

Lines changed: 46 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -480,10 +480,10 @@ p5.RendererGL = class RendererGL extends p5.Renderer {
480480
this.activeImageLight = null;
481481
// If activeImageLight property is Null, diffusedTextures,
482482
// specularTextures are Empty.
483-
// Else, it maps a p5.Image used by imageLight() to a p5.Graphics.
484-
// p5.Graphics for this are calculated in getDiffusedTexture function
483+
// Else, it maps a p5.Image used by imageLight() to a p5.framebuffer.
484+
// p5.framebuffer for this are calculated in getDiffusedTexture function
485485
this.diffusedTextures = new Map();
486-
// p5.Graphics for this are calculated in getSpecularTexture function
486+
// p5.framebuffer for this are calculated in getSpecularTexture function
487487
this.specularTextures = new Map();
488488

489489
this.drawMode = constants.FILL;
@@ -553,6 +553,7 @@ p5.RendererGL = class RendererGL extends p5.Renderer {
553553
this.executeZoom = false;
554554
this.executeRotateAndMove = false;
555555

556+
this.specularShader = undefined;
556557
this._defaultLightShader = undefined;
557558
this._defaultImmediateModeShader = undefined;
558559
this._defaultNormalShader = undefined;
@@ -1914,33 +1915,36 @@ p5.RendererGL = class RendererGL extends p5.Renderer {
19141915
* To create a blurry image from the input non blurry img, if it doesn't already exist
19151916
* Add it to the diffusedTexture map,
19161917
* Returns the blurry image
1917-
* maps a p5.Image used by imageLight() to a p5.Graphics
1918+
* maps a p5.Image used by imageLight() to a p5.Framebuffer
19181919
*/
19191920
getDiffusedTexture(input) {
19201921
// if one already exists for a given input image
19211922
if (this.diffusedTextures.get(input) != null) {
19221923
return this.diffusedTextures.get(input);
19231924
}
19241925
// if not, only then create one
1925-
let newGraphic; // maybe switch to framebuffer
1926+
let newFramebuffer;
19261927
// hardcoded to 200px, because it's going to be blurry and smooth
19271928
let smallWidth = 200;
19281929
let width = smallWidth;
19291930
let height = Math.floor(smallWidth * (input.height / input.width));
1930-
newGraphic = this._pInst.createGraphics(width, height, constants.WEBGL);
1931-
// create graphics is like making a new sketch, all functions on main
1932-
// sketch it would be available on graphics
1933-
let irradiance = newGraphic.createShader(
1934-
defaultShaders.imageLightVert,
1935-
defaultShaders.imageLightDiffusedFrag
1936-
);
1937-
newGraphic.shader(irradiance);
1938-
irradiance.setUniform('environmentMap', input);
1939-
newGraphic.noStroke();
1940-
newGraphic.rectMode(newGraphic.CENTER);
1941-
newGraphic.rect(0, 0, newGraphic.width, newGraphic.height);
1942-
this.diffusedTextures.set(input, newGraphic);
1943-
return newGraphic;
1931+
newFramebuffer = this._pInst.createFramebuffer();
1932+
// create framebuffer is like making a new sketch, all functions on main
1933+
// sketch it would be available on framebuffer
1934+
newFramebuffer.draw(() => {
1935+
let irradiance = this._pInst.createShader(
1936+
defaultShaders.imageLightVert,
1937+
defaultShaders.imageLightDiffusedFrag
1938+
);
1939+
this._pInst.shader(irradiance);
1940+
irradiance.setUniform('environmentMap', input);
1941+
this._pInst.noStroke();
1942+
this._pInst.rectMode(constants.CENTER);
1943+
this._pInst.noLights();
1944+
this._pInst.rect(0, 0, width, height);
1945+
});
1946+
this.diffusedTextures.set(input, newFramebuffer);
1947+
return newFramebuffer;
19441948
}
19451949

19461950
/*
@@ -1962,31 +1966,37 @@ p5.RendererGL = class RendererGL extends p5.Renderer {
19621966
const size = 512;
19631967
let tex;
19641968
const levels = [];
1965-
const graphic = this._pInst.createGraphics(size, size, constants.WEBGL);
1969+
const framebuffer = this._pInst.createFramebuffer();
19661970
let count = Math.log(size) / Math.log(2);
1967-
graphic.pixelDensity(1);
1971+
framebuffer.pixelDensity(1);
1972+
if (!this.specularShader) {
1973+
this.specularShader = this._pInst.createShader(
1974+
defaultShaders.imageLightVert,
1975+
defaultShaders.imageLightSpecularFrag
1976+
);
1977+
}
19681978
// currently only 8 levels
1969-
// This loop calculates 8 graphics of varying size of canvas
1979+
// This loop calculates 8 framebuffers of varying size of canvas
19701980
// and corresponding different roughness levels.
19711981
// Roughness increases with the decrease in canvas size,
19721982
// because rougher surfaces have less detailed/more blurry reflections.
19731983
for (let w = size; w >= 1; w /= 2) {
1974-
graphic.resizeCanvas(w, w);
1984+
framebuffer.resize(w, w);
19751985
let currCount = Math.log(w) / Math.log(2);
19761986
let roughness = 1 - currCount / count;
1977-
let myShader = graphic.createShader(
1978-
defaultShaders.imageLightVert,
1979-
defaultShaders.imageLightSpecularFrag
1980-
);
1981-
graphic.shader(myShader);
1982-
graphic.clear();
1983-
myShader.setUniform('environmentMap', input);
1984-
myShader.setUniform('roughness', roughness);
1985-
graphic.noStroke();
1986-
graphic.plane(w, w);
1987-
levels.push(graphic.get().drawingContext.getImageData(0, 0, w, w));
1988-
}
1989-
graphic.remove();
1987+
framebuffer.draw(() => {
1988+
this._pInst.shader(this.specularShader);
1989+
this._pInst.clear();
1990+
this.specularShader.setUniform('environmentMap', input);
1991+
this.specularShader.setUniform('roughness', roughness);
1992+
this._pInst.noStroke();
1993+
this._pInst.noLights();
1994+
this._pInst.plane(w, w);
1995+
});
1996+
levels.push(framebuffer.get().drawingContext.getImageData(0, 0, w, w));
1997+
}
1998+
// Free the Framebuffer
1999+
framebuffer.remove();
19902000
tex = new MipmapTexture(this, levels, {});
19912001
this.specularTextures.set(input, tex);
19922002
return tex;

0 commit comments

Comments
 (0)