Light Casters:
So lets maek some different light sources, different types of light behave differently. Some lightsources are super far away but super bright whilst some are close but weaker.
Directional Light:
Lets create the sun, or more the rays from the sun. So light is essentially just a bunch of different rays that come from a certain angle based on the object location and the source location. If something is super far away, like the sun the rays gather up closer to eachother (from our perspective), this makes it seem like the sun has one big continous sunray but its really just a bunch of tiny ones next to eachother.
With this in mind theres no reason to calculate how each fragment compares the the light source position, since they are all coming from the same place essentially. So lets remove that from our light struct and change the lightDir calculations accordingly.
And this should be the result. (Dont forget to set a direction for the light struct either!)

Point Light:
So lets do some point lights. Think of torches in minecraft, or like in real life. Light that radiates from an objects location but fades out and gets weaker and weaker.
Faking fading light looks kind of fake without the proper mathematical equation, point lights tend to shine bright at a close position but quickly fall of as you get slightly further away, less of a gradual fade and more of a harsh drop off before slowly fading out, this is called attenuation.
Now to properly simulate this effect of fading light theres a couple things we have to keep in mind in order to calculate it, a constant term to make sure the it never goes below 1.0. A linear gradual value and a quadratic value that, we also need the distance between the lightsource and the fragment.
Heres how to calculate the attenuation in code
![]()
Then we take our diffuse, specular and ambient values and times that by that attenuation in order to effectively apply this attenuation fragment by fragment / pixel by pixel.
Spotlight:
A spotlight is essentially a point light but the angles cut off the light so the light spreads (often) more in a cone shape. So we define things as usually with a light direction and spot direction but we also add a angle cutoff for the light. Essentially were saying that if the pixel is located at an angle beyond this angle then it shouldnt get any brighter. Now learnOpenGL does this spotlight implementation with a flashlight on the players / cameras position, so lets do that. Lets create some variables for our light struct so we can easily access it in our shader. lets declare the cutOff float variable aswell as the outerCutOff variable (more on this outerCutOff later). In our main render loop lets define the cameras position and direction of facing so we have a way of yknow doing that.

*** Boring math stuff, skip if smart ***
So we declare these just as we have done with everyother variable insinde our shader programs, by accessing the struct andsetting it that way.
So we do a dot product between the lightDir which is the variable that stores the direction to the light from the fragments position compared to the lights forward direction. We negate that so it properly aligns. So essentially light.direction which way the flashlight is pointing and lightDir is relative to the position of the fragment and the lightsource. So this dot product returns a cosine of the angle between the vectors. Now if that angle perfragment exceeds 12.5 degrees then we dont increase the light of the fragment / shader.
We then define the inner and outer circle which our flashlights light operates in. Picture putting a smaller circle on top of a larger circle, and then following the edges (edge?) of the smaller circle with an exacto knife we can cut out the outer circle that way. Now we have a hollow circle thats our outer circle and also the smaller circle which handles the proper lighting, we are keeping the outer rim of the bigger circle to transition smoothly beetween fully bright and dark so it doesnt look as jagged.
Then lets actually define whats inside the outer rim and whats inside the smaller circle, now esentially were doing this calculation and clamping the value between 0.0 and 1.0 based onif its inside the circle as in at the correct angle or if its outside the screen. Now we arent actually directly applying angle logic but using cosines to express our angles into a scalar form. So when i say "we calculate the angle" thats my brain trying to make sense of the cosine math and comparisons. Important to note is that it isnt actually a circle, but a cone and the cones tip is at the lightsources origin position.
Then we apply this intensity to our diffuse and specular so we can see the results.
TLDR: Skip this part next time
Endresult:
Okay now lets combine all these light systems into one strong scene.
Boom.




Top comments (0)