Attempting Triangular Area Lights


Recently, I’ve been wrestling with attempting to define the mathematics behind the illumination of a triangular area light. Although I have not succeeded yet, I figured I would chronicle my recent attempts. Here goes!

What problem am I solving?

When illuminating a surface in rendering, we consider our shaded area as a flat differential area. (A very small patch of surface). To calculate the amount of light received by this area, we typically consider the shape of our light projected onto a hemisphere centered around the normal of our shaded area. Lambert made use of this hemisphere to model skylight.[1]


We then take the projection of our light onto the sphere and project it onto the surface of our shaded area.


This is sometimes known as the projected solid angle of our area light.

With this in mind, my goal was to find a mathematical formula that would calculate the projected solid angle of an arbitrary triangle in space projected onto an arbitrary shaded area.

Why a triangle? Because we could take the triangle and compose larger more complex polygonal area lights from it.

Attempt #1 – Projecting A Triangle Onto The Unit Sphere

My first step was to try to calculate the area of the triangle projected onto the hemisphere. To do this, I considered the integration of a rectangle in space being projected onto the hemisphere. (I chose a rectangle because it simplified the integration considerably.)


I first began with the integration of a rectangle defined by a point P, 2 unit vectors u and v that point in the direction of the rectangle edges and the width W and height H.

The integral for the surface of a rectangle is simply


The next step was to take these small patches and project them onto the unit sphere. To do this, you can imagine that dy and dx are part of a triangle formed by the line between the point on our rectangle P+u*x+v*y and our shading point S.


Using the law of similar triangles, we can take the length of dx and scale it to the length at the boundary of our unit sphere.


Which can be formally defined as

\int_0^H\int_0^W \frac{dxdy}{||P+u*x+v*y-S||^2}

Unfortunately, as you might have noticed from the drawing, it’s not quite enough to simply define this integral. We also need to scale by the cosine of the angle between the vector to our point and our edge vector. We need to do this because if we simply took this integral, you would notice that if our rectangle was parallel to the vector to the shading point, it should have no area. However, our integral will give it area.


As a result, To get the cosine of the angle between both vectors we have to make use of our trusty dot product.



Plugging that into our original equation we get:

\int_0^H\int_0^W \frac{dxdy}{||P+u*x+v*y-S||^2}*\frac{(P+u*x+v*y-S).u*(P+u*x+v*y-S).v}{||P+u*x+v*y-S||^2}

Now I won’t trouble you with all the nitty gritty details, this integral has unfortunately no solution (that I could find). There is however a much simpler way to get the solid angle of a triangle onto the sphere.

Attempt #2 – Spherical Triangles

After some research, I stumbled onto the wonderful field of spherical trigonometry [2]. Spherical trigonometry has the concept of spherical triangles. The area of a spherical triangle is exactly what I was trying to find with the integral above. Interestingly, there is a simple formula to calculate the area of a spherical triangle (also known as it’s spherical excess) – \alpha+\beta+\gamma-\pi. These variables represent the inner angles of a spherical triangle. Just as a planar triangle has inner angles that add up to \pi spherical triangles have inner angles that add up to over \pi.

Unfortunately, we don’t have the inner angles of our spherical triangle, but we do have it’s side lengths. Interestingly, since our spherical triangle is on a sphere, it’s side lengths are the angles formed between the vectors pointing from the center of the sphere to the vertices of the triangle.


As a result, we can easily get the angle between both vectors by normalizing them and taking the arc cosine of the result of the dot product between both vectors.


With these lengths, you can calculate the spherical excess using this formula [2]


where s=\frac{a+b+c}{2}

Now that we have the spherical area of our triangle, we want to find the projection of that area onto our shading plane.

Unfortunately, simply having the area (or solid angle) of our triangle isn’t enough information to calculate the projected area. It does look somewhat convincing though.


Attempt #3 – Spherical Lunes And Their Projection

Unfortunately, simply having the area of our spherical triangle isn’t enough to calculate it’s projected area. After many attempts to integrate it’s area to calculate it’s projected area, I’ve moved on to the next most promising avenue.

A spherical triangle is made up of 3 spherical lunes. A lune (or digon) is the shape defined by the cross-section of 2 great circles (or geodesics) which are circles on a sphere of the same radius as the sphere. (The largest circles that can be inscribed on a sphere).

To get to the area of a projected spherical triangle, I considered going back and starting from the basics of a spherical triangle.

As presented earlier, the area of a spherical triangle can be defined by the equation \alpha+\beta+\gamma-\pi. We’ll start by deriving this formula.

If you imagine a spherical triangle (I recommend looking up a picture of it) you can imagine that it’s split into 3 lunes. The area for a lune is 2*\alpha where \alpha is the angle between both great circles forming it. (We won’t be deriving this formula).

Notice that if you sum the spherical lunes twice, you get the area of the sphere with 4 spherical triangles of excess. (I recommend doing this yourself, it’s neat)


With that in mind, we can rearrange:



Now, with the image of adding up the lunes and subtracting the area of the sphere, I considered that we could take that process and apply it to our projected plane.

If we were take our lunes and draw them onto the projected planes, we can see that if we add them up, we get 2 times our projected triangle as excess of the area of our circle of pi. (2*T+\pi=\alpha+\beta+\gamma)


As a result, all that would remain would be to calculate the projected area of the spherical lunes.

This is unfortunately not as easy as I would have hopped.

Sub-Attempt #1 – Integrating the change of basis

One attempt, was to change the basis of our spherical lune so that one of it’s vertices resides at the pole of our basis. This has the benefit of making both arcs joining at that vertex into straight lines.

Once we do that, we can integrate across the whole lune to calculate it’s projected area. Simple enough.

Once you define an appropriate basis for your lune, you integrate a series of patches and project them onto our projection plane.


Turned into an integral, our equation looks roughly like this:

\int_0^\alpha\int_0^\pi (cos(\phi)*sin(\theta)*i+sin(\phi)*sin(\theta)*j+cos(\theta)*k).n d\theta d\phi

Where i,j,k is our basis, n is our projection normal, \alpha is the angle of our lune.

This approach fails because our lune will inevitably traverse the horizontal plane defined by our normal and will result in negative area. (Note that once we reach a patch that points opposite of our normal we get a negative value).


What we would need is some sort of “absolute” dot product that would result in a solvable integral.

Sub-Attempt #2 – Integrating the great circles

Another approach I took, was to integrate the projection of the great circle in the range from the pole of our lune to the horizon.


The integral for that would look something like this:

\int_\alpha^\beta\int_{f(\phi)}^\frac{\pi}{2} cos(\theta)sin(\theta) d\theta d\phi

Where f(\phi) is a function dictating the elevation of a great circle according to the angle \phi.

Where f(\phi) = \frac{\pi}{2}-acos(cos(\phi-A)*n_x+sin(\phi-A)*n_y) (I can provide the derivation if there is interest)

Unfortunately, this integral has no analytical solution.

Sub-Attempt #3 – Geometry!

My final and most recent approach was to work in the projection plane. You can calculate the projected area of a projected lune simply by combining the area of a few of it’s pieces.

Simply by breaking down the projected lune into a spherical and elliptic sectors you can derive the area of the projected lune relatively easily.

By finding the intersection of the great circles of a lune with each other [3] and their intersections with the projection plane, you can use the area for a spherical sector S(\theta) and an elliptical sector E(\theta) to find the area of the lune.

Where S(\theta) = \frac{\theta}{2}

And E(\theta) = \frac{ab}{2}*atan(tan(\theta)*a/b)

Where a is our major axis, and great circles ellipses have a major axis of 1

And b is our minor axis.

With this in mind,

E(\theta) = \frac{b}{2}*atan(tan(\theta)/b)

Calculating the area of a lune this way can only give you the area of what I call the “acute” projected lune. The lune that containts the origin of the circle. To get the “obtuse” lune, you simply have to subtract the area of the “acute” lune from \pi


Unfortunately, turning this into a program has proven somewhat challenging. Maybe there’s a flaw in my logic somewhere.


Although I haven’t reached a definitive answer on getting the projected area of triangular area light, I’m excited about the various tools used in all the previous attempts. My integration skills have improved significantly and my 3 dimensional visualization skills have improved as well.

Spherical trigonometry opens up a large variety of promising tools to work in lighting. I’m excited to make use of them in future problems.

Thank you for reading this lengthy history!

If you have any ideas on how to improve on my methods, please reach out.


[1] The 250th anniversary of daylight science Looking back and looking forward




Leave a Comment

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s