We got the chance to sit down and chat with Simon Kozlov, Client Engine Lead for ROBLOX, about the implementation of shadows, how they came to be, and where he hopes they go in the future. What do you have for us, Simon?
People take shadows for granted. The placement of shadows on 3D models is integral for your brain and eyes to understand how large something is, how heavy it is, and how close or far away it is from you, just to name a few things. So creating realistic shadows in ROBLOX is very important to us.
This article was designed to explain our methods, both past and present, for rendering shadows and detail what we hope to achieve with them in the future. Shadows take a great deal of computing power — we’ve discovered that only 10-15% of our users actually have the hardware needed to utilize all of the features we have bundled into our shadow system. We’re actively working on making detailed, scalable shadows available for people who have slower systems and GPUs.
Shadows have existed on ROBLOX for four years. When we introduced them, they existed as an algorithm known as “Stencil Shadows.” A stencil shadow is a fundamental point to start at — it’s a darkened shadow with pixel-perfect edges that moves with you. Creating a shadow involves several tricks — it’s essentially an extruded version of an object that darkens everything within it. This makes shadows difficult to scale. Unlike most facets on ROBLOX, a shadow changes, in real time, dependent on any given players’ geometry. It also reacts to different sources of light, and the angle at which the sun is shining.
Essentially, the form of a stencil shadow changes based on the object creating it. It’s this weird, geometric, stretchable object. This makes them difficult to define, and also takes a great deal of computing power. Want proof? By default, most ROBLOX players have an individual shadow for their character model, but their computers aren’t suited for anything more than that. You can enable a mode where everything has shadows, but we’re warning you now, chances are this will slow your machine to a crawl.
To do it, enter ROBLOX Studio, go to “Settings,” click “Rendering,” then “Shadows,” then hit “All.” Warning: Your jaw may drop.
In 2010, advances in real-time graphics technology allowed us to begin entertaining the idea of ambient shadows. This would not replace stencil shadows overall, but it would significantly add to their depth and range of movement.
Here are the basics: Stencil shadows depend entirely on light. If you move the light, the shadows move. Ambient occlusion doesn’t operate under such specific rules. To keep things simple, imagine a cube on a floor. The sun is shining above. The amount of light on the top of the cube is radically different than, say, the bottom corner of the cube, right? Ambient occlusion is able to gauge distances between the walls of a cube, which leads to more realistic shading.
In other words, ambient occlusion allows us to add depth to 3D objects. So when we create an image for a scene in a game, we also create a depth image; it’s a special image where things that are close to your point of view appear darker, and things that are further away are lighter. It’s not so much about looking at the lighting of a particular pixel, as it is looking at the lighting surrounding that pixel. When objects move closer to each other, they start occluding light from one another, darkening as they converge.
The human eye relies heavily on this type of information, though we never think twice about it. If you saw a chair on a floor with no shadows, you’d think it was floating. Shadows tell you how close an object is to you, how far away, how heavy, how light. It pains us to report that most of our users don’t have the hardware to see our ambient shadows, though we’re actively working on scaling down the hardware needed to utilize these features.
Few people in our industry have explored the avenue of “Voxel Lighting,” but we’ve been tinkering with it.
Voxel lighting involves inserting a three dimensional grid that would break down any given scene into a bunch of cubes. Notice we’re using the term “cubes” and not “squares,” because a cube is a three dimensional object. Let’s call them “Lighting Cubes.” By adding this grid, we are now lighting objects in fully three-dimensional space. Each object, like a car, or a person, or a house, has its own lighting cube, and each of these cubes can share lighting data with one another, in real time.
Even if you have a huge object, like a mountain, that exceeds the confines of one lighting cube, the surrounding lighting cubes will share lighting data to create a realistic 3D shadow.
Voxel lighting would also allow us to create smaller, local lights like lamps or torches, as well as global shadows that cascade from every part of any given scene. We’re working on lighting a wide range of environments using this system, and will keep you posted on what we find and some of the hurdles we come across.