An Intro to A-Frame
Articles Blog

An Intro to A-Frame

October 12, 2019


– [Josh] Mozilla Hacks,
an Intro to A-Frame. So I’ve been working
on this module series, this workshop series,
this series of modules, on a bunch of different topics, and the idea is that this
should be simple enough for anybody to work through on their own or for a teacher to use as
the basis of a workshop. Even if you haven’t used A-Frame before, it should give you enough that you could put on a workshop. And I’ve got some notes here. The modules we got so far is the Introduction to
HTML, WebXR, and A-Frame, then Basic Geometry, Audio,
Lighting, Images, and Physics. Today I’m gonna skip Images,
and Physics, and Audio because they all use large files which just aren’t gonna
be very appropriate for a 13k competition. Physics doesn’t use any resources like MP3s or PNG images, but the Physics library
itself is pretty large. So we’re gonna start with our Introduction to
HTML, WebXR, and A-Frame. We’re gonna go through
and build our first thing. So the first thing I want you to do is open up this webpage. This is a glitch. So a glitch is a live coding environment, and it has this really cool thing where one person can create a glitch. Here’s a simple webpage. You can then go to this glitch, click Remix on Glitch. Now it is making a copy for you. I like to use the word
remix instead of fork because remix to a person who hasn’t been a programmer
for years and years, remix makes a lot more sense. The way it works is every time you type here, this is HTML as you undoubtedly know. Make this a little bigger. Now I can see a live version
in this tab over here. It says Hello World. Now I’m gonna go back
and say Hello Universe. And when I flip back over,
it has already updated. So it’s this live environment where you can create anything web-based, and immediately see
what you’re working on, and immediately share
it with other people. It’s all on its own website. So in this case it generated one called colossal-hedge.glitch.me. It’s all secure, you don’t have to worry about setting up certs or any of that stuff. It just works beautifully. So I’ve been using glitch
for all of these workshops. Now if you haven’t done HTML before, I’ll show you like this is header one which then becomes this
big text right here. Each one of these p elements is paragraph which is p stands for paragraph, and each of those becomes something here in the final document. And so if I was to add something, I want to build a cool game too. Now when I flip over, we’ll see that paragraph. So everything here in my source document goes into my final document. Now let’s take a look. Let’s do the same thing, except I’m gonna paste over
it with our A-Frame project. And now we can see here is a red sphere. So we’ll ignore this for now. It just sets up the page and
imports A-Frame like that. You can see here’s the scene and inside the scene is a sphere which is radius one, color red, and that’s the position. Let’s make it bigger. Let’s set radius two. Flip it over, that is
a very nice big sphere. Let’s change the color, how about tan? T-A-N. Yep, and you can see it’s
already got lighting set up. I can already move around. Now let’s supposed we
wanna have another sphere. Just create another thing here, a-sphere, radius equals one, color is, let’s make it aqua, and position. Now position is important. So the position is actually three numbers in three-dimensional space, x, y, and z. If you remember from math class in school, you have the x-axis and the y-axis where the x-axis goes left to right and the y-axis is up and down. Well, we have a third one now, the z-axis, which is into the screen
or away from the screen. And for various historical reasons, a negative value is into the screen, and away from the screen
is a positive value. Since we’re looking into the screen, let’s set it to negative four. And of course our other
sphere is right in the way, so let’s move this sphere off to the left which should be negative two, and move our new sphere off to the right which should be positive one. And you notice I set this to zero zero, and it’s actually below me. Well, that’s because the camera is not at zero, zero, zero. It is at zero, about 1.5, zero. So a height of 1.5 because these dimensions are actually meters, and it assumes that you’re standing up, and the average height is
somewhere around 1.5 meters. So there we go, that
looks a little better. So that is actually all
there really is to A-Frame. You create these objects and you can do cool stuff with them. So let’s head down to, we covered position. Oh yeah color. So we can change the color. You can use any color you want. It understands all of the CSS color names, so red, green, blue, yellow should work. Yep, probably even like golden rod, just one of those weird
orang yellow colors. And of course you can just
use hex values if you want, so I can do ff00ff would be magenta. So anything you would use in
the CSS, you can use here. We can also set the background
of the entire scene. Right now it is white. And you can set background to color red, and that would be, oh,
very hard on the eyes. Let’s set the background
to tan, how about that? Yeah that’s a little less offensive. And let’s set this to, let’s say teal. There we go. Much nicer. Now we’ve got spheres but we can do other things like cubes or boxes. So a-box. Again let’s set the position to zero, 1.5, zero, oops, negative four. I can put the position at zero for the z, but then it’s actually at the camera which means I probably
wouldn’t be able to see it ’cause it’s actually
too close to me to see. So, say negative four,
there’s our white cube. Let’s give it a different color, teal. And let’s give it a width,
let’s make it a little wider. So two, height is 0.5 so it’ll be really skinny. And then with the depth at one. And we can even rotate it to zero, zero, zero. Let’s rotate around the y-axis, let’s say 45 degrees. Oops, not rotate, rotation, there we go. So that’s the box. And again we could add as
many of these guys as we want. So if I wanted to build something
out of boxes and spheres, it’s pretty easy to do. For example if I wanna create
this Mickey Mouse shape, I just add a couple spheres, position them where I want it to be, change the colors, that works nice. And there’s a bunch of other shapes, there’s cones, cylinders. And in fact let’s go take a look at the A-Frame website, aframe.io. Let’s go to Docs. Now the A-Frame website
has some really good getting started tutorials, a lot of examples of all the crazy complicated things you can do. I wanna go down to the Docs here. These are all standard components. Let’s click at, let’s see we’ve got the box which you’ve already seen. We’ve got a circle. Now a circle is different than a sphere. A circle is an infinitely flat circle. So if you try to look at it edge on, then you wouldn’t be able to see anything. It’s used more for things like signs, or if you want, the floor of a surface. We got cones, cones, cylinder. Ooh, let’s do an a-dodecahedron. Let’s copy that over. Let’s add a dodecahedron here. We’ll give it a position of zero, 1.5, negative four. And dodecahedron. That might actually be too big. Let’s back it up, there we go. Whoa, dodecahedron, pretty
cool, and ginormous. Also we got icosahedron, octahedron, the plane which is just a
giant rectangle in space, a true ring, a torus, tetrahedron. Ooh, torus-knot is extra cool because you can set some parameters and get all sorts of funky things. Let’s set up our torus-knot. You can say how much
of an arc it should be, the radius of it, and the
radius, the tube part. Let’s set its color, position. Let’s get rid of these guys. And see what our torus-knot looks like. Whoa, that is a pretty cool shape. And if we change these
two q and p parameters. Let’s change that to three, and you can see the type of shape changes. And that is a very strange-looking donut. How about 7.1? Whoa. So with very little code, you even got all sorts
of cool crazy shapes. Let’s try 1.2. Interesting. I think only integers will
make the ends line up. So yeah torus-knot is pretty sweet. So all of this are built into A-Frame so you don’t pay anything
extra to use those. Alright, let’s get on
to the next workshop. So we talked a little bit about geometry, cylinders and cubes. And the way A-Frame works, everything is an entity. I’m using here like a-sphere radius equals one, color is red, and the oops, position zero, 1.5, negative five. This is okay, back to our sphere. Let’s look at the underlying geometry because it’s not actually a sphere. Computer graphics cards
can’t render a true sphere. At some point it has to
turn that into a series of flat surfaces usually triangles. So we can do, it says, oops. Let’s say wireframe equals true, true, there we go. So now we can take a look at
the actual underlying geometry. You can see it’s made up
of a whole bunch of stuff. And in fact it will let you, you can adjust how many, how it’s subdivides the underlying surface into those triangles. So in the case of the
a-sphere, we can say, segments, that’s the word I
was looking for, segments. So right now we can say
the default is to have 18 horizontal segments
and 36 vertical segments, which gives it this mostly
some weird-looking sphere. But maybe I want a really pixelated kind of a retro low poly style, so let’s set segmentsWidth to 10, and cut it down, let’s try eight. Oops, what am I missing here? SegmentsWidth is eight. Oh right. There we go. Segments-width. Sorry, when we’re doing
it as an attribute, it’s gotta be lowercase
with a dash in the middle. So now we can see that it cut down the total number of segments. Horizontally, segments-height,
set that also to eight. Now it’s a much more low
poly-looking sphere here. So you can adjust the underlying geometry which can be very useful depending on the kind of
effect you’re getting. And if you wanna look at the
geometry for any of these, just add wireframe equals true and you can see what’s
going on underneath. Now in A-Frame most objects are 3D, but some are in fact 2D. Yes, you really can have a
2D object in 3D graphics. They are just infinitely thin. So if you take a look at this little demo, come on, there we go, you can see when it gets to the edge, it is infinitely thin, but you don’t notice that. Now if you do notice that, your object disappears
when it goes around, and then reappears if it
continues all the way around. Then the problem is that you now are using a one-sided, oops, you are now using a one-sided object. Bring back my lesson, there we go. So make sure that you
turn it on both sides. That’s cool. And the way you do that is with, let’s see inside out
spheres, triangles, nope. Here we go. Let’s set side equal to double. You can set side to
front or back or double. For these two-dimensional objects, you can determine which side
you wanna actually be drawn. Now you might wonder, well,
why would you ever want something other than double side? You might be going for a special effect, or it may simply be that no one’s ever gonna
look at the other side, so it makes sense to not ever draw it just because that’s less polygons for the computer to process, and therefore your
project will run faster. Like if you’re making a floor, as long as no one’s ever
going below the floor, then you don’t need to draw
the bottom of the floor. And every polygon helps. Okay. Then you can also import 3D
objects in the gltf format, and gltfs are pretty slim for
containing full 3D geometry, but it’s still difficult to
find some that are gonna fit under13k even when compressed. So I’ll just let you know that they exist. You can use the gltf model attribute and a URL to the gltf file. Though for this competition, if you are using one of these, this should be a local relative URL. And then you can look
at cool stuff like this. Alright. Next thing we’re gonna cover is lighting. Lighting is exciting because it doesn’t really cost you anything extra in terms of bytes just to set up the light but it can dramatically
change how the scene looks. So here is a simple rotating cube. Now you’ll notice because
of where the light is that the cube looks
darker on the right side than on the left side. And that is because there
is a light set up here. Now by default A-Frame will
create some lights for you. So that’s why we can see stuff even though we don’t have any lighting turned on. But for this, let’s go back to
our nice little sphere here, if we turn off wireframe, there we can start to see
a little more of the edges, but even though it’s pretty low poly, it looks fairly smooth. Let’s add a light. So we’ll copy this out here, and add a directional light. Now the color of the light is white. You can have other colored lights, but it’s good to start with white because then it shows the true color of the thing you’re showing off, which in this case is red. So this light is a directional light which means it exists
in some point in space, but it’s not really a single point, it’s more like it’s infinitely distant. So whether you move left or right, it’s still coming from the same direction. Think like moonlight or sunlight, rather than, say, light bulb where you could get closer
or further away from it, and the angle matters. So we give it a position but really the position is actually a vector from the origin pointing in the direction
that the light is shining, and this is the white light. So, now we see we have
just this one light, and the shadow is much
darker than it was before. Well, that’s because by default, A-Frame actually creates
two lights for us, one is a directional light and one is an ambient light. You see in computer graphics, it only draws lights that we add, but in real life there’s nothing that’s ever truly in shadows, there’s always a little bit of light unless it’s nighttime, and even then there is
still a little bit of light that’s bouncing around the scene, but that’s too difficult
to model on a computer at least in real time with
the system we have available. So what we do is we add
this ambient light component which just means give
everything and every surface, no matter where it is and
what direction it’s pointing, give it a little bit of light. So let’s add in our ambient light here. Let’s give it, where’s
the ambient, there we go. Okay so we have a-light
directional with a position, and a-light ambient. Again the color is white, but I don’t want it to be full brightness, we just wanna bump it up a little bit so I gave it an intensity of 0.5. It doesn’t have a position because it doesn’t matter where it is, it’s ambient, it affects
everything equally. And now we can see in the shadow, it still has a little bit of color. Often you will wanna add just like a theater, a movie thing, you wanna have two lights,
directional lights, coming from different angles. So let’s set this to negative one. That’s a little too even, let’s make it a little darker. Intensity equals 0.2. And let’s move it to negative four. Let’s see how that looks, oops. Maybe give it a little
more of a highlight, move it around two. There we go. So now we have a little bit of highlight and this is our main light, and then with our ambient
fills in the shadows. So it looks a little more realistic. Okay. So those are the main two point
types that you’re gonna use. There’s a third type
that we use very commonly called the point light. Point lights are more expensive than ambient and directional, so only use them when
you really need them. But if you want something that looks like, actually before I get into point lights, let’s talk about, let’s talk about emissive. So if we’re gonna build a scene like this, we actually need two things. We do want the angle to matter. So I’m gonna use a point light where it has a position in space. And so this one is a little
closer to this thing. This is a little further away and the angle is more oblique so it fades. And then even though it’s completely dark, we want this thing to
actually glow at night. So that’s what an emissive surface is. So let’s come back here. Let’s change the background of our scene to black, there we go. Let’s create, let’s make
our sphere be a light grey. Get rid of that. Here is our light grey sphere. Now you’ll notice, we can still see it ’cause we have some lights in here, the default light. But what we want is
for it to actually glow even from a light grey. There we go. Now it’s actually producing its own light and so it gives us a uniform color. Now let’s add a point light which will take away the default ones that A-Frame gives us. So let’s put in a point light here. By the way sometimes I put the light before the objects in my scenes, sometimes I put them after. It doesn’t actually make a difference. The order that you put
things in the document doesn’t make a difference for
how it shows up on the screen. It will always do the right thing. So here’s a point light inside of where the moon is with intensity of one
and a distance of 50. So that means anything
that’s more than 50 away won’t show any light at all. Let’s add our, where’s my cubes? I had some cubes in here. There we go. Let’s just add a cube. a-box position equals negative 1, zero, 1. Color is red. And why can I not see it, oops. I want it to be, oops, negative
four like that, there we go. Now we can see our cube, it’s being lit here by the point light, but that’s obviously way too dark. So let’s give it a plane below. Let’s add a plane. The plane is gonna fill a lot of space. I made the width 40 and height 40. And that may seem weird ’cause height would be
like up and down, right? Planes are actually up
and down by default, so they’re our width and
height, and they have no depth. But we want this to be
on the floor, not a wall, so what we need to do is position it and then give it a
rotation around the x-axis which sort of folds it down. And now it looks like this. There, now we’ve got our plane, and you can see how the point light is nicely lighting up the plane, and it drops off as
the plane gets further, it gets darker and darker over there. And we’re not even using shadows yet and we’ve already got a scene with a lot of mood and a
lot of complex lighting and very little code. Okay so the next thing we
want is an actual shadow. Now shadows are a little tricky ’cause they involve three things. There is light which will
be used to create the shadow which is gonna be the moonlight here. There is the object which
is casting the shadow, which will be this cube. And then there’s the object
which is receiving the shadow, and receiving means that it’s the thing that is holding the shadow, like the cube is gonna cast shadow onto the floor, onto our plane. So what we need to do is, let’s go to our point light. And where is our point light? Let’s set castShadow equals true. I don’t need any of that. So I’m gonna turn on casting shadows. And we don’t see it, that’s ’cause there’s another part, we’ve gotta make the box do, it is shadow cast is true, right. And then we need the plane
to receive the shadow. So shadow-receive equals true. Remember to spell this i
before e except after c. Okay what did I miss? Shadow, oops. It’s not actually shadow-cast true, it’s shadow cast is true, shadow receive is true. I forget the syntax all the time, so if you do, don’t worry about it, that’s why I keep the
A-Frame documentation open. And so shadow receive is true. Let’s look it up, a-light, attributes, there’s the type. Oh, apparently we can’t set
up shadows with the a-light. We’ve got to use the longer syntax. So something I’ve kind of skipped over that we’re gonna have to dive into now. These things are shorthands. So and when I’m saying a-sphere, what I’m really doing is this. I’m saying a-entity, and the entity has a
bunch of components on it. One of those components is geometry, geometry mesh is sphere. I believe is what I wanna do. Then I would say like
material color is red. And position, that’s, oh wait, we’re
duplicating this one. So mesh is sphere, radius is one, color is light grey, and emissive is light grey, position is four, four, negative four. And if I did that right, we should see that, except it is a box, which means I have messed up my syntax. What we want is geometry, for, oh, not mesh, primitive. See, if you’re coding
in the Three.js level, it would be called mesh, but we’re using A-Frame, there we go. So that previous sphere, what we’re really doing
is we have an entity and it has all these components, and one of the components is geometry which is all of the attributes
which describe the shape, one is the material which
is the color of the object and how light interacts with it, and then one is the position. So we need to do the same for light. a-entity light equals type is point, shadow is true, position, oops, just get these here. Color is gray, intensity is one, distance is 50. And make sure that tag matches up. Oh, I forgot this position, equals four, four, negative four. There we go. Okay so here is my object
that light is projecting. We’ve got shadows turned on the cube, shadows receiving, so casting on the cube, receiving on the plane,
and then sending it up. Now what’s really cool is
that these are all live. So if I was to do something like, let’s add, where’s our
little rotation here? I always steal for myself. So I wrote some code here which makes this guy rotate. So now let’s just go take
a look, ah, there we go. Now let’s add some animation
so this box will rotate. And there we go. And you can see how the shadow, it’s completely live and updating which looks really awesome. Now shadows are still fairly
computationally expensive. There are things you can do, you can adjust like where the shadow falls to kinda reduce the computation. It’s running perfectly
smooth here on my desktop, it might not on my smartphone. So that’s something to be aware of. Let’s get rid of that. So that is the basics
of lighting and shadows. If you wanna dig some more into this, then you can find it on my
GitHub at webxr-workshops. I’m posting this in right here. Now I’m working on the next workshop which hopefully will come out this week is on doing advanced geometry, and that’s gonna be very
useful for this project because with advanced geometry, instead of using just the
primitives that we’ve been given, we can create our own shapes using math. So if you wanna create this weird wavy surface that animates, you could do that. So that’ll be coming in advanced geometry. In the meantime, on the A-Frame Docs, there is a demo of
Register a Custom Geometry where you can create custom geometry and then use it just
like we were using box. So in this one for example they
created one called Example, which then it goes down
to the Three.js level to create some geometry using input data, and then creates all the
phases, does all the setup, and sets it as a geometry
which you can then add to any other object just like we would with the cube or the sphere. So thank you all very much. Please reach out to me, send me an email, [email protected] I’m on Twitter, YouTube. Like me in all the places. I always hear my son
watching YouTube videos, and they always end with, “Okay, you guys, click
Like and Subscribe,” so click Like and Subscribe. And definitely message me on Slack if you have any other questions. I’ll be back in one week where I’m gonna do, and ask me anything about WebXR. So if you have questions about this, please come by there and ask me anything. Thank you all and have a good week, bye.

Only registered users can comment.

Leave a Reply

Your email address will not be published. Required fields are marked *