Who doesn’t like bike rides? Well, there are probably people who don’t. But cruising on your bike in nice scenery and sunny weather, listening to chirping birds is generally a pleasant experience. But what if it’s pouring outside or the temperature is below zero, and you really want to go for a ride? You can go for a virtual bike ride!
Lately, we’ve completed a VR bike ride application for our client – Wayne State University. We liked the idea so much that we expanded it and created a night scenery too! The whole art design is the work of three members of our amazing art team. Let’s find out exactly how they came up with and implemented the design.
Łukasz Grobelny – Art Lead
The project’s premise was to create a virtual reality application where users physically ride a VR-adapted bike in a straight line. This allows them to exercise indoors in a friendly environment. The VR aspect of the software was designed to make the activity more enjoyable and to create the illusion that you are riding in an environment other than where you actually are.
After learning the requirements, target equipment and budget, we decided to go for stylized graphics finding them the most optimal for this VR application. In order to save time on fine-tuning and polishing, we decided to use a ready-made pack of buildings and textures that fit our style and helped achieve the desired effect with less effort. This meant we could optimize our work and deliver the product quicker.
I myself created a general vision of the project and style we were going for. My idea and vision have been written down in the art direction document.
The main assumptions were:
- The project is a VR experience on Unity URP.
- It features a stationary bicycle moving in a straight line.
- The art style can be described as cartoon or low poly.
- It uses stylized textures without unnecessary noise.
- The color palette is a warm pastel set.
We used the work of Studio Ghibli as a graphic reference. This is a very stylized art style that works well in older city and town environments. The color palette used is warm and relaxing. It does not give the impression that a lot is going on on the screen.
Kiki’s Delivery Service (1989) by Ghibli studio https://www.imdb.com/title/tt0097814/
Kiki’s Delivery Service (1989) by Ghibli studio https://www.imdb.com/title/tt0097814/
Whisper of the Heart (1995) by Ghibli studio https://www.imdb.com/title/tt0113824/
We have chosen the following asset as a basis for creating our environment.
Creating such an asset from scratch would have taken significantly longer than buying and adapting it to our needs. Given the budget and project requirements, this route was much more efficient and allowed us to use the time we saved to refine the scene’s quality.
After consulting with the programmers, we concluded that it would be best to create a few premade modules for the road and pavement, which could be displayed on the right and left sides at the same time. They would then be loaded in random order during the journey.
For example, if we had three or four types of modules for the pavement, the application would select one to be displayed while loading the entire road module.
Before starting work with purchased assets, we tested blockout scenes in VR using simpler elements. To do this, we loosely based our work on street and sidewalk design documentation in the USA. https://nacto.org/publication/urban-street-design-guide/
The pavement is four to six meters wide. There is a green belt with street lights and benches 1.5 meters from the road. We also filled the space 1.5 m from the building with objects such as trash cans, shop signs, billboards etc.
Layout of the district
We decided that I would create a long road without intersections and gaps between buildings, saving time and optimizing the work. Buildings were to be present on both sides, and the pavement was to be symmetrical.
This created a layout very similar to what we wanted to achieve, but some adjustments still had to be made. First, the pavements needed to be wider. Buildings were set back further from the road on both sides. The dimensions were described in detail in the pavement section.
Here is the first simple blockout we used to check the dimensions in VR and for developer testing of the module spawn system.
Below is another blockout with buildings that we’ve already bought but haven’t adjusted or optimized yet. We used it to check the dimensions and driving experience at such distances from the camera.
Piotr Łaszczych – Generalist
My task was to create environment modules that would change randomly while cycling.
Each module has a set of buildings connected with each other in an integral way without any gaps. This minimized the number of required 3D models for the surroundings, as we needn’t place anything behind the buildings, therefore lowering the development costs for our client.
In order to create the impression of a diverse environment on the streets, six modules were created containing various buildings and different arrangements of street elements.
Additional elements, such as benches, walls and lamps, are separate models placed on the stage using prefabricated assets. Each prefab has a group of LODs. They are arranged in a way that prevents them from changing in an aggressive and conspicuous way.
Elements of the environment have been placed on the scene in a way that clearly and coherently separates the gameplay part from the purely visual part.
Before and after remapping. The scene below still lacks post-processes and polish.
The original asset didn’t have the buildings mapped so they had to be reworked. Originally the triplanar shader and world position were used which was unoptimal. It also wouldn’t work in this case because it made the bricks stay still even when the buildings were in motion. To tackle this issue, I mapped all items that used this shader in a way that allowed them to use the standard object space.
For the needs of the project, we developed object models that use previously created materials so as not to load additional textures into memory.
Maciej Bugajski – Support Generalist
After creating the day scene, the idea of creating a night scene came up. We realized that adding a night setting would improve the application’s quality and positively affect the user experience.
Making the environment dynamic instead of static was challenging. Effects like puddles and leaves moving with the wind were based on world space noise and had to be converted to object space. Otherwise, the wind would speed up whenever the player did, and puddles would follow the player instead of being fixed to one spot.
The wind was originally made by adding World Space noise to vertex positions, and the noise was scrolled through. Since the objects were moving in space, the speed of the moving objects added to the scrolled noise. As you can see in the attached video, the wind was no longer related to the world’s position.
The puddles mask was added as a WS noise. Because it was the environment that was moving, not the player, we had to make the puddles move with it.
We had to change the noise to object space and give tiling as an integer so it doesn’t cut off when the objects meet. Giving the effect of floating with the player, puddles don’t cover all cobblestones anymore, they just cover gravel between them.
The scene was later lit in such a way as to give the effect of a bright moonlit night. To achieve a strong, evenly lit scene, the light direction casts shadows directly on the buildings parallel to the road. The fog has the same color as the skylight horizon to eliminate the popping effect of new geometry being created in the frame.
To add dynamics to the scene, an animated cookie was added. This was made by making a custom URP unlit shader on which the cloud texture is scrolled. Next, this material is fed into a custom render texture which in turn serves as a cookie for directional light. The direction in which it scrolls is opposite to the direction in which the player rides. This movement adds a sense of speed.
Skybox has a custom shader created in the shader graph. It consists of two layers: the cloud layer and the sky with a star layer. Clouds rotate around the sky, and when they cover the stars or the moon, you can still see them shining through the clouds. They are slightly blurred when seen through the clouds, which is achieved easily through reading a high mipmap index.
The other function that is available in the shader is the ability to add the top-down gradient along the skybox height. This allowed us to synchronize the color of the horizon with the color of the fog.
Because the environment is dynamic and textures are tiled, it was impossible to bake the light or texture them on the objects. At first, we used the bloom post process to add to the effect of light shining through the windows. But it wasn’t enough – it affected only a small area and was temporarily unstable, so we added the decal projectors to add to this effect.
We wanted to add a halo around the lanterns to extend the area where the lantern light is visible. But point light halo isn’t supported by URP, and volumetrics are too expensive performance-wise. So we added a VFX graph consisting of two subgraphs.
One is supposed to simulate a stylized version of astigmatism. The other is supposed to simulate a bokeh camera effect on dust particles.
To improve the impression of speed, we added a wind ribbons effect around the player. To make sure it blends nicely with different backgrounds, we made it on transparent particles that distort the image behind it. In this sense, it can give a slightly radial blur effect by blurring the view around the player in line. With the distorted ribbons, we can see the leaves flying in the air. Those effects become more noticeable as the player’s speed increases.