# Lights

Lights present a problem for the rasterization-based graphics because they involve non-local, all-pairs interactions.
In this lecture, we'll talk about three strategies for dealing with lights: forward multi-pass rendering; forward light-loop rendering; and deferred rendering.

# The Challenge

We tend to think of scenes like this:

But interesting scenes are more like this:

So how do we render multiple lights that influence multiple objects?

# Strategy: Forward, Multi-pass

Handle lights one by one, adding up each contribution. (Uses the linearity of light!)

Complexity: for N object pixels and L lights, must perform N*L material computations, read N*(L-1) fragments, and write N*L fragments.

# Strategy: Forward, Light Loop

``````//Fragment Shader:
#version 330
uniform sampler2D TEX;
uniform int LIGHTS;
uniform vec3 LIGHT_LOCATION[40];
uniform vec3 LIGHT_DIRECTION[40];
uniform vec3 LIGHT_ENERGY[40];
uniform float LIGHT_CUTOFF[40];
in vec3 position;
in vec3 normal;
in vec4 color;
in vec2 texCoord;
out vec4 fragColor;
void main() {\n"
vec3 e = vec3(0.0);
vec3 n = normalize(normal);

//compute light contributions:
for (int light = 0; light < LIGHTS; ++light) {
vec3 l = normalize(LIGHT_LOCATION[light] - position);
float nl = max(0.0, dot(n, l));
float c = dot(l,-LIGHT_DIRECTION[light]);
nl *= smoothstep(LIGHT_CUTOFF[light],mix(LIGHT_CUTOFF[light],1.0,0.1), c);
e += nl * LIGHT_ENERGY[light];
}

//compute material albedo:
vec4 albedo = texture(TEX, texCoord) * color;

//compute final color:
fragColor = vec4(e*albedo.rgb, albedo.a);
}``````

Improvement: Move the light loop from the CPU to the GPU.

Complexity: for N object pixels and L lights, must perform N*L material computations and write N fragments.

# Strategy: Deferred

Render geometry like objects, then render lights like objects.

Complexity: for N object pixels and P light pixels, must perform P material computations, read 3*P fragments, and write 3*N + P fragments.