yhu420
yhu420

Reputation: 607

Fade out whole screen in A-Frame

I would like to make the screen fade out to black, and fade it back in programmatically. I could not find a clever solution to this yet. I know I can fade in and out an entity using the material's opacity, but can you apply this to the whole screen or the camera?

Thank you

Upvotes: 0

Views: 763

Answers (2)

Diarmid Mackenzie
Diarmid Mackenzie

Reputation: 826

I was able to do this using an opaque geometry around the camera, like in Piotr's answer. I used a box rather than a sphere, with material="side:back".

However I had to make some adjustments for the solution to be viable in my situation (specific context is that I was using a bunch of semi-transparent objects in my scene, and A-Frame/THREE.js tend to struggle with multiple semi-transparent layers).

  • I found that the presence of an additional layer with opacity=0 caused some flickering and other visual effects on other semi-transparent layers that I had in my scene. Usual trick for this kind of problem is to set renderer="sortObjects: true" on the scene, but I still got flickering even with this setting. The solution I adopted was to have the sphere be invisible (rather than just opacity=0) until it is needed for the fade-out, and then I made it visible again after fading in.

  • This caused further problems, where making the object visible and immediately starting the animation on the opacity attribute didn't work (it just snapped to black with no animation). I found that leaving a 50msec gap afterbetween setting the object to visible, and beginning my fade was enough to get a smooth fade effect.

  • One other observation (which I didn't come up with a solution for) is that this didn't get me a pitch black. There was a small residual glow directly in front of the camera.

Given the above complexity, it seems to me that a camera-based solution would be better, but I haven't yet found a way to do that.

Upvotes: 0

Piotr Adam Milewski
Piotr Adam Milewski

Reputation: 14655

I'd go with a simple approach - change the opacity of a black sphere around the camera:

<script src="https://aframe.io/releases/1.1.0/aframe.min.js"></script>
<script>
  // declare the component
  AFRAME.registerComponent("foo", {
    init: function() {
      // grab the "fading sphere"
      var fadingEl = document.querySelector("#lord-fader")
      // when clicked - emit the defined "startEvent"
      this.el.addEventListener("click", e => fadingEl.emit("animate"))
    }
  })
</script>
<a-scene cursor="rayOrigin: mouse" raycaster="objects: .interactable">
  <a-text position="-0.75 2.5 -4.5" value="click to animate" color="black"></a-text>
  <a-sphere class="interactable" position="0 1.25 -5" radius="1.25" color="#EF2D5E" foo></a-sphere>
  <a-plane position="0 0 -4" rotation="-90 0 0" width="4" height="4" color="#7BC8A4"></a-plane>
  <a-sky color="#ECECEC"></a-sky>

  <a-camera>
    <!-- our fake-fade sphere -->
    <a-sphere id="lord-fader" radius="0.05" 
              material="shader:flat; color: black; opacity: 0.0; side: double " 
              animation="property: material.opacity; from: 0.0; to: 1.0 dur: 500; dir: alternate; loop: 2; startEvents: animate"></a-sphere>
  </a-camera>
</a-scene>


A simpler solution could be animating a HTML element overlaid over the a-frame scene. A harder solution would be post-processing.

Upvotes: 3

Related Questions