Over the past few days I have been working on the ETC 2020 Museum, a Virtual World for my grad school’s (unofficial) virtual commencement. The world was built on the VRChat platform, and had a maximum attendance of around 32 people. Before we dive into the details, here’s a little digest video I made:
Looks pretty simple, but a lot of work has been done in the background to ensure a satisfying experience and technically optimal execution. Here’s a little write-up to detail these features.
Creating A Personal Experience
I chose VRChat as the platform for straightforward reasons: easily accessible, compatible with many VR headsets, and much easier to develop with as it provides an SDK based on Unity.
After some exploration in the existing worlds and the community, I’ve come to realize that social VR worlds, at least in VRChat, generally falls under two categories:
- Game worlds: These worlds are designed to have a specific mode, objective and rules to follow, such as Freeze Tag and Murder 2.
- Social Space: These worlds only provide an environment for people to visit, be in, and talk to other guests. Japan Shrine and Summer Solitude are great examples.
Considering our purpose as well as other conditions, such as time as a resource, it’s more feasible for me to create a Social Space.
The problem with social space worlds, though, is that these worlds are not relatable enough to the guests on a personal level. Sure, they make look marvelous and nice, but the setting does not provoke a connection to the visitors. I believe this connection is crucial to creating a meaningful conversation, and without that, talks can quickly die down and guests can become bored pretty quickly.
This is why I decided to showcase the works from our previous assignments, and there’s not a space better to do this in than a museum.
But there is just so much space allowed, which assignments should I pick?
Back To the Beginning
I chose the first team assignment to showcase. As a part of this two-year journey, it’s really a touching moment to look back at where I started, and in turn receiving that affirmation of “I have learned well”. It resonates well on a personal level, which is why I thought they would make great exhibitions in the space.
For this assignment, the class was divided in to two groups: one group works on AR projects, while the other creates VR worlds. For AR worlds, it was pretty straightforward for me to decide how they should be presented. Since these worlds typically don’t have a “surrounding” environment, I can easily showcase the main level to guests.
It is a different case for VR worlds, though. VR worlds only make sense when the surrounding environment is present, like a space station won’t feel like one if you don’t see space out of the windows. But there are so many worlds to include, and each world has a different setting. How do I include different worlds with different environments?
This quickly reminded of Space Mountain:
The general idea is to seal off the attraction from the outer world with a big box. If it’s just an inward box with textures, then it can be easily handled in Unity.
It’s a graduation ceremony, and nothing can be more iconic than tossing your graduation hats, so that’s also included in the space, but with some restrictions.
Some Other Details
This shouldn’t be just a festival for artists. It should also exhibit the works from sound designers and programmers. Unfortunately due to platform restrictions and optimization reasons, I can only put in a limited number of audio tracks; and since VRChat does not allow the execution of custom scripts, there was nothing I could do to include programmers’ work.
In this section I won’t go over too much on details specific to the SDK.
Rule of thumb: always think about optimization first. It’s harder to come up with patches in the end than starting out with the mindset.
Down to the Flesh
Exhibiting other people’s Unity worlds means extracting them from their original projects. They might include custom components, audio sources and even lights. Since most of these components are either forbidden in VRChat or has a minor impact on the experience, I took most of them out, leaving only the model itself to be included.
One question, though, is whether to leave colliders on these models. The general rule here is to leave them in only if they are traversable by the guests. Moreover, replace MeshColliders with conventional alternatives like BoxColliders, if possible. This reduces the need to calculate physics on complex surfaces. Otherwise, remove colliders and box them up with a BoxCollider, if needed.
Spare Those Polygons
It’s common sense that higher polygon count impacts performance. In VRChat specifically, it impacts Quest users even harder. Before exporting models into a .unitypackage, I turn on wireframe mode to check if there are objects that uses too much polygons. If they are too complicated and don’t make up too much of the experience itself, I’d leave them out.
For the museum space itself, I used a lot of quads instead of full models. They work well without using too much resource. The hubs for VR Worlds are also constructed using only quads.
On a side note, I talked about the decision behind choosing assignment 1 to exhibit. Turns out there is a side-benefit as well: generally, artists were still learning tools in this assignment, plus there was less time for teams to finish their worlds. As a result, models are usually built with less polygons, which was great news.
I expected VR worlds to be a more polygon-heavy than AR worlds, since their sets usually involve a lot of props. This is a big problem since there just really isn’t enough space for every project to be in.
This is when I thought about cross-over worlds. I took a deeper look (and revisited) each VR world again, and grouped worlds together that shared similar environments. Then, I took some props from all sides and merge them into one new scene. This ensures all teams are fully represented while not introducing too many polygons; plus, cross-overing is just cool!
This is probably the most painful part of the process. To begin with, baked lighting is a great way to spare your processing power. But every bake requires time; the more lights you have in your map, the more time it requires to be in the oven, and the bigger the size it’ll be when it’s done.
In this scenario, all of my lights and emissive materials are set to baked. I figured that I should save all those processing juice for other stuff, and since real-time shadows isn’t a big feature in the experience, it’s best to just leave real-time lighting out.
With that in mind, always bake lights near the end of development. Only re-bake for lighting errors, not for object displacements.
Picking the correct size of your lightmaps is also important. Using too small of a size means more loading overhead, but picking a size too big means too many wasted pixels.
Additionally, some materials are also set to be unlit. Although mainly for aesthetic reasons, it saves up some baking time.
In the end…
Turned out that the biggest bottleneck was not in the development itself; it was at the publishing stage. A user must have played VRChat “long enough” to earn the privilege to upload worlds. While it sounds pretty reasonable, how the verification system works is entirely undisclosed to the public. I had to take some time off to intentionally play VRChat in order to earn that rank, and I failed. In the end, we found a friend with privileges who would help us upload the world, so big kudos to him.
But other than that, it was a blast! People were OMG-ing over the works they’ve done in the beginning, and they really liked how worlds crossed-over with one another. People danced at the music, took pictures with the exhibits and threw hats at each other. I’m also surprised that the server held together and didn’t bounce anyone out. All in all, it was a really heartwarming and fun event.
With that, I’ll end my post here. Congratulations, and happy graduation.