Custom RenderNode - Cross-fade slide transition

Instead of the default fly-to animation when going from one slide to the next, this sample implements a custom RenderNode that applies a cross-fade transition when changing to different slides.

A new FadeRenderNode is created when a slide change is initiated by the user. When render node is ready, the desired slide is applied to the view, changing the view's camera to the new viewpoint in the background without a fly-to animation.

Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
9
10
11
slideThumbnail.onclick = async () => {
  // create a new fade render node, and set its animation speed
  const node = new FadeRenderNode({ view });
  node.duration = speed.value * 1000;

  // Wait for node to capture current view before going to next one
  await node.ready;

  // apply slide without fly-to animation
  slide.applyTo(view, { animate: false });
}

On its creation, the FadeRenderNode immediately captures the current framebuffer (input), and returns that captured framebuffer until the animation starts.

Use dark colors for code blocksCopy
1
2
3
4
5
6
7
// hold on to the framebuffer when the render function runs the first time
if (!this._startFramebuffer) {
  this._startFramebuffer = input; //retain ensures framebuffer is kept in memory
  this._startFramebuffer.retain();
  this._resolve?.();
  return this._startFramebuffer;
}

Once animation starts, the FadeRenderNode takes the current framebuffer (input) and the initially captured framebuffer (_startFraembuffer) and blends them together in each frame, according to animation time (delta). This creates the actual cross-fade effect between the start and the target view.

Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
9
10
11

const currentTex = input.getTexture(gl.COLOR_ATTACHMENT0);
const startTex = this._startFramebuffer.getTexture(gl.COLOR_ATTACHMENT0);


#fragment shader
void main() {
  vec4 current = texture(currentTex, uv);
  vec4 start = texture(startTex, uv);
  fragColor = mix(start, current, delta);
}

When the animation is done, FadeRenderNode has finished its job. _startFramebuffer can be released, and the render node destroys itself.

Use dark colors for code blocksCopy
1
2
3
4
5
6
if (delta >= 1) {
  this._startFramebuffer.release();
  this._startFramebuffer = null;
  this.destroy();
  return input;
}

Your browser is no longer supported. Please upgrade your browser for the best experience. See our browser deprecation post for more details.