The Making of Granite’s Megalith GDC 2016 Demo

How many megapixels can you cram in one scene? With our Megalith tech demo we wanted to show the crowd at GDC 2016 how Granite can be used to stream PBR materials, and lots of them! This blog post talks a bit about the demo and how we put it together. If you want to try out Granite yourself, check out the free trial for Unreal here.

Christoph from Real-Displacement-Textures was so kind as to provide us some of the source textures for the demo. RDT used highly-detailed 3D scans to get very detailed and unique textures. The source textures came with texture maps for color, ambient occlusion, normals, glossyness, roughness, and displacement. Our toolset packed the channels of these six maps together to end up with four Granite tile set layers: Color+AO (RGBA), Normals (XY), Glossyness+Roughness (XY), and Displacement (X). Granite works best if you pack channels together as no layer texels will end up being sampled individually.

When you build the Tile Set – the file Granite streams out of – the Granite tools atlas each texture into a huge texture space. The natural details in the textures lend themselves perfectly to be compressed using our proprietary codec. This resulted in a Tile Set of 7.1GB, putting the texture budget much lower than that of a lot of modern games. By coding the Tile Set using the industry standard BCn compression format, which saves a bit of processing power at run time, the Tile Set comes at 13.0GB and the coded textures become visually indistinguishable from the source textures.

Tile Set Viewer showing the atlased GTS file

After importing the build Tile Set in UE4, our plugin creates default materials for every one of these textures. We tweaked the materials based on the input of the textures’ author and came up with this very simple configurable root material:

Root material

Basically, the material does nothing more than piping the outputs of the Granite Texture node to the inputs of the root material, with some masking, contrast enhancements, and parameterization in between. For example, the glossiness and roughness texels which were packed together, are unpacked by masking operations, and passed along.

Now for the streaming part.

If you were to load all these textures in a conventional manner, without a streaming system, you would require somewhere between 12.5 and 40 Gigabytes of video memory depending on your texture format. By using its fine grained streaming system, Granite reduces this to a mere 640MB of GPU memory and an additional cache of 1GB of system memory (configurable). Granite only streams what is visible in the scene, hence the memory requirements are only dependent on the camera and render resolution, and not on the texture content. So a demo such as this can run on just about any GPU that has 640MB of memory available for textures.

Light maps and shadow maps are streamed as well. With our UE4 plugin, this is actually very easy to do. Just check the ‘Use GraniteSDK to stream lightmaps’ option, increase your light map resolution to your desire, and Granite takes care of the rest.

In terms of performance, Granite streaming has little effect on framerate and generates a very steady load on the system, however big the textures. On our GDC demo machine, a laptop with a GeForce 970m mobile GPU, the demo ran without any hassle at 90Hz. In fact, most of the GPU resources were eaten by our overzealous displacement mapping and high triangle count in the demo. On a high-end desktop GPU such as the GeForce GTX 970, the demo runs at around 200Hz.

Our Megalith tech demo shows the technical capabilities of a modern streaming system such as Granite, and how Granite allows you to increase texture fidelity without sacrificing performance. If you want to try Granite out yourself, try it out here.

Leave your information