[Music] right hello everyone my name is Nikolai and I'm the technical lead at Ubisoft massive and today I'm going to talk to you about global illumination in tone classes the division before we begin I've been asked to remind you to turn down your mobile phones and to fill out your evaluations at the end and if you got questions at the end please step up to the mics at the ale so a couple of words very briefly about the division it's an open world online RPG and it's based on massifs in health snowdrop engine so today I'm going to cover snowdrop solution for ambient light ink which we call precomputed radiance transfer fraud so purity pros for short with PRT probes what we can get is an
accurate approximation of global elimination in real time both on consoles and on PC we support dynamic light sources such as the Sun the sky point spot and area lights as well and we are able to evaluate the light bounce from these light sources with a great degree of accuracy our method was developed with production in mind and it's fast its GPU friendly and also has very low memory requirements so with purity probes lights can be added removed or modified without needing to rebake and this provides instant feedback to our lighting artists we is exactly the same techniques both for indoors and outdoors and we also take special care to prevent light bleeding the light coming through building walls
and also between the interior rooms so here are some comparison images which show the contribution of the PRT probes at the top we have the normal output of our renderer and at the bottom I've turned off the ambient lighting and replaced it with a solid black color so you can see the contribution better so here's some more examples from more indoor type areas nice time again top is the normal output and at the bottom you can see what happens when we switch off the ambient lighting completely so here's the agenda of the talk today first I'm going to give you a very high-level overview of the features of our approach next I'm going to talk about how we pre compute the radiance transfer online/offline sorry then we
get to the more interesting and exciting parts about what we do at runtime on the GPU and finally I'm going to talk about some of the problems that we encountered during production and I'm going to show you some ugly screenshots so the division is set in an open world our version of Manhattan is quite large in more than six square kilometers we have almost two million total lines displaced throughout the environment our artists have hand placed about 222 thousand vehicles in about 28,000 garbage paths and the size of the world and the number of objects in it makes traditional methods such as light mapping static light and I think unfeasible for production in order to manage our costs it was clear that we had to do with a pro based approach and as probably most
of you know here light probes or Iranians for loops are kind of similar to a 3d light map so rather than using a UV texture set to index them use the position and the normals of whatever it is that you render so from the production point of view this is very good because the artists don't have to worry about unwrapping v's we also don't have to trigger a rebake whenever somebody just changes slightly a model and this is especially important when you have a lot of models that are placed throughout the world that are instants throughout worse for example a generic car or a generic brick wall so the division also features a day/night cycle and because of this the quality of the ambient lighting becomes really important our artists can't really cheat and said the Sun Direction to make their environment look as good as possible and
also due to the tall buildings that we have in New York we have certain areas that are in shadow throughout the day so they can only receive ambient lighting the PRT probes allow our artists who tweak the lighting for any particular time of day and immediately provide an accurate approximation of the global illumination at that point and they can do that without waiting for a long rebate process during the night our Maysles source of lighting comes from local lights point spots and area lights which are placed throughout the world we don't do the typical Hollywood night thing where you get still a strong directional lights but just blue so in the previous iteration of our technology this that we did for far cry the secondary bounce from these lights would have to be actually baked inside
of the probes but for the division what we were able to do is to make these light sources completely dynamic in dynamic and also editable as well the lights can be freely added you can remove them you can modify them as you wish and you also get instant feedback applies to how a specific environment will look during the night the division also features many interior spaces a lot of these are often very large and densely propped our artists tried to light them in a realistic way as a general rule we don't use hacks such as negative lights and we also try to avoid doing things like artificially raising the ambient light level instead we just solely rely on the PRT probes to get good lighting a lot of the interiors also have large windows and openings and
as such are affected by the day/night cycle as well so this all fits together quite nicely with our pro based approach however we have to take special care in order to prevent light bleeding between the different rooms we also support different weather conditions in the division so we have clear sky we have overcast we have snowstorms and even we have blizzards and weather in game is actually randomized by script that runs on the server each weather preset defines its own lighting and the artist can tweak tweak things such as the Sun the sky color the cloud type the density of the clouds and so on and so forth one interesting thing is that the weather preset also determines how much snow is going to build up on the different surfaces and this is a phase if effectively changing the brdf or the shaders of the surfaces on the fly it
would be a problem if we were to go with the completely static GI solution but because of the way we do PRT this we can achieve quite easily with just a few share their instructions and at the minimal rendering cost so let me show you now a brief time lapse of of how everything fixed together inside the game so the white spheres that you see here are the probes where we've completed the lighting and you can see how the ambient lighting changes some moves across the sky so they get the correct light bounce from from the buildings and from the street here we have an example of the different weather conditions suddenly becomes a lot for here and this is where our volumetric fog solution is going to kick in finally at night we see that most of the
illumination actually comes from the streetlights and here you have another example of the volumetric fog being affected by the process all so after this brief introduction let's now go into detail about how we implement it PRT inside snowdrop so pre computed transients transfer or PRT refers to a family of rendering techniques where we figure out what the light transport is between surfaces for a particular fixed scene and this P or T we can store it per vertex in a texture or in the probes just like we did for Far Cry in the space of this presentation I can only give you just a very short background impurity but if you want to get more information I recommend looking at the course notes from SIGGRAPH 2005 they're really good so impurity in general we
only can support distant light sources such as HDR environment probe or directional lights for varkari I did develop a solution where we could also support dynamic localized but unfortunately they turned out to be too heavy and inaccurate and it didn't make it to the final release high frequency shadows are also possible but so far I have not been particularly suited to games unfortunately because of the complicated shaders that are required so in the bottom image here you can see an example of PRT done with a nonlinear wavelet basis so you can see the sharp shadows and the reflections and generally that's just not possible on the GPUs with that particular wavelet basis approach so to get around with these limitations what we did was we just decided to use
brute force rather than looking for something elegant and compact to represent PRT like all of these academic papers do we just were an explicit list of all of the surfaces that are visible from a particular probe so we have a list of surface or surfer elements each one of them has a position I'll be doing a normal so color and a normal and various other attributes such as how much snow can build up and so on and so forth and it's quite similar to having G buffer cube map per probe but not quite here is our circled several debug view which hopefully will make this a little bit more clear so for each probe what we do is we draw a green line from the probe towards the surface that that
probe sees so I said it's kind of similar to Jeep of cube map but you can also think of it as firing lots of rice from the probes and just storing the first hit you just store the surface properties there so for each direction where we don't have any geometry we assumed that the sky is visible and what that gives us is a spherical shadow term per probe it's somewhat similar to a large-scale directional ambient occlusion and you can see in these two images to the right how this works compared to SSAO sseo is a lot more local and enhances basically the corners of the objects the pre computed sky visibility on the other hand works on a much larger scale and can pick up occlusion from the train terminal tunnel in this case and from some of the buildings
and since we're using probes we count we can't only precompute radians transfer for just a particular normal we have to do it for the entire sphere and the way we do it is the way we did it for the Far Cry series with a transfer basis so in the top left image here you can see the light probe the HDR light probe of Grace Cathedral top right you see the cosine convolution which tells us how a purely diffuse surface is going to be illuminated from that particular light probe and what we're looking for is to get a compact representation of the light of the cosine convolution of the light probe or to compress it in some way and one standard way to do this is to represent it as coefficients of a particular transfer basis and here at the bottom I've shown you a comparison
of two of the most common choices that you can have for transfer basis in prt bottom left we have second-order spherical harmonics they are somewhat equivalent to having like a principal light direction so in this example that would be my principal light direction and in the single ambient value an easier problem with that is if you have two strong light sources coming from the opposite directions then you only can raise the ambient value but you lose any sense of directionality on the plus sides this is actually very good for GPUs because you can just store it as for floating point values and to the bottom right we can see another representation the half-life to ambient cube this isn't a real basis it's it's not real orthogonal basis is it's really
just six vectors that are axis aligned and what we do is we just compute the how much light each one of these vectors Rafi receive so essentially what we do is we just compute the cosine convolution for six different normals again the problem here is that if you want to have a rotating light source instead of actually seeing it rotate you will see it fade in or fade out from one of the directions and then fading to the other so it's actually just gonna blend smoothly rather than actually seeing it rotate and this is because basis vectors are fixed on the other hand after evaluating different choices for the transfer basis we finally settled on the half-life to ambient cube basis which is also quite GPU friendly as it only requires six floats so very shortly what we do is we just compute pre computed
ruddiness transfer for the six normals and we at runtime what we'll do is just a single blend between those six vectors and here you can see the isolated arranges from each particular direction so top sorry left right top bottom front to back so essentially if we want to shade something we just figure out how to blend properly between these six different values so let me talk about how we actually generate radians transfer we have to start with placing the probes in the world and we do this automatically in two major ways first we have a grid of Ray casts there are spread four meters apart so we just fire rate top down and we spawn a probe at every hit we also do a bunch of additional rate cuts in order to to move the probe slightly to nudge it so that it doesn't intersect any objects one
other thing that we do is we also automatically spawn probes alongside the building walls and this helps to make a smooth gradient and to prevent the buildings from looking flat and most most of this is down to the sky visibility that we also compute because the probes at the bottom are going to be a lot darker than probes that are at the top so how do we store that data on disk we divide the probes into a 2d grid of sectors each sector is 64 by 64 meters and can hold a maximum of 1000 probes typically we expect to have about 300 to 400 probes I think the maximum that we've seen is about 960 and that sort of depends on how many buildings you've got inside of a particular area how tall they are how many floors you got for a particular interior and so on so we store the
probes simply as just this very simple array but you can probably also try to organize them in some sort of bounding volume hierarchy in order to be able to do spatial queries fast and these sectors at runtime they're streamed in as the player moves around we keep a maximum of 25 sector slowly at any one time so if we want to relight a large number of probes every frame you can't just for the list of surface will probe and try to relight that it's just going to be too slow so what we have to do some optimizations in order to have the GPU do less work for frame and to do that the first trick that we do is that in each sector all the probes are actually sharing the same surface circles this way we can relight all the surface
in one go and then the probes will actually reference those and not do any duplicate work and you can see that this would actually work quite nicely here in the images to the right you can see that the probes that reference the same roughly the same surface all the time so with that we're we're actually able to reduce the number of the number of surface that we relied on the GPU quite dramatically and you could use a very sophisticated clustering algorithm here but we just didn't have enough time to implement it so we just went with a very simple two level hash great I'm gonna show you some details of that right now so we have two levels for our grid and the first level each cell in the grid averages the positions the normals the colors and everything else for the surface we use the surfer position and
also the principal normal direction of the surfer in order to index into the grid and we do that in order to avoid averaging surfaces that have drastically different opposite directions so the cell size cell size here for this grid determine is how much work you're gonna have to do at run time in order to to compute the lighting and you have to be careful here because if you set this to course you gonna have problems for example with narrow spotlights because you're just simply evaluating the the lighting get a very at a very coarse grid we found that for our game one meter cube was actually a very good compromise between performance and quality so the second grade level averages multiple circles into one irradiance brick and this is an optimization that
is required in order to reduce the amount of work we have to do for probes so rather than the probe referencing each individual circles it actually references a brick instead so you have to do a lot less computation per probe here and again you can I have to be careful here if you set this size too large then you're going to have inaccuracies if you set it too small then your performance is not gonna be that great and for us for meter cube cell size works quite nicely so now we're going to go through a very high-level overview of how we actually store all that data on disk so for each sector we have our array of probes that you can see here on the left each probe has its own position and also the half-life 2 MB M cube coefficients for this curve is
ability so we only store the scale visibility poor probe it also has a range two indices into an array of brick factors so brick factor basically defines how much influence how much light a particular probe receives from our irradiance brick and again we just have half life to ambient coefficients of 6 float values and also we have a particular and we also have a brick image that is a index into our irradiance array array this brick array so the bricks is the brick is very simple it just has two indices that define a range inside the circle array that you see here on to the right and finally we get to the last part the surface where we just store anything
that we need to do in order to be able to relight them so their position the color normal and any other attributes so in order to generate this we have an offline baking process we start by rendering GDL for cube maps for all the probes inside a certain sector we read back the G buffers to the CPU we unprojected Texas the humid Texas and compress the normals and so on and so forth after we've done with rendering all of the cube maps what we do is we put the surface into the hash grid in order to get the average surface and also the irradiance bricks and as we do that on the CPU we can start actually rendering the other sectors that are in the queue so we do that interleaved and all of this takes around 5 to 6 second per sector again it really depends on
how many probes and what geometry you're gonna have in that particular part of the world so for the Manhattan map that equates to about one gigabyte of data on disk we have about four thousand sectors 1 million probe and fifty six million surface and we can generate the entire data set of line in about eight hours but here our lighting artists don't ever have to do that manually and they can only do it once and then work off of that particular nightly set of data so I hope everybody is still awake up to that and we're going to go to the more exciting part the rendering what's happening at run time on the GPU so super high-level summary of what we're doing every frame and I'm going to go into details about each one of these super shortly we start by real lighting
all the surface and the brakes so this is simply calculating the lighting and every circle and then summing it up for a particular brick very simple the next thing that we do is we relied the probes we compute the lighting that comes from the sky and then we just add it to the lighting that is referenced by every single brick and finally at the bottom here we put everything into an irradiance volume so this is just this is just a normal volume texture that has a single RGB color for each each one of the six directions and we use that for shading so each frame we start by taking our PRT data for the probes we plug in the new lighting environment and get the probe irradiance back and this is not
just a simple blend between different irradiance solutions for different types of Bay and allows us to have very accurate lighting at a specific time and to capture GI facts that are otherwise impossible to capture because they're very short duration and here's the right you have an example of such an effect so in the left image we get a strong orange light bounce that's coming from the top falling because it's directly illuminated by the Sun and this happens only for us very few minutes during the day so if you were to do to basically pre compute irradiance for certain times a day you have to be very lucky or sample it quite quite densely in order to be able to capture that and at other times the Purple Line is in shallow so the wall of the building is primarily
illuminated by the Sun and the boss from from the street so how do we do that it's actually super very surprisingly simple this is some pseudocode for me as a programmer it's quite easy to understand this I hope it will be for you as well first we can give the radiance at every brick for each brick we just go from the list of every circle we compute the lighting there and finally we average overage that for that particular brick and that compute lighting function is nothing more but like in your deferred shading function you can just reuse that given the normal the position the albedo you can just compute their lighting from that one as well so as the Sun lighting and the shadowing is evaluated per circle we can achieve much better accuracy than our
previous PRT methods such as the one that we used in Far Cry 3 where the shadowing term was just approximated per probe with some spherical harmonics coefficients and here we can see the difference that this makes we have a scene here where the Sun Direction changes changes throughout the day and the irradiance of the Sun isolated here to the right changes quite dramatically we just have a difference of what is it three hours and you can see how much difference it makes just for the solution and this is something that you cannot very easily capture with PRT and you also have to sample quite densely if we were going for different probe sites and computing them for a specific time of day so one thing that you have to be careful about if you're going to implement this is that the dynamic shell map from the Sun actually follows the player and is only
guaranteed to cover the visible frost notes all of the surface so any surface that are outside of the first time do not have a valid shadow map so depending on your indexing mode you will just get strange results and to illustrate the disastrous effects of this what I've done is I've just completely turned the shadow from the Sun and you can see that it sort of looks alright but you get like weird ambience where certain objects are illuminated even though they are completely in shadow so this is just incorrect we could solve this by rendering a dedicated shadow map that would cover all of the surface but that would be too expensive so what we do instead is we just keep track we just keep a history of whether a particular circle has a valid shadow sample and we just use the last known value and it's kind of ok because the Sun doesn't actually change direction that that fast
so another improvement over our previous PRT implementation is that we can easily incorporate local light sources point spot area lights what you have to do is simply to light each surfer with this and you automatically get the correct light mouse in that compute lighting function that we saw on in the pseudocode and in order to do this we just have to do a little bit of extra work on the CPU in order to figure out which lights intersect the sector's bounding box and then we just simply store these their properties into GPU constants and upload them to the GPU and then we've done one nice optimization that we also do is that license our mark this topic so you can't actually shoot them or they won't change they won't blink or they won't move we
just stored them in a separate buffer we compute them once and then store them and just we add them and this allows us to support many more light sources than I thought originally would be possible so I'm going to show you now a quick video of how dynamic light sources work with snowdrop so here what we have is a spot light very bright spot light bell bass shining towards them all and the wall is multicolored is godlike these different tiles so as the light moves it lights up the tiles and then the probes captured the bounce from them so you get this really nice multicolored effect so as I mentioned in the beginning of the talk each one of our weather presets also defines how much snow is going to
build up from the different surfaces and in order to support this we just stores tiny bit of data that tells us how much snow is supposed to accumulate on that particular surface so then simply when we relied the bricks we read the value from the weather preset of how much snow we're supposed to go and then we just lurk between the original the original color of the surface and purely white and you can see here a comparison of what it looks like to the right here here to the left I've turned the effect off so what we get is like this still kind of correct but not quite grayish ambience that's coming to the probe and to the right you have a much more pronounced white ambient light from the bottom so it works really nicely and it's very cheap so as some of you probably figure
out by now we only pre compute a single bounce for the surface for the PRT and in order to simulate additional bounces one of our programmers figured out a very nice way to do that we just used the computer T radians from the previous frame and we feed it back to the current surface when we do the lighting so it's circle just stores an index to the probe that is closest to it and just uses that as an ambient lighting term and this feedback loop allows us to capture the load by the light bouncing from the light from the sky bouncing from the floor and you can see the effect here in the bottom image here just a little bit of a close-up if you just use a single bounce then the ceilings I don't to be quite dark once you turn on the feedback loop then suddenly everything gets a lot
more correctly illuminated couple more comparison images to the lattice so here we have an outdoor environment and the feedback loop just makes everything brighter and brings up the bottom of the light probes so it illuminates the bottom of the objects so in although it works very nicely for outdoor environments for indoor environments it's not the effects is not quite as pronounced here again to the left you see the effect of a single bounce and the right you see the effect when we turn on the feedback loop so you can see just a tiny tiny bit of difference where the probes are a little bit brighter but in reality it doesn't give you much so the next thing that we have to do after we've done the bricks and the radiance
from from the bricks we have to go through each probe and relight the probes so first what we do is we compute the irradiance from the sky for that it's a very simple process we render the entire sky to assembly to a very small texture and then we project we compute the cosine convolution of that and we store it as just basis coefficients of the half-life to ambient cube basis and now all that we have to do here is just to multiply that with this car visibility that is stored inside of the probe so what do we have to render a small texture mainly because our skybox uses a large combination of techniques which are difficult to express analytically we do have the prism sky model but also on top of that we have this six point
lighting cloud textures that allow us to dynamically relight them based on where the Sun is so here you see the same scene with different sky configurations the bay sky color is the same for both scenes but at the top you don't really have any clothes and you have this blue type ambience which is captured by the probes and on the bottom you have quite quadrant quite a lot more sky coverage so these the sky is actually more grayish rather than blue and this is also correctly captured inside of the from our PRT solution is no dope this is another example where we have this time the same clouds the same base color colour but we've just moved the Sun so it's like it's sunset or sunrise I don't quite remember so in one of the in one of the cases the clouds are very orangey and to the bottom you see it during
during the day so the clouds are now whitish and you can see how this is also correctly reflected in the light probes so finally what we have to do after we've computed the Iranians from the sky we just simply have to add the lighting that comes from the sky with the lighting that comes from the bricks and then we get the final result so we just go through all of our brick factors and add them up that's it and then we've done we've got the probes completely relieved so let's talk about the things that you're probably very interested in the performance I have to preface this by saying that the performance kind of depends on where you are in the world how many probes you've got how many surfaces and so on but the numbers I'm going to give you are quite representative so every frame
what we do is we've relied to full sectors the one that the player is in and also we choose one other from the sectors that are currently loaded so this is done in a GPU compute task just right after the shadow right now we actually have to compute task 1 to relight the surface and bricks and want to relight the probes themselves so this is also done with ASIC computer on consoles which is running at the same time as we do the G before rendering some example timings for the Xbox one it takes about one millisecond we turn this by putting the computer in nan a signal normally though this this one's a thing and it doesn't really matter if we turn it on and off it's just absolutely the
same performance it does it's not that expensive at all and the time here is roughly split 60% 40% between lighting bricks and surface versus lighting probes on the PC on a gtx 760 it takes about half a millisecond to do the same the same amount of data and the timing here is roughly split 50-50 between lighting bricks and lighting probes so once we've run the relighting computer the next step is to put all of the Iranians data into one volume up and we do this in order to have trilinear filtering and in order to support large objects or small objects the volume map follows the camera and covers 100 by 50 I 50 by 100 meters with 32 by 16 by 32
voxels and we use a single texture for all of the six basis directions and the shader computes just an offset into that texture in order to figure out where to read from so this volume map is used both in the different lighting paths in the forward lighting path so we have consistent consistent lighting between purely opaque objects and also transparent objects or particles so 100 by 50 by 100 meters with such relatively low dimensional volume up will create probe leading so this is just the effect where you have the trilinear filtering reading the wrong values so basically you have the effect of a light bleeding through a thin surface such as such as
the wall of a building and you hear it at the top right you can see an example of this what happens is that the probes on the outside gets illuminated by the sky and this incorrectly illuminates the interior the entrance here so you get like this sort of wrong blueish ambience and in order to fix this we use a separate volume texture for both indoor and outdoor we for a particular mobile we know which room it and we write that volume inside the stencil buffer then in the deferred lighting pass what we can do is we can read from the stencil and figure out whether to read from the outdoor or from the indoor from the indoor volume texture we also try to prevent bleeding between different rooms and we did that by determining what the extent of the room is in volume space and then
clamping our reads just to just to this particular AABB in the volume map and of course this only works if you have rooms which are axis aligned and you can see the effects of these fixes in the bottom right here so we have a lot more correct ambience so the entrance to the staircases alot looks a lot more natural outside of the volume map we shade using up to the large 2d texture which we call the fallback texture and this is a single 2d texture that covers the entire world each pixel inside of it represents a single sector probe and we compute the information for that by just placing a probe like very high up in the environment and for this one we don't actually do any of the light bounces we just compute the radius from the sky so
you can see the effect of the distance shading in these two comparison images to the left I've turned it off completely so the buildings far down the streets are now suddenly completely black and to the right afternoon back home and you can see that it's almost like an invisible blend between the volume up and the fall back texture so it works rather nicely as pretty much everybody else we use ambient occlusion as a shadow term for the indirect lighting ambient occlusion can come from a couple of sources so things like as a CEO it can be baked into the models into the materials into the textures as well and it also comes from the sky visibility of the probes so for sseo and the baked in ambient occlusion we store it in a separate channel with our G buffer ideally what
you want to do is to only to use this ambient occlusion for the sky term only so you don't really want to apply that to the secondary bounce that's coming from the bricks but we kind of cheat here and apply to everything in order to not having to store two terms and not having to use more than one volume map so one of the things that we've found during the project is that it's difficult to make sseo good underneath vehicles one of our tech artists came up with this cool way to fake ambient occlusion with just a squeeze paste projected vehicle and you can see the difference that this makes in the comparison images to the right at the top the decals are switched off so the vehicle kind of looks disconnected from the street whereas at the bottom you suddenly get this idea that it's actually something that's grounded and
it actually casts a shadow and this is just done with a very simple texture boat box in the vehicle prop you can see here some screenshots from our snow drop editor the vehicle isn't just a simple model is actually an old graph with a lot of parameters that you can tweak and you can also place place this additional primitives inside of it in that case is just an invisible box that has a simple gradient texture and that texture just writes out to the dedicated G buffer Channel it's very simple but it also works surprisingly well so snowdrop also uses the purity probes in the volumetric fog rendering we just use the standard frame arching and sample the lighting environment in order to simulate scattering from participating
media particles in addition to the Sun and the local lights we also sample the ambient lighting that comes from the probes themselves as an optimization we store the average irradiance for all of the six basis direction in a separate volume up so just a single RGB volume up and this is what we actually sample and do trilinear filtering on as we're remarking and it kind of works because the scattering is supposed to scatter in all directions so taking the average ambient lighting is correct in this case so we've come to the final section of the presentation where I'm going to talk to you about some of the problems that we encountered with our approach during production and as promised I'm going to show you some ugly screenshots so it's no drop initially was using an
irradiance volume like pretty much a lot of other games but with a twist instead of having a breaking step for the probe soft line what we would do is we would render q maps on the fly and then store them on disk so as you were working around we would render the cube maps and store them in a cache and this works very nicely with one major drawback is that the update rate isn't really fast enough so what you could see is visible light pop likes a particular area would be dark and suddenly boom it would become brightest we we render the probes and as a whole we decided that this wasn't quite suitable for our requirements like the day/night cycle or the dynamic lighting you just couldn't get it to work fast enough in order to in order to have the dynamic lighting that we wanted so when we switch to PRT probes we started with eight basis
vectors that cover the entire sphere and you can see those eight basis vectors as the white dots on the probes there this worked fine except that at some points the artist noticed that the streets were a bit too dark they just couldn't put their finger quite on why but everything seems a little bit too dark so we sat down and eventually realized that it was because none of the vectors actually pointed straight up or straight down so this meant that the light from the sky or the bounce from the street we couldn't actually represent it properly we could just blend between two vectors that were pointing this way so for that reason we decided to go back to half-life 2 MB mq basis and it uses six basis vectors which is fewer so you would think it's less accurate but it actually is better for our needs because there's one vector that points straight up so it can capture the lighting from the sky
accurately and then there's another one that points straight down so it can capture the balls from the terrain on the street during production we also had occasional problems where the automatic probe placement algorithm would decide that it was going to stop working properly and for various reasons probes would not be spawned in certain areas and this causes dark spots in the irradiance volume so like places where we just don't have any lighting information and to the right here we have one such location we have this particular building and on one of two of the floors you just don't have any probes and you can also kind of see it on the on the crane there to the right as well and this is just caused because the the probes just missed the crane completely so you don't spawn anything
there and we have also a special debug tool for these situations which would color these areas with a high light color so that we can easily spot them and to solve problems like bass is not fun and also requires quite a lot of coder effort and we were thinking that the way to address this in the future is to give art is more control over how the probes are placed so to allow them to add new probes to move the automatic probes allow around in order to adjust things since you fine-tune all of the details one other possibility that we were thinking about is to support UV mapping for the buildings so for large structures so effectively what we would do is we would compute the same sort of PRT but instead of six direction we will just compute it for the four three direction in the tangent space and this allow us to this will allow our artists to control the resolution of the PRT a
lot more effectively so we also have the problem that sometimes probes are missing from indoor entrances and because we have the outdoor and indoor volumes this presents itself as a sharp line transition between the indoors and the outdoors and you can see it here in the comparisons images to the right where I've just isolated the ambient lighting so one might solve this is to automate the placement of the probes so that we spawn them at particular entrances and windows unfortunately we only thought of that quite late during the production so this didn't make it in the final game luckily for us these type of artifacts are not so visible when you have full shading on because the change in material actually masks the transition as well so one of the other areas where we thought we could improve
is the resolution of our solution it's fairly easy to change the grid sizes and so on so it's just a bunch of parameters that you put into the baking but you have to be careful about the performance cost in order for us to increase the resolution of the probes what we have to do is to look into optimizing the baking times first and also to optimize the compression just because we don't want to our memory budget and as I mentioned as well we only pre compute the single bonds and we approach you we approximate the rest with just coarsely at runtime and this is primarily because we just didn't have enough time to make a more complicated complex solver offline but I think as we move on to for the next iteration of snowdrop what we have to do
is actually to buy the bulletin to implement the proper GPU path tracer that will allow us to capture the multiple bounces when we bake the probes so finally just a couple of words our tech snowdrop was developed at the same time as the division and because of time constraints sometimes we did not have enough time to do proper bug fixing instead we just gave the artist some parameters to say here tweak this until it kind of looks right so this effectively sort of hides the problem but doesn't really solve them and at the end what happened was that we have a huge mass of parameters each one of them had sort of obscure effects or once we feed we fix the bugs we just disconnected it in order not to for it not to mess up the solution so something's straight up don't work some things don't work eggs expect that and it's very confusing for the lighting artists because they don't know which
things actually have which things actually will allow them to tweak the lighting and this sort of showed us that proper bug fixing is very important rather than just giving some numbers to the artists and letting them tweak things by themselves so we we're thinking that for the next iteration of snowdrop we have to simplify the interface and just provide just a couple of intuitive sliders that people can tweak okay I have to thank all my colleagues at massive at the end of the presentation especially NR and Dennis who did a lot of the work so if you've got any questions this is my email the websites for massive fan Ubisoft so we're done I think we have about five minutes for questions I would like to step up to the microphone please
thank you for sharing good idea and I have a question how long does it take to very crew and the placement approve it any man you try to put it yeah we mention it in one of the slides it takes about eight hours of course it depends on like the speed of your engine and the type of Jim's really have and I think there are many many data period under-wing Priya in San Aditya and some will pop up will probably okay I think what what how do you thin English if you feel more comfortable we can talk later also be here to answer questions as well so feel free to come and ask me so I
will try to if it's a little bit easier okay thank you yeah right yes my question is I don't know if you mentioned that how do you update the video grid like which grid cell corresponds to which probe in the world it's one thing so basically the probes aren't really tied to any particular grits because we can spawn them at multiple locations we also nagy them a little bit they can be spawn that right right so my question is like for each cell you find the closest probe for each level yet that's right so we just find the closest probe offline which it's just a dumb thing that just goes for each each of the probes and figures out which one is the closest that's it so another question is have you experimented with like cascaded approach
having several grids like more resolution it's it's a good idea I think in general we just didn't have enough time to utilize it okay thank you thank you um did you ever have problems with um incorrect lighting at the edge of a sector because say there was a large building at the edge of this sector and then on the sector beside it was only taking those all of the time it's it's there's like all sorts of weird things that you're gonna see but most of the time they kind of masked because we do trilinear filtering as well so you don't just do one sector and then another sector you actually do Trentino filtering between the two different sectors so it's kind of masked but the problem is there yes thank you yes I wanted to know how you validated the accuracy of your solution like do you have a tracer or anything like that is just way now does that kind of artistic we just tweaked it until it
looked fine and our our director said this is good so what's the disk size of the writing data it's in one of the slides it's about one gigs so it's fairly low and you can basically make that as large as you want by increasing the the properties all right thank you very much [Applause]
Auto-generated captions from YouTube — names and numbers may be misheard.
Game Developers Conference · 2026
Game Developers Conference · 2019
Comments