Today’s update is an important one for Camelot Unchained™, and an exciting one, as it revolves around a part of our engine that, in all fairness, was just placeholder tech. Every since the Kickstarter launched for our game, we have played down certain expectations of both our team and our Backers regarding how the game was going to look at launch. We did this for a number of very good reasons, not least of which was that both Andrew and I believe that we would rather surprise people with good news, rather than disappoint them with bad news. As we have always said, no way are we going to get aboard a “hype train”; we are going to let our actions speak for themselves.
Thus, it is with no small amount of pleasure that I present the following article, where CSE’s co-founder Andrew talks to you about something that we have been working on behind the scenes, and that we hope to deploy to Hatchery within the next two weeks. And with that, I’m outta here!
P.S. Of course, what follows will be a config setting for the game so those players with older, less powerful rigs will be able to disable these features.
Until now, CU has gotten by with fairly simple lighting, the kind of light you might find in a high school theater production. We’ve had a sun in the sky casting a golden “key light”, and a “fill light” that shone at an angle to cast a broad blue wash over the shadows, while everything else was just darkness. This worked to quickly get something up and running when we started, but we always wanted to revisit it. Right now, George and I are doing a sprint to bring things up to the standards of 2016. We expect this game to be around in 2026, so we’re building for the future.
One part of that is indirect lighting. Look around your room — most things don’t have a light shining directly on them, yet nothing is in completely black darkness. When light hits a surface, it bounces off in all directions. A small part of that light hits your eyes, which is what you see, but most of it goes in other directions, hitting other things and illuminating them. Capturing the look of all the ways that light bounces between objects is a key part of making computer graphics look realistic, but the sheer number of interactions makes it computationally expensive.
Some game engines pre-compute those computations, but that’s not good enough for CU. Our entire world is dynamic. Players can build and destroy structures. The terrain can shift depending on who controls a zone. The time of day and light angles change constantly. We need lighting that can adapt on the fly to a world that adapts on the fly.
As part of capturing that look, we’re adding what are called “cube map light probes”. A cube map is a special kind of 6-panel texture that wraps around to cover all six faces of a cube, like so:
If you put your eyes at the center of that cube, you’d see, in all directions, that entire scene. Try http://www.humus.name/index.php?page=Textures for some more examples.
Generating a cube map on the fly is easy — you pick a point in the world, and then you use your game engine to render six frames from that point, with the camera pointed up, down, north, south, east, and west. Fold those six images together, and it’s a cube!
That’s perfect for capturing the dynamic world of the game, but what does any of that have to do with lighting? Well, remember up top about how all indirect light is just the light coming off of a surface, the same as what you see. So we take what you’d see in the cube map, and we turn every pixel in it into a light source. Imagine if you were at the center of a box, and each side of the box had tens of thousands of tiny lights laid out in a grid shining in on you. All those tiny lights would illuminate you in exactly the same way that you’d be illuminated if you were standing at the place where the cube map was originally captured.
To see the difference, compare these two images, one with just the sun, one surrounded by a grid of tiny lights. You can spot details in the building and see how shadows aren’t black any more, but nothing is completely washed out. The different colors of all the different lights in all the different directions creates contrast that varies depending on the surfaces.
And that’s perfect, but tens of thousands of tiny lights add up to a lot of math for a game engine to do in real time. So, we use other math and statistics to chop that problem down. By merging together lights that are close together with similar colors, we end up with a much, much smaller list of lights to apply to an item. In the end, we only apply two extra things per pixel — one for the broad diffuse lighting that doesn’t vary with your eye, and one for shiny reflections that change depending on which direction you’re looking at the object, as seen in the armor above.
There’s more that we need to do in terms of optimizations to make this work on the fly at the same time the game itself is running. First, we have to render the cubemap itself — but isn’t that rendering six extra frames? And won’t that take six times as long as rendering one frame? Not necessarily.
First, there are fancy shader tricks that let us render one omnidirectional view into all six images at once. Where that doesn’t work, we spread the work out over six different frames of the game, so that we only render one complete cube every six frames.
We do everything we can to re-use data from the main scene when rendering the cube scene, like keeping the same shadow data. Whether or not something is in shadow doesn’t change depending on your viewpoint, after all.
And finally, we get smart about what things really need to be rendered in the cubemap. Seeing one enemy character on a faraway hill is really important to gameplay, but it’s not an important part of how light shines on you. Likewise, particles can frequently be eliminated, as can grass and lots of brush. Models used in the game generally come in several “levels of detail,” ranging from tens of thousands of triangles when you’re up close, to a few hundred far away. The low-detail faraway version is plenty great for lighting. The most important objects are the sky, the terrain, and the major nearby buildings, and the result is almost always good enough — and more importantly, fast enough to support the large battles at the core of Camelot Unchained.
Here is a link to Andrew’s gallery of sexy lighting improvements here (http://imgur.com/a/Ec7Yk). FYI, the dark images are under the old (current) lighting system and the better looking and lighter images are the new system.