How to render 3D objects in Vuo — an explanation of objects, scenes, and Vuo’s 3D coordinate system
Hey I’m Travis with Team Vuo. In a previous tutorial, we walked through this composition, which displays an image on a window. In this tutorial, we’re going to learn how to display multiple 3D objects, or a scene, on a window. We’ll also dabble with how to manipulate the objects we display. As a quick refresher, here’s how this composition works.
When we click Run, we set the composition in motion. Fire on Start sends an event out of its “started” port here, down to Get Image’s refresh port here. Upon receiving the event, Get Image takes a look at this URL we pasted in here, which is a link to the Vuo logo image on the Vuo.org website. Then the original event from Fire on Start, plus the data of this image, are sent to the Render Image to Window node, which creates a window and displays the image upon it. Let’s try it out. And there’s our image. Notice that the image takes up the entire window and we can only adjust the window in a way that keeps the image exactly proportional.
Alright, now instead of just sending a plain image to a window, let’s convert a different image to a 3D object and send it to a window. Let’s open up a new composition so we can start from scratch. I’ll keep this window in the background for reference. We’ll put our original composition to the side, and we’ll select “File”, “New composition.”
Just like in the previous composition, we need to start off by getting an image, so our first two nodes will be the same. First we’ll find Fire on Start in the node library, and drag and drop it onto the canvas here. Next we’ll find Get Image and drag and drop it here. We’ll drag a cable from the “started” port of Fire on Start to the refresh port of Get Image. Previously, we got an image from the web, this time we’ll get one from my computer. In the future, we’ll just be able to drag and drop an image onto the canvas, but Vuo is still in early Beta, so we need to help it out little bit.
To do this, I’m going to walk through what it says at the bottom of the tooltip about getting an image’s file path. First I’m going to find the image I’m looking for on my computer. For me, it’s right here on the desktop. Then I’m going to go up to the Spotlight, type in “terminal,” and open the Terminal application, which is built in for Mac. Then I’m going to drag and drop the image into the terminal. Now, the file path I’m looking for appears right here, after the name of my computer. I’ll select and copy the file path, go back to the composition, and paste it into the image URL port. And we need to go to the beginning of the file path and type in “file://”. Alright, now we have our image in the composition.
Up to this point, the composition is the same as the previous one. Now, instead of rendering the image to a window, we’re going to turn this image into a 3D object. Let’s go to the node library and type in “image” and “object.” Here we see Make 3D Object from Image. Let’s hover over it to get our tool tip, which says: “Turns an image into a 3D object that can be added to a 3D scene. The 3D object is like a piece of paper that displays the image on one side…” Then it goes on to explain the details of the 3 dimensional grid system, which we’ll get into a little later.
We’ll drag and drop Make 3D Object from Image onto the canvas here. Cool, so we have a handful of inputs, with the top one being “image,” and it outputs a 3D object, which in our case, will be our image displayed like a 3-dimensional piece of paper. So we’ll send our founder image, into the image input port, here.
Before we talk about these other inputs, let’s focus on displaying our new object on a window, so we can see what we’re working with. Since our object is 3-dimensional, it first needs to be placed in a 3-dimensional space, which is called a scene. Let’s go to the node library and type in “render scene”. Here we see, Render Scene to a Window. Let’s drag and drop that here.
The way this node works is, it receives objects at its input here. This feature is called a drawer, and it expands so you can input a significant number of objects. Then is places those objects within a 3-dimensional scene, and renders that scene to a window. So let’s send our object in here. We’ll save discussing the function of the output ports for a later tutorial. Let’s click run and see what happens. Great, we see a nice founder badge here.
To begin to define scenes and objects, let’s start with what is different from when we simply rendered an image to a window. Let’s bring our previous composition back up, and set it next to our current one to compare. Notice from our previous composition, we’re working with a two-dimensional space, the image takes up the entire space of the window, and the window can only be stretched in a way that keeps the image proportional.
At first glance this 3-dimensional object (remember it’s like a flat piece of paper) only takes up about half of the window. When we stretch it horizontally, it maintains proportion, and when we stretch it vertically, it varies, and can actually be eclipsed.
Now let’s take a look at how the Vuo 3D coordinate system works. We’ll start by walking through each axis. If we look at the left vertical edge of our window and find the center-point, and right vertical edge of our window and find the center point, then envision a line between them, the line would be upon the X axis. The center point of the X axis line, somewhere in here, is assigned the value of zero, it’s the absolute center of this 3D space, and is called the origin. Now, from the perspective of our eyes, the way the coordinate system works, is that it begins with the value of zero at the origin, and it increases as it goes to the right to positive one at the edge of the window. Then, to the left, as you might guess, the coordinates decreases from zero at the origin to negative one at the left edge. As we begin to think in terms of distance, the gap from the origin to the right edge is a distance of one unit, and the distance from the origin to the left edge is a distance of one unit, which equals a distance of two total units across, from edge to edge.
The Y axis is setup in similar fashion. If we find the center points of the bottom edge of our window, and the top edge, then envision a line between them, it would fall upon the Y axis. The center point of the Y axis will cross the X axis at the origin. All axes cross the origin, and all axes have a value of 0 at the origin. The way numbers work for the Y axis is, they increase going upward from the origin, and decrease going downward. The Y axis maintains the proportions of objects in the scene. It does this by automatically adjusting its range, depending on the aspect ratio of the window. So if we have a perfectly square window, the top of the window will have a Y value of one, and the bottom will have a Y value of negative one, just like the X axis will have a value of positive one at the right edge, and negative one on at the left edge. However, if the window is tall, the Y range will adjust to become greater than one in each direction, and if it’s short, the Y range will adjust to become less than one in each direction. In doing so, it keeps our object from becoming disproportional.
The last axis is the Z axis. Starting from the origin, the negative direction would travel directly into the space behind this object, away from you. In the positive direction, it would travel directly to the front of this object towards you. Excellent.
So the overall 3D space that we’re defining is called a scene, and our flat sheet that says Founder on it is one Object within the scene, with the possibility to add a whole bunch more. Now that we have a basic understanding of Vuo’s 3D coordinate system, and what scenes and objects are, let’s head back to the canvas and begin to explore what we can do.
As our composition is set up now, when we start it, one event will immediately travel through all of our nodes, then it will cease to flow. No matter how we adjust our inputs, nothing else will happen in our window until we send another event through. To be able to explore and receive immediate feedback, let’s send a continuous stream of events through the composition. That way, if we adjust something, we’ll can immediately see our adjustment reflected in real time on the window.
In addition to Fire on Start, let’s add Fire Periodically. We’ll drop it on the canvas. We’ll set the input value to .02 seconds. Now, fifty times per second, Fire Periodically will send an event out of its fired port. Let’s send that stream of events to the node where we’re going to start making some changes, which is the Make 3D Object from Image node. So we’ll link the cable from the “fired” port of Fire Periodically to the refresh port of Make 3D Object from Image. Now, fifty times per second, Make 3D Object from Image will send out a fresh version of its information.
We’ll run the composition — and our events are flowing. Let’s get the desktop set up so we can see our canvas and the window at the same time. Now, even though we’ve adjusted the window to be a rectangle, Vuo is still going to maintain its aspect ratio. From the left edge of the window to right edge is still a distance of two units along the X axis, and the Y axis has automatically adjusted to keep our object proportional.
Now we’ll take a look at the Make 3D Object from Image node and talk about our 3 remaining input ports. Let’s start with “width.” Width is measured horizontally and uses the same units of measurement as the X axis. The current width of our object is set at one total unit, and the total width of our window is two units. Therefore, the width of the object takes up half of the total horizontal space. Now, if we double click the port, and adjust the value to two, it will take up the entire horizontal space. If we continue to increase the width, the object will expand beyond the current visible space. There is no adjustment for height, as the height, just like Y axis, is determined automatically by the object’s aspect ratio. Let’s bring it back to one.
Next let’s take a look at the “center” port. For the center of our object in this 3D space, we can adjust the value of each axis, from left to right, “x, y, z.” When we double click, we get an adjustable text box for each axis. All values are currently set to zero, so the object is centered at the origin. Let’s make the object move directly away from us, then upward, and to the right. In the Z axis, we’ll move in the negative direction. In Y axis, we’ll move in the positive direction, and in the X axis, we’ll move in the positive direction. Now, notice that since our object is further away from us, and in 3D space, we can see a greater distance around the object. Because it’s not set right before our eyes we can see the object travel a distance of 5 units upward in the Y direction. And when we bring it back to the origin, it disappears after traveling only 2 units upward in the Y direction.
Lastly, let’s look at the “rotation” port, my favorite. So we can see it a little better, I’m going to set the width to “two” so it will take up the whole width of the window. Now, just like the center port, there’s a value for each axis. The difference is, these values control the angle of the object along each axis. For example, if we adjust the angle of the Z axis, it begins to rotate around it. We can manually type in “90,” and it will spin to 90 degrees. I’ll bring it back to zero. When we adjust the Y axis, it begins to spin around it. And the same with the X.
It’s also important to note that as values flow through this input, they don’t need to be between 1 and 360 — they can be larger or smaller. The trigonometry equations work so you can keep pushing an object around and around. For example, if I set the rotation of the z axis at 350, and start spinning upward, the object will keep rotating after the number exceeds 360. And if we were to keep spinning around and around this way until we got to 10,000, we would end up here. (Input “10,000” on Z axis) So every number has its own place in a revolution, and we can just keep feeding values though.
The count node can count way more smoothly than me, so let’s get it involved. We’ll put Count on the canvas and I’ll connect our stream of events coming out of Fire periodically, and link it up to the “increment” port of Count, so that it’s counting upward by ones, fifty times per second. Then I’ll take that ever-increasing number and drag it to the rotation port of Make 3D Object from Image. A type converter pops up to let us know that since we only fed in one number, it’s only going to channel it directly to the X axis, and not the Y or Z.
Cool. A specific location within a 3-dimensional space is called a point. If we look at the value for the center, this is how a point is written out, with a number for each axis, separated by commas. There’s a node that allows us to make 3D points. And that’s what its called. We’ll drop Make 3D Point onto the canvas, here. The way it’s setup is simple. It begins with the default value of zero for each axis, and we can modify any or all numbers as we’d like, and it outputs the respective point.
Now, if we delete our current link from Count to “rotation”, then send our count through the X axis on Make 3D Point, and link our point back to the “rotation,” we’ll get the same effect, but now we have the option to do more. We can drag that same number from count to the Y axis. And the Z axis…. Now it’s moving all over! And we’re interacting with our composition in real time. Awesome! This is only the beginning.
If we want, we can drag another Make 3D Object from Image onto the canvas. Now we can input the same image from Get Image, the same stream of events from Fire periodically, and the same 3D point into the “rotation.” Since our stream of events from Fire Periodically isn’t traveling through Get Image, an image hasn’t yet been sent down to our new Make 3D object from image node. So I’m just going to restart our composition, that way a new event will flow from Fire on Start and will ensure that an image gets down to our new Make 3D Object from Image node. Lastly, we can take our new “object,” to become a second object, in our scene. And we should have two objects doing the same thing. We can change the center of our new object to have a Y axis of one to find out. There it is! Now we have two objects dancing together. And notice that they disappear and reappear at different times. That’s due to the vantage point of our eyes in this 3D space.
As you can see, there’s an infinite number of directions we can go from here. So this is where we’ll stop, and turn it over to you. Thanks so much for checking out Vuo and this tutorial. We hope it was helpful and we look forward to seeing what you create.