A-Frame Tips

I've spent the last week diving into A-Frame, a toolkit from Mozilla for quickly building VR experiences on the Web. Unlike most other Javascript libraries, A-Frame is centered around declarative markup rather than functions and callbacks. This makes it much easier to get started and learn. Throughout the week I've written down a few notes to share with you.

Links and events don't work without a cursor

As of version 0.6.0 A-Frame has a new Link component to jump between pages. Before this version you could create your own navigation component to change the document url. However, if you are just getting started you may be surprised that links and click events don't work out of the box. It turns out all events in A-Frame are synthetic (since it's designed to work with many kinds of VR headsets), so you will need to add a cursor to your scene to make events fire. Your code will look like this:

<a-scene>
.... some markup
<a-camera>
<a-cursor color="red"></a-cursor>
</a-camera>
</a-scene>

Background Music

You can create a sound in an A-Frame scene using the a-sound element, but sound is always positional. This means the sound will become louder or quieter as you move closer or away from the position of the sound. If you want an object in the scene to emit some sound, just put the sound inside the object.

Positional sound is great, but how do you create background music that is the same loudness from wherever you are in the scene? Easy: add the sound to the camera! The camera is always at the same place in the scene, relative to the viewer, so the sound will always have the same volume. This is what I've done to create background music for my game:

<a-camera>
<a-sound src="url(hub-music.mp3)" autoplay="true"
position="0 0 0" loop="true" volume="0.5"></a-sound>
</a-camera>

Fixed Dialogs

When you create a scene in A-Frame you are placing objects in certain positions so that you can walk around them. Sometimes, however, you need something that is fixed to the screen, such as a HUD display. To do this we can use the same solution as background music, put the fixed object inside the camera.

<a-camera>
<a-box id='box' position="0 0 -3" rotation="0 0 0" color="#4CC3D9"></a-box>
</a-camera>

Flat Shading

A-Frame has two forms of flat shading and they are very, very different.

If you set the material.flatShading property to true then it will turn off smooth shading for that object. This means each face of the object will receive only one color, creating a low-poly look that has become popular recently. Most importantly, the lights in the scene will still affect this object.

However, if you set the material.shader property to flat, then it will use the THREE.FlatShading instead of THREE.StandardShading. This different shader does not use the lights in the scene. Instead the object will have full brightness regardless of the lights or viewing angle. Generally this setting is used for object should should look the same regardless of where they are in the scene, like a background image or a video.

<a-box material="flatShading:true">  for low poly look
<a-box material="shader:flat"> for objects not affected by lighting

Planes are Vertical

By default the plane object is, counterintuitively, vertical and centered at 0,0,0. The camera is also at 0,0,0 but only shows things starting at a short distance in front. This means if you just drop a plane into your scene without any other settings you won't be able to see it. If you want to use a plane for the floor, be sure to rotate it around the X axis by 90 degrees.

<a-plane rotation="-90 0 0" color="red" width="100" height="100"></a-plane>

The code above creates a horizontal plane below the viewer at floor height (since the default camera is at height 1 and the plane is at height 0).

Low Poly is Easy

Most people fill their A-Frame scenes with high resolution models, as you typically find in video games. However, if you are a fan of the cute low-poly style, that is easy as well. I've been building things out of spheres. To give them that special look I switch to flat shading, reduce the number of faces, and then make sure they are well lit with directional lights. The contrast between light and shadow is what gives them that low poly look.

a red sphere
<a-entity position="0 50 -0"
rotation="0 0 75"
material="flatShading:true; color: #ffff00"
geometry="primitive:sphere; radius:5; segmentsWidth: 8; segmentsHeight:5"
/>

You may notice that I gave it a slight rotation around the Z axis. This helps to show off more angles.

Talk to me about it on Twitter

Posted July 24th, 2017

Tagged: