[State]
- To Be Continued...
[Conception]
...- Lighting
...
[ Content ]
[ Types of Light Sources ]
[ Directional Light ]
...Directional light is a light that has a direction, but doesn't have a position, i.e. it's rays are travelling through the scene in a specified direction, but they are not coming from single source. Such light is sun for example - it illuminates everything around, but it's too far from the scene, so its rays are practically parallel and affect every place of scene equally. Depending on the phase of a day, the rays direction from sun change.
[ ambient intensity ]
What's that?
In real world, if you have a lamp that illuminates dark room, even objects that aren't illuminated directly, but are let's say behind other objects are slightly illuminated.
This is because light gets scattered all over the place.
Of course, to simulate this would be a horror, but approximating it with simple constant - ambient intensity is enough for this tutorial (I wanted to simulate rays in shaders, but then I took an arrow to the knee ). It says how much will objects be lit by that light no matter the direction they're facing or their position. In this tutorial I set it to 0.2. So the ambient contribution to final color is ambientLightColor*ambientIntensity.
...Fragment Shader...struct SimpleDirectionalLight
{
vec3 vColor;
vec3 vDirection;
float fAmbientIntensity;
};
[ Point Light ]
...Point light comes from a single source, like a light bulb. It radiates to all directions, and also has an attenuation - the further object it illuminates, the less light reaches there. This type of light source has a greater computational complexity, but it's still pretty fast and easy to implement...
[ Spot Light ]
...Spotlight is most difficult from these. It emits a cone of light, with inner cone that has more intense light than outer cone. Only things inside the cone gets illuminated. The most common example is the flashlight. This one is computationally most expensive, and will be implemented later...
www.mbsoftworks.sk |
[ Normal Vecor ]
Before we proceed, we must learn about normal vectors. Normal vector of a polygon is a vector that is perpendicular to the plane in which polygon lies - forms 90 degrees angle with it. In our case, polygon will always be triangle, because it consists of 3 points and three points, if not colinear, define a plane, whereas 4 points don't have to lie on a same plane neccessary. This vector simply tells us, which direction the polygon is facing. I wrote an article about it very long ago and I edited it when writing this tutorial, so if you are looking for a bit more explanation of normal vectors and vectors generally, and how are they calculated, take a look there right now - click here. So if we have a normal vector and know the direction the triangle is facing, we can start with its illumination. We will implement directional light in this tutorial. So let's get into it.
[ Diffuse Intensity ]
Another type of light contribution to final color is diffuse.
This one does depend on direction between normal and light. And that's the variable fDiffuseIntensity in fragment shader - how much additional light will get applied to final color.
If normal and light direction are parallel and facing opposite directions, for example normal is (1, 0, 0) and light direction is (-1, 0, 0), then that face should be lit as much with that light as possible. And that's why diffuse intesity is calculated with -vLightDirection- the opposite vector.
In our example, dot product return would return -1.0 and this is cosine of angle between these vectors. Converting to actual angle will result in 180.0 degrees.
But when facing opposite directions, we want the object to be lit, so that diffuse component should be 1.0 instead. Reverting light direction will alter results of dot product, which will be 1.0 now, and we are good (angle is 0 degrees). Notice, that if angle is between 90 and 180 degrees, diffuse contribution is 0.0, because the dot product returns negative value, and we clamp it to 0.0 with max function, because we don't want to suck out the light from the place, even though we directly don't illuminate it:
Let's examine these shaders to understand directional lights. Look at the vertex shader.
There is a new matrix called normal matrix.
What exactly is this?
Well, when we transform objects into eye-space coordinates (rotate whole universe ), we also need to transform normals somehow, so they will face the right direction. We simply need to work in same space with vertex coordinates and normals as well.
When using translation, there's no need to change normals - we're just moving our objects around, directions of normals stay the same.
When using rotations, we need to rotate normals as well, and when scaling objects, another problem may arise, because it involves changing lengths of normals. In uniform scales (i.e. we scale by the same amount along X, Y and Z axis), this doesn't cause any problems, because it acts like scalar multiplication of vector - we just changed its length, but preserved directions. But in non-uniform scales, the new normal isn't perpendicular - say we scaled the polygon by (1, 2, 1), the new normal won't correspond the polygon. This picture will show more than thousand words:
So we must find a way how to transform this normals depending on the previous transformations and we want to find some nice way to do it.
It turns out, that the proper way to transform normals is to take transpose of the inverse matrix of transformations performed locally on object. Transpose of matrix is matrix flipped around its diagonal and inverse matrix of A is such matrix B, that A*B = B*A = I, where I is identity matrix...
[Standard Diffuse Lighting]
...Diffuse lighting refers to a particular kind of light/surface interaction, where the light from the light source reflects from the surface at many angles, instead of as a perfect mirror.
alfonse.bitbucket.org |
An ideal diffuse material will reflect light evenly in all directions, as shown in the picture above. No actual surfaces are ideal diffuse materials, but this is a good starting point and looks pretty decent.
For this tutorial, we will be using the Lambertian reflectance model of diffuse lighting. It represents the ideal case shown above, where light is reflected in all directions equally. The equation for this lighting model is quite simple:
Equation 9.1. Diffuse Lighting EquationThe cosine of the angle of incidence is used because it represents the perfect hemisphere of light that would be reflected. When the angle of incidence is 0°, the cosine of this angle will be 1.0. The lighting will be at its brightest. When the angle of incidence is 90°, the cosine of this angle will be 0.0, so the lighting will be 0. Values less than 0 are clamped to 0.
[Surface Orientation][Gouraud Shading][Directional Light Source][Normals and Space]
Normals have many properties that positions do. Normals are vector directions, so like position vectors, they exist in a certain coordinate system. It is usually a good idea to have the normals for your vertices be in the same coordinate system as the positions in those vertices.
So that means model space.
This also means that normals must be transformed from model space to another space.
That other space needs to be the same space that the lighting direction is in; otherwise, the two vectors cannot be compared. One might think that world space is a fine choice. After all, the light direction is already defined in world space.
You certainly could use world space to do lighting. However, for our purposes, we will use camera space. The reason for this is partially illustrative: in later tutorials, we are going to do lighting in some rather unusual spaces. By using camera space, it gets us in the habit of transforming both our light direction and the surface normals into different spaces.
We will talk more in later sections about exactly how we transform the normal. For now, we will just transform it with the regular transformation matrix....
[Drawing with Lighting]
...The full lighting model for computing the diffuse reflectance from directional light sources, using per-vertex normals and Gouraud shading, is as follows. The light will be represented by a direction and a light intensity (color). The light direction passed to our shader is expected to be in camera space already, so the shader is not responsible for this transformation. For each vertex (in addition to the normal position transform), we:
This is what we do in the Basic Lighting tutorial. It renders a cylinder above a flat plane, with a single directional light source illuminating both objects. One of the nice things about a cylinder is that it has both curved and flat surfaces, thus making an adequate demonstration of how light interacts with a surface.
- Transform the normal from model space to camera space using the model-to-camera transformation matrix.
- Compute the cosine of the angle of incidence.
- Multiply the light intensity by the cosine of the angle of incidence, and multiply that by the diffuse surface color.
- Pass this value as a vertex shader output, which will be written to the screen by the fragment shader.
...
...
[The Following From www.learnopengl.com]
...[ Basic Lighting ]
...
Ambient lighting : even when it is dark there is usually still some light somewhere in the world (the moon, a distant light) so objects are almost never completely dark. To simulate this we use an ambient lighting constant that always gives the object some color.
Diffuse lighting : simulates the directional impact a light object has on an object. This is the most visually significant component of the lighting model. The more a part of an object faces the light source, the brighter it becomes.
Specular lighting : simulates the bright spot of a light that appears on shiny objects. Specular highlights are often more inclined to the color of the light than the color of the object.
...
No comments:
Post a Comment