<p>It's completely possible to do all pixel lights in the fragment shader (or, say, do 4 at a time) by looping over an array. However, this comes at a great performance cost: You're going to be calculating lighting for every light on every fragment of the scene, even if that geometry isn't actually affected by the light's influence.</p>

<p>I suspect that is reason why Unity doesn't do so: it probably culls the objects and submits only geometry that might be influenced by the respective light on each pass, meaning that shading for a light is only evaluated in the fragments where it may have an effect. This is a trade off between processing less fragments but duplicating the geometry cost.</p>

CC BY-SA 3.0
2015-08-20T21:39:29.170Z
Now that you mentioned culling this makes a lot of sense. I just checked and there's a culling mask property in light objects to control which meshes (in a layers) are affected by it.
Felipe Lira
CC BY-SA 3.0
2015-08-20T20:34:15.230Z
2015-08-20T20:34:15.230Z
yuriks
<p>If you would do all lights in a single pass then you would need to loop over all lights in the shader. You would also need to get all information to the GPU at the same time.</p>

<p>GPUs are limited in the number of uniforms you can pass into an invocation. This limitation has lessened with UBOs and SSBOs.</p>

<p>However you are still limited with how many textures you can bind for shadow mapping.</p>

<p>Lights often only affect a small portion of the screen so the engine may only render geometry that is close to the light or adjust the viewport to only render the area the light would affect.</p>

CC BY-SA 3.0
2015-08-21T10:07:42.677Z
2015-08-21T10:07:42.677Z
ratchet freak
<p>I was looking into ways to implement multiple lights shading and I've noticed <a href="http://docs.unity3d.com/Manual/RenderTech-ForwardRendering.html">Unity uses multiple passes to achieve it</a>. It performs a base pass to apply the brightest directional pixel light + 4 vertex lights + SHs and an additional pass for each pixel light, up to a limit defined by the user on the editor.</p>

<p>I'm wondering, since I previously know how many pixels lights I need to shade, why not doing it in a single pass like vertex lights are done? What are the problems of doing so?</p>

<lighting><shader>
Multiple Lights Shading - One Pass vs Multiple Passes
Felipe Lira
# Multiple Lights Shading - One Pass vs Multiple Passes

(Asked by: username_0 on 2015-08-19)

I was looking into ways to implement multiple lights shading and I've noticed [Unity uses multiple passes to achieve it](http://docs.unity3d.com/Manual/RenderTech-ForwardRendering.html). It performs a base pass to apply the brightest directional pixel light + 4 vertex lights + SHs and an additional pass for each pixel light, up to a limit defined by the user on the editor.

I'm wondering, since I previously know how many pixels lights I need to shade, why not doing it in a single pass like vertex lights are done? What are the problems of doing so?

**Tags:** lighting, shader


---

## 2 answers

### Answer by username_1 on 2015-08-20. Score: 2 | Accepted answer

It's completely possible to do all pixel lights in the fragment shader (or, say, do 4 at a time) by looping over an array. However, this comes at a great performance cost: You're going to be calculating lighting for every light on every fragment of the scene, even if that geometry isn't actually affected by the light's influence.

I suspect that is reason why Unity doesn't do so: it probably culls the objects and submits only geometry that might be influenced by the respective light on each pass, meaning that shading for a light is only evaluated in the fragments where it may have an effect. This is a trade off between processing less fragments but duplicating the geometry cost.

> **Comments:**
> **username_0**: Now that you mentioned culling this makes a lot of sense. I just checked and there's a culling mask property in light objects to control which meshes (in a layers) are affected by it.  

---

### Answer by username_2 on 2015-08-21. Score: 1

If you would do all lights in a single pass then you would need to loop over all lights in the shader. You would also need to get all information to the GPU at the same time.

GPUs are limited in the number of uniforms you can pass into an invocation. This limitation has lessened with UBOs and SSBOs.

However you are still limited with how many textures you can bind for shadow mapping.

Lights often only affect a small portion of the screen so the engine may only render geometry that is close to the light or adjust the viewport to only render the area the light would affect.


---

