After the announcement of the Reddit + Mapcore mapping contest, the website has welcomed many newcomers. A proof that, even if it is a twelve year old game engine, Source engine attracts map makers, and there are lots of reasons for that. It is common knowledge that technology has moved forward since 2003, and many new game engines have found various techniques and methods to improve their renderings, making the Source Engine older and older. Nevertheless, it still has its very specific visual aspect that makes it appealing. The lighting system in Source is most definitely one of the key aspects to that, and at the end of this article you will know why.
About the reality...
Light in the real world is still a subject with a lot of pending questions, we do not know exactly what it is, but we have a good idea of how it behaves. The most common physic model of light element is the photon, symbolized as a single-point particle moving in space. The more photons there are, the more powerful light is. But light is in the same time a wave, depending on the wavelengths light can have all kind of color properties (monochrome or combined colors). Light travels through space without especially needing matter to travel (the space is the best example; even without matter the sun can still light the earth). And when it encounters matter, different kind of things can happen:
Light can bounce and continue its travel to another direction
Light can be absorbed by the matter (and the energy can be transformed to heat)
Light can go through the matter, for example with air or water, some properties might change but it goes through it
And all these things can be combined or happen individually. If you can see any object outside, it is only because a massive amount of photons traveled into space, through the earth’s atmosphere, bounced on all the surfaces of the object you are looking at, and finally came into your eyes.
How can such a complex physical behavior from nature be simulated and integrated into virtual 3D renderings?
One of the oldest method is still used today because of its accuracy: the ray-tracing method. Just to be clear, it is NOT used in game engines because it is incredibly expensive, but I believe it is important to know how and why it has been made the way it is, since it probably influenced the way lighting is handled in Source and most videogame engines. Instead of simulating enormous amount of photons traveling from the lights to the eye/camera, it does the exact opposite. If you want a picture with a 1000x1000 resolution, you will only need to simulate the travel of 1 000 000 photons (or “rays”), 1 for each pixel. Each ray is calculated individually until it reaches the light origins, and at the end the result is 1 pixel color integrated in the full picture.
By using the laws of physics we discovered centuries ago, we can obtain a physically-accurate rendering that looks incredibly realistic. This method is used almost everywhere, from architectural renderings to movies. As an example, you can watch The Third & The Seventh by Alex Roman, one of the most famous CGI videos of all time. And because it is an efficient way to render 3D virtual elements with great lighting, it will influence other methods, such as the lightmap baking method.
OKAY LET’S FINALLY TALK ABOUT THE SOURCE ENGINE, ALRIGHT!
A “lightmap” is a grid that is added on every single brush face you have on your map. The squares defined by the grid are called Luxels (they are kind of “lighting pixels”). Each luxel get its 2 own properties: a color and a brightness. You can see the lightmap grids in hammer by switching your 3D preview to 3D lightmap grid mode.
You can also see them in-game with the console command mat_luxels 1 (without and with).
During the compilation process, a program named VRAD.exe is used. Its role is to find the color and brightness to apply for every single luxel in your map. Light starts from the light entities and from the sky (from the tools/toolsskybox texture actually, using the parameter values that has been filled in the light_environment entity), travels through space and when it meets a brush face:
It is partially absorbed in the lightmap grid
A less bright ray bounces from the face
Here is an animated picture to show how a lightmap grid can be filled with a single light entity:
When you compile your map, at first the lightmaps are all full black, but progressively VRAD will compute the lightmaps with all the light entities (one by one) and combine them all at the end. Finally, the lightmaps obtained are applied to the corresponding brush faces, as an additive layer to the texture used on that face. Let us take a look at a wall texture for example.
On the left, you have the texture as you can see it in hammer. When you compile your map, it generates the lightmaps and at the end you obtain the result on the right in-game. Unfortunately, luxels are much rougher, with a lower resolution, more like this.
On the left you have a lightmap grid with the default luxel size of 16 units generated my VRAD, a blur filter is applied and you obtain something close to the result on the right in the game.
In case you did not know, you can change the lightmap grid scale with the “Lightmap Scale” value with the texture tool. It is better to use values that are squares of 2, such as 16, 8, 4 or even 2. Do not go below 2, it might cause issues (with decals for example). Only use lower values than the default 16 if you think it's really useful, because you will drastically increase your map file size and compilation time with precise lightmap grids. Of course, you can also use greater values in order to optimize your map, with values such as 32, 64 or even 128 on very flat areas or surfaces that are far away from the playable areas. You can get more infos about lightmaps on Valve’s Wiki page.
But as we said before, light also bounces from the surface until it meets another brush, using radiosity algorithms. Because of that, even if a room does not have any light entity in it, rays can bounce on the floor and light the walls/ceiling, therefore it is not full black. Here’s an example:
The maximum amount of bounces can be fixed with the VRAD command -bounce X (with X being the maximum amount of bounces allowed). The 100 default value should be more than enough.
Another thing taken into account by VRAD is the normal direction of each luxel: if the light comes directly against the luxel or brushes against it, it will not behave in the same way. This is what we call the angle of incidence of light.
Let us take the example of a light_spot lighting a cylinder, the light will bright gradually the surface - from fully bright at the bottom to slightly visible at the top.
In-hammer view on the left, in-game view on the right
Light Falloff laws
One of the things that made the Source Engine lighting much more realistic than any others in 2004 is the light falloff system. Alright, we saw that light can travel through space until it meets something, but how does it travel through space? At the same brightness, whatever the distance is between the light origin and destination? Maybe sometimes yes… but most of the time no.
Imagine a simple situation of a room with 1 single point light inside. The light is turned on, it produces photons that are going in all the directions around it. As you might imagine, photons are all going in their own direction and have absolutely no reason to deviate from their trajectory.
At one time, let’s picture billions of photons going in all the directions possible around the light, the moment after, they are all a bit further in their own trajectory, and all the photons are still there, in this “wave”. But, as each photon follows its own trajectory, they will all spread apart, making the photon density lower and lower.
As we said before, the more photons there are, the more powerful light is. And the highest the density, the more intense light is. Intensity of light can be expressed like this:
You have to keep in mind that all of this happens in 3D, therefore the “waves” of photons aren’t circles but spheres. And the area of a sphere is its surface, expressed like this:
(R is the radius of the sphere)
If we integrate that surface area in the previous equation:
With ♥ being a constant number. We can see the Intensity is therefore proportional to the reverse of the square of the distance between the photons and their light origin.
So, the further light travels, the lower is its intensity. And the falloff is proportional to the inverse of the square of the distance.
Consequently, the corners of our room will get darker, because they are farther away from the light (plus they don’t directly face the light, the angle of incidence is lower than the walls/floor/ceiling).
This is what we call the Inverse-Square law, it’s a very well-known behavior of the light in the field of photography and cinema. People have to deal with it to make sure to get the best exposure they can get.
This law is true when light spreads in all possible directions, but you can also focus light in one direction and reduce the spread, with lenses for example. This is why, when Valve decided to integrate a lighting falloff law in their engine, they decided to use a method not only following the inverse-square law but also giving to mapmakers the opportunity to alter the law for each light entity.
Constant, Linear, Quadratic... Wait, what?
In math, there is a very frequent type of functions, named polynomial functions. The concept is simple, it’s a sum of several terms, like this:
Every time, there is a constant factor (the “a” thing, a0 being the first one, a1 the second one, a2 the third one...), multiplied with the variable x at a certain degree:
x^0 = 1 : degree 0
x^1 = x : degree 1
x^2 : degree 2
x^3 : degree 3
a0 is the constant named “constant coefficient” (associated to degree 0)
a1 is the constant named “linear coefficient” (associated to degree 1)
a2 is the constant named “quadratic coefficient” (associated to degree 2)
Usually, the function has an end, and we call it by the highest degree of x it uses. For example, a “polynomial of the second degree” is written:
Then, if we take the expression from the inverse-square law, which was:
With a2 = 1 and D being the variable of distance from the light origin.
In Source, the constant ♥ is actually the brightness (the value you configure here).
It is simply an inverse polynomial of the second degree, with a0 and a1 equal to zero. And we could write it like this:
And here you have it! This is approximately the equation used by VRAD to determine the intensity of light for each luxel during the compilation. And you can alter it by changing the values of the 3 variables constant, linear and quadratic, for any of your light / light_spot entity in your level.
Actually you set proportions of each variable against the other two, and only a percentage for each variable is saved. For example:
By default, constant and linear are set to 0 and quadratic to 1, which means a 100%quadratic lighting attenuation. Therefore, by default lights in Source Engine follows the classic Inverse-Square law.
If you look at the page dedicated to the constant-linear-quadratic falloff system on Valve’s Wiki, it’s explained that the intensity of light is boosted by 100 for the linear part of equation and 10 000 for the quadratic part of equation. This is due to the fact that inverse formulas in equations always drop drastically at the beginning, and therefore a light with a brightness of 200 would only be efficient in a distance of 5 units and therefore completely pointless.
You would have to boost your brightness a lot in hammer to make the light visible, that's what Valve decided to make automatically.
The following equation is a personal guess of what could be the one used by VRAD:
With constant, linear and quadratic being percentage values. The blue part is here to determine the brightness to apply, allowing to boost the value set in hammer if it is as least partially using linear or quadratic falloff. The orange part is the falloff part of equation, making the brightness attenuation depending of the distance the point studied is from the light origin.
The best way to see how this equation works is to visualize it in a 2D graph: https://www.desmos.com/calculator/1oboly7cl0
This website provides a great way to see 2D graphics associated to functions. On the left, you can find all the elements needed with at first the inputs (in a folder named “INPUTS”), which are:
a0 is the Constant coefficient that you enter in hammer
a1 is the Linear coefficient
a2 is the Quadratic coefficient
B is the Brightness coefficient
In another folder are the 3 coefficients constant, linear and quadratic, automatically transformed into a percentage form. And finally, the function I(D) is the Intensity function depending on the distance D. The drawing of the function is visible in the rest of the webpage.
Try to interact with it!
This concludes the first part, the second part will come in about two weeks. We will see some examples of application of this Constant-Linear-Quadratic Falloff system, and a simpler alternative. We will also see how lighting works on models and dynamic lighting systems integrated in source games.Thank you for reading!
The creation of a map begins with an idea.
In the case of my most recent project, CS_MUSEUM, I needed a basic look which would resonate with players immediately. The thought of making a Museum worked… it was a simple one, it had been done before (although this wouldn't be a re-make of the classic DE_MUSEUM by Theropod-X). Players would understand a Museum environment, and it fit in the Counter-Strike world.
Forming a map’s final look is complicated, though, and requires thought about what kind of architecture, colors, and lighting you – an artist or level designer – will pursue.
I’d been playing a lot of the classic map CS_OFFICE, which requires players to storm into close quarters for indoor combat. That kind of game-play is fast and unforgiving, I dig the kind of matches it creates. CS_ASSAULT, I shouldn't forget to mention, is another great map that defines the "siege a building and rescue the hostages" genre. Actually, most of my favorite CS_ maps including Militia also foster similarly dynamic games that challenge you to be sneaky but also use brute force to accomplish your objectives.
So, I set out to make a hostage rescue map like Office and its kin. Studying prior maps is a good way to establish what works well, and avoid what doesn't.
One other map that influenced my thinking: CS_CABARET by Alex Roycewicz.
Cabaret is a great map — it got Alex a job at Infinity Ward long prior to that illustrious studio being kicked in the nuts super hard by mega-publisher-that-will-remain-unnamed.
It was from Cabaret that I basically ripped off the front of Museum... with a few changes.
In truth, though, I had some bones to pick with Cabaret.
Unforgivably, there was no sense of vertical space on the outside of the strip club. Also, while the building exterior is convincingly rendered, the overall space is too geometric: everything seems to face the viewer on an imaginary grid, which is no coincidence, that’s how the Hammer editor encourages people to make maps.
Cabaret on the grid:
Museum screws the grid:
If this analysis is starting to sound harsh, it’s worth noting that Cabaret was one of the best custom maps of its time, so this is more of a modern critique of older game art.
As is often the case with older game art, most of the limitations or flaws obvious to modern eyes were not the creator’s fault: Hammer around the era of Counter-Strike: Source (for which Cabaret was made) did not have all the technology I made use of for Museum. One example is “instances” (the pale green elements in the overview above) which are brushwork more akin to models than typical brushwork, because they can be rotated “off the grid” and not cause compilation problems normally associated with brushwork which is off the grid. Thanks to instances, I was able to rotate buildings to achieve a more natural, organic look — such as this bridge:
In order to actually create the specific buildings in the map, concept art and photographic references were key.
Here's an explanation of the Museum front.
The most pertinent point to make here is the difficulty of knowing when a photographic reference is valuable, and what makes it valuable. To explain this in extreme detail might be delving into an area of “talent”... or it might be worth the subsequent explanation I’ll now provide. In any case, this should explain my process.
The best photographic references share one crucial element: readability. Complex buildings such as the one above, if they are to be useful for our purposes, must be able to be broken down into clean, clear shapes. I was confident using the logic explored in the line-work above (I did this part in my head), that the building could be broken down and translated successfully.
The building begins to take shape, with the red lines becoming props. When using Hammer, what becomes a prop and what remains brushwork largely comes down to the default assets you have to work with.
Talented 3D modelers have their choice of creating new content, but their time is precious and each art asset is an investment, so even then it’s best to think about default materials and their role in your work.
This lovely picture inspired the placement of the obelisks, and secondarily the pond on the right of the Museum.
Using concept art and photos in conjunction with my imagination, I had derived a basic visual identity for the map:
Obvious reference: the Brooklyn bridge; non-obvious reference, this lovely piece from Deviant Art:
Making a map is about looking at the world around you and seeing something inspiring enough to create a desire within you to render it and mold it for your own purposes.
By this point in time you may be shouting IT’S A MAP – TALK ABOUT THE GAME-PLAY, TALK ABOUT THE GREY-BOXING YOU FOOL! …and, while the playability of Museum ended up better than I could have imagined, there is no glory in my process for that particular aspect of the map. Uh oh, he’s gonna say he didn’t grey-box it, isn’t he…
First, the excuses: previously, I'd recreated the Natural Selection 1 map NS_VEIL for NS2, based solely upon my own literal eyeballing of the geometry, without any scale-guide, in a different editor and a different unit system. To put all that gibberish into other words, I’d done nothing for two months other than study the rigid grey-boxery of another mapper, then spent another 10 months making that geometry fit into the context of a new game and engine. I’d worked with fastidiously organized layers, done everything by the book, guv, I swear.
While important for a commercial product, that experience had temporarily tired me somewhat of the (smarter) formalistic approach. As a result, no substantial grey-boxing would take place for Museum. Manic energy took the place of “rules” and “common sense”:
Basically, I was creating stuff I thought looked cool, not getting terribly fussed about what direction it would all head. This is the way newbie mappers work, or idiots, or both… but it can be done if you’re smart about it.
Certain things can’t be bullshitted around, though: your map must be in proper proportion to the players, and it must maintain sensible sight-lines considering the game type. You need to know the game you’re making the map for, and know it well.
So working free-form has its advantages, creating a whimsical sense of liberation in the budding mapper. It comes at big costs to him, though, in other aspects. This open doorway, and the entire route it signified, never made it into the final product. People have noticed its conspicuous absence, however, to the point that it may make it's return soon enough.
Working toward a result, with certain restraints in mind, but willing to cut: my method for Museum.
Mistakes were made. Certain areas violated basic good-practice principles, such as this one:
I call this piece of modern art “Abstract Red Light Number 48.” So… this elevator shaft was painful for a few reasons: too noisy inside, not clear enough about what it was meant to be, and the idea of it having a purpose seemed impossible given the amount of crap stuffed into the scene.
I believe I settled on a better, cleaner result:
Which was based off of this reference:
This shipping area was another idea that got cut (considering that it was over-dark, this was not too sad):
Everything else seemed to go swimmingly, however:
My biggest advantage when working with these references is my ability — and perhaps your ability as well — to discern from them what elements are most relevant and work best geometrically. These judgements influence what makes it into the map. While you may be able to follow a similar protocol by examining the pictures, you would be doing so in hindsight; it was quite necessary during this project for me to be able to sift through literally thousands of images in order to find those which, at first glance, provided the requisite inspiration.
References must be clean, they must convey a certain tone, and the architecture they illustrate must be plausible among the rest of the map geometry. This process of looking through seemingly endless references is a task which must be begun anew with every new map.
Back on topic: a month or two after starting out on the map, I recruited a talented 2D artist named penE who had a style congruent with mine. With his help, rooms like this began to form their own identity:
The map began to develop a sense of humor. We based the name of the museum on HURG — Hero of MapCore! (Don't ask.)
PenE brought his full enthusiasm to the project, getting almost all of his work done in a month or so, a rapid pace which would be a major motivator for me while I was working with (read: waging war against) the Hammer editor.
Here is a sample of penE's work for the map:
Nevertheless, the map did seem to require more art…
I had envisioned a T-Rex in the above room, and had designed the room around that eventuality. I was concerned that such a 3D model might not fit well (it’s a relatively cramped room), or might not be appropriate looking, but I put out a call for a talented 3D artist.
3Dnj answered that call with a stunning T-Rex model based on square-shaped geometric restraints. I basically stacked a bunch of cubes on top of one another and said, “OK now make me a T-Rex that fits inside the squares.” Seems hopeless, right? Thankfully, Valentin, as 3Dnj is known, e-mailed me this bad boy:
Owns right? Imagine waking up and seeing that first image of the T-Rex with that brilliant sheen, I was ecstatic.
At that point I realized I’d found a true collaborator and not just a “prop guy”. Valentin would go on to help me optimize the map, and reform a lot of my map geometry into more sensible models. Here’s how crazy things had gotten:
Hammer is unlike a modeling program in that it is “brush-based”, and things that are not literally six-sided cubes give the editor trouble. Trying to create an interesting shape out of a single brush? Take a hike.
So it’s obvious why a more extensive collaboration was needed: it was never going to be realistic to proceed in such a manner and expect an optimized result which would (ugh) compile. Hence, the logic of making a map which looks the way Cabaret does, unfortunately all the same limitations applied more or less in 2012, with just a few exceptions like instances.
So there were technical challenges, but four months on, most of the major lessons of the map were learned and my vision for the map was realized almost exactly as it existed in my brain.
My workflow can be best summarized as: find a fitting photographic reference, get a basic interpretation of the geometry into the game, and then polish with aesthetics and navigation in mind (lead players with lights and colors).
Rather than attempt to convince you I pursued the traditional level-design approach of iterating a grey-box, I hope this document serves to explain the approach I actually took: a risky and improvisational one that I know I’m lucky was successful. It’s good to state how lucky: a layout that emerged without argument, finding two brilliant collaborators with a lot of faith in the project, etc. Hopefully anyone looking to duplicate my exact method will be given pause, but at the end of the day there will always be logic in working hard and having a well-formed mental image of your goal.
As for Museum, I can promise you one thing: if you load up the map, and I hope you will, I think you will enjoy it. (If only for the giant, motherfucking Tyrannosaurus Rex.)
Thanks for reading.