We were inspired by the field of proceduralism and its use in places like Pixar's Cars (procedural city based on London). In addition, we had an interest in graphics, and wished to play around with VR. There was a SIGGRAPH paper that suggested a psuedo infinite city that would use a constant amount of memory, so that was our challenge in creating a mobile app that was compatible with VR.
What it does
Everything in the project was generated procedurally, there was no hand modelling or texturing. A camera drifts around an infinite pseudo-randomly generated city (both the building shapes and the building textures are random).
How we built it
Procedural Texture At runtime, we generate a random texture of size 512x512, partitioned into windows. The windows have a random overall grayscale value to represent the shift in light for the building, and the bottom of the windows have noise to represent activity that you may see from a window. Each face of a window has randomized subset of this single texture, which we applied with UV mapping.
Procedural Geometry Geometry is created as a rectangular building. Each building is a group of rectangular prisms that have the same local transformations, with randomized offsets to show variation in the geometry. These buildings are created at runtime.
Graphics and CPU Optimization We attempted to use a technique called frustum filling. We don't want to create geometry that we know will not be in the viewport. Because of errors with the near clipping plane, we decided to draw buildings that are within a certain range of the camera, and offset the entire city plan to be in front of the camera. We optimized the CPU usage and memory usage by deleting buildings that are no longer in the viewport, and recreating them when they are in the viewport.
Procedural City Layout Geometry is the same with every generation of the building. We do this with Psuedo Random Number Generation and Hashing based on the location of the building on the grid, so though we recreate/create buildings that are new in the viewport of the camera, it will always be the same, so technically, you can "return" to a particular building!
Challenges we ran into
The first challenge we ever ran into was hardware limitations - using Unity for the project allowed us to rapidly prototype, test, and deploy on both iOS and Android devices, however, we ran into a glaring bug involving the procedural texture. The texture was created at runtime, but would simply not be mapped onto any mesh. In fact, even setting the texture of the geometries to a solid color algorithmically did not work. We ended up creating a material from the generated texture, and using sampled regions of this texture for each building.
Once we got the texture to render, we ran into issues because the texture was expensive to render. The textures would not render completely, which made the viewing experience subpar. We needed to be really efficient because we needed to rerender every time there was a shift in view. We did a lot of things to make sure that rendering in realtime was as efficient as possible. We slowed down the flythrough so that textures from far away could render while in the background. We also turned off shadows, lighting, anti-aliasing and other unneeded effects, and used a flat texture for the buildings.
For the frustum filling, we successfully created and removed buildings based on the location and if it was inside the camera view. It was probably the most efficient way to place and create geometry, since there was not a single geometry outside of the camera view, but it was not a good viewing experience since the near clipping plane would cut off geometries suddenly if they were too close to the camera, so we did a very hacky way of rendering only visible geometry. We rendered geometry that was only within a certain distance, which created a circle of buildings around the camera. We then moved it forward so that most of the geometry would be in front of the camera.
Accomplishments that we're proud of
Our hacky way of fixing our camera viewport problem, everything is procedural (all code, no modeling!), the aesthetic and pleasant viewing experience, our first multiplatform app, our first graphics related app, our first VR app
What we learned
You don't have to implement things exactly as a paper or other people suggest (especially at a hackathon!)
What's next for cityscapes
More building geometries, twinkling stars using sprites, details such as streets, lights, and cars, STABLE BUILDS :(, maybe changing the windows from a texture to planes that can have their own colors (can simulate the animation of lights!)