{"id":50,"date":"2010-03-01T00:40:45","date_gmt":"2010-03-01T00:40:45","guid":{"rendered":"http:\/\/the-witness.net\/news\/?p=50"},"modified":"2010-03-02T05:29:35","modified_gmt":"2010-03-02T05:29:35","slug":"graphics-tech-precomputed-lighting","status":"publish","type":"post","link":"http:\/\/the-witness.net\/news\/2010\/03\/graphics-tech-precomputed-lighting\/","title":{"rendered":"Graphics Tech: Precomputed Lighting"},"content":{"rendered":"<p>For the past 15 years or so, graphics technology in games has been driven by shooters. \u00a0Most shooters generate visual interest in their scenes by having lots of dynamic lights, with extreme use of bump mapping, and moving shadows, and particle effects.<\/p>\n<p>For <em>The Witness<\/em>, I wanted to develop a graphical style that values simplicity. \u00a0 It would be suited to mellower environments, with both indoor and outdoor settings. \u00a0Some kind of global illumination solution seemed like the right idea here. \u00a0(Global illumination is when you simulate light bouncing around in a scene; the resulting look is usually much richer and subtler than the direct lighting that games usually do.)<\/p>\n<p>Clearly, full real-time global illumination would be the most versatile solution. \u00a0I investigated some licensable packages that provide this, such as <a href=\"http:\/\/geomerics.com\/\" onclick=\"_gaq.push(['_trackEvent', 'outbound-article', 'http:\/\/geomerics.com\/', 'Geomerics\\' SDK']);\" >Geomerics' SDK<\/a>. \u00a0However, these solutions will invariably use a lot of texture space, and consume a bunch of processing time, and they seem like overkill for this game (<em>The Witness<\/em> does not have many moving light sources, relative to other types of games).<\/p>\n<p>So, some form of precomputed global illumination seemed like the right thing. \u00a03D modeling packages have plugins to compute global illumination, but they are very difficult to interface with, and they could not even come close to handling a full game scene. \u00a0 The only thing that knows where all the objects in the world are at once is the game itself (and the in-game editor), so it seemed appropriate to develop our own in-game system for global illumination. \u00a0It could have been radiosity, could have been something like Monte Carlo Path Tracing, but <a href=\"http:\/\/www.cbloom.com\/\" onclick=\"_gaq.push(['_trackEvent', 'outbound-article', 'http:\/\/www.cbloom.com\/', 'Charles Bloom']);\" >Charles Bloom<\/a> suggested the very simple solution of just rendering the scene for every pixel in a lightmap, and that seemed like a good idea. \u00a0With an approach like that, you don't have to do a bunch of monkeying around to make radiosity or ray tracing match the completely different algorithm that is used to render your realtime game scene; light transport is computed by that same algorithm, so it will automatically match unless you mess things up.<\/p>\n<p>For several months, <a href=\"http:\/\/castano.ludicon.com\/blog\/\" onclick=\"_gaq.push(['_trackEvent', 'outbound-article', 'http:\/\/castano.ludicon.com\/blog\/', 'Ignacio Casta\u00f1o']);\" >Ignacio Casta\u00f1o<\/a> has been working on this system. \u00a0He is writing up a highly technical explanation of how the system works, which I think he'll be done with in a few days, but in the meantime, here is a lighter-weight overview.<br \/>\n<!--more--><\/p>\n<p>At preprocess time, we just walk a camera over every surface, pointing the camera away from the surface and rendering the game scene into a hemicube in video memory. \u00a0The render target textures of a hemicube are packed together into an atlas, and when the atlas fills up, we download it into system memory, integrate the values in each hemicube to find an average light value, and then store that value in the lightmap. \u00a0Most of the shots below were generated using 128x128 cube maps and multiple samples per texel.<\/p>\n<p>Because we are just using our regular rendering code, this precomputation process is hardware-accelerated by default.<\/p>\n<p>Note: <em>In the images below, all geometry and textures are placeholders. <\/em> As with Braid, we are using rough-draft versions of all these things while the core gameplay is built. \u00a0Bloggers, <strong><em>these are not to be considered screenshots of the game<\/em><\/strong>. \u00a0They aren't supposed to look good yet -- they are just supposed to show the precomputed lighting.<\/p>\n<p>First, some shots of the house. \u00a0The precomputed lighting is responsible for most of the light in the room. \u00a0The places where you see sunlight hitting surfaces directly are dynamic; everything else is a static precompute. \u00a0(Without the precomputed lighting, the entire room would be black except for the patches of sunlight).<\/p>\n<p><a class=\"shutterset_\" href=\"http:\/\/the-witness.net\/news\/wp-content\/gallery\/lighting\/house1.jpg\"><img class=\"ngg-singlepic ngg-center\" src=\"http:\/\/the-witness.net\/news\/wp-content\/gallery\/lighting\/thumbs\/thumbs_house1.jpg\" alt=\"house1\" \/><\/a><\/p>\n<p><a class=\"shutterset_\" href=\"http:\/\/the-witness.net\/news\/wp-content\/gallery\/lighting\/house2.jpg\"><img class=\"ngg-singlepic ngg-center\" src=\"http:\/\/the-witness.net\/news\/wp-content\/gallery\/lighting\/thumbs\/thumbs_house2.jpg\" alt=\"house2\" \/><\/a><\/p>\n<p><a class=\"shutterset_\" href=\"http:\/\/the-witness.net\/news\/wp-content\/gallery\/lighting\/house3.jpg\"><img class=\"ngg-singlepic ngg-center\" src=\"http:\/\/the-witness.net\/news\/wp-content\/gallery\/lighting\/thumbs\/thumbs_house3.jpg\" alt=\"house3\" \/><\/a><\/p>\n<p>Note the ambient occlusion, soft shadows, and other nice effects that all come naturally from this system.  (In the third image, the picture on the wall hasn't been lightmapped yet, which is why it sticks out so brightly.)<\/p>\n<p>Here's a simple bunker interior consisting mostly of a single material and color.<\/p>\n<p><a class=\"shutterset_\" href=\"http:\/\/the-witness.net\/news\/wp-content\/gallery\/lighting\/bunker1.jpg\"><img class=\"ngg-singlepic ngg-center\" src=\"http:\/\/the-witness.net\/news\/wp-content\/gallery\/lighting\/thumbs\/thumbs_bunker1.jpg\" alt=\"bunker1\" \/><\/a><\/p>\n<p><a class=\"shutterset_\" href=\"http:\/\/the-witness.net\/news\/wp-content\/gallery\/lighting\/bunker2.jpg\"><img class=\"ngg-singlepic ngg-center\" src=\"http:\/\/the-witness.net\/news\/wp-content\/gallery\/lighting\/thumbs\/thumbs_bunker2.jpg\" alt=\"bunker2\" \/><\/a><\/p>\n<p><a class=\"shutterset_\" href=\"http:\/\/the-witness.net\/news\/wp-content\/gallery\/lighting\/bunker3.jpg\"><img class=\"ngg-singlepic ngg-center\" src=\"http:\/\/the-witness.net\/news\/wp-content\/gallery\/lighting\/thumbs\/thumbs_bunker3.jpg\" alt=\"bunker3\" \/><\/a><\/p>\n<p>Lastly, the tower:<\/p>\n<p><a class=\"shutterset_\" href=\"http:\/\/the-witness.net\/news\/wp-content\/gallery\/lighting\/tower1.jpg\"><img class=\"ngg-singlepic ngg-center\" src=\"http:\/\/the-witness.net\/news\/wp-content\/gallery\/lighting\/thumbs\/thumbs_tower1.jpg\" alt=\"tower1\" \/><\/a><\/p>\n<p><a class=\"shutterset_\" href=\"http:\/\/the-witness.net\/news\/wp-content\/gallery\/lighting\/tower2.jpg\"><img class=\"ngg-singlepic ngg-center\" src=\"http:\/\/the-witness.net\/news\/wp-content\/gallery\/lighting\/thumbs\/thumbs_tower2.jpg\" alt=\"tower2\" \/><\/a><\/p>\n<p><a class=\"shutterset_\" href=\"http:\/\/the-witness.net\/news\/wp-content\/gallery\/lighting\/tower3.jpg\"><img class=\"ngg-singlepic ngg-center\" src=\"http:\/\/the-witness.net\/news\/wp-content\/gallery\/lighting\/thumbs\/thumbs_tower3.jpg\" alt=\"tower3\" \/><\/a><\/p>\n<p>There are lots of caveats on these images. \u00a0The game renders in HDR, but we haven't balanced our lighting constants or done tone mapping yet, so I have gamma-corrected the output images by various amounts. \u00a0For now, we are computing only the first lighting bounce. \u00a0We'll probably do at least 2 or 3 bounces for the final game, and when we have that running I'll post some comparison images. \u00a0I believe our model of sky illumination is still overly simple and wrong (though I'd need to check with Ignacio on that, maybe he has fixed it up). \u00a0I haven't played around with the results of the current system in outdoor areas (e.g. lots of small branches and leaves), though if we find that we have too many aliasing problems, we can always make the lightmaps higher-resolution in those areas.<\/p>\n<p>In areas that have doors or windows that open and close, we are planning on layering a supplemental lightmap that gets scaled by the openness of that light aperture, then added to the base lightmap. \u00a0This will provide a pretty good approximation for the way the indirect light in the room changes as the aperture opens and closes. \u00a0Direct light will be completely correct since it uses the fully dynamic shadow system. \u00a0I'll do a post about that shadow system sometime in the future.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>For the past 15 years or so, graphics technology in games has been driven by shooters. \u00a0Most shooters generate visual interest in their scenes by having lots of dynamic lights, with extreme use of bump mapping, and moving shadows, and particle effects. For The Witness, I wanted to develop a \u2026<\/p>\n<p class=\"continue-reading-button\"> <a class=\"continue-reading-link\" href=\"http:\/\/the-witness.net\/news\/2010\/03\/graphics-tech-precomputed-lighting\/\">Continue reading<i class=\"crycon-right-dir\"><\/i><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[4,7],"tags":[],"_links":{"self":[{"href":"http:\/\/the-witness.net\/news\/wp-json\/wp\/v2\/posts\/50"}],"collection":[{"href":"http:\/\/the-witness.net\/news\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/the-witness.net\/news\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/the-witness.net\/news\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/the-witness.net\/news\/wp-json\/wp\/v2\/comments?post=50"}],"version-history":[{"count":15,"href":"http:\/\/the-witness.net\/news\/wp-json\/wp\/v2\/posts\/50\/revisions"}],"predecessor-version":[{"id":62,"href":"http:\/\/the-witness.net\/news\/wp-json\/wp\/v2\/posts\/50\/revisions\/62"}],"wp:attachment":[{"href":"http:\/\/the-witness.net\/news\/wp-json\/wp\/v2\/media?parent=50"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/the-witness.net\/news\/wp-json\/wp\/v2\/categories?post=50"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/the-witness.net\/news\/wp-json\/wp\/v2\/tags?post=50"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}