Reputation: 607
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
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
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