Virtual Reality 101: Build Your Own 3D World with HTML | Alvin Wan | Skillshare

Playback Speed

  • 0.5x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 2x

Virtual Reality 101: Build Your Own 3D World with HTML

teacher avatar Alvin Wan, AI PhD Student at UC Berkeley

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Lessons in This Class

7 Lessons (56m)
    • 1. Introduction

    • 2. Immersion in 3 Simple Steps

    • 3. AFrame "Hello World"

    • 4. Step 1. Primitives

    • 5. Step 2. Color

    • 6. Step 3. Motion

    • 7. Conclusion

  • --
  • Beginner level
  • Intermediate level
  • Advanced level
  • All levels

Community Generated

The level is determined by a majority opinion of students who have reviewed this class. The teacher's recommendation is shown until at least 5 student responses are collected.





About This Class

In this class, I’ll show you three simple steps to convert ANY scene into a beautiful virtual reality getaway! With this skill, you will be able to build interactive virtual reality experiences for anyone to experience. This class will touch on several takeaways:

  • What are the components of an immersive virtual reality experience?
  • The three simple steps to a beautiful virtual reality scene
  • How to experience your virtual reality scene, with Google Cardboard, Oculus Quest etc.
  • Guided walkthrough for one natural scene conversion into virtual reality
  • Code available for three additional completed, beautiful virtual reality scenes

The class is highly interactive, as we’ll be coding together. By the end of the class, you will understand how to build virtual reality scenes from scratch. So, let’s build your ideal virtual reality getaway together!

Interested in more creative coding? Follow me on Skillshare to be the first to hear about more Spring 2021 creative coding courses!

Interested in data science or machine learning? Check out my Coding 101 (Python), SQL 101 (Database Design), Data 101 (Analytics), or Computer Vision 101 (Applied ML) classes.


Acknowledgments: B-roll used in introductory video CC-0 licensed by fauxels, cottonbro, max fischer, pressmaster, julia m cameron, miguel a padrinan on Pexels.

Meet Your Teacher

Teacher Profile Image

Alvin Wan

AI PhD Student at UC Berkeley

Top Teacher

Looking to learn coding? machine learning? Let me help! I'm a computer science lecturer and PhD student at UC Berkeley, where I've taught for 5 years. I've designed a few courses to get you started -- not just to teach the basics, but also to get you excited to learn more. Check out the courses on my profile! Or scroll down for a guide to getting started.

Website | Github | YouTube | Twitter | Research


Featured Reviews

"Alvin Wan is a fantastic teacher. The instruction format was just what I was looking for. This is fun due to the format... Due to Alvin's teaching method I'm not only grasping the content I'm having fun le... See full profile

Class Ratings

Expectations Met?
  • 0%
  • Yes
  • 0%
  • Somewhat
  • 0%
  • Not really
  • 0%
Reviews Archive

In October 2018, we updated our review system to improve the way we collect feedback. Below are the reviews written before that update.

Why Join Skillshare?

Take award-winning Skillshare Original Classes

Each class has short lessons, hands-on projects

Your membership supports Skillshare teachers

Learn From Anywhere

Take classes on the go with the Skillshare app. Stream or download to watch on the plane, the subway, or wherever you learn best.


1. Introduction: Most storytelling is done through words and drawings, leaving gaps for the viewer's imagination to fill. But what if you, as a storyteller, could design an entire experience leaving no gaps? What if you could share a virtual world, a virtual reality in its entirety? Hi, I'm Albert. I received International Design recognition from brands like Adobe for the past few years. I've also taught several 100 students how to code through Airbnb earning over 50 five-star reviews. In particular, I've taught this exact to your class countless times in person. For the first time, I'm packaging this into an online class for you. In this class, you'll learn the three simple steps to convert any natural scene into a beautiful virtual reality experience. You'll build the foundations of your VR coding skills as you view the world around you in a different lens. This class is made for all levels. No coding experience is required, and even seasoned web developers will find value in creating their own virtual world. This class is for you, if you're a coder looking for creativity, a creative looking for coding, or an onlooker looking for both. The goal is to give you a new tool, a new space as a storyteller. With the virtual reality, you're no longer constrained to a page or a flat screen. The audience is actually in your world. Right now, as you're watching this video, think of a beautiful scene in nature then take the next lesson. You're just three steps away from stepping into the world that you are just imagining. Let's get started. 2. Immersion in 3 Simple Steps: Your project for today is to create a virtual reality experience that encapsulates your favorite scene in nature. It could be a childhood park, a summer hide out, your first ever campsite. You don't need a virtual reality headset for this class. A standard computer browser works just fine. However, to fully experience your virtual world, I highly recommend the Google Cardboard for 15 bucks or if you're a VR junkie, I'd highly suggest the Oculus Quest 2. No need to make your scene realistic. Your scene should reflect how you see it, and here's why, immersion in a virtual world doesn't just mean photorealism. It means cohesive across visual, audio, and motion cues engage at the viewer in all these ways and that is an immersive virtual experience. In the next few lessons, you'll build just that, an immersive virtual reality experience in just three steps. First, breakdown your scene into a number of different primitives, like cylinders and boxes. Second, add lighting. Change your materials to add color, reflections, and shadows. Third, add motion. Keep your audience engaged with something to look at in the scene. This could be leaves rustling, water flowing or flames rising. My advice to you, start small. A scene with a few objects and a clear focus, but complete all three steps, primitives, lighting, and motion. Then you can graduate to more and more complex scenes as you become more comfortable and more confident. I hope you still have that easy, breezy, beautiful scene in your head. In the next lesson, we'll start to make your imagination into virtual reality. 3. AFrame "Hello World": Welcome to Lesson 3. In this lesson, you'll create your very first Virtual Reality model, a Hello World VR model, using a library called a A-Frame. Start by navigating to this URL 101/helloworld, this will open a new project in glitch. You should see a screen like my right half of the screen, some files, some code and a header that is cut off my recording. Then I suggest placing your glitch and sculpture windows side-by-side as shown here. I'm going to minimize my file browser by clicking on the arrow that's pointing to the left so that you can see more of my code at once. You don't have to do this. To explain the code that you're looking at, you're looking at an HTML webpage. HTML is made up of a bunch of tags, like the one shown on the left. Tags have a start tag and an end tag as shown here, and tags are denoted using the forward slash. If you're already a Web Dev Pro, you can skip over the first minute or so where we talk about HTML. This is your Hello World HTML code, notice the entire document is wrapped with an HTML tag. Here's a start tag, and here's the end tag. Inside of the HTML tag, there are a pair of head and body tags. These three tags, HTML, head and body, more or less define the starting point of any HTML document. Inside the head tag, we add invisible properties of the webpage, in this case, we've added a title for the webpage, and we've also added a line that allows us to create Virtual Reality experiences using head frame. Inside the body, we add the Virtual Reality scene using a-scene. I've added two lights for you, we'll talk about lights in more detail later. Back to the slides. Throughout this class, you'll create objects in this virtual world using HTML, the simplest of objects are called primitives. Primitives are basic duty shapes like cubes, cones, and spheres. In A-Frame, you create a primitive by using an HTML tag. As we said before, tags in HTML have a start tag and an end tag as shown here. End tags are denoted using the forward slash. There are several different tags we will use, all tags have the same less than, greater than, and forward slashes as denoted in black here. However, each tag will have a different tag names denoted in orange here. For example, here's the body tag that we saw earlier in A-Frame, here's a box tag, this creates a cube in our virtual world. Here are all the parts annotated, let's try this code now. Go ahead and click right where it says, "Your code here." I'm going to click on the end of line 11, hit "Enter", and now type in less than a dashed box grater than. Notice that glitch auto completes to end tag after we add a greater than. If you have a typo, for example, let's say I forget the dash, I'll type in a box, Glitch will create an end tag with your typo. You'll need to fix both the start and the end tags manually. To preview your model, go ahead and click on the top-left, "Show", and then click on, "Next to the code". Right now, this preview looks empty, you don't see anything, but that's because we're inside of the box. Go ahead and click into this preview window, use the arrow keys or WASD to move outside of the box, and here is the box on the ground. You can also drag with your mouse to rotate your camera. Primitives can be customized in a few different ways using components. For example, here's the box we just defined, we can now add the shadow component. This component shadow will allow the box to cache and received shadows, it does not require a value. Let's try this now. Back inside of your code, go ahead and right before this greater than sign, I'm going to type in shadow. Once again, to preview your model, go ahead and click on the preview window and then use the arrow keys or WASD to move around, and you can see now there is a shadow. We can also change the color of the box, we will do that by setting the color component equal to the blue value. The text colors here are only used for emphasis. The purple text is the component name, the pink text is the component value. Sometimes I'll add line breaks between properties like this, this is just so that you can see all of my code without me scrolling horizontally, whether I put all of the code on one line or on multiple lines, the code would behave the same way. Now, let's change the color of your box to blue, so in your code on the right hand side, I'm going to click on this to minimize our preview so you can see more of my code. Right after that shadow, I'm going to type in color equals "Blue". Make sure don't forget your double-quotes. Once again, to open the preview, you can go to a show and next to the code. However, in this case, I noticed that the preview's already been opened because there is a gray box behind this button, so I can go ahead and click on this button on the right to re-expand my preview. Once I have re-expanded my preview click into the preview and I can move around to see my brand new blue box with the shadow. Let's change the position of our box. Position is defined using three axes. The x-axis is horizontal, positive x is right, negative x is left. The y-axis is vertical, positive y is up, negative y is down. Finally, the z-axis sticks out of the screen, positive z is towards you, negative z is away from you, here are the three axes illustrated. To change the position of the box, set the position attribute. The first coordinate is x, the second coordinate is y, and the third coordinate is z. Here we changed the z coordinate to negative three, this means we move the box three units away from us. Notice the coordinates are denoted without commas, just spaces between each pair of coordinate values. Let's go ahead and try this in code, I'm going to once again minimize my preview window by clicking on the right arrow. In here, I'm going to now type position equals "0 0 -3". Now, if I re-expand my preview, you can see the box without having to move the camera manually. It is especially important to include double-quotes around your attribute value, so don't forget those. To complete your knowledge of transformations we'll also cover rotation. The three axes are the same as before, we can rotate along the horizontal or x-axis, the vertical or y-axis, or the z-axis which points straight out of the screen towards us. To understand which way a positive rotation turns, use your right-hand. Curl your right hand into a fist and with your thumb pointed in the axis positive direction, the curl of your fingers indicates a direction of positive rotation. Try this now, curl your right hand into a fist, except with the thumb sticking out. You can verify the x-axis, and z-axis rotating arrows here are correct, positive z rotation rotates the object left, positive x rotation rotates the object towards you. To change the rotation of the box, set the rotation attribute. The first coordinate is x, the second coordinate is y, and the third coordinate is z. Here we changed the x-coordinate to nine degrees. To understand what direction that is, check with the diagram in the top left and check your curled right-hand. Positive x rotation rotates the box towards us. Notice coordinates are denoted without commas, just like before, just spaces between each pair of coordinate values. Don't forget double-quotes around your attribute value. Let's try this now, I'm going to minimize the preview and then type in here rotation equals, and I'm going to actually write 9 0 0. Go ahead and re-expand your preview, now, you can see that the box has rotated towards us very slightly. We can move left if we're not quite convinced. Now, we'll cover three tips for keeping your HTML code organized. Tip Number 1, add an ID to all tags, I'm going to show you now in the code. Go ahead and minimize your preview, and inside of your code, I'm going to add another attribute here, ID equals player. Since we just have one object, this ideas don't help too much, however, in later lessons we'll have many objects. At that point, IDs are very helpful for finding objects in our scene. Next, we'll need to explain what a frame of references in order to introduce our second tip. First, I'll create another entity, this entity is not actually an object, it's just a way for us to group objects together. Go ahead and type in "A-entity id equals to parent". I'm going to delete the automatically created end tag, and I'm going to paste it right after this tag on the bottom, the original box that we created. Once I've done that, I'm going to select this line 13, with a player, and I'm going to tap. This tag is what we call the parent tag or parent element. We refer to the box as the child tag or child element. Then I will move the parent, not the box to the right, change the parents position to 1 0 0. Go ahead and type in "position equals 1 0 0". If you open up your preview, you'll notice the box has now moved to the right as well. Go ahead and minimize your preview. I'm now going to move the box up, here I'm going to change the y-value in the position to attribute to one. If I open my preview, you can see now that the box has moved up. What's going on exactly? Let's go ahead and look at this frame of reference. Our parent was moved to the right as shown in the diagram on the top half of the slide. Relative to the parent, our box was moved up as shown in the bottom half of the slide. As a result, we perceived the child box as being in the top right of the screen, this is what is called a frame of reference. This leads us to our second tip, which is to use parent entities to group objects together, this keeps our code more organized. You'll see examples of this in later lessons. Tip Number 3 is to indent all children tags. Here's an example, you may have noticed me indenting inadvertently to some degree Glitch also does this for you, with proper indentation you can tell which primitives belong to which objects. That's it for our three tips. In the top left click on "Show", and then in a new window. In this new window, you can then access the URL for the web page. You can share this URL with anyone that you'd like to view your VR model. If you'd like, you can now load up your VR experience in your VR headset. If you have a Google Cardboard, load the URL on your phone, click on the "Virtual Reality button" in the bottom right, which says VR right here, then put the phone into Google Cardboard. Take a look through the lens. You may have to turn around to find your blue box. The process is similar for an Oculus Quest, access the Oculus browser, and access the URL. The Oculus browser will access the website directly in VR mode. This concludes the lesson, you've learned a lot in this lesson. This is a quick summary of the concepts you've touched on primitives, components, position, rotation, and frame of reference. You also got three tips for clean organized HTML code. If you'd like to access and download the slides, visit this URL. That's it for your Hello World Virtual Reality model. In the next lesson, we'll start building our Virtual Reality version of a scene in nature. 4. Step 1. Primitives: Welcome to Lesson 4. In this lesson, we'll start converting a scene in nature into a virtual reality experience. Start by navigating to this URL, aaalv/vr101/helloworld. This will open a new product in Glitch. You should then see a page like the one on my right, a file browser, a heading that is cut off and some code. Like before, I suggest placing your Glitch and Skillshare window side-by-side as shown here. In these next three lessons, we'll make a stylized virtual reality version of a temple. I've pulled photos from a website called, where you can find high-quality, free to use photos. In particular, I've picked one of the first photos of a temple, a Japanese shrine or gate. The takeaway from this lesson is learning how to simplify pictures like this one into basic primitives like boxes and cylinders. There are four parts to this lesson. In part 1, I will cover the basic primitives for this temple. Here's the temple again. On the right-hand of the screen, I'm going to click on the left arrow to minimize the file browser so that you can see more of my code. Let's go ahead and get started. Start by defining an entity to contain your temple. Note this entity is not actually an object in your VR world, is just a way for us to group other objects together. Go ahead and click on line 16 in your file, I'm going to add a few extra lines and then type a-entity ID equals to temple. That is the ID of our temple. This spacing right front here, so I've added a few different tabs, that doesn't actually matter but just to keep your code clean. I have tabbed it so that it's aligned with the previous lines. Now that I've got the ID, let's go ahead and add the shadow so that your temple can cast and receive shadows. All child objects will inherit the ability to cast and receive shadows. We'll also change the position. I'm going to move the temple up by one and back away from the viewer by three units. Let's now start by making the left pillar. To stylize this model a little bit, we'll use a cone so that the base of the pillar is wider than the tip of the pillar. Before we begin defining this left pillar, go ahead and click in-between your two start and end tags. Hit enter to create a new line. I'm going to do that again and then hit tab so that now you can define your child tags within the temple. As always, start by identifying the primitive, the ID of the left pillar. We're going to make a cone and then type in ID equals to pillar-left. I'm going to add a greater than sign to complete the cone. Now, give it a radius on the bottom of 0.15. I'm going to type in radius-bottom equals 0.15. You'll notice that I've created a new line here instead of just a space between the two components, ID and radius-bottom. This line break is completely optional. You could keep all of your code on one line if you wanted to. I chose to create a new line for each component so that you don't need to scroll horizontally to see the code for this pillar. Let's next define a top radius of 0.07. Radius-top equals to 0.07. We'll also give it a height of two because the temples origin is at y is equal to 1. Let's now define height equals to two and we move the pillar to the left by 0.65, which means x-coordinate of negative 0.65. In case you're wondering how I got these oddly specific values like 0.07. I tuned these values beforehand to find the best value. If you're wondering how to pick the best value yourself, I've got a tip. This tip is to use the A-Frame Inspector. Now because my screen is already so tiny, I'm going to maximize my Glitch window. Here is now my Glitch window maximized. To use the A-Frame Inspector, you'll first have to open the preview. I'm going to click on the top-left show next to the code. Now you can see my preview on the right hand side, you can see the one cone standing up the left pillar for your temple. Inside of your preview window, click inside of your preview window, then hit control option I, all at once to launch the Inspector. In the Inspector, you can then select the object that you want. In my case, I'm going to select the pillar. Then you can change any attribute you want and see its impact visually in real time. In order to see more of this Inspector, I'm going to drag this resizable bar right here. So here I'm going to actually change the y position to be lower or higher. I can also change the rotation along any of the axis that I want. However, you might want to plug in here 30, for example, to see what it looks like rotated along the x-axis by 30 degrees. Important note though, without additional setup, you can't actually save the edits that you make inside of the Inspector. For simplicity, you should make as few changes as possible in the Inspector. This is just because the export function in the top-right, right here, as of the time of this recording, actually sometimes fails to export your adjusted settings. So in short, use the Inspector to see changes quicker, but add your adjusted settings to HTML manually to be safe. I'm now going to click on back to the scene so that I can close the inspector. I'm also going to drag this preview window so that's a little bit smaller and then I'm going to minimize the preview by clicking on the arrow. Now, let's go ahead and copy and paste for the second pillar. Just to be consistent, I'm going to click right after this double quote and hit enter. Then I'm going to copy and paste this code and paste right below and then rename this to pillar-right. The right pillar is just to the right of the origin. We're going to change the x-axis value to positive, so 0.65. Now I'm going to show you both the picture and the code side-by-side once more. So here's the temple once more. Next, define the lower of the two bars running horizontally. We're going to define here a-box, we're going to give it an ID, so this is bar-lower. Then we're going to set the width, height, and depth. However, instead of defining the width, height, and depth separately, I'll use the scale attribute. This attribute as it sounds like, scales the object in each direction, scale of one is equal to width of one. So the first coordinate is the scale along the x-direction or in other words, the width. We're going to set scale equals two and the width will be two. We're going to make it short, so the height will be 0.15 and we're going to make it a little bit wide, so the depth is going to be 0.1. Finally, we're going to give it a position. Let's raise the bar to a height of 0.65. So we're going to type in position equals zero, 0.65, zero and make sure to add a greater than sign and that will complete the tag for you. Next we're going to define the higher of the two bars running horizontally. Start by defining the primitive. So we're going to write a-box, give it an ID, just like always. We're going to now set scale equals 2, we're going to give it a width of 0.2, a height of 0.2 and a depth of 0.25. Then raise the bar to a height of 1.05, so position equals 0, 1.050. Now, we've scaled the objects so that it has some width, height, and depth, and we've also given it a position where we only change the y-coordinate so that the object is higher. Finally, we're going to add a cap. This top, very, very tippy top portion of the temple. Once again, this is going to be a box, so I'm going to go to the end of line 31 for my file, and hit Enter, then let's type in a-box, and we're going to give it an id just like usual, cap-higher. We're going to make it slightly wider and deeper than the bar beneath it. It needs to be slightly wider, so instead of 2.2, it's going to be 2.6. It looks pretty thin in the photo, so I'm going to give it a height of 0.05, and it also needs to be slightly deeper, so we're going to give it a depth of 0.3. We're going to raise the bar to a slightly higher position. Position equals zero along the X-axis, a Y-coordinate of 1.15, and then a Z-coordinate of zero. Type in greater than to complete your tag. This actually completes our temple. Let's now take a look and see what the template looks like. Click on this preview on the left-hand side, and here you can see a temple. Here is now the completed temple and we can see that it somewhat visually matches the temple on the left. If your temple doesn't look like mine, as in a piece is missing, or a piece is not at the right position, double-check that you're code matches mine in this section for the temple. Your code may be missing a few different double-quotes, make sure you include those double quotes, or it may be missing an end tag. You can also go to this URL, to see a completed version of this code. In the next step, we're going to now define a lantern. I'm going to once again open up my code in full screen. Underneath this temple, so make sure this is outside of the a-entity tag. We're going to now create a lantern. Define a lantern, a-entity, this is just a group, or objects together, and we're going to identify the lantern with lantern-center. They're going to be three lanterns, and this lantern is going to be in the center. We're going to once again give it the ability to cast and receive shadows, and we're going to move it so that it is zero units, so that it is in the center, and then it's also one unit off the ground, and then three units away from us. Go ahead and add a greater than sign to complete your tag. I'm going to add this position right in between my start and end tags, hit Enter twice, and hit Tab once so that I am inside of this lantern. Top off the lantern with a triangular prism. Here we're going to identify the primitive which is a cone, a-cone. We can then effectively make a triangular prism by using a cone, and setting the number of radial segments to be four. Here we're going to first identify the cone with id equals to lantern-cone. We're going to give it, segments-height equals to one, and then we're going to give it full radial segments; segments-radial equals to four. Once again, don't forget your double-quotes, and don't forget your dashes. We're going to now set flash shading to true. Otherwise the shadows and shading will still look round or like a regular cone. I'm going to type in flat-shading equals to true. Now, we can set the radii, so the bottom radius will be 0.1, and then the height of this object will be 0.09. Don't forget that equal sign like I almost did. Then we're going to move this triangular prism up a little bit, so position equals to zero, 0.16, zero. Then we're going to rotate it so that it is facing us. I'm going to hit Enter here right after this double quote, and there's our triangular prism. I see what this looks like, I'm going to open up the preview on this right hand-side. If you haven't already, make sure to click on Show, and then Next to The Code. If you see there's gray box right behind this Next to The Code like mine has, then that means your preview is already open so click on the arrow right over here. You can see there's a floating triangular prism right there in between your true pillars. Now, we're going to add a box for the roof of the lantern underneath that triangular prism. In your code, right after this cone, I need to tab that once more. Again, that white space, that tab doesn't really matter, it's just to help us see how the code is organized. We just want to see visually that this cone is inside of this lantern. Now that we've got this cone, let's add the box for the roof of the lantern. We're going to type in a-box give an id just like before, lantern-roof is going to be our id. Now, let's set the width, height, and depth. We're going to type in scale equals 0.2, 0.02, 0.2. Then give it a position of one that is slightly high up. This is just a little bit raised up. What this means is again, the width is 0.2, the height is 0.02. This should actually be 0.2. Again, the scale is width of 0.2, height of 0.02, and depth of 0.2. You can now see if you move around this world, again, click into your preview, use the arrow keys or WST, and you can now see that there is a roof right underneath that triangular prism. Now, let's add a box for the bottom of the lantern. This is the box that we just created, I'm going to move to the end and hit Enter. Then now we're going to create another box; a-box, id equals to lantern-bottom. Scale equals to a width of 0.15, a height of 0.02, and a depth of 0.15. Once again add a greater than sign to complete your tag. Now, there is the bottom of the lantern. We're now going to add a glowing looking orb, a sphere with emissive properties. We'll add an actual light to lantern in the next lesson. Type in a-sphere, id equals to lantern-orb, radius equals to 0.03. We're going to move it up a little bit, a tiny bit by 0.05, opacity equals to one, and emissive equals to white. What this final property does is it makes the object look like it's glowing. You can actually see that white orb right over there. It looks like it's glowing. That doesn't seem to have any shadows cast onto it. That's what this emissive property does. [inaudible] that double quote, I'm going to enter just like before so that we can see how this is organized. Now, again, if you're wondering how I got these really, really strange 0.03, 0.05, and 0 values, this is just me tuning values inside of the A-Frame Inspector, and then copying them over. Now, I'm going to go back to the split screen, and for our final and last step, we're going to clone that lantern two more times. We're not going to copy and paste, we're going to do something a little bit cleaner. Back to the code in full screen. This was the lantern that we had just created in the previous step. We're now going to clone this lantern a few extra times. Go ahead and type in a-entity. Just like before, give it an id of lantern. We're going to define this as a lantern that is to the left. We're going to type in a new component that we haven't seen before. This is clone is equal to lantern-center. You can give this whatever value you would like. I'm giving it a position of negative 1.25. To indicate a lantern to the left, I'm going to raise it up off the ground, and I'm going to move it away from us. There is your Lantern. I'm going to do this one more time so that we have a third lantern on the right-hand side. I'm going to type in a-entity, id is equal to lantern-right, and clone is equal to lantern-center. We're going to clone the central lantern, and then I'm going to give it a position. Position equals 1.5, 2, negative 2.5. Now, we have three total lanterns. I'm going to move this in a little bit so you can see the third lantern there are our three lanterns. Just to explain this clone component, we are actually using what are called CSS selectors. With CSS selectors, the pound sign, or the hashtag denotes an id. You specify the original lantern using an id of lantern-center. That's what this clone component does. We didn't cover any new concepts in this lesson, but we've practiced the concepts we learned in the previous lesson. [inaudible] component and staying organized by grouping entities. We also covered two extra tips. One is the inspector, the A-Frame Inspector that we saw for tuning values. The second is the clone components. This allows us to keep our code organized instead of copying and pasting. If you'd like to access and download these slides, visit this URL. This concludes step 1. In step 2, we'll add color to your scene. 5. Step 2. Color: Welcome to Lesson 5. In this lesson, we'll continue converting a scene in nature into a virtual reality experience in particular, we'll be adding color to our experience. Start by navigating to this URL, This will open up a new project in Glitch. Like before, I suggest placing your Glitch, and Skillshare windows side by side as shown here. We'll first expand our knowledge of components, then we'll change colors, and add lighting to the scene. Let's start with components. Here is a component that we've seen before. The color component has one value, blue. This is called a single-property component. It has one property which is the value of the color. Here is a component that we haven't seen before called material. Material is what's called a multi-property component because it supports multiple properties like color and opacity. The property names are shown here in blue, like before, the values are shown here in pink. Notice that to separate property names from property values, we use colons denoted in red. To separate properties from each other, we use semi-colons denoted in red. We're now going to use multi-property components to change the color of the sky. Now, let's color our sky. This is our Step 2 starter code. Once again, I'm going to minimize the file browser here. I'm going to start referring to objects inside of our scene by their ID, so the IDs that we assigned it here. Let's go ahead, and navigate to the scene. The scene is this tag right out here on line 13. Darken the sky by setting the background components color property, type in background equals color, and then we're going to give it a purple color. This pound sign now denotes a hex value. We're going to type in 0011a, this is just one way to define a color. Now see what this looks like. Go ahead and open your preview window, click on "Show", next to the code. If you've already done this, then they'll be a gray box behind next to the code, just like mine, in which case you can click on the preview on the left. You can see there's that dark purple in the background. Now that's it for the sky. Let's next change the color of the ground. In our code, we're going to change the ground's color to be an indigo. The ground is at the very bottom. This is line 42 with an a-plane. I regretfully should have given this an ID, but it is what it is. Let's now change the grounds color to be in indigo. The current color is white or fff. We're going to change this to be a #841fde, and this is actually also a shade of purple. Right now, this looks absolutely horrendous, but we'll change this later on. That concludes the ground. Next, let's talk about some lights. Before we continue coding, I'll have to explain the five different types of lights you can use in A-frame as a version 1.1.0. There's no need to memorize these, you can always google A-Frame lights to find this list of lights again. In this lesson, I wanted to find each light visually so that you can get an intuition for when to use what light. Here is the scene we'll be using. The first type is an ambient light. It's an omnipresent light. Think of it like the exposure in your camera. All entities are equally affected by the ambient light. Turning down the intensity of the ambient will darken all objects, and increasing the intensity will brighten all objects. You can also add color to the ambient light to give it a scene of warm or cool taste. Back to the original settings. The second light is a directional light. Directional light you can think of like the sun. It's the light casting the box's shadow in this VR environment. Turn down the intensity of the directional light, and you get less contrast in your shadows, and here's even less contrast. Notice that I could've turned up the overall exposure using ambient lights. However, no matter how intense my ambient lighting is, I won't get back the shadow contrast without directional lighting. Back to the original scene. For light number 3, we'll add hemisphere lights. To better show you its effects, I'll change these boxes to white. Here's hemisphere lighting. It basically functions like ambient lighting, except you can specify a color from below, and a color from above. Here we have blue from below and white from above. Here's more hemisphere lighting with blue from above, and blue from below. This is identical to ambient lighting with blue. Back to the original scene. For light number 4, we'll add point lights to better show you it's effects, I've turned down the ambient lighting back to 0.2. Here's a point light right above the left-most box. Notice the light shines in all directions like an uncovered lightbulb. Like with directional lights, it can cast shadows. Here is the same point light shifted to the right. Back to the original scene. For light number 5, we'll add spotlights. True to its name, spotlights will cast light in one direction as the A-Frame docs put it, this is like the bat signal. To better show you its effects, I've turned down to ambient lighting back to 0.2. Here's a spotlight shining on just part of the box, like lights you'd expect in a theater, Las Vegas water shows, or at a museum exhibit. Here's the full list of A-Frame lights available to you as a version 1.1.0. Don't worry if this list seems overwhelming, we're going to use these lights now in an example. To start, you can simply copy my lighting in each new project you make. Let's now set up your environment's lighting. Go ahead, and scroll up to the very top of your file. Now, we'll add three lights to the new environment. Notice that there are already two lights here. In my case, this is on lines 14 and 15. You can go ahead, and delete both of those lights. Now I'm going to define a new light. We're going to type in a-light, we're going to set the type as directional, we're going to change the intensity or how brightly it shines to 0.3. Again, don't forget your double quotes or your equal sign. Finally, we're going to give it a purplish hue. We're going to define color equals to 6909b3. This is a purplish light. Not finally, we still need to add more components. Go ahead, and move the light to the top right. Position equals, the right means a positive x, up means a positive y, and towards us means a positive z. We're now going to add a multi-property component. This is the light component with the cast shadow attribute, sorry, property, and then the value is true. This means that our light can cast shadows. We're now going to add a greater than sign to close our light, and we're going to move this back here to line up with this. Something's not lined up. That's the best I can do. Next, we're going to add another light, we're going to repeat this process for another directional light. We're going to type in here a-light, type equals the directional, intensity equals 0.2. The color is white, and the position is going to be very close to our last light. Finally, make sure to also enable shadows that are cast. Now that I've got these two directional lights, let's go ahead, and add our ambient light so that this entire scene is a little bit brighter, right now is a little bit too dark. For our third light, a-light, type equals to ambient. Go, and add intensity at 0.15, and then the color is going to be another purple, 6909b3. All right, and that is our scene. Still seems a little bit dark so if you'd like you can turn up the intensity of any of these values, and see how they work. For now, these are the lights that we need. Now, if you're confused by how to extrapolate or use these lights in other projects to start, I always recommend adding one directional, and one ambient light to any scene that you're working with, then refining or adding lights as needed. You can in fact, just copy these lights that I have here if you'd like to. For our final step in this lesson, we'll add point lights to your lanterns as though the lanterns were glowing. These were the lights that we defined earlier. Let's go ahead, and scroll down to the lantern. This is the lantern that we defined in the previous lesson. We're now going to change the color of this orb right here. We're going to change the orb's emissive light from white to a cyan color. We're going to define here 09edda, don't forget that pound sign right before your color. Notice emissive doesn't actually cast the light, emissive just configures that object to look like it's glowing. We'll now actually have to add a light. We now add a point light at the center of the lantern also with the same shade of cyan. That's a tongue twister. Right after our orb, let's go ahead, and now type in a-light, give it an ID of lantern-light, and type is going to be a point. There's our point light, intensity is 0.2. The position is going to be slightly up above the bottom of the lantern. We're going to give it a cyan color just like before, and then we're going to ensure that this light can cast shadows. Remember this capitalization right here for this property, cast shadow is very important. Don't forget your double quotes, don't forget those equal signs. Go ahead, and now end that tag with a greater than sign, and you can see they're a lot of shadows being cast, one from each of these lanterns, and one from both of the directional lights, and that's it. In the top left, you can click on "Show", and then in a new window, and you can share the URL for this webpage with anyone that you'd like to view your VR model. If you'd like, you can now load up your VR experience in your VR headset. If you have a Google Cardboard, load the URL on your phone, click the VR button in the bottom right, and then put your phone in the Google Cardboard. Take a look through the lens. You may have to turn around to find your temple. The process is similar for an Oculus Quest, access the Oculus Browser, and access the URL. The Oculus Browser will access the website directly in VR mode. Have fun. That concludes this lesson. In this lesson, we covered multi property components, and different types of lights in A-Frame. We then practiced both concepts by adding color, and lighting to the scene. If you'd like to access, and download these slides, visit this URL. This concludes Step 2, adding color. In the third, and final step, we'll add motion to your scene. 6. Step 3. Motion: Welcome to Lesson 6. In this lesson, we'll start adding motion to your scene. Start by navigating to this URL, This will open up a new project Glitch. Like before I suggest placing your glitch and SKILLSHare windows side-by-side as shown here. A frame itself doesn't include support for the first step of our five steps and Star system. However, a third party developer created a Star system that we can use. In your code this is our step three starter. I've already minimized the file browser and left hand side, and I've opened up the preview. If you haven't already opened the preview, click on the top-left show and select Next to The Code. On line 9, I've already added a line of code that allows you to use this third party star system. We're going to now add this star system to the code. Right underneath your a-scene, go ahead and create a new component, a-entity. Star-system equals to a radius of 200. This radius of 200 makes some stars look bigger and others look smaller. You're probably wondering, well, where's the motion? That's a great question. There isn't any motion yet. We'll have to add some motion to the ground next. The ground is going to be replaced with an ocean, just like in our photo. Well, just like with a star system, a frame itself doesn't support an ocean object. However, one of the a frame Bella of Brisk created notion that we can use. Inside this code, we're going to scroll all the way down to the very, very bottom where the ground is. This ground is just an a-plane. We're going to remove this crowd for me, this is line 71. I'm going to delete this plane. Instead of that plane, we're going to now define an ocean. I've already created code for the ocean in a file called ocean.js. If I click on the file browser in the left-hand side here, you can actually see the ocean.js. For now we don't need to worry about the contents of that file. We're going to close this file browser and once more, and we're now going to add the ocean object on the very, very bottom. We're going to now type in a-ocean. Position is equal to 00.10. This will move it up just a little bit off the ground. We're going to give it the ability to receive and cast shadows. We're going to make it fairly deep and fairly wide. We're then going to configure how quickly and how slowly it actually fluctuates. You can change these values however you see fit. I've set some arbitrary values here. I'm going to give it an amplitude of zero, amplitude variance of 0.2, speed of 1.5, and speed variance of one. But you can change these values however, you'd like to see how the ocean behaves and reacts. We're now going to set its opacity to one, so that's not see-through. We're also going to set the density of the points in that space to 50. There are a lot more polygon beaming around to simulate the water. Now you're going to give it a color, 841fte, and add a greater than sign to complete your ocean tag. Now our ocean is a purple hue. We're going to add another ocean tag that is transparent so that there's a little bit more water-like behavior. So a-ocean position equals to again, the same position, so it's slightly off the ground. You're going to give it the ability to receive shadows, a depth of 50, width of 50, so the same size. We're going to now make it slightly transparent. We're going to make this have a little bit more variance in amplitude. We are going to give it the same speed and the same speed variance. Then the density, or how many waves that you can see here, it'll be 50, and then the color will be the same color as before. That completes our ocean. You can see now the preview on the right hand side. Next up, we're now going to move the lanterns. We're going to translate or change the positions of and rotate each of the lanterns. Back to the code. In here, go ahead and scroll up to where you are lanterns are. In this case, we have lantern-center here on line 40. To animate an object will use the animation component, like with other components that you've seen previously, the animation component has multiple properties. Let's create an animation now. In a frame, you can create multiple animations for a single object by adding two underscores and adding a unique identifier. In this case, we're going to click into the start tag here on line 40 right before that greater than sign. Again, right before this greater than sign, we're going to hit enter and type in animation. We're going to give it two underscores and then a unique identifier. In this case, we're going to call it a position animation. There are three different required properties for any animation. The first is you need to specify which property you want to animate. In this case, you will animate position property. We're going to type in property position. Make sure to add a semicolon right after that. There is a second property that we need to add, which is the starting value. In this case, the starting position will be the original position of the object, or zero one negative three. Here we're going to define from zero one negative three semicolon. The third required value is the ending value. In this case, the ending position is some arbitrary position. I've set negative one to negative four. Here two is negative one to negative four. Remember, spaces between these values, no commas, make sure there's a semicolon. There are a few extra animation properties willing to set to ensure that your lantern keeps moving. We're going to set loop to true, so that it continues to loop this space after the colon is completely optional. You'll notice that I've been inconsistent with this, unfortunately. But this loop true will loop the animation definitely. If you don't set the loop true animation will happen only once. Next, we're going to set the direction or just dir: alternate. This means that the lantern animates in both directions from point A to point B and back. If you don't set direction to alternate, the lantern will animate from point A to B, then jump back and animate from point A to point B again. Next we're going to set the duration short for our dur to 8.5 seconds. We're going to set here 8500 because this is actually measured in milliseconds. I'm going to add a semi-colon. Now that I've done that, we're done with this animation. You'll see in the preview now that the lantern is moving, right or not? Yes, right here. Now it disappeared for a little bit there. You see the lantern is actually moving a little bit. But we want to do now is make the lantern wiggle a little bit with some rotation. Right after this, let's type in animation rotation is equal to and the property will be the rotation property this time, we're going to say that it's from five ten five, and to negative ten five negative five. You can set these to whatever you'd like. Just make sure it's small values so that it's not rotating to aggressively. Just like before we're going to loop this animation forever. We're going to alternate directions so that it smoothly animates between two points and the duration will be two seconds, so 2,000. Now we've finished the rotation animation, but what you'll notice is that the lantern isn't actually wiggling. It's not rotating at all. Let's go ahead and pull up the inspector like we learned in the last lesson to go ahead and hit control option and I. Now if you look at this lantern, go in and click on the lantern left-hand side here, the lantern-center, and you'll see there's the animation position just like we'd expect, but there's no animation rotation. That should tell you that something is wrong here with the name. In fact, if you look on the left-hand side, do you see the bug? The bug is really subtle. This is one underscore instead of two underscores. Like we said before, animation must be followed by two underscores and then the identifier. Let's go ahead and add in the second underscore here. Now the lantern is clearly wiggling, both rotating and moving. Again, make sure that you ever double underscore, make sure you have your equals sign, your semicolons, colons, and just in general make sure that your code matches mine exactly here. That's it for the lanterns. Let's go ahead and move on to the next part. We're going to now define animations for the Lantern Orb. It's going to pulse and grow in intensity and then shrink in intensity. Go ahead and scroll down to the orb. This there will be lantern-orb right here. We're going to change the opacity of the orb so the orb appears to glow brightly and then more dimly alternately. Later will make the light itself brighten and dim accordingly. Like before, we'll specify the property to animate to the start value and the end value. Loop infinitely and alternate directions. Here we're going to define animation-__opacity. We're going to give it the property that we want to animate. We're going to say where animates from where animates 2s. This is the n value one. We're going to loop it forever and then alternate directions for the animation. Make sure to have your colons and semi-colons and double-quotes equals signs, double underscores all the punctuation. Now you can see that the orb is actually changing opacity. This one, the one in the center and the one on the right, all of them are changing. That concludes our Lantern Orb next to me to actually animate the light itself. Make a light brighten and dim. Let's go ahead and scroll down to the light itself. Here we want to animate the lanterns light to brighten and dim periodically. We're going to add animation. Distance intensity is equal to. Then let's name the property. You want to say what it's from, the starting value of the n value. Then we're going to loop it forever and set the direction to alternate just like before. Now this is the intensity of the light. How strong the light is within its radius of impact? But we want to actually expand the light so that its distance or the radius of impact actually increases. Let's go ahead and add another animation. This will be animation_distance. This is going to change the distance property of our light. We're going to start from one that defaults to so that it appears to affect more of a region around it, loop it forever and alternate directions. You can see here that only the light or the lantern and the center is actually animating the other two lantern in the site or not. I'm going to go ahead and animate those other two lantern as well. Feel free to follow along and can also customize them however you'd like. That's it for the scene. You can now see that all three lanterns are wiggling. If you'd like to access and download the slides, visit this URL. In this lesson, we added several types of motion cues. That concludes this virtual reality experience. We've covered the three steps involved for creating any virtual reality experience. Primitives, color, and motion. 7. Conclusion: Congratulations. You've now finished a virtual reality experience, that you can share with friends, family, really anybody that you want to. We've covered primitives, lighting, motion, even if you forget the code specifics, the exact techniques that we use. What I hope you take away is how accessible this vehicle for storytelling is. How easy it is to get started creating a virtual world with A-Frame. I hope you're excited to experience your class project, because I definitely am. Please let me in to your virtual world, and upload your project to the projects and resources tab. Make sure to include a screenshot of your virtual world, and include a link for us to access your virtual reality experience. If you're interested in learning more about creative coding, make sure to follow me on Skillshare for updates when a new class launches. If you're interested in learning more about data science or machine learning, make sure to check out my 101 classes on my Skillshare profile in Python, SQL, data science, computer vision, and more. Congratulations again on making it to the very end of the course, and until next time.