Let's go for a ride, see in detail how this animated music video utilized the Unity engine and the Unity Asset Store.
A little background
A lot of my friends were talking about "Unity Neon Challenge", they we're telling our artists friends to join if they want because why not it's awesome. I like the challenge, but more specifically I like the theme, "Neon". I took on the challenge, but I got a problem. I'm no artist (but a frustrated one) I'm a programmer, and so my 2 weeks journey continues.
One of the inspirations that I tried to catch with the project are those instagram, or article photos of anything neon, combined with vaporwave, dystopian, and neo-noir elements. Mixing them up lead me to that output. A VR world, that pays homage to vaporwave, that also houses a dystopian city where human enhancements, underground metros, and sins rule.
I've had a friend who helped me out through this (shout out to her!), and there's a couple of moods/themes that came out: Dystopian city, Neo-noir, Vaporwave, Virtual reality, and Cyberpunk. Apparently it was hard to choose, so all were incorporated in some sort of way in the end.
Originally the project was a 3-part scene, but the Arcade, and the Outside was scrapped as the project goes on due to time and resources constraints (as I was only a one-man team). Focusing on the VR game, it turned out to be a racing scenario, then was stripped down again throughout the project becoming a sort of "test drive".
After those paper concepts, I was so pumped to fire up Unity 2017.3 to test the idea. The VR game scene had a "vaporwave" concept, and the one I've had in mind is the iconic sunset. It was pretty easy to do especially with the procedural skybox, after that I put some primitives and lights. I liked the results, so I pressed on.
With "drive" in mind and having no skills doing 3D assets (I do have knowledge with how 3D assets are utilized in-game, I just don't know how to make them), I turned to the Asset Store. I spent days scavenging for free high quality assets that I ended up with a huge spreadsheet to keep track and sort.
The race track was pretty big, with its terrain being 2000x3000 world units in size. Racing games usually have gorgeous environments which serves as eye-candy (as I call it) while you drive. Going with the city-ish idea as indicated by the early concepts, I've raided the Asset Store yet again.
Unfortunately, the free side of the Asset Store didn't bless me with assets that's according to the concept. So I searched the paid side and settled with this one which suits pretty much all my need.
It wasn't an easy task designing the track, it was big, and I wasn't a level designer too. It was hard for me to fill it with objects that can keep things interesting as the camera flies by. So I trusted my instincts instead, and turned to people to ask for feedback here and there. As the project unfolds, it required some more assets. There were the mountains, Unity-chan, Kohaku-chanz, grid material, just to mention a few (links are below this article).
Because I was using a terrain, it became pretty easy to paint details, and lower height if I want.
Firstly I need a car asset, so I imported Unity's Standard Assets to get one (It's pretty and enough). I can now drive through my scene, but I'm not of course gonna drive as I record the video right? that would be horrendous and cumbersome. Luckily the Unity car comes with an "AI driver" component, so I tried that. I painstakingly put waypoints across the huge track (took me awhile), it was all good when the road wasn't that much complex but unfortunately I just can't get the right value combinations to get it to drive smoothly.
So I scrapped the idea and went to animating the car myself across the track. I am no animator too, but thankfully Unity made it a fun thing to do.
As for making really awesome shots, I didn't even consider manually animating the camera, I went straight for Cinemachine and holy smokes did it blow my mind. I didn't know how to actually use Cinemachine, so I've had to watch two "hour-long" videos taken from Unity Unite videos. Once I knew how to "correctly" use Cinemachine it has done wonders. I easily made dutch roll shots, overhead, look-at, etc. with less effort.
Then of course we also have the timeline which is also a delight to work with, it was really easy to use. I know how to do some video editing, and with the timeline I felt like I was using a video editing software and not a game engine. It's just pure magic when this is combined with Cinemachine, the ability to easily "blend" camera shots is just amazing. Not only camera shots, but you can actually pretty much blend everything you put into it. You could even animate values directly into the timeline, the animation assets saves inside the timeline asset too so you don't worry about it cluttering your project. As for the actual usage, I used it to sequence everything in the video; from the intro-sequence until the last fade. Nothing was done outside Unity editor except for recording. I even used Timeline to optimize my scene's framerate! (Check out the Optimization section)
Effects and Post-Process
Post-processing was easy, as I've said I've used Unity Post-Processing Stack V2. I've also utilized the Asset Store by getting an asset called "Post-Processing Profiles". It perfectly captures the post-process I want via its "Lomo" profile. It definitely saved me a ton of time, and is pretty cheap.
Different Post-Processing for Skybox and Depth
Others might know this already, but I think it's worth a mention for those who don't. As you can see there's some sort of "TV lines" going on for the Skybox (that's an effect from the "Camera Filter Pack" from the Asset Store), and it doesn't affect anything but the Skybox. In order to achieve this effect you need to have two cameras.
Volumetric lighting, fogs
In this screenshot, you can see the effects in the streetlight and the neon sign. I've used two separate volumetric lighting solutions, for the neon sign I've used the same volumetric fog used in the ADAM demo. For the streetlight, I used SlightlyMad's volumetric lights which supports directional and spot lights (the latter doesn't). Both tools are pretty easy to use, you just attach a script on your camera and your light and you're good to go. Just don't go crazy with alot of them as they of course can pull your performance down.
Alright, we get to one of the meatiest meat of this project. I've made it a challenge to somehow achieve 60FPS in 1080p (at least most of the time). A lot of trial and error, and gotchas were made which I think would be nice to share.
Here I've used pre-computed realtime GI, first problem I've encountered here is that it bakes so slow (hard to iterate if it bakes several hours long). So I searched for possible solutions on how to lessen the baking time. One thing that stuck on my head is to use an Indirect Resolution of 2 - 3 texels per unit for indoors, 0.5 - 1 texels per unit for Outdoors, and 0.1 - 0.5 texels per unit on terrains, so in my case I used 0.25. Another is that to use Default-VeryLowResolution lightmap parameters because I don't need that much detail as this is an outdoor scene. Lo and behold my baking times went from hours to 3-10 minutes.
Optimizations using Timeline
The scene uses a lot of lights, from the sun, to the neon signs, to the streetlights. Having them all activated at once just makes the framerate sad. So I divided the lights into what I call "Areas", lights activate when the car enters an area, then deactivates when the car exits. It's an easier and faster approach in my case than coding a "LightManager" to handle activation of lights.
The profiler gave birth to all the smaller gotchas below, it's a delight since you can use it in editor, or on a built player.
I've tried occlusion culling, but unfortunately my scene wasn't just optimized for it. So it ended up pulling down my performance even further. If you'll ever use this, make sure to plan your level/scene to support this technique from the ground-up.
If your scene can't use occlusion culling, you can still opt for Level-of-Detail. What it does is that objects are rendered depending on its distance from the camera. Let's say if your camera is really far from the object, then it will be culled/not rendered.
GPU instancing is what probably saved my scene from the horrors of constant stutters. It helped my scene alot as it uses many objects that share the same mesh and material. GPU instancing batches those. To enable this, just go to the material of your object and toggle "Enable GPU instancing" below the material settings.
The volumetric lighthing solution from Unity had some hiccups for me, apparently the commented code runs every frame which takes at least 5ms (we all know that FindObjectOfType is a slowpoke of a function). I don't also know why it still calls FindObjectOfType even though the code breaks once it returns the current instance. Anyway, the problem went away with this patch.
I got crazy with Shadow Distance at first try, so I ramped it up to 500. Don't be me, stay at lower values unless you know what you're actually doing. Else you'll gonna have alot of quality time with the Profiler.
This project is really a treat to work with. Especially using Unity to bring a vision to life. P. S. Cinemachine is probably the best of the bunch!