diff --git a/src/core/rendering.js b/src/core/rendering.js index 6d5aa5804a..0d7d53d26a 100644 --- a/src/core/rendering.js +++ b/src/core/rendering.js @@ -326,12 +326,11 @@ p5.prototype.createGraphics = function(w, h, renderer, canvas) { * @example *
* - * let prev, next, cam; + * let prev, next; * function setup() { * createCanvas(100, 100, WEBGL); * prev = createFramebuffer({ format: FLOAT }); * next = createFramebuffer({ format: FLOAT }); - * cam = createCamera(); * noStroke(); * } * @@ -345,12 +344,11 @@ p5.prototype.createGraphics = function(w, h, renderer, canvas) { * background(255); * * push(); - * // Draw the previous texture farther away, but scaled - * // up to fill the screen, plus a bit extra scale so it grows - * translate(0, 0, -200); - * scale(1.001 * (200 + cam.eyeZ) / cam.eyeZ); * tint(255, 253); * image(prev, -width/2, -height/2); + * // Make sure the image plane doesn't block you from seeing any part + * // of the scene + * clearDepth(); * pop(); * * push(); @@ -375,6 +373,76 @@ p5.prototype.createFramebuffer = function(options) { return new p5.Framebuffer(this, options); }; +/** + * This makes the canvas forget how far from the camera everything that has + * been drawn was. Use this if you want to make sure the next thing you draw + * will not draw behind anything that is already on the canvas. + * + * This is useful for things like feedback effects, where you want the previous + * frame to act like a background for the next frame, and not like a plane in + * 3D space in the scene. + * + * This method is only available in WebGL mode. Since 2D mode does not have + * 3D depth, anything you draw will always go on top of the previous content on + * the canvas anyway. + * + * @method clearDepth + * @param {Number} [depth] The value, between 0 and 1, to reset the depth to, where + * 0 corresponds to a value as close as possible to the camera before getting + * clipped, and 1 corresponds to a value as far away from the camera as possible. + * The default value is 1. + * + * @example + *
+ * + * let prev, next; + * function setup() { + * createCanvas(100, 100, WEBGL); + * prev = createFramebuffer({ format: FLOAT }); + * next = createFramebuffer({ format: FLOAT }); + * noStroke(); + * } + * + * function draw() { + * // Swap prev and next so that we can use the previous + * // frame as a texture when drawing the current frame + * [prev, next] = [next, prev]; + * + * // Draw to the framebuffer + * next.begin(); + * background(255); + * + * push(); + * tint(255, 253); + * image(prev, -width/2, -height/2); + * // Make sure the image plane doesn't block you from seeing any part + * // of the scene + * clearDepth(); + * pop(); + * + * push(); + * normalMaterial(); + * translate(25*sin(frameCount * 0.014), 25*sin(frameCount * 0.02), 0); + * rotateX(frameCount * 0.01); + * rotateY(frameCount * 0.01); + * box(12); + * pop(); + * next.end(); + * + * image(next, -width/2, -height/2); + * } + * + *
+ * + * @alt + * A red, green, and blue box (using normalMaterial) moves and rotates around + * the canvas, leaving a trail behind it that slowly grows and fades away. + */ +p5.prototype.clearDepth = function(depth) { + this._assert3d('clearDepth'); + this._renderer.clearDepth(depth); +}; + /** * Blends the pixels in the display window according to the defined mode. * There is a choice of the following modes to blend the source pixels (A) diff --git a/src/webgl/p5.RendererGL.js b/src/webgl/p5.RendererGL.js index 171b4aa622..80f2132124 100644 --- a/src/webgl/p5.RendererGL.js +++ b/src/webgl/p5.RendererGL.js @@ -1507,6 +1507,15 @@ p5.RendererGL = class RendererGL extends p5.Renderer { this.GL.clear(this.GL.COLOR_BUFFER_BIT | this.GL.DEPTH_BUFFER_BIT); } + /** + * Resets all depth information so that nothing previously drawn will + * occlude anything subsequently drawn. + */ + clearDepth(depth = 1) { + this.GL.clearDepth(depth); + this.GL.clear(this.GL.DEPTH_BUFFER_BIT); + } + applyMatrix(a, b, c, d, e, f) { if (arguments.length === 16) { p5.Matrix.prototype.apply.apply(this.uMVMatrix, arguments);