 Everybody my name is Martin. I'm from Switzerland and I love to be here. I'm super excited to see you all and it's gonna be a great great time There's one thing that is not an official administrative thing That's something that I just care about a lot, which is I do this workshop for you. It's not for me, right? So if you have any questions or if there's anything unclear or anything not working, it is my fault not yours So please please please please Tell me if something's unclear or something doesn't make sense or something doesn't work because then we can fix it together That's why I'm here for If you wouldn't ask questions or like say something doesn't work on my computer or something like that Then you could as well just watch a YouTube video or something So I think it makes the most sense to just you know talk to me when there's something wrong That's what I'm here for or at least I hope that that's what I'm here for Robots won't replace me anytime soon. Hopefully We have a Wi-Fi if you haven't seen that already. There's like a Shangri-La Wi-Fi that should not require a password and it should work TM I have a fallback solution in case things are not working But it's gonna be a little inconvenient to set that all up So I'd rather try let's let's try Wi-Fi if that doesn't work then we can still fall back Anytime else like anyone having problems connecting to the Wi-Fi No, good If so, let me know if the Wi-Fi dies for you doing the workshop Let me know as well And I'll share the files with you in a different way and then we can just you know have it all work Also, if things should go horribly wrong I can always ask the organizers to help us out because they Promise they have a fallback solution, which I definitely think they will have because they're well organized here Which is nice regarding the details. There's gonna be lunch at 12 30 It's gonna be basically it's not as centralized as they wanted it to be apparently so we have two lunch spots One is Two floors down on three if you go that direction You see like dying on three or something like that and if you go around the corner. There's like a buffet restaurant It's called the Silver Shell Cafe Alternatively if you are more a fan of sitting at the beachfront Well beach from the seafront more or less you can also go completely down to floor one And then go in that direction. There's something that's called barnacles by the sea I think that's probably gonna be a seafood restaurant. So that's not gonna be where I am being They also have a different Wi-Fi at the barnacles by the sea building So if you are having lunch over there and need a Wi-Fi connection and Shangri-La should not work There's also the JSConf Asia Network with the beware of the cat's password So lunch is gonna be at 12 30. You have drinks here. Should you feel thirsty then just get up and get a drink We're not in a classical classroom setting 5 30 p.m. So 5 30 in the afternoon. There's gonna be a group photo at the beach The beach is pretty large. So I'm not exactly sure where that's gonna be But I guess we're gonna work that one out and then 545 after the group photo that's gonna be dinner at the beach as well Um Yes, so toilets are available here on this floor as well as on every other floor. So that's certainly not be a problem Yeah, that's like we have been whoops That we have been Promised snacks between 10 and 11. So let's see if that's helping But as I said, like if you want some water or some coffee just grab one anytime The coffee may be only when I'm like having you all figure out something Because it's kind of is loud. So it's not like the best thing. I can talk over it I can be louder than a coffee machine, but I'd rather not Have to be cool. So if you have a full-day workshop You would be able to leave your stuff here, but I highly recommend taking your things with you for lunch Because I'm a not sure where the where the next workshop is gonna be if it's in the same room I don't know But also it's not guaranteed to like be locked up and stuff So just take your things with you during lunch and then bring them back when you come back. Cool All right So I Would say let's start. Um, I know that a few people are like doing slides and presentations and stuff But I'm like, no, we're here for a workshop. So let's do things together. Um, and I would suggest That we that we get going like this So should the Wi-Fi not die and I really really hope it doesn't then you should be able to go to the following URL It should be I gonna I gonna make that larger in a second. Just give me a moment the frame workshop So if you go To this URL and I can make that even larger No, I can't okay fair enough Jesus, this is annoying This is better So this wonderful URL should take you to a Glit what's called a glitch a glitch is nothing like magical or fancy It's just a way to have like a really really easy setup in the browser. It's basically just serving static files And that's like convenient because we don't have to set anything up We don't have to run any software on your computer. You can just start with what is there Anyone not having this URL typed in already Bear in mind. I have put taking it from my brain So it might actually not lead you to where I think it leads you. So let me let me double-check. It's the right URL. Yes heck yes, so if Okay, right, that was not the best idea that I had if I go here. I should see something like this right So if you click on remix your own You should see Dun dun dun dun dun dun dun dun dun dun dun dun dun dun dun dun dun dun dun dun dun dun dun dun Yes, this Now. This is not very exciting and it's like the standard placeholder thing but the interesting thing is happening in index html So we want to have a look at index html probably by the way if you cannot read this Let me know and I can make that larger. Is that readable people in the back row? Give me a thumbs up or thumbs down good. Okay. Good As I say like this is for you not for me if you have anything or anything is not making any sense then let me know. So I basically set you up with some things that I just think make sense. Like ignore all this crap here. This is like boilerplate stuff in the first couple of rows. No one cares. This is the more interesting things. We're loading a few libraries. Let's actually comment out the second one and the third one for a moment. So I'm going to remove these two scripts and let's just load a frame. And actually, I don't know why this is still here. Let's remove the class hidden as well. I don't think it does anything, but let's remove it just for shits and giggles. So this is basically like a boring old website. So if I put in an H1 tag and say like, hello, JS Conf Asia, and then an H2 tag, like how's it hanging. And then we click on the little show life button. A new tab should open with our beautiful website, which is like probably the best website I've ever done. And the projector is cutting something off, I think, but okay. That's not a problem. You know, it's not that exciting. So we have just like a normal HTML page, but because we have this particular thing here that's called a scene, we have some special magical powers. Actually, let's not remove that. Let's go in here. And if you press control alt I, and that's control on a MacBook keyboard, it's not command, it's control alt I. You should see this. Ha, that's curious, isn't it? Does that work for everyone? Does it not work for you? Oh, that's interesting. Anyone else who's not having this on screen? Yeah, it should be control alt I or control option I. Control option I. Nope. Okay. Well, then let's wait with that. Just like, so this is basically a hint that I want to give you. There's something going on under the surface, and we're going to see what this is in a second. Let's go back to our HTML. So I'm going to remove all this crap for a second, and we're just going to go in here. Now, what is this a scene? Well, for VR, AR, and just generally 3D content on the web, we need a way to actually express what we're going to do. And there's a few metaphors, right? So for instance, if you think about it, a website is not a web page. It's not actually a page. It's not a page in a physical book. It's not something that you can take into your hand. So while we are using the page abstraction or the page metaphor to work with like 2D content, we are working on a frame and decided to work with a scene metaphor for 3D content. And basically what it is about is, so how would you design or express 3D content in a way like how do you talk about it? And the easiest way to talk about it is basically staging a theater play or staging a movie. So we have a scene which is an empty space somewhere. So this could be my scene. And then we have objects like me. Yes, I'm objecting myself for today. So basically you have objects that you put in and you can move them around and you can make them do things and you can combine them like or even like I can move this thing around. This is an object as well or an entity in this case. And I can maybe like rotate it. That was not the best idea. There's a physics engineer at play here. So yeah, I can rotate the objects that I have. Well, I can't in the real world, but I could scale them up. I could make them larger or smaller and I can move them around in space. So this is kind of like the thinking metaphor that we've got. And there's actually two more things. What do you also need when you do a movie? So I have a scene and I have like actors and objects and props and stuff, right? Well, making a movie is pretty hard when you don't have a camera. So we have to have a camera. We have to have a scene and we have to have objects that we are going to film. Also, if this is a closed room, it's not going to look very fancy if there's no light. So we also need light. Now conveniently here we have some lights. So this light is shining on me. This light is shining on me. And I'm an object on my scene. These objects in AC, A-frame are called entities. It's just a terminology. Sometimes other libraries call them differently. Very popular is also to call them meshes. Sometimes they are called objects, but for the sake of A-frame, we're calling them entities. So A-frame, by the way, is a library from Mozilla, like super cool stuff. And it's making things much, much easier than they used to be. I can show you how it looked like before we were doing A-frame. Like we're going to do some A-frame and then I'll show you how it looks like when you're not having A-frame available and you're going to see why we're doing it in A-frame. So our A-scene is basically exactly this. This is empty space. There's nothing in here. Okay. So now how can we fill that with something? Well, as I said, we have to put in entities, which are our objects. So let's do that. And A-frame wraps everything in these custom HTML elements, which is like super nice. So we can say A entity, and then we have an object on our scene. But if you're like me and would now reload, you would see nothing. Well, that's unfortunate. And the reason why is that an object itself does not resemble anything. It's not visible. It's basically just a point in space, an invisible point in space. You don't see anything because it's not looking like anything. So what you want to do is you want to add something to it that actually makes it look like something. Well, how can we do that? Well, A-frame does what's called the entity component model. It's basically a way of doing things and organizing your code that game engines usually use. And so we now have to add a component. And how do you add a component? Well, conveniently, it's just an attribute to our HTML tag. So we're going to start with, we want to have something that looks like something. So we probably want to start with geometry because we want to need some, you know, we're going to need a shape. So let's give it a shape. Let's say geometry and these components can have good morning. Oh, I'm so sorry, was it not? Oh, all right. You didn't miss out too much yet. So take a seat. We're going to catch you up real quick. So I was explaining that you want to start with the following URL and I'm going to show you the URL real quick. And from there on, you're going to go like remix and then you can catch up. Sorry for that. We're just going to put in a moment's time. By the way, is anyone not having like working Wi-Fi on their computer right now and not having this working? Well, fair enough, you two excluded because you're literally just setting up. Yeah, the Shangri-La Wi-Fi should not require a password and seems to be working. All right, you're both on the, on the website. You're both having the remix button. Their remix, remix your own is the button that you want to have for this holy crap, why I'm not seeing anything. Are you called up as well? Okay, perfect. Wonderful. So you click on the remix your own thing and then you should be, oh, I'm not signed in. Okay. I'm okay with that. Got it. If I lose it, I lose it. That's what happens like living on the edge. So what we also did is we, we commented out the last two scripts because we're not going to need them right now and we removed the class hidden from the A scene. There was a class on here. We removed that as well because we're going to only use it later on. So yeah, so as I explained, everything is an entity, but an entity doesn't look like anything by default. So we have to add this geometry component. And it's kind of nice that we don't have to like make up geometries because in 3D graphics, everything is made from triangles. So we would have to now figure out like all the triangles all over the place. So instead of doing that, what we can do is we can use a primitive, which is basically built in simple geometries that we can use. For instance, we can say primitive box, which is going to give us all the points and connections between the points to form a box. Okay, that's lovely. However, we're not going to still not going to see that. By the way, what we are looking at here is basically, so this is the entity. This is a component and components can have multiple parameters, right? So one of these parameters is which primitive we want to pick. And it looks a little like Jason without the quotes. So we can also do like, I don't know, ASDL or like foo bar or something like that. We can even do like buzz and then give it an array of things. Now, obviously all these attributes are not known to the components. We're just going to remove them. I'm just wanted to show you that all these kind of things are possible. So we start with a primitive box. But now, what color do you think the box will have? How does it look like? Any guesses? Okay, transparent is one guess. Nothing. Well, what color is nothing? White. White is a good choice. So here's the thing. We don't know because a frame tries to not, you know, screw us over. So it's going to pick a color at random, which is nice. Like, this is actually nice because, you know, it tries to do its thing. Oftentimes it's white, but it's not always white. And it's like, can be like super confusing. So to fix that, we just going to give it a material. So this is another component, right? We're following the same pattern here. It's a component. And this one has parameters as well. So the first thing I probably want to figure out is like, what's the color? So we can make this red. And this is nice. It supports a bunch of actual color names. It doesn't support all the CSS colors, I think, but it supports like most of them. So we can use a color name, but we can also say 0x, ff0000. So that works. Actually, no, sorry. No, that's actually not the, no, no, no, ff0000. Like we are used to from HTML and CSS. But I'm going to stick with red for the sake of simplicity for the moment. And now what happens? Now let's see. Let's reload. Oh, nothing. What did we do wrong? Oh my God. Now, now try to get the, try to get the key command that I did earlier on. So like click on something somewhere here and then go control option i or control alt i. And you should see this. Does that, it doesn't, it still doesn't work. What the heck? See, this is the fun thing. This is, I love it when it doesn't work because, you know, that's what I'm here for. Yes. I'm worth my money and doesn't do anything. That's like really weird. That's like a weird thing. Why is it not doing this? A frame should be fine. It should be loading the freaking thing, but it's not. This is a fun one. No, that's okay. Well, fair enough, but there's no arrows here. So I'm not exactly sure why it's not, this is a fun one. Do you have any other shortcut keys? I don't think so, but we can try. So in that, that's one of the cases. Wait, anyone else not seeing this particular screen? There's a few people. All right. So I'll, I've never seen that before. So I'm excited to figure out what else we can do to get this working. So I'll, I'll really quick. So by the way, this is like, if you ever have a problem with a frame, this is like all you want to be at. This has all the information and all the links to communities and GitHub issues and stuff. So what we're going to do is I'm going to try to figure out if there's another way to get the inspector up and running, because what we are seeing here, these are like the built-in developer tools for a frame and they are super handy. So I know it says I control all I, so I'm not, I'm not like dumb or doing something ridiculous. This is not coming up. So that's an interesting one. Let's see if they have help here somewhere, because I'm pretty sure there is a way to programmatically call this. All right. Time to explore it. Let's, let's do something. It's not something that I've prepared, but you know, this is the stuff I live for. It's like the adventures. Let's go on an adventure. Let's get our A-scene and ask what components are up. Okay. Fair enough. I saw that coming. So let's see. Dot components. Dot inspector. Does this thing have something that I can work with? Initialized is playing true. Uh-huh. What the hell? Right. Let me reload this because you're not at this point where the inspector's actually loaded. So let's try this. So without the inspector being loaded, it has the exact same details here. That's a weird one. Okay. So it doesn't seem to be having a method that I could call unless it's not showing. Let me, let me try something. That's what happens when I do this. Okay. Nothing. That's perfect. What happens when I do this? Nothing. That's perfect. What happens when I do update? No. Okay. Fair enough. Let's try this one then. Does it have like systems maybe? Let's see. No, it does not. Okay. Cool. So the inspector is a component which is nice. What kind of data does it have? It only has a URL. So that's not really helpful. Okay. Cool. Let's have a look at the component in here because it must have some sort of method. So this is actually not part of the regular workshop, but I think we can squeeze this one in because it's just going to be interesting to have a look at how these things actually work under the hood. So let's have a look. So we do have, no, those are the widgets. So that's not going to help us. Oh, maybe. Oh, this is a react thing, isn't it? Ah, shit. But it has to, at some point, visible. Aha. Well, but that's not, I don't think that's, that's helping toggle sidebar. No, that's not what I want to do. Okay. Right. I'm not exactly sure. So let's, let's Google this. Inspect AFrame, Inspector without, or programmatically program. Yeah. And Google it also, I just put a few components into the AC. Yeah. Right. And it works without turner. Aha. Wait. Actually, I have an idea. That's, that's a very good one. And I think I have an idea, actually. Let me give me a second view source because a co-worker of mine did this button that shows it. So maybe, just maybe, how does he do the button? Ah, look at that. So basically, aha, aha, aha. So instead of, so the people who have problems with the key combination should probably be able to do the following thing. Then let me zoom in. Yeah. So if you do like window.postmessage, inject AFrameInspector star, that should apparently trigger the inspector as well. I'm very sorry for that little detour. Window.postmessage. Window.postmessage.injectaframeInspector like this. So this is, whoopsa, where the hell do I, all right, here we go. This is like the line that you want to go for. So if, if that is the workaround you have to do because the keyboard, a key combination doesn't work, then that's how you, so anyone in this work, yeah, does work. So does everyone have this wonderful dev tools open now? Yes. Good. If not, let me know because now is the time to figure that one out. So the nice thing about the dev tools is they're like super handy and they show something that, yes, you don't, right. You needed this, I guess. Is that the one you're looking for? Does it work for you if you do that in the console? You're basically like, you open the dev tools and then in there you should run this command and then it should give you the, works. Look, this thing is called bleeding edge because it, you cut yourself every now and then. So this is, this is like the cuts you get. Does everyone have the inspector now or is there like still, still someone not having the inspector open? Okay, sweet. So now again, so these dev tools are built in into AFRAM and they're like super nice and they show us something that we didn't know because AFRAM is actually nice to us. So I said early on if we want to, if we want to think about what we're doing in terms of like 3D, AR, VR content in the web, we're basically making a movie. So we have an empty scene and we have a camera and we have a light and then we have objects, which are called entities in AFRAM. Now, if you notice in our HTML, we have only added an entity, but we do not have any light or any camera, right? We didn't do that. But AFRAM is so nice and saying like, well, look, if you don't have a camera, you can't really have a movie. So people would be like super annoyed by the fact that they are not seeing anything. So if you do not have any light or camera, we're going to add that for you. So AFRAM makes sure that we always have at least like one light and one camera available. So what you see here is like this thing that looks like a bit weird, like a star with a white thing coming from it. That's the camera. So basically we're standing here and looking in that direction and everything within these these lines, these orange lines is what we actually, I'm not exactly sure, can I turn off the light in front of here? Because I think it's really hard to see, isn't it? Let's see. I don't know what's going to happen when I press on this. Nothing. That's awesome. Nope. Nope. I have no idea. Oh, look at that. Here we go. Magically, it did the thing. Probably running Java. That's why the delay comes to be. Anyway, so you see like everything in this box that looks like in this direction is visible. Everything else is outside of our field of view and that kind of mimics how humans like see. We have this like field of vision and we're seeing like everything that is around here. But if I put something here or under me, I'm not actually seeing it. So what we have here is everything, unless I give it an explicit position is at zero, zero, zero, except for the camera, which is at one meter 60 in the air. And that's because it goes like, well, okay, in this case, I have no information how tall the user is. I don't know how tall you are until you tell me, right? So I'm assuming an adult is probably like the average adult is like one meter 60. So if I put your eye level on one meter 60, it kind of looks like natural. So it automatically moves the camera up to one meter 60 above the ground. Our box is at zero, zero, zero. By the way, notice that the position that something is is always the center of it. Well, not always, but in this case it is in the center. So the center point here in this box in the middle of the box is at zero, zero, zero. The box is below us. We're not seeing it because we're on top of the box. Also this white thing here, that's a light. That's a light shining from this direction. And you can see that it's slightly brighter here than here. And that's because the light's coming from this direction. Okay, so we're not seeing anything right now because we are on top of the box. But that means that if I use, and again, AFrame gives us this for free, if I drag with my mouse, I should be, whoa, why is it not showing? Okay, whatever. Yeah, this is the day. Oh, I'm looking upwards now. That was very smart Martin. Here we go. There it is, right below us. You can use WASD to actually move around as well. This is also like a default from AFrame. So it gives you a reasonable default that you can move around and then you see like the box here. Okay, cool. Nice. But if I reload, I have the same problem. I'm standing on top of it. I'm not seeing anything, right? So what's nice is in this developer tools, it's not just like a way to actually look into the scene, but it also gives us a little bit of power. So what happens if I click on the box? You see that now that I clicked on the box, a few things appear. First things first, there's like this blue box around the box. This is called the bounding box. And then you have like this, these bunch of things here, right? So what happens when I press on this? Oh, look at that. I can move it around. Surprise. What happens if I, if I press this, oh, I can move it around. So we basically get a few controls that allow us to move the box around. And if I go back to scene, the box is now at the position where I put it. This is not the only thing that we can do. So if you look here, up here, you see like there is, there's a few things up here. Right now in blue is this one. And that's because we are in the moving mode. So we can move objects around like this. But if we click here, we get a different cursor. We get this like weird lines around the object. So now what we can do is we can rotate it around. And you see that the box is merely there to show us like where's the, where's the maximum distance from the, from the middle point of this thing. So basically like this is called a bounding box because it always surrounds the object as tightly as it can. Sorry, could you repeat how you got there? Right. Let me zoom out again. So here we are at this moment, right? So in the, like, wait, you have the inspector open, right? Yes. So up here in the inspector, there, and I'm, I'm zooming in again. We have these three buttons and it allows you to switch to rotation and it also allows you to scale. So you can also go, and if I zoom, ah, if I zoom out again, you now have different controls again. Yes. Like you don't get the inspector. Wait, um, did you join us later or something? Or does this, right? Okay. So does the scene look like this right now? Do you have removed the class hidden from AC because it was like this before? And I think there's a CSS that actually then hides the scene. So if you remove that, you should see the scene again. And, well, now I, I undid all my changes. So I'm just going to quickly move things again, like here, and then I rotate this a little bit. And now I can also scale it up in all directions. So I can scale it like here and here and here, or maybe not, oops, maybe not like the, ah, okay. That was not the smartest plan I had, um, to like scale it like weirdly. Here we go. And then you have like the scene as you presented it. So this is a very visual way of creating these things. And this is convenient because it gives you other possibilities as well. So first things first, you can also see the position rotation and scale up here. So if you, in the upper right hand corner, you have the current object that is selected. You have the information of position rotation and scale here as well along the three axes. I think we haven't talked about the axis system, uh, for, for this moment. So let's actually try that out. So first axis is the x axis. This is how far to the left and to the right it is in meters. So one means it's one meter to the left, sorry, to the right minus one means one meter to the left from the, from the middle, which is like this line here. So I can move that around like this, uh, or I can put it like minus two meters and then it's going to be here. I can also just enter the scale here and then it's going to scale along the same three axes. The rotation is sometimes a bit confusing, but if you think about rotating around an axis, you can like, or I remember it like this. So we have the three axes. We have the x axis like this. We have the y axis like this and we have the z axis negative values go, uh, sorry, go into the screen. Positive values go towards the screen. So if we want to think about how rotation works and we rotate around an axis, if I rotate around the y axis, so this is my axis that I rotate around, basically I put like a skewer through me and then rotate like that, right? If I rotate around the x axis, what's going to happen? Correct, like this. If I rotate around the z axis, I'm going to do like this weird wonky movement. So this is how rotation, uh, works in the three axes and the axes are kind of like always the same. So they follow the object. Wonderful. The rotation order as far as I'm aware is y, x, z, but I might be wrong. It might be x, y, z. Luckily that is normally hidden behind the interface. So yes. Okay, cool. Great. There's also some, some more stuff down here on the right hand side. So what is there, for instance, is the, actually I'm going to just generally zoom in the page, I think. Um, what we also have here is like, if it's visible or not, so we can hide this object entirely by just clicking on it. Uh, you can also do the same thing here. So that's like a shortcut. You also see all the objects in the scene on the left hand side, but we're going to look into that in a second. Um, but we also see all the components individually listed here. So this, this box, this entity here has like a box geometry. So like there's a geometry with a primitive box. Nice. And it has a material that has a color of red. Nice. So basically all these information, all the components are always going to be listed here. So what we can do is we can also change things in here, which is like super nice. So for instance, like a box is nice and fine. Um, and I'm probably going to reset like the, the orientation and the scale and I'm going to put it at like zero, zero minus two. So I put it minus two meters. Sorry. Yeah. Two meters into the screen so that it's like in front of me. Actually, let's put that into code. How do we do that? Again, position is a special kind of component, but it's a component. Um, and it takes a position in XYZ. So they say like nothing to the, no meters to the left or to the right, no meters to the up or down and minus two meters. So like minus two meters out of the screen or two meters into the screen, uh, the box by default is one meter by one meter. So it's going to be well in the screen right now. So if we reload, we see like down here. And the fact that we have to look down on it is because we are one meter 60 high, right? Our eyes are not on the ground. So you could also, if you want to, let's, let's do that. Let's, it looks a bit more boring, but let's do that. We can put it on one meter 60. Uh, what X and Y, and then we have it like on eye level. So this box is now on eye level. Wonderful. But what we can do when we select the box and go into the geometry component, we can change the primitive. So for instance, we can use a cylinder or we can use a dodecahedron, whatever. Um, we can use pretty much everything that 3JS comes with. And there's a bunch of them. A sphere, a torus. Yeah, let's have a donut. A torus nut, which is like the least useful thing ever, but it looks kind of fancy. So here we go. Yeah. It's the pretzel of 3D or the pile of poo. It depends a little bit on the perspective. So we can do that. And we can do that for all the components. So basically we can change like the, the, the parameters here, um, which for the torus nut are not very intuitive for the material, it's a little easier. So I can, for instance, click on the color in the material component and say, I don't like red. I want this to be blue-ish like this. And maybe I want this to be, I don't know, uh, like super shiny. So let's set that to like one. And then you get like the super shiny torus nut in blue. Um, or maybe you want the wireframe, uh, you know, optics. So now it just looks more likely, I don't know, 90s things that you would see on screen. Um, nice. That's pretty good. So you can basically control everything in here. But now the problem is if I reload, I lose all that, right? And I don't want to type everything out that I changed down here. So that's like super annoying. So I have a bunch of possibilities to make that easier for me. One possibility is I can just copy the attributes of one individual component. If I only made changes to one of them, but I didn't, I actually changed the entire component like where it's positioned and everything. I can change that like this. Uh, maybe I want to move it over here. And then there's this button over here that allows me to either download the thing as an, as a file or just copy it to clipboard. And that's what I'm going to do. I'm copy this to clipboard. And, uh, if I now go back into my code and say, okay, I want to put this in here, then you see that it puts all the things, it's quite a bit, but it's, it puts all the things into our code. I'm going to make this a little more readable by putting these, um, below each other. So that's just nicer to actually read this. But this is nice because I no longer have to like remember these values. I can just copy this around. Um, and let's say if I, if I change just the material, because I don't want this to be a wireframe anymore, I can open the inspector again, click on the object, uh, go to material and say wireframe. No. And then go back up and say copy at trip. No, that was the wrong one. Copy attributes and put just the attributes in here. So basically I kind of go like, no, I don't want this. I want, oops. Uh, the problem with this is this is basically like copies the entire thing, which is a bit of a bug, but okay, let's, let's not get into that. Yeah. Exactly. Like copying everything is usually not the best idea because it has exactly this problem because under the hood. So this is an interesting thing for performance reasons under the hood job. Um, a frame users objects in the attributes. So it overwrites the set attribute and get attribute methods, but obviously the DOM only supports like strings. So it has to like wrap between the two. So sometimes this leads to a bit of confusion between what the DOM needs to see and what a frame sees. But normally that's not a bigger, bigger, not a bigger problem, but like actually material is like the worst thing because it has so many objects in its properties. Anyway, cool. So now we have like our two objects here and we had, we know how to like copy it to and from, but it's kind of boring, isn't it? Like we have how, but how many primitives do we have? We have like 10, 12, maybe. I don't know. See like one, actually let's start from, from the top actually one, two, three, four, five, six. Yeah. I don't know. It doesn't scroll anymore. That's nice. Um, it's like maybe like 12 or something like that or maybe 20. Who knows? But it's not that terribly exciting. So let's, let's add some more interesting things. For instance, if you want to have a background color, because right now this is white because the page is white. And if we would go into the page, uh, with, whoops, that was the wrong keyboard combination. Control shift. Wow. Whatever. If I give me my freaking death tools, come on. If I would go to the body and give it a background color of let's say, uh, background green, then this is, this is not nice. This is actually convenient for AR because basically the scene is transparent. So it takes whatever color is behind it. So if we would have to have a, uh, an AR application, we will take the camera picture and just put it in the background. But this is not quite what we want, right? I don't want the page behind to dictate what I'm going to see. So what we do instead is we create a new entity, um, sky. And I think there's, I think sky blue is supported. Let's see if it is. No, it's not. Great. Oh no, I'm doing this mistake. I keep making these mistakes. Material color sky blue. And I think sky blue is supported. So sky itself is a property. Should be. Well, you know what? I'm actually not sure, but I'm not using the sky that often. So there's actually a thing that I tried to not show you, but let's, let's do it anyways. There's usually a direct variation of these components that is used like this. So you can do a sky as well. And then you can do actually like sky blue. And I'm pretty sure that I'm should be getting the sky blue background. Yes. Now I do. So you can do that. And what it does is it puts a really, really, really large sphere around us, a gigantic sphere like the sky would be a sphere around the earth, which is obviously not true, but you know, there's like hollow earth people that think that's the true thing, but let's not talk about them too much. So we can give this a color and that's nice. So yes, that's a good start. But we can also put an image onto this. Now it might not make sense to put any image because what we really want to do is we want to put a 360 degree image. So let me actually, I have a, I might have to take a turn on the lights again. I have a little 360 degree camera with me that is the Ricoh Theta X. And I hope that it's charged because I charged it yesterday, but I'm never sure if the outlet, because my adapter is a little wonky and, you know, long story short, it's shit. So let's turn on the light. Java has had a hot cash and it's pretty good. So this thing requires me to connect my phone to this particular Wi-Fi that it's boning. Don't get me started. And here we go. And then I can take the app, connect it. No internet. No, really, my phone, my camera does not have internet. How does it? So let's see. It's going to look like super weird because my hands are going to look like gigantic probably, but that's going to be fine. So say cheese. That was it. It's super exciting, isn't it? So I get a 360 degree picture from us, which is nice, transferring. Then I have to upload it to the cloud to download it to my computer to share it with everyone because that's how technology works in 2018. Isn't it exciting? Not really. So let's connect to the actual Wi-Fi that we want to use here. Shangri-La. Come on. No, don't forget the Wi-Fi. Connect to the Wi-Fi. You bastard. Okay, seems to be connected. Does the thing do the thing that I want it to do? Let's see if it's uploaded in my photos already. Let's go up here. Yeah, it has already uploaded to the cloud. That's amazing. So I'll quickly go to my other browser and go to photos. I hope that I don't have any incriminating photos anywhere near here. And here we have like this gigantic image that I'm going to download it and show you how it looks like by itself. So this is how the image looks like. And it looks a bit weird. You see like it's like stretched here and it's like stretched there and my hand looks like I have an arm of like 10 meters length or something. So yeah, let's put that on a glitch, which is where's my other window here. So I can upload it and then I can share the link with you all. We get computer and this is the image that I just took. It's going to be a super long URL. So what I'm going to do is listen carefully now because I had so many problems with what's going to happen in a second. What I'm going to do is I'm going to put the link in a link shortener. However, that link shortener does not work as a source for the texture. So what you want to do is you want to click on the short link that I'm going to share with you, take the long URL and copy that into your AFrame scene. Again, if you use the short URL into your AFrame scene, it's not going to work. I'm just going to use it so that we have a better experience than using the gigantic URL that this is going to give me unless you want to type that out. So let's go to like, I don't know, you know, google.gl. I don't think they need a registration. I'm not a robot. Go away. Good. Thank you. Here we go. So this is the URL that you want to copy over. Let me actually, you know, that. So this is the one. You do not put that into your AFrame scene. You click on that link or put that link into your address bar and you get the longer version back. And the long link is what we need. The long URL is what you want to copy. Very important. Yes. Sure. I'm sorry. Yes. Of course I can do that. There we go. All right. All done. Everyone got the terrible long URL that we are looking for. Wonderful. So the terrible long URL, and I'm just going to check if it actually does. Yeah, it automatically replaces with the long URL. So what we do is, I don't need that anymore because I want to be back in my HTML. So instead of saying color, what we can do is we can give it a source, SRC, like an image would get a source. And we can copy in or paste in that long URL. And then, so basically a sky source, SRC equals and then this long URL, we're going to get this. And we can turn around and hi everyone. How are you all doing? Yeah, I can't wave back in VR just yet. But all right. So yes. And you can do that with pretty much any of these pictures. These pictures are called equirectangular pictures because basically what you're doing is you take a 396 degrees sphere and you unroll that onto basically you take like, you have to imagine like wrapping a balloon in a piece of paper and then rolling that down to like this, the plain piece of paper again. So as this, the sky is a gigantic sphere and this picture was a gigantic sphere, it lines up perfectly. It's just, we just have to put it on as a texture and it looks like the right thing. And by the way, if you were wondering like this is a VR workshop, why are we not doing VR? Why are we typing things into our computer and looking at our computer? The reason for that is A, it's really hard to get enough devices like we have a few to try out in a moment. But also it's like super inconvenient to debug most of the times because you like have to put it into like a USB and then you have to get like the remote debugger working and all that kind of stuff. And then you're like, oh, shit, this is not looking right. So it is it is better than with like unity or anything on any of these because you don't have to like compile anything beforehand. But it's still like a little uneasy. And the good thing is A frame is responsive. So you see like there's this little button down here, but I don't have a VR headset right now, right? So if I click that, it just goes into full screen mode. Nice. If I would have a device that has a like a phone, if I would have done it on the phone, it would automatically figure out like, oh, I can do VR with this and basically like show you an actual VR picture and use the actual device orientation to look around. So like it is responsive to the device that you're on. So basically all you're seeing here in non VR, you can try out later in VR with no additional magic. And that's the beauty of it, right? And it works on like HTC Vive, it works on Oculus Rift, it works on cardboard, it works on Gear VR, it works on Daydream, it works on Windows Mixed Reality headsets, not the HoloLens though. I'm working on that with Microsoft, this is going to be an interesting journey. So yeah, basically all the VR headsets that are out there on the market do support or most of them support WebVR and AFrame just works with them without having to do like any magic. So basically we are settled, when we got 3D right on the screen, we are done for VR as well. We're going to explore that in a bit, like I have a few headsets here that you can try with your phones. Okay, right. So this, this is nice as well. It's cool. Yeah, we have a 360 degree picture, but you see like if I'm, if I'm now I'm moving around with WASD, but it doesn't look like I'm moving around. And that's because the sky is gigantic, right? So like you see that I'm actually moving around, but the picture in the background does not move. And the reason for that is that the sky is like, I don't actually know how large it's probably like 10,000 meters or something, or maybe 1000 meters and inside. So if you think about it, if you would be walking on a field and there's like a tree a kilometer away and you walk toward it, it's not going to be like, oh my God, the tree is going to move so much because that's the parallax that we get in our perception that things that are far that way are not moving as much as things that are closer by. So that's why this is actually like motion is working in it, but you're not really seeing it because the sky is so huge. But you know, let's, let's try some more interesting 3D objects. So how can we get 3D objects? Well, you have to become a 3D artist. No, just kidding. You should know because it's like a super interesting experience and I can highly recommend it and it's not as hard as it looks to be honest. It's like, it's not too complicated. But we're going to do it easier. We're going to get our scripts back. So I suggest that actually know, you know what, we're going to start with the first script first. So this is like a shameless plug because this is what the company I work for, Archaeologic builds this thing. It's a platform that we build for you to build VR, AR and 3D applications for architecture and interior design. And what we are trying to do is make your life easier. And we started our journey with an experiment and we're going to show you in a second what that experiment is going to look like. So here's my scene. Nothing has changed. Nothing new has appeared, except what happens if I open the inspector. Do you notice a difference? Probably not because it's like super subtle because we're not like marketing dicks. So up here in the sidebar, there's a new button that hasn't been there before. It's the 3D.io button. And we did that to make your life a little easier. So what I can do is I can click on it and I get this wonderful little menu here. And aha, this is interesting. There's a bunch of stuff. One of them being poly.google.com. So Google has built a few applications that allow you to create 3D content really easily in VR. One of them is tilt brush. Actually, tilt brush costs money now. So I'm not that happy about it, but it's like $20 or something. But it's really worth it because basically what it is is like paint but in 3D space. So you get like a brush and then you can just start like painting. And you can paint with fire and water and stuff. I mean, you can paint with fire at home once maybe, but in VR it's a lot safer. So that's like nice. And then you can export that to like their platform, which is called Poly. And there's also another thing that's called Google blocks. And it's like basically like you were in VR and you have a bunch of primitive shapes like spheres and boxes. And basically what if AFIM has is as primitive as well. And you just like put them here and then you drag them up and then you remove bits and pieces and then you color them in and hey, you have a car or a house or whatever. So we can like look for something like horse. So this is stuff that people created. Wow. Okay. This is underwhelming. Let's try tree. Okay, better, but still not good. And here we're actually going to see like one of the biggest problems with these objects. So if we click on this tree for instance, I'm taking like the first one that I get here tree by and I'm unfortunate. Oops. Okay. High projector. How are you doing? I'm clicking on the first tree that I got. And it's going to say like loading and it's going to load and Hey, here's a tree. Do you see the tree? It is tiny as fuck. And, uh, and that's exactly my problem with this kind of stuff is like, where's my, okay, I have like this is a tree. Come on. And it gets better. So I'm not blaming the author. The problem is like 3d modeling is actually hard and we see why it's hard here. So first things first, you might see a weird, what the hell is going on with the projector? You might want to see, you might see a thing that is like a little odd, which is like, I'm here on the object, but the, the cursor is here. Huh. What the heck has happened? So now I'm, I might go like, Oh, this is not a problem. I can make the tree larger. So let's, let's try scaling up the tree. So let's say like two, two, two, double the size. Hmm. Did that actually scale it up? I don't think so. Let's try like four, four, four. What the hell is going on? Okay, now it's not actually, because I'm scaling the light. Okay, that was fun. Um, so let's say like, okay, still we have a bit of a problem here because you see like the cursor is not where the action, am I, am I, am I killing the projector with like a too high of a resolution or something? Let's, let's scale to whatever it says it has. Hopefully that's going to fix the graphics problems. Okay. Anyway, um, so you can see the cursor is not where the actual tree is. And if I now start scaling it up, just watch, just watch where the, the thing is two, two, two. Goodbye tree has been a fun ride. Bye. And why is that like, what the hell is happening? Is this a problem with a frame? Uh, no, the problem. Oh, this is so weird to have yourself in the background. Okay, whatever. Um, no, this is not a problem coming from a frame. This is actually a problem with the 3D models. And, uh, unfortunately, a lot of 3D artists don't know this either. So a lot of 3D artists come from a background where you're making it look nice when you render an image. So they're like, yeah, and I have this object here and it looks perfect for my camera. And it's, oh, it's great. And I just put it on the internet and people can download it and then have fun with it. Um, but there's a few things that they don't know. They simply don't know because no one tells them. And we are actually fixing that right now by having like a guide for 3D artists to, to not make these mistakes. And one of them is the origin of the 3D program should be the origin, like the middle of your object. If you're not doing that, then you have the, the weirdest problems. Just imagine it like this. Let me, let me show you something. So if I take this water bottle and I model it in a 3D program, then I have a coordinate system in the 3D program and I have a coordinate system in a frame, for instance. So we could start with like, if I'm now, let's say I'm a smart 3D artist and I put my, my zero, zero, zero is right in the middle of the bottle, right? Right in the middle. I can't actually put my finger. Actually, I can put my finger in. It's right, it's right here. Uh, oh, that was inappropriate. Um, anyway, so like my, my bottle is right here. So now if I, if I rotate it, I'm going to rotate it around this point and everything will be exactly as I expected. But what happens if my zero, zero, zero is here and my bottle is here? What do you think happens? That's the right gesture. So I'm still rotating around this point, but now my bottle in my scene goes, whee. And you're like, no, that was, no, that was not exactly what I wanted to do. And scaling has the same problem. When you scale, all the math is wrong. And then it scales like in a different direction. And you're like, no, this should not have happened. So it should always be like in the middle, we're at zero, zero, zero in your 3D editing program. And you should also take care of the scaling, poly and, um, uh, paint brush, uh, tilt brush and, um, what's the other thing called blocks do not give you a hint on the scale. So the problem is like 3D programs use units and units mean whatever you think they mean. Now 99% of the people on the world say one unit is one meter because it's an easier system to work with than like inches and feet and stuff. But some people just don't care because when you render something, I'm actually going to show you something real quick. Uh, I just want to, because I basically just recently learned 3D modeling from a coworker of mine and I made all the mistakes myself. Um, so I can show you what's, what's wrong with people making 3D models. And it's not like I'm not blaming them because the tools are just not helping. So let's say I want to create something. This is Blender. This is one of the 3D editing softwares, but you don't have to install it. I just wanted to show you something real quick. So I can create a cube. Cool. Now, can you tell me how large this cube is? One by one by one. Whatever. Whatever. That's correct. And the thing is like, I don't even, I honestly, like Blender is a magical tool of wonder that can do all the things and the interface is really powerful because you can do things like this. And I'm like, what? Um, so it's like, it's actually, it's not that hard to work with Blender. Surprisingly, even though it might look like that, uh, it's actually not that, that dangerous or, or tricky to work with. It is actually kind of nice. But the problem is you have no indication of what the units are. So you have to, like in the, somewhere in the settings is actually well hidden. And I'm honestly, I'm not sure if I'm going to find it today. So let's see. Um, yeah. So pretty good in you. Good morning. Are you okay? Where did they find this pre-war projector? I hope everything is okay. Everything's fine. Nice. So I'm just here to say good morning. Welcome to day number two. I hope you're enjoying yourself so far. So few announcements. I mean, if they are not yet, they're going to be next soon between 10 and 11. I think they brought some in back there somewhere. Yeah. Perfect. We also have, whenever he allows you to do that, you can join us at the Hackadeck, or, you know, we have nitro coffee there. I'm not holding your hostage. Just FYI. We have nitro coffee there, which is really nice. And we have a cocktail robot there. The cocktail robot likes QR codes. And we posted one of them already on Twitter and Facebook. So if you're not following us yet, JSConfAsia is the handle. Get the QR code, hold it in front of the robot, and it will make you a cocktail. Mocktails for now. I think that seems a bit early for Mocktails. I'm sure you can enable the cocktails too. So that is about it. Would you mind standing there and I take a picture? Oh, damn it. All these, all these, exactly. You missed our 360 degree picture. Fricking photo ops. Thank you. Yeah. Yeah. Like, seriously, I'm not holding your house search. So if you, you know, want to have a coffee, go ahead. As I'm kind of like digressing anyways. So yeah, you see like the problem is if, if I would do this, um, and I might even like, like put it somewhere here and then move my camera somewhere and then like start rendering it like this. And I'm like, yeah, no, this looks good. This is exactly how I want it. But if I then export this to, um, to a 3d file, then it's all wrong because you can, you can tell if I go to the top level view that if I would now rotate it in a frame, this being my 0, 0, 0, it would like do this entire like bananas, crazy movement around a sun that doesn't exist. And, uh, and that's like really, really hard to get right. Um, so yet bear that in mind when you download things from the internet, learn at least the minimum blender you need to actually fix models. So like, let's say like, um, I'm actually going to show you this just real quick because it's not that hard. So let's say we downloaded this wonderful model and it's not in the right position. What you definitely want to do is you want to put your camera on the top and probably disable perspective. So that's a little easier. And then you can use G like grab and then move it to the center like this. Obviously that's not always that easy. There's actually better way. Actually, I made a video with a coworker of mine. I'm probably going to share the link on my Twitter account later on, um, because we explained this in much, much more detail. And then you would go like to the front and you see like it's too far up. So I actually got now gonna, gonna move it down. And now this is, this is nicer to work with for artists, uh, or sorry for programmers. But anyway, um, there's a video that explains it now that I think about it. Let's ignore that. But basically what we want to do is we want to have like models that have the right scale. So we don't have to scale them up with that have the right rotation. So we don't have to rotate them that much and that are centered around the origin so that we don't have these weird behaviors. So Paulie is not the best source for this, unfortunately. And now, by the way, we're doing a little trick here. So you see like all the objects in the scene are on the left hand side. So we can click the little trash can I can and off we go. Goodbye, little tree. Can we reset the center point within our frame? Um, not that easily. It is possible. It's just like a lot of gymnastics and it's just easier to fix it and it's not worth it. Um, we also have like other things in, in, uh, in our wonderful little plugin. So here we have the furniture library and the staff picks. Staff picks are basically we have a service and it's, it's for free. Actually, we have a service that allows you to, to get a 3D model from the floor plan. Obviously we're not going to show everyone's floor plans here, but we have like a few 3D models that we created. For instance, like the big bang theory apartment and you can just drag and drop it in and boom, here you have it. Um, and if I now go back to the scene, I am standing in. Okay, this is weird. Let's go inside. Whoops. Where am I right now? Oh, there's a gigantic thing in here. Yeah. Talk about scale, right? Hi. So this is, this is to scale. This is a Sheldon spot and stuff like that. So, um, this is scaled correctly and it is normally aligned to the axis and it is nice to work with. And then you can just, just drag and drop things in and export them. Um, like the other things, let me actually remove like some of my stuff here because it's like super annoying. Uh, let's get rid of the sky as well and let's get rid of the box to goodbye box. So what we can do then is we can click here. Uh, you can click on the little duplicate here to make it appear more than once, or what we can also do is over here on the right hand side, outside of what the projector shows. That's amazing. Let's see. Pop. So we can copy this again, copy, go into our editor, go away, uh, go into our editor. I'm going to remove the sky here as well. And I'm going to remove these two primitives as well. And then if I paste this, I get like, oops, I get the A entity. And now if we are coming back here, then we are back in the, in the apartment of Big Bang Theory. The same thing works with the furniture library. So if you only need a single piece of furniture, so let me remove this gigantic piece of, of architecture and just like load one piece of furniture. Let's say like I want this sofa. Um, I can select the sofa. I'm, I like this sofa a lot. So I'm going to pick it. And these are actually real furniture pieces. And you can tell like the, the scale makes sense. We could sit down on this one. And if I put like, I don't know, do we have plants? I don't, I don't know. I've never tried this. Let's see what happens. Ah, we do have plants. That's nice. A little greenery. And you see that like the bounding box fits correctly. And the, the cursor is at the right position. And I can just like drag and drop things next to it. And they look like they are reasonably sized. If you think about a sofa, this like little palm tree, why would you put like such a tree and whatever? So like this looks reasonable. And you can import them really easily into your A frame scene. So that's nice. But you can also do other things. So like, um, what I like to do is like 3d free 3d model gives you a bunch of 3d warehouses there called sometimes you can also pay it like please, please, please. If you see a nice 3d model, just pay the artist. It's worth it. But there's a bunch of free stuff available as well. But what you want to do is, um, consider performance. Performance is always a bit of a problem. When you have lots of objects. So you want to probably try the low pulley things if possible. And like, how do I put this? Depending on what you want to do as a 3d artist, you can take a different amount of triangles for the same object. Let's say I get a chair. A chair is not that complicated normally. And you can do a lot of things with like ticks that with like tricks that 3d artists might use to make it look really nice. So you can use, let's say a thousand triangles for share chair, or you can use a hundred thousand triangles for chair. And if you consider like 200,000 triangles being like the maximum that is reasonable to put in a scene, like into your entire world, then a chair with 1000 100,000 triangles is like half of everything you've got for your entire world. That's not necessarily a good idea. So you want to try to find like the polygon account to be as minimal as like as low as possible while still looking great. And low polygons does not necessarily mean like it looks terrible. For instance, this, this horse is actually relatively low on polygons, but it looks pretty great. How many polygons does it actually have? Let's see polygons 4,200. So that's like not too bad. It's not too great either, but it's not too bad either. So you want to find the ones that are actually making sense. Or you create your own ones. That's also a possibility. Nothing's impossible. Kill. So we can do that and we can like use a bunch of these models and we can combine them as well. So let me go back to the staff picks. There's a model that I particularly like, which is this one is like called the Stahlhaus. It's a famous building, I think in LA. Maybe I should not put it where like the couch is now in the pool. So I might want to reconsider that. So we can go in here and I can remove these ones because you know the plants are nice, but if they are standing in the pool, I don't know. I don't feel confident about that. And I can now go and copy that one into our A-frame scene as well. So I'm going to remove the original one that I put in and put in the Stahlhaus instead. Let's do that. And here we go. Now we have the Stahlhaus maybe put like a sky around again so that we have a nicer looking surrounding. So I do like a sky color, sky blue. Yeah, that's looking a little better. Not exactly sure why we're not. Oh, because it's one of the things where we do like a look into. So this one does not have a roof. Okay, well, it's a bit weird to not have a roof, but let's not go into that detail right now. And we can walk on the water. That's also nice. So importing 3D models is not as complicated. But what if you don't want to use one of our 3D models? Well, that is absolutely fine. In which case you probably want to import a 3D model. Let me actually see. So Glitch is a bit particular about paths, which is not making it easier. But I'm going to quickly do something for you. So imagine that I find a blender file online, which I conveniently did because it's the exact same model. What I can then do is I can take this and import export it into a format that makes sense. And to be honest, there's like a lot of different 3D formats. And I highly recommend you to use what is called the GLTF format. I'm going to explain a little bit why that matters in a second. So that's not actually, I do want to export all this. I do not want to export the camera. I do not want to export animations because we're not having animations in here. So let me export this into GLTF. Bless you. So GLTF is basically just like a format for 3D data. It's like the JPEG for 3D, if you want. It's a format specifically optimized for using on the web. And I'm going to show you what other formats exist. So like one of the one of the other very popular formats is OBJ. OBJ is like a super old format that is basically supported by every 3D software in the market. So you oftentimes find OBJs, but they have a huge disadvantage. Now let's have a look. So this is one of these OBJ files. Let's have a look inside how it looks like. So this file is actually a text file basically. And if we look at it closely, and I'm going to zoom in a lot, if my browser is still like, okay, Blender is in the background still exporting. So that's going to eat up a lot of power. So we see like a lot of numbers here. Do you have any idea what these numbers might mean? Correct. Those are points. In 3D, you're oftentimes not calling them points. You're calling them vertices. And three vertices usually form one triangle, which is also called a face. So here we have like lots of points and lots more points and even more points and blah, blah, blah. And then down there somewhere, you have like VT, those are texture coordinates. I'm going to explain that in a little later. Or UV coordinates called them as well depends a little bit. And then we have like faces, which are connecting these points to triangles. And then, you know, maybe we have groups and stuff. So you see like it's a really, really long file. And that's for 787 polygons, 102 triangles. It has 3000 lines. And it has a size of it has the size somewhere, doesn't it? No, it does not show the size. Why does it show does it do it here? Because somewhere GitHub shows the size, right? It's a few megabytes actually. Yeah, no, actually, no, it's not that large. This one is relatively small. So 86 kilobyte, but it's 86 kilobyte for 100 triangles. That's not very good, right? And there's like no material information here. That's in a second file. It's the MTL file. And that looks more or less like this, you have like a material with a bunch of like color numbers here. And then it references the images. So it's like, you have to do a lot of text parsing and you have to get all this text over the wire. So it's not very efficient, right? Because if you think about this, let's think about the data that is in here for a second. So we basically have a bunch of points in here, and they're like three comma values. So comma values are usually, or floating point values are usually saved as 32 bit values. So 32 bit is four bytes. So we have three of them x, y and z. So we have three times four bytes makes 12 bytes for one coordinate, for one vertex, right? But if you look at it here, each of these characters is a byte. So they're like one, two, three, four, five, six, seven, eight, nine, 10, 11, 12. So this much space is what it would normally take to store one of these coordinates. So we're wasting a lot of space. And even worse, we're wasting a lot of processing power because we have to read this line by line, break it up into smaller bits and then parse that into floats and then put that into the memory for the 3D engine to pick it up. So like a lot of CPU power needed to actually parse this into a 3D model. And you can imagine that on mobile, doing that with like a two megabyte file of this format is not going to be great. So that's why there's other formats available like GLTF, which is a JSON-based file format, but it can also be binary. And then it like saves a lot of space. So that's actually, you know what, let's export this into OBJ as well, just to get a comparison. So I'm going to export this into OBJ and we're going to do that export. Okay. And now let's have a look at the files. This is not the right folder. This is the right folder. So here we have like the GLTF file completely including everything. All the images is quite large. It's 150 megabytes. The OBJ is like 16 megabytes. But what happens if I'm not including all the materials, all the files? Let's see. There must be an, where is it? Actually, here it is. Stahlhaus GLTF. Let's have a look, get info. So this one is like 400 kilobytes, 448 kilobytes versus 16.2 megabytes. And I can get that as a single file version, which is nice. It's quite large, but it contains all the images. And the reason why I did that is because unfortunately, glitch is not making it easy to upload things that are referencing other things. Because normally what you would do is you would use browser caching. So you would have like a GLTF file referencing all the images. Because then if like the model changes and one image changes, you would only download that one image. And the JSON file is like 400 kilobytes. And you would not download all the textures again. But unfortunately, glitch has a problem with like linking to other things. So you only have to upload one file to make that work. And that unfortunately means that I'm in the wrong folder here, I believe. Is that the right folder? Yes, that looks like the right folder. Let's see how that goes. We're uploading 150 megabytes. That's gonna be, oh, okay, no, that looks more like it. I was like, oh, look at that. It's half done. How does that work? Yeah, never mind. Oh boy. I think it's time for a coffee break. But basically how we can use these GLTF files. Oh Jesus. This is gonna be painful. Conveniently is like the same thing. A frame comes with a, can I actually, yes, I can, that's lovely, comes to the component for GLTF model. So what we can do is we can say like a entity, GLTF model, and then just give it a URL to the GLTF model. So now we don't have it. But so I'm basically going to be like, to be found out dot GLTF. So basically we put in the GLTF file name here, and then it loads the GLTF automatically. It's actually faster than I would have expected. That's pretty good. And then we would basically get the same model. So it's a bit of pointless, but you can use GLTF models like this. It's nice. Okay, now we have 3D models in here, and we have experimented a little bit, but let's, let's do something more interesting. Let's add something that is moving and, you know, something more interesting into this. So let's say I do my geometry, primitive, box, material, oops, color, red, and I position, nope, nope, nope, nope, position it 0, 0, minus 2. And I'm removing this as well because we don't really need that. Oh, do I have the URL now? Oh, that's convenient. Let's, let's try if that works. GLTF model, and write. I honestly have never tried what happens when you export it as a single file, so I'm looking forward to find out what happens when you export it as a single file. That's what I thought. It doesn't complain, so it's probably still loading it. Who knows, let's try that out. Yeah, that might take a while. And that's precisely why you don't do single. This is an important lesson learned, by the way. Like, do not use the single file option because it's just like not worth it as it like blocks the rendering until it actually comes back from the network. Okay, I'll leave that in though. Actually, no, I won't because I'm going to use it anyway. But this is basically how you would do it. You would take the URL and put it into the thing and then you'll be good. Why is this thing coming back the entire time? So let me move this down here and let me move this down here. It's one gigantic model, so it's going to start rendering once it has everything in. Then it would basically render as they are arriving from the network. So if you have like smaller models, that's exactly, it's like, basically what happens is if you would not have the single file version of this model, it would download the tiny JSON and then discover all the different bits and pieces and it would discover the binary files for all the vertices and faces and it would discover the images and start downloading them in parallel and basically once it has everything that it needs to render, it would start rendering. It renders other entities as well in the backgrounds. It's not like blocking everything. It's just like, obviously if you have too many to actually download at the same time because you have this download limit of I think like 16 connections per host, then that would start blocking but without that it wouldn't. Okay, so what we haven't done so far is we haven't done what's called hierarchies. So what we can do is we can actually conveniently put things inside of other things. So let's do like NA entity. Actually make the outside primitive sphere and the color yellow and then inside here we do like geometry primitive box. Well, this is a bit shit. No, let's do sphere. Come on. Material color blue. Now, and actually probably also what's going to be interesting is like we can do like scale up the scale and then go like 0.25. So 25% of the original scale. And now we only see like our gigantic, well not gigantic, but our yellow blob here, our yellow blob. Where's our blue blob? Well, it's inside because it's in the same position. So what we can do here is as you can see like this is now nested. This is a child of the other thing. We can address it in the inspector like this. So here you see like there's an entity but now you have a tiny little blob on the side to it. So if I press on that, you see that there's like an entity hidden inside. Oh my God. And I can move it out. And hey, look at that. Hi, there's a little thing here. So now we have, I don't know, a sun and a planet. Nice. What's worth mentioning is that they are now hierarchically connected. So the sun is the parent of the little, actually let's, let's get them ID so that we can easily spot them later on. So ID Earth. So if I now say I want to position them somewhere else, and I'm going to do that in a second, I'm just going to clean up the code here a little bit as well. So it's a little easier to read on the projector. So if I now say, oops, position, let's say like three, zero, zero. You wouldn't be able to tell that this is like not the global position. This is a relative position to this one. But what happens if I'm now moving the sun, maybe let's say like I move it to like minus five and maybe like 1.6. So that's on eye level. And look at that. Our little planet has moved with it. So the position of this little planet is no longer like in world coordinates. It's now in coordinates relative to the sun. So basically what I'm saying is my son is somewhere. Let's say like my son is like, I don't know. So let's say this is zero, zero, zero. And my son is like zero, zero minus one. And now if I say the little sun, the little earth, which is like my child, will be at zero, zero, zero. It's going to be where I am. And if I move, it's going to be moving with me because it's attached to me, right? So if I say like, can this please move one meter into the, oh sorry, into the screen, like minus one, then it's going to be behind me because it's going always from where I am and not like in world coordinates. This is convenient for an interesting reason because we can do things like this. We can use this to create an animation. And we're going to do this not inside the earth because then it's going to spin the earth, but we're going to do it inside the sun. So on the same level as the earth, we're going to do like a animation. And I have to look up the syntax for this because like for the life of me, I can't remember the syntax because I think it's like prop or is it attribute, it's out attribute. Okay, cool. That's what I needed to know. So the animation tag is using its parent, its direct parent to change a property over time or an attribute over time. So I have to tell it which attribute I want to change. And I can for instance, say I want to change the position. And now if I say we started, let's say like minus two, then I can say actually it doesn't really matter. Let's say like we started zero and then say like I want to start from and it takes the value that makes sense in the context. So in this case, this is a position. So we need to give it three numbers. So I say like, I want to start at minus two, one, 1.6 minus five, oops, two, two, 1.6 minus five. So it's going to move from the left to right. And I think it's like dur, not like actual duration, right? Yeah, it's dur. So we give it a duration for the time that this motion should take. And I would say like five seconds. So it's 5,000 milliseconds. And if we reload, you see that it does a motion. Hurrah. And it does it exactly once. Now there's a bunch of properties that I can set. For instance, I can set repeat indefinitely. I think I can never tell. It's like English not being my first language. I'm having a hard time actually spelling that right, to be honest. Yes. All right. So if you do like repeat indefinitely, it's going to keep repeating that animation. The problem now is that you can see that it doesn't do what you might want to have it do. Like it doesn't actually bounce between the two. It just basically restarts the animation after like five seconds. It's like hui, blip, hui. This is not quite what we want. So there is a few attributes down here. And this is like the nice thing. Everything that AFrame comes with is really, really well documented. And you have like lots of documentation available. And if you find something that is unclear, you can edit the page or go to view source or go to GitHub and actually suggest that there should be a fixed being made. So this is nice. And here's a direction property that you can set to alternate. So we do that. So actually let me redo the way that we do these attributes. So that's a little easier. Yes. Yeah. Well, yeah, that's a tricky one. So there is AFrame itself has an animation component, but there is a better one that I don't go into because we would have to use an external component. And I would like to show you the AFrame bits and pieces first. But it does say, and I would have actually mentioned that there is an external component done by Kevin Goh that is having more possibilities because this is a limited component. So for more cool stuff, you can actually check out the AFrame animation component and they have like more things and they're a little well ahead of the actual thing, unfortunately. And they have things like you can have timeline to actually coordinate multiple animations and stuff like that. It's just a little too much for a basic workshop, I would say. And you see like elasticity. They have a way to not round the values, start events, pause events, if it should auto play, you can combine multiple animations, all that. But we start with a simple animation. So we are now in the documentation for the built-in animation component. But if you would have more complicated animations, I highly, highly recommend not using the AFrame component, but using the external one as it is more powerful. But for the simple ones, this one is perfectly fine. So if we now say direction, alternate, we're getting this alternating pattern. Now, this is not quite what a star does, what a sun does. But what we can do is we can say, okay, maybe what we want to do is we want to change the rotation. And we're going to start from zero, zero, zero, which conveniently it is already, so we don't even need to mention that. And we want to rotate around, let's say the, yeah, let's say only the y-axis to begin with, like let's start with this. And we want to go 360 degrees. And I don't want the direction to alternate in this case, because that's going to look weird. And here we are. Well, this is not quite how a rotation works, right? This is going to be, this is going to be a really, really weird day here. Why does that happen? Well, this is because of easing. By default, it eases in and out. So basically it becomes faster and slower to the, to the ends and the beginnings. So we would have to fix that. And we can do so by saying easing linear. So that's not actually doing like modification of the speed. Weee. Weee. So now we have a rotating Earth. That's nice. But there's a little bit of a problem. Actually, I want to show you something real quick. And I'm going to go to Google image search. Obviously don't do that for various copyright reasons, but I'm going to do it anyways. Sun surface. Okay. Let's, let's use, I don't know. Let's use like this one. That sounds like a reasonable thing. View image, copy image address. So in the materials, you can't just specify like a color, but you can actually also give it a source. So I can say like source and then use an image source like this. And it's not working because probably this is an HTTP. No, this is an HTTPS URL. So what is the problem? Oh, is it one of the cases where, so the syntax has recently gotten a little inconclusive. Let's put it that way because depending on the, no, what's the problem here? Oh, that's it. Oh, shit. It's a cross origin shizzles. Come on. Okay, fine. What I'm going to do is like, I'm going to save this image. Why do I have to do this? And I'm going to upload it here to the assets. Boom. And as that is not such a large file, it should actually upload relatively quickly. And here we have it. It's probably going to look weird because I don't think it's a proper, proper equirectangular image, but it's going to be fine. So cross origin like seriously. Come on. Don't be like that, people. Don't cross origin your things. Here we go. But now this is not what we want. Right? It's weird that why would the sun rotate the same speed as the as the earth? This is not really what we want to do. And this is where the fact that, oh my god, what the f**k is the projector doing? Do you see like the little halo behind the, what the rip? This is not a thing. This is the projector. Nice. Okay, whatever. This is fascinating. So if you remember from the very beginning, an entity is invisible, right? Unless we attach a component to it that makes it visible, it is invisible. So what we can do is we can change our code a tiny little bit. What we can do is we can say, hey, I would like this entity to maybe not rotate. Instead, we have like an invisible child that we put both the animation and the, ah gee, both the animation and the earth goes in there. So I remove them here and I put them into this entity and move them in a little bit. So that's easier to spot. And I should probably like do it like this. It's a little easier to spot where the indentation comes in. So now we have the sun and as child of the sun, we have an invisible entity and the invisible entity has an animation and the earth is relative to this particular invisible entity. And now we have this effect. And it's not a performance problem because an entity that has nothing to render does not render anything. So it's not having any overhead really. It's a tiny little JavaScript instance in the rendering list, but it's not actually rendered. So you don't have to worry about like performance problems with invisible entities. Regarding performance, I also wanted to highlight something else that is a pitfall that a lot of people get really, really confused with. So what happens if I put the earth exactly around where the camera is at the beginning? Ah, sorry, the sun. So now this is confusing, right? Why am I not seeing this? I'm in the middle of the sun, but I'm not seeing anything. And the reason for that is a performance optimization that is usually done, which is it assumes that if you have an object, 90% of the time, so if I have this object here, it doesn't make sense to render anything inside that is not visible from the outside. So basically it tries to be clever and goes like, this part here, I actually don't have to render it because it's hidden. You can't see it. So why would I render it? So the problem with that is that it's not necessarily smart about if you're inside of the thing. So this is not rendering because the material is by default not rendering the insides. We can fix that and if you look into the, no, that's the camera. I don't know what's the camera. I want the sun. If you look at the material component, you see something where it says side and it has front. So this is like the outside of something. We can as well render the inside and then here we are in the middle of the sun, which is probably not a good spot to be in. But yeah, so now it's rendering the inside. But the fun thing is if I now go outside of the sun, it looks a bit weird, right? Because it's now only rendering the insides and not the outsides. So this is probably not what we want. What we want instead might be that we want to render both sides. So this has a performance impact because you're always rendering both sides, but it's sometimes the only thing that actually helps. So you might have things like, let's say a building with a window and you want to see through the window into the building and then the insides would not render if they would not be set up correctly. We actually, our models do that because we assume that only the insides of the walls are not something you want to render. So basically walls that are indoors are actually facing in the right direction, so it actually renders correctly automatically. But yeah, that's the thing that you have to figure out. Also transparency is supported. You have to set the transparent flag and then the opacity to 0.5, for instance, and then we have a half transparent sun. Sometimes that looks a bit weird and funky, and this is in this case because we're rendering double-sided. And it doesn't know which side is the actual thing that it wants to render, so you want to avoid having double-sided renderings with most of the transparent objects because it just doesn't know which side it is showing where. So it's like giving this weird effect. Okay, any questions so far? Could you just stop at the code? I can. Anything not working? Anyone wondering about a thing? I'm trying to get to the animation. I kind of just have like a stationary thing. How would you suggest debugging like an animation or not? Oh, that's a tricky one. Look at the code and see. So you have the animation at this. So did it work in the beginning or did it like never ever work? Ah right, okay, fair enough. So what you want to do is like the animation always animates the object that it is like its parent. So in this case we have like the A entity is an invisible thing but it has two children. It has the animation and the earth and the earth has an offset. So like the earth because it's just a blue blob. If you would rotate it or you wouldn't see it so you would have to move it off the origin as I explained earlier with like the 3d models. I move this thing so basically let's have a look at this. I move this thing to the right three meters that's off the origin of the actual entity. So we have this invisible entity here. I move the earth to the side and now I have the animation as a child as well and the animation is turning the invisible entity and because this thing is off the origin it's just like there. So this is what should happen. The next step would be to check the attributes because I think sometimes they are not very obvious like attribute rotation. Okay, I get you that but durr. It's like not the most obvious thing and repeat indefinitely for me as a non-native English speaker. It's also pretty hard to spell right to be honest. And if all of that is right then I would wonder why it's not working. Should I have a look? How can you just describe the structure again? So it should be an asine like let's say just a base would be an asine and empty entity and then inside of it are two entities in an animation. Yeah for instance. Okay so I'm gonna try to add just adding another like entity on the outside. Like probably like the simplest thing you could build is something like this. So let's let's start with like an a entity that is basically empty and inside you have another a entity that is positioned slightly off let's say like three meters to the right and you have to give it something that is makes it visible. So like primitive sphere material, material color red. So let's do that. Let's put it here and let's put this here and then on the same level of indentation. So in the say in the external like in the surrounding entity not in the entity that is the little sphere that we just created. You do like a animation and attribute rotation to 0 360 0 dir 3000 maybe. This is like the smallest thing you can probably do and then you should have oh it's not it's not moving that's great. Ah it's because ah it actually might have moved it's just like it has moved three seconds long and that might actually have been passed already. So let's actually give it like the repeat. Sorry. But it wrote no no no yeah this is this is where it's where I find it confusing when I learned this this stuff is um it is a solid sphere that is correct but it's not rotating around itself because and let me repeat that again. Look at look at the structure real clear. So basically um yes the animation is going to its parent right so actually I can I can like collapse oh shit the collapsing is not really helping much is this um yeah so basically this this would rotate this invisible entity and the sphere is slightly off the origin so that should actually rotate around me and it does. We I love the blur on the projector it's like the best thing ever. Can you describe from here if you want now like so now I have like the smaller sphere spinning just around the the camera. How would you make that center point now move out to where the other sphere is? What I then do is uh where is the other sphere actually is like okay it's right where we are so let's let's say like it's minus five. I move this top level entity where the other thing is or so that's one one way of doing it so basically I would have to like figure out like zero one way six minus five and I might want to actually move this somewhere else let's say like I move this to five maybe because I don't want to have them like rotate on the same it has the easing okay I give you that it's like still doing like the weird easing thing but basically now this this does the thing but this has the downside of if I'm now move the sun down here right as I say like minus five then the sun and the earth has moved but this one thing hasn't moved right so if I want to make that follow what I would do is I would take the entire thing let's let's call this like uh I like to call them anchors because they're kind of like invisible anchors right so I call this the anchor and then I use the entire blob here and I would move that into the same entity as the sun or actually make it a child of the sun that works as well so I would make the entire anchor a child of the sun and then um the anchor would not have to actually be positioned off the sun because I wanted to be like the same a point as where the sun is so I can do that and now I have like the whoops okay now I have the effect that this is moving with the sun so if I move the sun back to zero on the x-axis the red thing still rotates around the sun okay so you have to be like it actually I really really really love the inspector for this because you get like this tree structure nicer here right so now we see like the sun has two children one is the anchor for the blue little planet and one is the anchor for the red little planet and then you have like the entity of the red planet is a child of this entity of the anchor and then you have the same setup here for the earth all right so you get this like hierarchical um relationship let me say as far as the positioning uh so I guess the the understanding I have is that you give each entity a position yeah and then any entities inside of it the position you give adds to it yes correct that is correct okay like if you have these these hierarchies then the positions are always like relative to its to its parent and that actually is true for all of them like that I mean the sky has a position that is relative to the scene it's always relative to the parent and if you share the parent then you share the offsets okay so you can either take the the entity that is the parent of the animation and put that inside of the entity of the bigger planet yeah or you can have them be two separate entities and just position them to the same yes correct with the downs like the second one with the downside that if I move the thing then the other thing does not automatically move with it right it's like exactly you have to then figure that one out so basically you can use invisible entities to group items and then make sure that they stick together which is actually what happens under the hood when you load 3d models because a lot of 3d models are actually made from individual smaller bits and pieces that you can address individually and you don't see that because it's normally not exposed to you but basically it's exactly the same thing like you have one container entity that is invisible and then all the small let's say you have a robot right and you have like the two arms of the robot and the two legs of the robot and the head of the robot but you don't want to have to like say like I'm now moving the head and the leg and the other leg to the same new position but you want to kind of have this all go in one place so basically what the loader does is it creates an empty entity that holds everything the entire robot and it only gives you the robot but then internally the animation bits and pieces actually address the individual arms and stuff so yeah and yeah sometimes it's like super convenient to actually have access to this kind of stuff so let's use any other questions by the way anything unclear as again let me repeat what I said earlier on one second this is for you so if something's unclear I screwed up and I really really love to have your question and figure out a how to better explain it next time and b make this work for you yes in the inspector or I guess in the scene you can press A, S, D, W to move up and down very good question so actually we haven't touched that topic yet but it is I wonder if they have it here yes so as you can see like the the camera that gets inserted into the into the document automatically and we can do our own if we wanted has not only like a bunch of properties itself but it also has two components the look controls and the WASD controls look on look controls are the the mouse dragging around or if you're in VR your head motion so the look controls are what makes the camera move with your head if you're using one of the VR headsets and the WASD controls are literally like moving around in space or if you have a headset like the HTC Vive or the Oculus Rift that also tracks position in the room then it also lets you literally walk around in the room automatically so and if you want to fly that is a setting for the WASD controls where you literally just have to say like I want to fly so there's like a little checkbox here I mean move zoom in a little bit whoop so you have in the WASD controls you have a fly parameter that's the camera entity so I selected the camera here and what does that actually yes and now if I'm looking up and we use W then you see that I'm flying up over the so it now actually does it no longer restricts my movement to the to the to the ground plane but it actually lets me move whatever be aware that this does not work in VR for the obvious reasons that if you are like having the position data from the HTC Vive it's going to use that it's not going to let you fly up yes it is possible to do that it's just like you would have to probably use a different way of controlling things um and you can I have I think I've never done that but it's it's definitely possible with the influences with the cardboard it should the cardboard you don't have position data so you can just like move the user where they look for instance and then that would work probably also there's an interesting thing if you are if you're using the URL that glitch gives you on your phone you're going to see something interesting um because the the look controls that are automatically used and we go to like fortunate dash tendency it's an interesting one tendency dot glitch dot me you get what's called the magic window function which can be like super nice or can be super terrible because if you are then like turning around in the room you're actually turning the camera and that's what the look controls do automatically so um I can show you why that is not necessarily the best thing ever like it's super cool but it's not always what you want so if I now load it takes this as zero and basically it shows you actually my screen is like super dark I should probably crank up this okay right you see you see the sun here right everyone sees it and I can now like move my phone that's cool but now imagine that I'm I don't know I'm walking somewhere now I'm sitting down in the train like this I see nothing and I have to actually like move my head around or reload the page so it's not always what you want but it's kind of like an interesting interesting thing um it's an interesting default I would say uh to start from and if you don't want that you would have to remove the the look controls and find something else that does the right thing for your scene okay is everyone back everyone seeing the people next to them or are we are we did we lost someone to the to the coffee break I think there's like two people missing for the coffee break uh bum we'll wait a few more seconds also another tip that I keep seeing people make a mistake with so you can place a camera I'm going to explain that in more detail later on but basically what you can do is you can say like I want my own camera and I can say like I a entity camera and hey look at that we have a camera first things first if I do that and reload you might notice that I can no longer use the mouse or the keyboard to move around so if you do that like you lose the default camera which automatically has the controls attached to them but also what some people unfortunately like to do and this is really unfortunate is they position the camera somewhere so let's say like I put the camera to like I don't know the five meter sorry 005 let's say like that and this is nice for a regular like 3D thing and it looks okay and great but what do you think happens if I'm going into VR is it going to look like that it's not and the reason is that if for instance I'm using an HTC Vive I actually have a position in the room right because the HTC Vive tracks the room so I know where in the room I am so that's where the camera will automatically move to and even worse if I am using a cardboard or a google cardboard sorry daydream or something like that it's going to start at it doesn't have position data so it starts at 000 and then that's where the camera moves so I'll not be where I think I am and I've seen that a lot of people like mixed that up and basically like when like oh but my up like my 3d object that I found on the internet and I'm using is unfortunately not positioned around the origin so it's like in 10 meters over there and 50 meters over there so I'm just going to move my camera there instead of moving the object around the origin with the downside that it looks great on the on the computer and they're like yeah this is awesome this is great let's let's send it out and then the first person to put it onto VR goggles is like I'm standing in nowhere and back in the at the horizon in like 50 meters away from me is something but I don't know I don't know how to get there right and that's that's a problem so you always want to make sure that the the origin position makes sense which means you might want to move like your objects and your scenery around to make it match the origin position but you can't guarantee that you can't guarantee that but it is it is more like the let's let's face it like the maximum room size I think that the HTC Vive supports is like 6.5 meters so you could theoretically just move over but not necessarily not necessarily but like you can you can for instance try to figure out the position at start and then like move things around a little bit or something like that and actually I think recently Firefox fixed it and now you actually always started 000 and it just adapts to to where it should be but I think it wasn't like that in the beginning so it's a reasonable assumption it's a reasonable assumption that 000 is a good point to start with but actually there's like VR has a lot of interesting challenges one of them being now cool you have an HTC Vive but a not all your users are going to use that some are being on cardboards for instance actually most of them are probably on cardboards and b what happens if I have an HTC Vive but I only have like two by two meters I think the minimum is like 1.5 meters by 1.5 meters space and now I have a 10 meter room how does that work and the answer to that is there's the thing called teleport controls and you can use a controller to actually teleport you somewhere like you point on the floor and then you teleport there it's better but then you have the UX problem that not everyone knows how that works it's not obvious how this works and yeah it's like a lot of a lot of work has to be done so what we experimented with is I don't remember the URL so be be nice with me right now because I'm basically doing something off script I love to like do things that just come to my mind but sometimes it backfires which is like super annoying so then an experiment that I did that works with pretty much everything is you have this cursor that looks so basically works where you look at so you look at this thing unfortunately now the model is loading and to move I look on the ground and it should trigger but it's obviously not triggering because screw me that's why here we go oh great I broke it as I said I go off script this is like the fun thing ah okay now it's not broken nice that's probably an old version that has like a maximum range or something so basically you look on the ground and then you move there you teleport there oh shit I teleported through the model so I probably want to teleport back real quick and then like look at this thing and then it goes whoop and I did user tests and my sample size is super small so don't quote me on it my sample size is like 20 people and I tested with people who have never done VR before with the cardboard and they understood what they had to do so people understand this way of navigating is like so how can I move over there just look on the ground oh yeah it makes sense and actually I only had to tell like three people that and the other people just knew what they had to do magically so this is but again like 20 sample size 20 is like nothing so basically just don't trust me on that one um but yeah so there's like a lot of stuff going on and it's going to be super interesting and with AR for instance you don't have that problem because you are using the real world as a as a reference point so moving around is not that much of an issue and yeah lots of interesting user experience things going on and the best moment I had was when when I felt so bad for like making a bunch of UX mistakes in one of our projects and then I went to a conference um where they had someone demoing VR and they had like a room escape game and the user had five minutes to escape from the room and pretty much every user that tried it took like three minutes to figure out how teleport works and and they were like super super confused about everything like so how do I oh this is how I move all right okay oh oh my time is over already what and I'm like yes it's not just me so yeah teleport controls are super nice but not obvious to people yet we're gonna see that also by the way how many how many let's say uh Oculus rifts to use think have been sold in 2016 I don't have the numbers for 2017 unfortunately like worldwide just a rough ballpark a million 10 million okay less what hundreds of thousands is around the right ballpark like I think it's like 400 000 or something HTC Vive's global sales in 2016 were I think like 500 000 ish um how many cartboards do you think have been sold and I have a guess in the what like what is it 100 000s or is it millions or how many millions do you think less than 10 has been 82 million devices in the market and that's only like the official channels because you can get like weird knockoff things from Ali express or something like that and yeah they don't count I think so that's like it's it's bananas so this is like the reality or has been at least the reality of VR in like 2016 beginning of 2017 I still haven't found numbers for 2017 so I'm really really looking forward to see when the numbers come out for that for last year because I expect that to change a little bit but it's like just just seeing that let me see if I actually I have slides for tomorrow so you're gonna get like a super sneak peek of what you're so totally not supposed to see right now but I just the graphic is just like beautiful um I hope that I have it in this version of the talk I might have removed it yeah damn it I don't have it in this one in that case you see something that no one else is going to see um I'm going to go to an older version of this talk because I'm pretty sure I had a chart somewhere uh that was like super fun to look at because it's just like bananas where is it ah here we go yes no no no no no no don't just jump ahead of myself okay here we go so like this is this has been like the VR market in 2016 right you have like Oculus Rift, HTC Vive, PlayStation VR is actually doing pretty well Daydream has just entered the market uh that that year so it's like this is comparing a full year against like maybe a quarter maximum and then you have like the gear VR that outsells them it's like 2.2 million units and then you have like the card oops the cardboard slightly more so it's like pretty pretty impressive I might actually enter these slides back into my talk for tomorrow so the at most yeah because there's older versions of cardboard that do not have a button like they have this magnetic thing that basically works with no phone and yeah so you have one button as an interaction and obviously the gaze of the user where the user is looking at and then like there's this established pattern of having a gaze cursor but yeah that's what I mean is that you lose the ability to do like any type of key navigation absolutely and it doesn't have position tracking so it doesn't know where in the space you are so you can't do like whoa I'm gonna now look down here that doesn't work it only has the orientation so it only looks it knows where you look at so that's like yeah that's the harsh reality so I mean it's kind of interesting to see like a lot of people are building um building VR applications specifically for like one type of hardware and then it's mostly like the high end things like oh yeah we have this amazing demo for Oculus Rift I'm like cool what happens when I open that in my cardboard uh right so it's like it's it's not easy this um AFrame has this lovely thing called progressive controls so they are basically like upgrading themselves and you get like more interaction so for instance for click it figures out oh this is a thing that doesn't have any controllers attached to it so I'm just gonna use the gaze so you have a little cursor that like zooms in onto a point and then actually fires a click event on the object that you have looked at last and that's like super nice and if you then have a cursor like a sorry controller then it goes like oh there's a controller that's like super nice and if it's like a cardboard controller you only get one thing so I can then actually point at something and like press the button and it's a click event so the rest of the code doesn't care and then I have two controllers because I have an Oculus Rift and I'm like oh this is nice pew you basically have like a laser kind of thing going from the controllers and you're like okay click and it does a click event so the rest of the code still doesn't care um I'm not gonna like it's not always that easy because some some interactions are just not easy to map like for instance when you have something where you edit things if you have two controllers and you know that then you can just go like yeah and I'm gonna drag these out how do you do that on a cardboard not easy does not naturally come like immediately obviously but you can detect what you've got and then there's like things I saw I made that mistake a lot of times a lot of times and I got myself really angry with myself so that's kind of cool because I learned something there when I built something for the HTC Vive I was like I have two controllers so I'm gonna make use of two controllers but they are wireless controllers so they do have a battery in them so this one might actually run out of power eventually and they do not always like need to be recharged at the same time so I ran into a lot of situations where I knew the hardware I would be using but I assumed that I have two controllers when I really only had one because the other one needed to recharging so I was like and now I use the second controller which is and then you go out and like the entire immersion is broken it's not not not very good so don't assume things like number of controllers or system that you're on assume cardboard and then enhance based on that unless you really really really really know this the setup that you've got so for instance I built a demo for google chrome depth summit where I knew that I would have like recharged controllers all the time because it's basically a short demo and straight back to the charger and I had an HTC Vive so I actually just optimized for that but it's not a good idea to do that for that VR because the promise of that VR is it responsively responds to the environment you're in and it works everywhere and if you're not making sure that it does then you're probably letting your users down which is not something that you want to do all right moving swiftly on any any other questions anything you're wondering about anything that's not working no okay well let's let's go back to the camera thing that I was talking about real quick and then we're going to have a look at the lighting as well so as as I said this weird thing here with the with the orange lines and the white line that's our camera and that's nice because AFM automatically adds this for us if we are not doing it so I can click on the camera in the left hand side scene graph and then on the right hand side the the entity pops up and we have like a bunch of components we have like a camera component that has the field of view of 80 degrees we can change that let's say like 60 degrees then we just have a like tighter field of view it doesn't really matter that much I would just leave it like that we can specify the user height so if for some reason we are mostly around people that are one meter 80 then we just change it to one meter 80 but it also has added other components so it's not only the camera component it's also look controls and WASD controls and look controls and WASD controls are components that make the camera respond to input so we can move WASD we can use the WASD keys to move around and we can use the look controls to use the mouse to drag around or in VR this would then also be be using the orientation so if I put my phone into into a VR headset this one does not know where in the room I am but it knows if I'm looking in that direction or in that direction so that's what the look controls do if you disable the look controls the user can't turn their heads you can do that but prepare to have a bucket around because people then usually vomit it's a bucket full of fun to do that you can also create your own camera you don't have to rely on the camera that AFRAM gives you so let's do like an an A entity camera here A entity camera so you're not going to see a difference except for the problem that you can no longer move with WASD or turn with the mouse or even in VR you would just like get the straight look and it's not going to do anything useful it also allows you parameters like the user height that I specified earlier on so we can give it like the user height of 1 meter 60 or 1 meter 80 or whatever notice here there's an important bit right there which is I would always use this instead of because you can basically do what you could do and you should not do is you could do like position 0 0 1 meter 60 0 right and it kind of looks the same right except that if you're now going into VR you're gonna see something weird happen and what's going to happen there is that in VR it assumes or it tries to get the actual camera position in in y direction and also in the other directions if possible and what happens if I do it in a cardboard or in a google daydream or google sorry Samsung Gear VR it's going to set it to 1 meter 60 there's like a sane default or whatever we set in user height that's going to be used so if I put my camera onto 1 meter 60 in position it's going to add 1 meter 60 on top of that so then we have 3 meter 20 tall which is very unusual for humans for most humans at least it's going to be an interesting experience but unless that's what you want that's going to be weird and also if you have the actual height it is kind of nice to to be actually like as tall as you are in real in the real life so Oculus and HTC actually give you this information so you should use it and user height takes that into account position does not right so you don't want to do that you want to leave it where it is um you can also put obviously you can position it anywhere else like I can do like zero zero minus actually you know 10 just plus 10 so you go really really far away but I said that earlier on but I'm going to repeat it for for people grabbing a coffee in the meantime if you do that the problem is that once you start VR you are actually at zero zero zero with a camera or even like in the room if you move around the room if your VR gear supports that um so what's going to happen is it's going to not look like you expect it to look like so what you should be doing is you should be keeping the camera at zero zero zero and assume that that's like a reasonable thing so we can leave this out actually we can also do animations with the camera so let's do that let's just for for shits and giggles a animation uh attribute rotation to zero 360 zero duration five seconds and now our camera turns we if your user is using the r goggles and that this is when I'm not going to look at this week yeah that's that's where vomiting happens um so don't do that don't move the camera you can do that as long as you know that you're not in VR and you can check that you can actually um I would have to check I'm relatively sure that it's on the a scene actually there is a property somewhere uh I don't know but there's it's in the docs let's let's uh check the docs because this is actually important um to know my brain's not working that well when it comes to remembering things so I need documentation for everything um it has it sends you events that's for sure and I'm pretty sure it also has a uh it has a component that actually gives you the information but this is the wrong thing it does definitely have a property somewhere but you could listen for events as well like enter VR and exit VR gives you definitely this information um that you need isn't it giving us all right so you want to listen to these events to figure that one out we do that for camera tours um because it's just like it's not a good pattern to never in VR never you move the user's point of view unless they expect it to move so if you have like a roller coaster ride it is fine because you have a reference point that moves do not just move the camera around move an object around the user be it like a carriage or a train coach or whatever like anything an elevator is fine as well just never ever just move the user without the user willingly doing that and that starts with things like teleporting is always already like a gray area cool now if we want to get back like the look controls and WASD controls we just add them like this ASD controls so now it's basically the back to the original functionality so I can look around with a mouse and with the keyboard I move and on a on a VR headset like these that we have here we would still be able to like look around um but we wouldn't be able to move actually because it doesn't have position information these people so at least this uh headsets do not have position information unfortunately we can also control some of the parameters so for instance you might have noticed that when we have the WASD controls we're always moving on the same plane so we're not actually moving up or down and this entire like user height missing actually makes me nervous so I just like add it in so now we can only move like forward and backward and left and right we can't move up or down like we can't fly around what we can do in the WASD controls it has a fly property or attribute that allows us to basically change that and if we look up and use W then we're actually flying up if we look down and use W we fly down and stuff like that so now we have like flying controls that does not mean that in VR you can fly unfortunately you would have to implement that yourself I don't think there's anything that does that automatically okay let me move some of the things here so there's also lighting coming into play here um as I said like 3js app a frame automatically adds lights um so we don't have to which is nice but maybe we want to have different lighting conditions so what we can do is we can do like a entity slash a entity and then we give it a light how do we do that well there's a component for that so we do like light now we have to figure out what type of light we want and one of the easiest types is the ambient light ambient light is basically like daylight it doesn't come from a certain direction it's just like all around us and it shouldn't be too bright because it's going to apply to all the things all the faces all the objects in our uh scene so what we can do is like we can give it a color let's say blue now this is really really dark blue so that's not the best idea I had so let's actually um give it a slightly brighter I don't know yeah so it's actually not a good not not a bad idea let's let's try the cyan so now you see something curious it's actually not that easy to spot on the on the projector maybe if I go closer no it's actually really really hard to see but on your screen the sun is now like greenish and that's because the the blue well actually the cyan light mixes with the color of the sun's like so we have like this orangey color and cyan mixing into this like weird greenish color if I would instead of using this this particular image if I would use a color as a plain color let's say like ah come on I use color white then the sun is no it's actually not white it's actually using the light color and you also see something else if I move around the sun as I as I mentioned earlier the problem with the ambient light is it doesn't have any direction it's just everywhere and that's usually a good idea but you should never like use super bright colors if you need an ambient light that gives you some colors probably use like a darkish gray um and then use other lights on top of it by the way if you want like a night scene you can also abuse this um by actually just like putting a black light in so this is now a night scene because it doesn't actually have anything that's like driving it so if I don't use that if I use it like a darker blue as I actually still like too bright let's use like a super dark blue yeah so now we have like a light scene and you don't see anything that's not not very interesting right so what we probably want to do is we want to want to use more interesting lights let's let's start with the point light let's start with the point light that we position uh we don't have any positioning here so it's at where the camera it's below the camera actually but it's like where we are and we give it a color let's say see on just because we had like that early on I shouldn't use like the the hash type point and then we see that now we actually do have like a light bulb that is below the camera that lights straight onto our well sun if you want to call it a sun um actually let's let's make this the sun yellow again just you know now the sean color shines on the yellow sphere making it green it's probably not exactly what we want so we can make this white and then it looks like what we would expect if we wanted to make the sun glow uh that's an interesting one not an ambient light but you could put a point light into the sun so what I can do is I can take this make it a child of the sun and it's not quite what you would expect probably we're going to see that in a second so this is not what you expect right no and what the reason why this is is because we have a problem so how how does lighting actually work let me let me quickly it's going to be this is one of this is one of my favorite explanations um because it's actually pretty simple but it's it's not obvious so how do we calculate light well let's have a have an example here we have a light source there and we have a surface here right and now obviously I have it like black but technically this is like fully bright as bright as the projector makes it based on the light coming from the projector hitting this fully frontal now what does fully frontal mean well if you think about is this surface here is facing in that direction and the light coming in faces in that direction there's a 180 degrees between the two so it's like full on it's a hundred percent light of the light that comes from that direction hits this surface now what would happen if I would start to move the surface like this right now it's no longer the same now we have a different angle now we have like the light coming this way the surface facing this way so we have 45 degrees so we only have like half of the light actually hitting it if you think about it it's like half of the light kind of like goes bonk and goes somewhere else and then only half of the light actually comes back to our eyes if I would like lift it up entirely and I can't actually do that far but basically if I would lift it up to 90 degrees so that it faces this way and the light comes from here the surface is not being affected by the light at all now how do we model this in computers because we can't actually like you know shoot light rays and then see what happens in the real world and then somehow like map that no what we have to do is we have to figure this one out differently and what you can do is it's relatively easy to figure out based on the geometry it is not too hard to figure out where something's facing the direction something is facing is called the normal vector right so if we if we go into our coordinate system x being like this y being like this and z being like this the light has a vector of minus one like zero zero because it doesn't go to the left or to the to up or down so basically zero zero and then minus one because it goes in this direction the length of the vector doesn't matter so we're just going to set the length to one we normalize the vector that's what's it called and then we have the normal vector from the surface going the exact opposite way so it's like zero zero one so now what we can do is we can figure out from the textbooks or google how to actually calculate the angle between the two and then we have the angle so we would know okay 180 degrees and we want a hundred percent of the light if we have 90 degrees we want zero percent of the light and if we have 45 degrees we want 50 percent of the light how do we model this in an equation if you do a bit of trigonometry and look at like circles and Pythagoras and all that kind of stuff eventually or if you just google for it that's an alternative to this a function that with an angle of 180 degrees is one and with an angle of 90 degrees is zero happens to be cosine so this is how lighting works in computer graphics you're not doing like any magical sorcery you're just figuring out my light goes that way my surface for phases that way what's the angle between them cosine that and we have how much color we got right so basically we have like let's say we have a red color here and a white color here we just multiply the two with a cosine and then that's it that's what happens so like cosine of 180 is one called one times one which is like the bright white light plus one only for red and then you basically just forget that together and then you have like a fully lit white um or sorry red sphere here and obviously because the sphere has more faces facing in the other directions you do that for each of these faces and then you get the different shades of a color this is why you get like you know the the come back okay why it's not as bright here as it is here this is all it does ish like this is the simplest way of doing this kind of lighting it's called Lambert lighting Lambert lighting has a problem it has multiple problems actually first things first when we do that for for each of the faces if these faces are very large it's not going to look as good we can we can simulate that by going into the inspector clicking on the sphere and somewhere here it should have segments yes so let's set the segments to a relatively low number and go back so now you see like we are not having as many like the shape is not as round anymore and maybe i should actually stop rotating it because it's like super annoying um can you maybe not rotate that'd be like super cool thank you and i should have said so here it looks kind of nice right it looks kind of smooth actually i'm not never sure how how well the projector does um but if i remember like if i reduce the number of of vertices and faces then it's not going to look as smooth and you see like the lighting also does not look as nice anymore it's a little rougher here and it's like not as nice here and that's because we do it once per face there's also ways of doing like more calculations by doing it for each of the vertices and then like interpolating between the two um so that's another way of doing it but like this is the way that lambert does it and the other problem is if i want this to make it like super shiny then i'm not going to have and i can actually return actually let's just reload um to the smoother thing but you see like it's not very shiny right there's no like nice shiny light and that's because this this lambert equation does not allow that we would have to make sure that something that is coming straight on it is much much brighter and then quickly stops being as bright around the same like like angles so there's different equations and one of them being the fong equation that allows more complicated lighting situations and conveniently you don't have to worry about it i just wanted to let you know that these exist if you're here like fong shading that's like shiny glossy material metallic materials and lambert shading is like silky smooth materials we can fix that lighting problem if you want to make this like more glossy conveniently by just increasing a value here we don't have to worry about all this kind of stuff what we can do is we can say hey um can we be like more metallic and i can like set it to a value of one for instance and then like it's like super shiny uh it's probably like even too shiny because like the spotlight is like super bright so now this looks more metallic i would say because it has this spotlight it has this highlight over here it's going to look nicer on your um computer screens probably than on this screen but hey um so i can say like metalness zero point let's say like 75 so 75 percent metal and then you get like a nice highlight instead but now the question was how can we make the sun like shine and look nice yes we can the problem is with the light internally it doesn't mean that it actually lights up the surface because the surfaces are like the surface of the sun goes like this way the light goes like this way zero degrees not going to be nice what we want to do instead is we want to set a different type of color so what this is actually like misnamed a bit because in computer graphics books you're going to find this as the diffuse color now what does diffuse color mean diffuse color is the color that um is being reflected from the surface because that's how lights or how material colors work right if you have a green car it means that uh red and blue are absorbed and green is reflected so that's basically it diffuses it spreads the light in different directions as a reflection is when it comes exactly back where it came from and diffuses when it likes like you know goes astray a little bit so this is the diffuse color if you want this to shine a light or like looks shiny then we would have to emit light right because the sun looks like it looks because it emits light now this is not the same as having the light there the light that you put there the point light that we put in the sun is lighting up other things it's not lighting up the sun because we're inside the sun and it doesn't work with the angle so we have to set the emissive color as well i can say actually no no i'm not doing it on the red sphere that's not a bad not a good idea a board mission abandon ship so emissive yellow and look at that that's a tricky one theoretically hypothetically it should work when you set up the so let's see actually that's a good question i know how to do it in blender but i'm not exactly sure actually we have textures here they're gonna look weird but it proves the point um so oh no actually i do have the actual texture that i wanted that was well completely forgot about that we downloaded this here because of cause origin shizzles um okay so that's like source this and uh that's what i thought so this is this is gonna be tricky you're probably gonna have to write your own material to make that work i don't think it actually what happens when i say like can i can i actually do that never tried it no it doesn't support because there's no such thing as an emissive map so you would probably have to do this like differently um a way to fake it is to let's see uh this is nice a way to fake this and i actually don't know the the parameters for this again um so we're gonna look them up is to actually say that it should not it should not care about light because there's different way like light in a 3d scene is not something that you physically intrinsically have to have it's something that you choose to need if you want that so you can actually tell it to like ignore lighting entirely and i think uh-huh here we go uh flat shader is that the thing that i want standard material do i get to actually pick a different material i wonder how do i say it like i'll try something because i've never used that property now that i think about it so let's see what happens um call shader basic i don't know if that's the right thing no it's not okay cool i kind of expect that to happen we're getting somewhere i'm not exactly sure where we are getting was interesting anyways is it a flat shader because it aha right so a flat shader um it's a bit confusing because it a frame uses 3js under the hood and 3js calls it a basic material and the basic material just ignores light and just uses this color um and here's like a flat shader which to me is something different but okay it's whatever um so basically by saying that you want the shader to be flat rather than the standard you get a shader that ignores lighting entirely and just uses the texture that you give it and which effectively looks if the texture is right looks like it's emitting light but it's actually not emitting light okay so now we have like this wonderful little scene with the sun and the little planet orbiting and actually let's find the an earth texture as well just why not very good question not as easy um for glowing you would have to write your own material and an old shader i think there's might be an effect for it um let's actually let's actually look for it i don't i don't know for sure right hemisphere light um but it doesn't have a position the hemisphere light shouldn't have a position make it look like this and oh okay yeah it looks more or less nice so but are you sure it looks the same on the on the back of the sun um if you go if you go around the sun i'm relatively sure with the hemisphere light you might not see because hemisphere lights are basically working like the natural sun would work on the earth so they shine in one direction it's it's like a point uh light but it's bigger and if uh i believe if i said hemisphere size bigger might work but i'm i would be surprised because it's normally literally meant to like shine on one side of a thing and not like all around it i would be surprised if that works but you know if if you're right that'd be amazing because that means i learned something today that'd be cool try going behind the sun does the back of the sun also get lighted that way or below the sun because the hemisphere light has to like it literally is a half a sphere so it has to light from one direction but i don't see you would have to have a second hemisphere light to actually light from the other direction as well anyhow that's really cool cool um yeah so to make it glow you would have to oh what the hell uh you would have to use a component to actually make that work and i would not necessarily use that because it will definitely have a performance impact you can write your own shaders and there are probably custom shaders available for glowing somewhere um like when when you use our 3d models you actually get a different shader than the 3js or a frame shaders because we do light maps differently i mean there's other types of light as well you don't only have the um the point lights you also have the hemisphere light you also have the directive light a directional light jesus you can then start to like experiment with things so for instance we might want to do something slightly different i'm actually not going to remove all of this but i'm going to comment it out so that it doesn't get in our way um so i'm going to leave the sky in because it's nice to have the sky here so what i can do is i can have an a entity geometry primitive plane and i oh god i can never remember i'm going to do it like this and i'm going to see what happens because i can never remember which way i have to rotate it to make it look the way i want to make it look like so i'm going to start with this and i'm going to figure out the rotation by just like turning it and see it's negative okay fair enough so we're going to rotate this rotation zero no sorry minus 90 zero zero so we are rotating around the x axis and i'm gonna i'm gonna give this one a width of 100 and the height of or depth i think it's depth depth of 100 so now we have like a plane that is our ground plane and i'm actually not seeing it and it might be because i might have done something that is wrong right it's not depth in that case it is is it height that's like super weird yeah okay fair enough and you see like i didn't give it a material yet and immediately 3js as i keep saying 3js jesus christ a frame jumps in and for our ground so we now have created a ground plane um and for that to like look like something it just generates a color uh and makes sure that we are we are seeing it but i can also give it like a material and i can say i don't know i want this to be color 0 0 a a 0 0 so we have a bit of that um now i can actually make that white whoopsa shit make that white no not hashtag white and i can create a light light and position it somewhere and i'm just gonna position it actually i don't have to position it i think um i wanted a different light i wanted directional light and again i can never remember the parameters so i just gonna check them out here directional what kind of direction does it automatically go to the example below creates shining from the upper left at a 45 degree angle where does the 45 degree all right okay all right yes yes yes because the directional light is basically it's not quite like the sun actually works but it's basically like light coming from some direction and going towards the origin so the position doesn't actually matter that much and it except for we need to figure out like the the difference between where the light is positioned and the origin is the direction that the light is going to shine in towards so if i say 0 1 0 the light is going to come from the top and shine to the bottom because this is our ground and this is our light so the light this is the the difference between the light position and the origin position so it's going to shine in that direction from the top and i give it a color oh yeah let's do something vapor baby let's go um ha let's try a a 0 0 a a and then we do a second light same light except for i do a different color and i do a different position so now this light's shining from the bottom up and so we have a magenta light shining down from from above and another light shining up and now we put an additional entity in a entity geometry primitive sphere material color white oops color white and we position that in front of our camera so that we actually see it and actually maybe i move it up a little bit as well so that we see something and hey the 80s called nah that's too much still too much no way what okay it's like super super intensive better so like yeah the 80s called they want their models back and this is how you do vapor wave um and you could also now like uh let me actually see so i go to images google.com and i need a grid image that is nicely tileable no that's all bullshit i just need to ah god damn it tile ah this is not what i am looking for right you know what i'll do it myself because i'm a great graphical artist uh this is gonna be fun come on i can't be bothered to buy adobe products so i'm like yep gim bit is and i was like who the what why would you use gim but i'm like you know let me do my thing i know what i'm doing no i actually don't but you know it's kind of cool anyway so uh let's use black and then use white to create a little bit of oh Jesus Christ how do i make this grid parent tileable so it's like 256 pixels it's like 128 so i go like 124 to 132 it's like nah that's actually pretty tiny but it's going to be fine i guess and then just like drag it like here i'm going to share the the url to this particular beautiful image in a second so that you don't have to do like this complicated uh image editing process so i'm just going to copy the layer here and then just actually no actually i can duplicate the layer and then no i can't because it's not transparent ah Jesus Christ ah make it transparent put it in here and then i do like layer rotate rotate rotate rotate 90% clockwise here we go so this is my grid hurrah okay cool so export as png yeah let's call it grid why is it why is it putting it into documents no don't put it into documents this is not a document this is a this is terrible um but it's okay i got this Jesus so we put this into assets uh where's like the upload thing there's an ah here from computer i go to downloads i go to grid i upload my grid and i can now go to my which is this one i should probably give it an id so that i can just easier identify later on and i can give my ground a different material where i'm saying like source is this wonderful your oops what uploading url no don't no don't you Jesus okay great now i have like five times um i get a url from the assets and i put it in here and whoa okay this is like gigantic now this is not what i want it okay let's do like oh i can't remember i think it's like repeat 1010 or something like that is that yes right okay now we have we have fully gone vapor wave here we can make the overall scene a little less dark by adding another light uh like a really really gentle a entity light type ambient color six six six six six yes that looks like enough sixes um that's too bright actually already so let's let's actually make that darker yeah still still pretty bright yeah it's nicer um so yeah hurrah this is the kind of stuff that you get to create and then like walk around and then have a lot of fun um could you show the tag for the ground again yes the ground is a actually let me let me fix that a little bit so that's not as as hard to read on the projector let's move it around here and then the rotation and then the material with the certain source and that should be it yes okay cool so yeah uh oh no oh shit is it all lost now it is probably all lost now oh no actually it's not because no it is all lost no i i think i think it isn't because it must have been saved because i was able to actually go to it on my phone so it was like fortunate something something if you're logged in i think i don't know i wasn't logged in so that's like that was the danger stranger danger um let's see fortunate tendency okay fortunate tendency dot glitch dot me if that's still there then we should be good and it's still there so we should be good so let's see it's like glitch me and then like this i know it's actually glitch.com isn't it the naming convention never occurred to me this is like oh look at that i i'm not signed in but it magically figures out that it's me awesome thank you so much glitch because that was like not expected to happen um so yeah we have a plane we give it a certain width and height we rotate it minus 90 degrees around the x-axis so that it actually faces upwards and then we give it a material with a given grid image if you want to use the grid image i can create a short URL if you want yeah sure so you know it's super like i totally have the uh no not that uh i totally have the copyright on that but i'm i'm okay i think i make it public domain i don't i won't make you pay for this like it's probably to be honest the thing is actually better like than like like one percent of the of the uh stock photos are just like shit so i think this is actually better like you know there's stock photos where you're like what the hell women laughing at salad is one of my favorite ones is like what again don't use the short URL if you use the short URL in the thing it's very likely to not work because it does like a redirect instead of actually giving you the the thing and then that breaks um cross origin sharing i think right any questions so far should you go back to the code i could totally do that anything particular you're missing if you don't put a week and a half and apply you will just extend it firmly no it will be like one by one meter you can also use scale to scale it up um but that that means that basically you're like stretching it a lot and that not necessarily gonna look great with textures yeah um so i kind of prefer that because it makes clear that light is a component on its own that you can attach to pretty much any entity that you wish to but technically it's not much of a difference there is pitfall here is for certain entities there are differences for instance writing a camera is not a good idea because of the way that the camera component system interacts with the scene so it's like it's a it's a little tricky and whoops is someone co-editing this right now because i'm not exactly sure where the color comes from like is someone highlighting can i see is there someone like oh yeah look at that hi uh very nice meeting y'all interesting interesting i did not know that glitch can do that but it's cool to to figure that one out you know so it's also like i i saw a lot of people got like super confused um for instance when you like a entity and then people are like color blue and they're like it doesn't work anymore why does it not work i'm like well because it's an entity and color is not a component that it can use by its own it only works when you use it with a primitive component so i kind of prefer that style i actually to be honest when i write a frame component a frame code i usually don't do that but i find it easier to teach that way because it's like consistent uh and you always do it like that i mean i made an exception for the sky because i couldn't be bothered to actually look up how the the sky material thing works because it's just like not really useful in most cases also by the way we don't we are not constrained to use like the things that a frame comes with so there's a thing um called the a frame component registry and i'm actually not sure i've never used an inspector so i'm going to see how that works so we can add things to the scene in the inspector so we can say like add a new thing and this is an entity so it's an empty nothing thing right it doesn't have anything attached to it so we can't really see any of of what it has and um i'm actually wondering if i'm able to oh this is interesting so it has all the components that that a frame comes with but it also has this has this a frame component registry and in the component registry you can search for things for instance i can search for environment and i find this and it allows me to to basically like get the url of the component and i can copy this i should have actually copied it on the on the thing before so again like if you add something you can see all the components that a frame comes with and we also actually see like the i o 3d components because we have loaded i o 3d i o into our scene as well so here we have all the wonderful a frame components and then you have like the a frame registry next to it and it gives you an overview of all the different available components and there's like a lot of them um you see for instance like an ocean or a force graph gaze control yada yada yada layouts leap hands if you have a leap motion yeah so there's like lots of these components available which is like super nice and uh i have just copied one and i'm gonna go here and after our scripts i'm gonna do like script this is super confusing whoever highlighted this thing can you please unhighlight it just nice so what i again what i have done is in the a frame inspector i clicked on a frame registry and i looked for environment and you get this component here and i think they actually also have like previews yes so here we have a preview of the component what it does how to load it and how to use it and he says like it has a bunch of presets and has a bunch of parameters and yada yada yada so i just loaded this javascript into my scripts sorry into my documents it's a frame environment component and now i can use it in my scene and i probably want to remove my uh my ground because i'm relatively sure that the ground actually also the lights probably because i'm relatively sure that it's gonna collide with uh what the what the component does so if i'm now going back and reload oh i magically lost reload capabilities so i probably want to do like show live all right so now this component creates an environment which is like very nice and as we've seen in the a frame inspector even for these components that are not a frame components built by a frame themselves but actually built by um built by by the community you get to see all the parameters in the a frame inspector so we can now explore and try things out so for instance we can use a different preset let's use tron and then you get like this trony environment it's a bit weird but okay i don't like these weird towers so let's find out what these towers are where are they coming from ground spikes maybe what happens when i say like hills instead all right okay no that's not the okay that's not what i wanted so i kind of want to do like spikes it's okay ah dressing towers i don't like towers i would like trees make no sense mushrooms are like super weird in this case so how about oh okay yeah no that's very nice but not what i want so can i say like nothing oh cubes no that looks even worse um let's go with nothing so you get to like explore different things like this this environment component is really nice because you don't have to do much and you get like a nice environment um if you're not that much into like cyber punky things then what you can do is you can also try i think there's like forests somewhere and there's like actually a nice forest here we go forest and then you have like a brightly lit scene so you don't really have to build your own environments you can use one of these templates if you really quickly want to like build something up but i highly recommend at least like trying to build your own environments because it's kind of fun and gives you like a more better feeling for the the thing you are creating i'd say fortunate tendency all right okay um if we wanted to get that into into our code we should be able to just say like copy this and i'm gonna oh jeez you know what i'm gonna i'm gonna remix this don't you dare don't you dare okay um so this is actually like dragging in everything that it generates so what you see here is there's a bit of an interesting secret in this one so what we've seen in the inspector if you look closely is that this actually generates a bunch of more entities right so i had an entity with like the environment component but it actually generates a bunch of entities inside and i can either keep them or i can remove them and it's going to regenerate them that's basically up to me but yeah so your components could theoretically create more whoops okay this is not exactly what i wanted more more things inside so this component is actually slightly buggy because it should not do it should figure out that it has children and then just reuse the children but instead it's actually generating them on top of each other okay what the hell i think i'm just going to remove everything except for the for the preset so let's let's just not have that yeah okay better by the way if you ever see like weird things happen let's let's let's try something i want to show you something and explain to you why it happens because that's some some of the problems that i keep seeing people having so let's say like color red so now we have two skies right we have this sky that is red and we have this sky that is dark blue and what happens is and i'm not sure if it's going to happen that no it's not violently happening which is nice um okay in that case let's let's not show it in the in the thingy and what instead i'm doing is i'm doing i'm doing this i'm going to copy the sphere and i'm going to give this a red material ah dang it's not happening which is nice but it's also not what i expected um i scale this slightly smaller maybe scale 0.99 0.99 0.99 because what i try to show you is if you have two entities that are overlapping quite exactly how this is interesting this is still not happening 0.001 hmm it's interesting that i can't demo it when i really really want it but if if i don't want it to happen then it happens this is like typical uh what i'm trying to show you is like z fighting but i can't actually reproduce the problem great um basically what you want to look out for is if things are starting to flicker that's normally when two objects are kind of like on the same position and because it's the same position the rendering engine has to kind of decide on random which one to draw at the last one so it's not guaranteed to be drawn in the same order so basically is then like it starts to fight over who's going to be drawn first and last and that starts to like flicker especially when you move um when you see that it's normally because two things are in the same position uh it can also be a problem in 3d models when 3d artists are not careful enough they might actually accidentally create two faces on top of each other and then that exactly is what happens um good one last thing that i'd like to show you before we we try to do something in in vr uh or i give you the time to actually explore vr a little bit if you're interested is i want to show you how to write your own components because surprisingly it's not that hard it's not like super obvious but it's not that hard because there's really really good documentation um that explains it really really well so what i'm going to do is i'm first going to i'm going to get our nice uh nice steam back because i kind of liked it yeah that's the thing um oh one one more one more one more thing before i do that there's also an a text component that gives you the possibility to actually create text uh it works slightly different than you might want to expect um the text component is documented in here as well as it's part of the uh text um sorry a part of the a-frame distribution um you can use google funds and stuff with it if you use an additional um an additional uh component for that and it has like these funds uh fund faces built in basically so that that works as well you can also generate funds from it i've always always found that to be like confusing and weird so i never did it but um you can hypothetically do that and how it works is you position it as anything else you would position so let's say like zero two minus two and then you give it the text ah shit that is actually incorrect it's an a entity see that's what i meant with like being consistent uh a entity and you give it the text component and you give it a value and in the value you say like hello world and then where is it it doesn't show up because i think i forgot to give it a material as well to color white do i have to give it a font no oh probably our sphere is in the way isn't it ah bum dash dash yeah there it is hi there there's also an external component so this this one has one downside uh it has an upside as well performance wise this is really nice because it just basically renders a single uh face but on the other hand it doesn't have any depth right and if you're standing behind it well right it's gone um so if you want to have something more like thick and and with a bit of depth then there's like the a text geometry which is really nice but it has the downside of actually rendering more triangles so it's like a a bit of a you have to figure out what makes more sense in this particular case um you can also render two-dimensional images as well there's like an a image component that actually renders a single image that floats in space you can also do that um i think i haven't done that yet but it's not too like too exciting but if you have like regular images that you want to have like an image gallery or something like that then you can do that by basically saying a entity image and then you give it like a source and you can also give it a width actually like i don't know a jpeg and you give it a width like 0.5 which is like half a meter height it's like i don't know 0.25 or whatever and you position that as well so that's not like super exciting but i wanted you to know that this exists it's not only 360 degree images you can also do like normal 2d images so what i'd like to do is i'd like to get our i don't need to defer um our script used so if we want to create a a frame component we do that using the a frame is it a frame was it like a frame i can never remember i think it's a frame register component and we give that an object and um i think we also give it a name and yes we give it a name in an object so basically i would call this planets i don't know we would have to figure this one out um so let's give it like a planets component and the first thing that we have to do is we have to figure out our schema so if you remember we had in the inspector we had like all these different properties right that we could set like the material it had like color and the geometry had like primitive our component might have the same and we want to define it in here so let's say in our in our um planets thing we might want to give it the number of planets that are or actually call it solar system that makes more sense solar system the number of planets and for the inspector to figure out what kind of data this is we have to give it like a bit of help so number is any number including floating point numbers but that makes no sense because we can't have 3.5 planets that does not really work so let's use int which is any integer number we can also give it a default value if it's not specified it should have a default value and i say this one it can be two it doesn't matter it's just like that's going to be the default and we can have multiple of these we can have i don't know um moving shall have like type i think it's boolean i'm never sure and default shall be true so this is how we define the properties that our our component will have and aframes has two methods that it's going to call on this one is the init function that's going to be called initially and it's the update function that is called whenever something's changing oh i forgot a comma here i'm sorry for that so let's just start like with the update function and call like updating solar system it's not very exciting it's not doing anything interesting just yet but it does log something to the console so we can figure out if our component would be working so again in the schema we're defining all the properties that our component will have and then we have an init function and an update function um to well create the thing initially and then afterwards whenever it needs updating we can update it here violent typing so i'll wait a moment so now we're not really using this component um so we want to want to change our index html to actually use this component so let's say like we have an a entity and we have a solar system now if we reload we're not seeing anything because we haven't created anything yet right we haven't done anything visible but in a console it says updating solar system yay so basically this is the moment when the component is basically getting like updated information on what it should be doing based on the schematics and if we now go into our inspector actually let me remove this and go into the inspector and we select the entity which should probably be this one then we see that the properties that we've given it in the schema appear here right and i can change them and i can say four and i can say i don't want them moving so you see that based on the type that we've given the interface actually updates and it has a few nice things like i said four but i can also like drag and then it increases in steps of one because we said it's an integer number so it doesn't do like floating point numbers in this case and if we look at our console again then we see that it has been called more often now that we've changed it and if i change this again you know you see like anytime this information changes um it is actually changing or updating our components it's calling this function that we have in our component we can also do that manually and i'm not exactly sure if this is going to work the way that i want it to work so let's see like i want all a entities yes thank you and i want the one that is i should have given it an oh shit i should have given it a um an id so that it's easier for me but this looks right so components lists all the components that this particular entity has and here's our solar system components so we can go in and say solar system and now in the solar system component we have data and data is exactly what we enter here right these two match so if i now type in like five here and i call it again and we see like number of planets is now five so you can programmatically access and change this information not that you should do that but you can and then you can also manually like call update so i can actually go in here and say like solar system dot data dot moving equals true and i think it was false before and then we can call update on it and um okay the inspector doesn't update that's an interesting one but if i now close and open the inspector again then it's actually updating the inspector there must be a leak somewhere cool but this is not interesting right we haven't actually rendered anything we haven't done anything interesting in our in our component so can we can we do something interesting here yes we can hell yes so how about this how about we go in and um say this which is the component um get oh god is it i get object 3d or is it get 3d object i can never remember the syntax here let's let's check uh is it like get object 3d 3d get objects no ah get 3d object okay time to look at the documentation uh i'm so sorry but it's like to be honest everyone reads the documentation all the time and i i'm not gonna lie to you and go like oh i learned this by heart no i just we're not in school here come on um set object 3d and get object 3d so okay it's like with the uppercase d all right so basically what we can do is we want to create our own um things and there's two ways of doing this as i said a frame is wrapping around 3js so if you happen to know the 3js library then you can use that so what we can do is we can for instance say var mesh equals new three mesh so mesh is basically the exact same concept as an entity in in uh a frame it's just then a different term for it and then you like 3 box geometry 111 so this is like the geometry so here we have that and then we need a material we learned that earlier on actually let me reformat that a little bit so that's a little easier to see so like it's a mesh basic material and by default that's going to be white so that's going to be okay and then we close this one and then we say like this set object 3d mesh and now our component actually explodes because this set object okay right ah is it ah maybe i'm an idiot let's see i might just be an idiot no i'm not an idiot okay cool that gives me this element object 3d all right i know it takes an ah damn it because it can have multiple of these we're just going to be like the mesh shall be this mesh and then hey look at that our solar system is now a white box uh very exciting um i'm dying of happiness um this is this is one way of doing it and it's definitely the more flexible way but that means that you have to learn 3js to write your own components but what if i tell you that's not true another way of doing this kind of thing is by saying look at that we have this element is actually the html element that we're in so we can append children to it now how do we create one well it's an html element so what we can do is we can say okay i i want the sun because we have to have a sun we are solar system we have to have a sun come on um i want the sun to be an afame element an a entity so we create an instance of an of an a entity tag which is what the dom does behind the scenes anyways when we were writing the html and then i can say like sunset attribute uh let's say like emissive oops uh oh this is not what i wanted sorry for that emissive yellow oops what the hell and then we append the sun to the current element so emissive is a property of light or we can use that directly uh you can actually use that i was no you're right i'm an idiot it's uh it's the material component that has like emissive yellow sorry that was my my bad very good point very good for pointing that one out before i'm like what the hell is going on here and by the way i i kind of want to move this around a little bit so right now it's under our camera that's also like not very nice let's move this around tiny little bit so that we actually see it in front of us uh huh why is it not doing it oh because we yeah another thing is obviously uh i forgot to set another component which is the geometry component so yeah that was not very smart um geometry primitive sphere so we're literally like using the dom api to create this for us and here we are and then what we could do is uh we can move forward so let's let's say like four var i equals zero i smaller this dot data dot number of planets i plus plus we're going to like var planet equals document create element a entity so this is this is now starting to get repetitive hopefully um that's really basically it's screw this crap i'm like just gonna you know screw it let's let's do that um for the sake of simplicity we're just gonna make them all i don't know red um it's not sun anymore it's planet that was my bad copy and pasta error and then we say like sun append child planet also we probably want to move the planet a little like somewhere else so we do like set attribute position is like uh let's go like i times 2.5 meters plus well that's the better in the way now zero zero yes i'm hitting an initial offset so we are now moving them a little off and then we are pending the the planet to the sun uh there's a bit of a problem now that um wait where's my planet no i do not get my planet uh oh it's big ah that's what you meant with an offset yes i vey okay right yeah that makes sense um 2.5 plus only times 2.5 so that we do not start with zero there we go it's quite large isn't it uh so maybe we want to do like planet planet set attribute scale so like i don't know um 0.25 0. oops 0.25 0.5 so that we get like a smaller planet but basically that's that's it uh we would now have to work out how to deal with this when the number of planets changes um alternatively we could always like recalculate i mean the the number of of planets is probably not going to change as often so what we could do instead is we could say like okay so the sun is not never going to change so we don't have to do this uh so what we can do is we can say like instead of sun actually we can do like that and then like this sun equals sun so that we have a reference from it and then we take this off into the uh the update function and what we can do theoretically is we can say like this dot sun dot inner htm there's definitely better ways of doing this but like for the sake of simplicity this is fine so like this dot sun uh because what should be happening now if i'm not oh wow what oh is it calling wait wait wait wait wait am i doing something stupid right now because i probably am i think actually it's oh shit it might actually be oh my my tab died good night um it might actually call it when we are updating the the children but i'm not sure it shouldn't actually so let's see huh now it doesn't now it works fine okay whatever um oh no this is the wrong nope still the wrong key hello uh there we go um control out i so if i now zoom zoom zoom if i now go in here and i say okay this thing here shall have three planets then i'm wondering what's happening oh there we go three planets surprise surprise and then we could do like all the the the animations and all that basically the tree can get more complicated and then we could move it if moving is true so you can build these these components like that and i prefer it over the 3js way for most of the things because it's it's how components can easily uh kind of be composed together to build more complicated components but then again if you really need the 3js objects don't shy away from them it's not as complicated this is still a really nice um abstraction over the raw web gl also you can do things like you can actually query the children inside of your components so you can say like if you want to change the way that the sun looks or if you want to give me a different entity for the sun then just give it an i don't know class or something and then i can just load that from what you give me instead of creating myself yeah it's yeah it's possible there's also a callback and components have a callback that is called when the children change so you can even observe that so like it's it's a really flexible system and the the dom makes this relatively easy to actually build this kind of thing so we can get to all of these components through the dom yes yes they're all represented in the dom there's one exception so as i said like the a-frame does these optimizations um for the attributes so uh they they turn it turns the attributes different component attributes into objects which the dom does not support right so you have instead of position as a string zero zero zero you actually have an object x y z zero zero zero um it doesn't always update the dom immediately so if you really really need to export that to the dom there's a function called flush to dom that you can call to actually get like the string versions back into the dom that's causing a little bit of a frame rate rate drop for us like for half a second or something whatever um but if you really need to export it that's the way to go like i've seen people who have like an editor where you put something together and then you click a button and then you get like a text field with the html inside and they're like oh it's missing all my information because it's not unless this goes like solar system equals empty string and it's like no there's information in here like number of planets should be five and it's moving should be false and you can use flush to dom to make that happen like to make it flush it out as a string to fix that the individual so here we've been setting like the whole position string at once can we set just the x or just the y you can do that by using the the javascript method that i used early on so basically what we would do is you would go like um let's let's just do like pseudocode yeah entity components position data z equals five and then you would have to yes i know it's not an actual actual thing you would then have to call update manually to make sure that it's actually like reflected in the component but that's totally possible no i don't want to what no go away um so yes it's lunchtime i already no actually i did not steal any minutes yet it's like three we have three more minutes do you have any questions anything else that i should cover yeah would you recommend for documentation for example for light just looking at the a frame docs it doesn't describe the types of life are you sure about that uh when i want to like the light it said it should i guess it's a drop down on the side for different types oh yeah right yeah right yeah we have like them here listed out in in quite a bit of detail actually okay so just a frame io the a frame a frame documentation is really good there's a there's a slack for a frame you find the links in in the a frame on the a frame site actually so like here's a community tab that has like the documentation github stack overflow stack overflow is also really really great um to if you have actual questions um but the slack is really really helpful as well if you have any questions you get quick help there uh yeah go to meetup groups that are doing stuff like that if you have some some nearby i don't actually know if there's that many meetup groups around a frame yet but i would i would recommend the slack if there's anything that's not clear in the documentation because to be honest like the the project is relatively young isn't like it's probably like a year old maybe now or maybe like one and a half or whatever it's it's not that old yet so there is holes here and there but everyone's like super helpful in making sure that you understand everything there's a few mozilla people at the back by the way um hi long time to see um and like everyone's like super helpful and if you find something that's missing all the documentation is on github so you can literally just edit the page make a pull request and then make it better for everyone sorry yeah exactly who's staying for the afternoon afternoon workshop it's a few people uh i think so theoretically they are all full but i highly recommend if you're really interested in just stay for the afternoon workshop you might get a seat if you're lucky um just stay around and see if there's like spots left uh and then just you know hang out because it's gonna be super cool it's gonna be an advanced workshop and you're going to do the the city thing right yes yeah i mean the reason why i'm super excited about a frame and why we are also actually excited about it at 3d io is that it's relatively easy with a few lines of code to actually build things like this for instance so we have like an application that loads this entire thing and you have like camera tours that take you to the different rooms let's go to like bedroom too i don't even know which one it is that one okay fair enough and um if you look at the code it's actually not that complicated so you have a bunch of css okay cool yes sure um and afterwards you have a bit of a bit of um oops shit what the hell is my no why is it navigating when i don't want to navigate and then you have like um a bunch of buttons you have a logo here which is literally just an image uh you have a map which is like the the um the thing and then you have the buttons that that use a frame components here you see exactly what i showed earlier on like components dot tour it has a go-to method it goes to a certain bookmark uh and then it just does the magic in in the a-frame and the a-frame code itself is what jesus christ my computer goes bananas no don't navigate away when i try to what the heck okay right um the a-frame code itself is basically you have the camera you have the different tool waypoints and uh you have like a light and you have here this is the apartment and that's it right it's like it starts here and the actual scene is done here and the rest is just like specific like like tweaks and nice nice tease so it's not that much code it's not that hard to get there uh and you can basically build like really really cool stuff really quickly and it's like super flexible huh yes so check out your local communities uh check out meetup and just play around i think the most important thing is to just like start playing around with it thank you very much enjoy lunch and um yeah if you have any questions i'll be around at lunch