Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Directional light causes significant drop in frame rate

Discussion in 'Global Illumination' started by coffeefery, Aug 18, 2016.

  1. coffeefery

    coffeefery

    Joined:
    Apr 10, 2014
    Posts:
    21
    I have a scene with many props inside a building being hit by a directional light with hard shadows turned on. The frame rate ran at 47 fps with 3.8M triangles. When I set the props onto a layer that's not being affected by the light, the frame rate jumped to 62 fps with 2.1M triangles. Does the directional light take into account objects that are not being hit directly by it (or are the props affected by the light despite them being inside the building)? I'm using deferred lighting in Unity 5.3.4.

    I'd appreciate if someone could explain why that happens. Thanks.

    LightingQuestion.jpg
     
  2. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    I'm fairly sure in deferred, the directional light is the most expensive light, and will affect all objects renderable by the camera at that time. It doesn't understand occluded objects, so if something will be rendered, it will be affected by directional light fill rate. But usually that's not such a big hit. Shadows however are another story. If using GI then the quality of this and other factors will come into play as well.

    I can see a large amount of batches, so perhaps set some objects to not cast (they will always receive in deferred though). You want to look at combining geometry where possible (static batching) and generally merging geo. 5k draw calls and 3m triangles is not a lot for a mid range GPU for an optimised engine. Trouble is not sure how optimised Unity is here or what setup / shaders / other things you have going on.

    Try to use profiler, not FPS.

    Hopefully someone else will chip in with more thoughts.
     
  3. goat

    goat

    Joined:
    Aug 24, 2009
    Posts:
    5,182
    Ambient light from the direction light source should come into through the windows of the building. If you look at the two pictures posted it looks like the props are darker and casting shadows in the picture with the direction light and props in the default layer. Honestly though unless you have indoor lights you are not mentioning here, it is the picture with the props in the other layer that should look like the props are darker.

    Depending on the location of the directional light even without the bounced ambient light from the directional light source some non-bounced directional light should be coming though the windows of the building and indoors there will be ambient light too from any point lights and such light sources.

    Often if looking at an object with multiple sources of light around you will see multiple shadows being cast in multiple directions from those light sources. That is expensive.

    So to remove the effect of bounced ambient light from the directional light source outside your building into your building set the number of bounces to 0 for that directional light source. That setting is called Bounce Intensity for the light. That will have mostly the same effect of making the windows as if they were walls in your building. Only where the light can enter through a window without bouncing will you get light through a window.

    https://docs.unity3d.com/Manual/GlobalIllumination.html

    You can set the objects that don't move in your scene all to static, all lights to mixed or baked it you don't might moving objects not casting shadows at runtime, and bake but really it an indoor scene like yours that's going to look noticeably fake unless the directional light source is always in the same location which is true for most games.

    Bottom line is though for each set of shadows generated you will have extra geometry generated and will get frame rate slow down because of it.
     
  4. coffeefery

    coffeefery

    Joined:
    Apr 10, 2014
    Posts:
    21
    To: goat,
    With regards to the scene shown in the image, it does have point lights acting as ambience on the windows and it's being baked with precomputed realtime GI. However, the point lights do not cast shadows and thus should not have any impact on the scene. And since it's baked, any bounce lights from the ambient or the light should not have additional cost to it.

    I did a test with a single directional light only and the results seem to show a negligible difference between a scene with bounce light and one without.

    GI_Comparison.jpg

    To: hippocoder,
    You are probably right that the directional light does not understand occluded objects. Since I have shadows turned on, it seems to me that setting the objects to not be affected by the light is one way of maintaining a higher frame rate. I wonder if this is Unity's limitation or all game engine's in general. Also, does this limitation apply to all lights as well?
     
    Last edited: Aug 19, 2016
  5. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    It's a general engine design. It would require path tracing otherwise, and that's still requiring custom hardware to be of any use.

    What is your concern? if it's performance, please show CPU usage, as GPU perf is going to be down to shaders and vert count, while CPU perf is passes and draw calls. When on CPU perf, sort the column by Time MS, and expand to see where you're spending it. It will tell you if its shadows, or whatever.

    From what I'm seeing here, it's just draw calls eating through your frame time. There's lots that can be done of course, but no magic bullet.
     
  6. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,236
    All of this is because of shadows.

    In real time rendering shadows are done with shadow maps. This requires rendering the scene a second time from the light's point of view, effectively meaning everything in view, plus stuff out of view but between what's in view and the light, gets rendered twice. However you're obviously seeing the tri count go up by more than just 2x, and that's because rendering a single shadow map tends to mean shadows look terrible close to the camera or requires a significant amount of memory, so instead most real time rendering uses cascaded shadow maps, which is 2 or more shadow maps (Unity defaults to 4) that focus on different parts of the view.

    So, now the game is rendering the entire scene 4 additional times, though Unity does some amount of culling in each to try avoid rendering objects it doesn't need to for the larger cascades.

    So that explains the tri count, what about it being so slow?

    Well the only way to know if something is occluded from the light's "view" or not is to test against the shadow map, which means it calculates the lighting for every pixel on the screen ... then multiplies the result by the shadow possibly throwing all that work away. That might seem bizarre and wasteful, but that's kind of how shaders work. There's some optimizations that could be done to improve this like render the light twice, once to mark which pixels the light hits and the a second to only render those pixels, but this is often slower than just rendering it the "dumb" way.

    You could try making a copy of the Internal-DeferredShading.shader (the shader that Unity uses to render lights in deferred) and add "clip(atten - 0.01);" around line 45 and see if that improves performance for you. It might on some hardware depending on how the graphics drivers decided to handle the shader, it might also make it slower.
     
  7. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    @bgolus do you know if the way Unity does it is standard for optimised AAA titles? I'm curious to know if what we have is just how it is in general or not, and what can be done? thanks!
     
  8. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,236
    Basically, yeah.

    If it's an open world game with time of day changes there's probably a hard level load or oddly zigzagged hallway going from outside to a detailed interior (think GTA, or older Far Cry games) where they can turn the directional light on and off without you noticing. Ever noticed most games interiors have no windows, or if they do they have curtains / covers and just have a glow to them? Part of that is so they don't have to render what's outdoors, but the other part is so they don't have the cost of the directional light and shadow that isn't doing much. Some games might fake it with localized projectors or spot lights at the windows.

    Other games you'll flag stuff that won't be hit by the sunlight, just like here with using the layer masks. This is either done manually or as part of some baking process. Alternatively they just do baked light maps / cached shadow maps. I think some games have used occlusion culling like Unity has for the camera, but it can be an expensive thing to do for a mostly outdoors game to spend time saying "yep, the light can see everything" every frame vs manually disabling objects at a distance, or using LODs.
     
  9. coffeefery

    coffeefery

    Joined:
    Apr 10, 2014
    Posts:
    21
    To: hippocoder and bgolus:

    The explanation of how shadows work helped me understand more clearly what's happening within my scene. As someone new to game development, I'm grateful for the help being given. A few questions though:

    1. I read somewhere that it's better to have an object with many polygons than many objects each with a few polygons. If I have a pillar that's used in a game scene numerous times, is it better to combine them inside Maya or should I place them after importing the pillar object into Unity? (Does it make a difference if I place them inside Maya or Unity?) Also, is there any benefit to combine them into 1 mesh if they are spread across the whole building (in this case, the mansion has about 13 rooms and uses about 70 pillars.)

    2. In my mansion scene, I have around 25 indoor lights consisting mostly of spot lights and some point lights. For each light turned on, the scene becomes heavier, even when the objects are behind walls. According to Unity's documentation, it states:

    "The rendering overhead of realtime lights in deferred lighting is proportional to the number of pixels illuminated by the light and is not dependent on scene complexity. So small point or spot lights are very cheap to render and if they are fully or partially occluded by scene objects then they are even cheaper."

    What does it mean and how does that apply in a scene where there are objects behind a wall but not viewed by the player's camera because it is standing in front of the wall? Will 'hiding' the object using Unity's OC help?
     
    Last edited: Aug 23, 2016
  10. Acreates

    Acreates

    Joined:
    Dec 12, 2016
    Posts:
    37
    When you add those objects to a special layer, they are probably not receiving light from the Directional light and or the camera does not render them. One function I do not like is that ALL lights in the scene share the same filtering of layers. That's pretty bad. Looks like you have ambient occlusion on as well?