Let’s pick up where we left off in Part 12. Using the same playground we worked on last time, we will learn about lighting and
3D objects today. Remember the sun eclipse we worked on a couple of weeks ago? It’s back! Well, we are going to remove the sun and just focus on the planet this time.
First, let’s clean our kernel to only include this code:
You surely recognize all this code from few weeks ago. The only thing we did is replace the outside circle color with
black and the inside circle color with
white. The output image should look like this:
So far so good. The planet looks pretty flat and the lighting is too uniformly distributed to look real. Let’s fix that next. Geometry tells us that in order to find any point on a sphere, we need the sphere equation:
In our particular case x0, y0 and z0 are all 0 because our sphere is in the center of the screen. Solving for z gives us the the value of the
planet color, so let’s replace the last line in the kernel, with these lines:
The output image should look like this:
As you expected, the color is now calculated starting with fully white in the center of the circle and ending with fully black on the outer circle. For that to happen, we had to divide the color by the
radius, in order to normalize our range to the [0, 1] interval for the
z value, which gives us a full range light effect. We actually faked having a light source positioned at (0, 0, 1). This brings up to the next topic:
Lighting is what gives life to our colors. In order to have lights in our scene we need to compute the
normal at each coordinate. Normals vectors that are are perpendicular on the surface, showing us where the surface “points” to at each coordinate. Replace the last two lines with these lines:
Notice we already had the value of
z in the
planet variable. The output image should look like this:
This is probably not what we wanted to see, but at least we now know how normals look like when calculating the color at each normalized coordinate. Next, let’s create a source of light located to our left (negative
x) and a little behind us (positive
z). Replace the last line with these lines:
We adopted a basic light model called Lambertian (diffuse) light, where we need to multiply the normal with the normalized light source. We will talk more about lighting in a future article, however, if you are interested in learning more about lighting models, here is a great resource for your reference. The output image should look like this:
Remember from last time that our kernel also gives us a timer uniform? Let’s use it for fun and profit! Replace the
source line with this one:
By using the
sin functions, we gave the light source a circular movement.
y are both ranging from -1 to 1 using the parametric equation of a circle. The output image should look like this:
We how have a good looking, illuminated object in the scene (planet in the sky), however, the object still presents a homogeneous surface. We can make it look more realistic in two ways: either apply a texture to it, or add some noise to the
planet color. The source code is posted on Github as usual.
Until next time!