Canvatorium Recap One
Collecting my thoughts from Labs 000-008.
As I mentioned during the introduction of this project, Canvatorium is a long-term side project. Instead of writing articles for each lab or publishing notes on a regular basis, I’ve settled on the idea of writing recap articles from time to time. These recaps will summarize what I’ve been up to in each lab and will highlight anything I find particularly interesting.
Welcome to Canvatorium Recap One, covering Labs 000-008.
At this early stage in the project, most of the work so far has involved setting up the project. There are a few objects that make up the Canvatorium Project.
- Source code: A Vue 3 project where the bulk of lab work takes place. Most of the labs can be found here, but in the future some labs may require their own project.
- Issues and ideas: A GitHub Project made up of issues and drafts. New ideas are in the “No Status” column, “Todo” is a list of what I want to work on next, and “In Progress” contains any labs that are in active development. You can also review notes for completed labs.
- Day to day updates: If you want to follow along with the details, you can follow me on Twitter. I often share short videos with my commentary on the lab or idea.
- Recaps: You are here. I’ll write a recap article from time to time to summarize what I’ve been up to.
- Published version: I haven’t settled on where to publish builds yet, but the idea is to ship regular updates so people can try out the labs for themselves. For now, I’m running this locally.
The Canvatorium Web App is made up of a simple sidebar with a list of labs and detail region where each lab is rendered on a canvas.
You can find the labs in src/labs
and some tools in src/lab-shared
. At the top of each lab, there is a const
called labNotes
that contains a description of the lab in markdown. This is rendered as HTML on the lab page, and will be included in the WebXR scenes soon. The title, subtitle, and status of each lab are stored in the meta property of the router data. I’ll move this to a data stored eventually, but for now I wanted a way to easily create a the sidebar with data for each lab.
Now, on to the Labs
Lab 000 – Hello Canvatorium
This scene is based on the object interface pattern that I used while working on A Vue into 3D. I setup reusable objects such as the room with the grid texture, lighting, and a camera.
Lab 001 – Picking Colors
I selected some colors to use for the project and rendered them on some boxes. This lab also uses Vue 3s <script setup>
syntax to unify the elements of the component and wrapper into a single component. I love this syntax and plan to use it for most labs.
Lab 002 – watch() / watchEffect()
Playing with reactive references and watchers in Vue 3. I have a button that can increase a count value, which is a reactive ref. The button only knows about the data it needs to modify, not the other scene objects that use the data. The watch functions at the end of the file watch for changes to this data and will update scene objects as needed. Spoiler alert: I’m going to use this pattern a lot…
Lab 003 – Default XR Experience
Using the createDefaultXRExperienceAsync
from Babylon JS to setup a WebXR session. Since this uses await
I can follow this up with some scene setup tasks when the session is created. In this case, when entering VR I reposition the player closer to the UI. I also added some observers for controller input, using the watch pattern from Lab 002.
Lab 004 – XR Controller Buttons
Expanding on Lab 003, I added observers for each of the standard buttons found on most VR controllers, testing with Oculus Quest 2. Babylon JS provides a useful abstraction layer for controllers and inputs, making it easy for me to make scenes that work with a variety of controller types.
Labs 005 and 006 – Vue Router Scene Navigation
These labs are identical and represent my first failed labs in the project so far. The idea was to see if I could link from one scene to another while in immersive VR mode using Vue Router. Oculus Browser has a feature flag that allows navigation from one scene to another on the same origin, but I could not get it working with Vue Router. I’m not sure where the issue is, but I did confirm that I can navigate between scenes when not using Router.
// This does not work
router.push({
name: "Lab006",
});
// This does work
window.location.assign("/lab006");
I’ll come back to link navigate in the future.
Lab 007 – Console… Log(?)
By far the coolest lab in the project so far, this was a proof of concept to see if I could display data from the console while in immersive VR mode. Yes. Yes, I can. I overrode the console.log function so I could intercept the message data and send it to a reactive variable. The current version has a lot of limitations, but it allows me to log strings to the console while learning new features of Babylon JS.
- String only, no arrays, objects, classes, etc.
- Brute forces the reactive data, overwrites the entire array for every log
- Babylon JS scroll view has some UI/UX limitations that make interacting with it in VR a bit of a pain.
I may turn this into a full-fledged console replacement in the distant future, but for now I’ll just add what I need as I go.
Lab 008 – Near Menu
Babylon JS 5.0 (currently in beta) has several new 2D and 3D GUI features. The Near Menu is one of them. It uses a simple Holographic Menu as UI and tracks the position of the player in VR. The player can move around the scene and the menu will follow them. This could be helpful for making toolbars or docs that launch other bits of UI or scene content. I uncovered a couple of bugs and reported them on the BJS forum.
That’s it for the first Canvatorium Recap. Hit me up on Twitter if you have questions or ideas that you want me to try in future labs.