寫這些的目的是為了做自己的學(xué)習(xí)筆記,建立自己的知識(shí)庫(kù)。
概念
diffuse 漫反射
ambient 環(huán)境; 周圍的,包圍著的; 產(chǎn)生輕松氛圍的;
specular reflection 鏡面反射光
directional lights? 定向光源
spotlights? 點(diǎn)光源
attenuation 變薄; 弄細(xì); 稀薄化; 減少;
Phong reflection model:如下圖片解釋的夠清楚了吧
環(huán)境光+漫反射+高光 環(huán)境光覺得更應(yīng)該理解為固有色;
顏色理論
Using only three colors of light, we can make eight different colors: red, green, blue, yellow, cyan, magenta, black and white.
RGB三色光滿強(qiáng)度,在白紙上產(chǎn)生8種顏色如圖
But what about the other colors, like orange? Well, if you take the green light and make it half as bright as it used to be, you would see the image below.
綠光亮度減半后
Lowering the intensity (a.k.a. brightness) of the green has made a few new colors: dark green, sky blue, orange, and pink.
降低綠光強(qiáng)度(亮度),產(chǎn)生了新的顏色:深綠、天藍(lán)、粉紅;
Absorption & Reflection Of Color
顏色吸收與反射
If you look at the RGB value of each color, you will notice that the values represent reflectance. (0,0,0) is black, which means reflect none of the light. (1,1,1) is white, which means reflect all of the light. (1,0,0) is red, which means only reflect the red. Cyan is (0,1,1), which means only reflect blue and green. The RGB color of a surface represents how light is absorbed and reflected by that surface.
Calculating the reflected color is simple. The basic formula is:
intensities × surface color = reflected intensities
cyan light × magenta surface = blue light
線性代數(shù)計(jì)算
(0, 1, 1)? × (1, 0, 1)? ? ? = (0, 0, 1);
Angle of Incidence( 入射角)
決定了表面(看起來(lái))的亮度
If we represent the brightness as a single number, where 0.0 is completely dark and 1.0 is maximum brightness, then it's easy to calculate based on the cosine of the AoI. The formula is brightness = cos(AoI). Let's have a look at the cosine of some angles, just to prove that it works:
cos(? 0°) =? 1.00 (100% of maximum brightness)
cos(? 5°) =? 0.98 ( 98% of maximum brightness)
cos( 45°) =? 0.71 ( 71% of maximum brightness)
cos( 85°) =? 0.09 (? 9% of maximum brightness)
cos( 90°) =? 0.00 (Completely dark)
cos(100°) = -0.17 (Completely dark. Negative value means light is hitting the back side)
Once we have a brightness value between 0 and 1, we can multiply it by the intensities of the reflected light to get the final color for the pixel. Here is an example with cyan light:
brightness × light intensities = final color for pixel
1.0 × (0, 1, 1) = (0, 1, 1) (cyan, unchanged)
0.5 × (0, 1, 1) = (0, 0.5, 0.5) (turquoise, which is darkened cyan)
0.0 × (0, 1, 1) = (0, 0, 0) (black)
This "brightness" value between 0 and 1 is sometimes called the "diffuse coefficient."
Surface Normals(表面法線)
要計(jì)算AoI入射光夾角就必須知道表面法線和入射光向量;
N = the surface normal vector
L = a vector from the surface to the light source
θ = the angle of incidence
The vector from the surface to the light source, L, can be calculated with vector subtraction, like so:
L=lightPosition?surfacePosition
Calculating The Angle Between Two Vectors: The Dot Product
dot(v1,v2) == length(v1)*length(v2)*cos(angle)
dot(v1,v2)/(length(v1)*length(v2)) == cos(angle)
acos(dot(v1,v2)/(length(v1)*length(v2))) == angle
float brightness = dot(normal, surfaceToLight) / (length(surfaceToLight) * length(normal));
Matrix Transformation Of Normals
法線的矩陣變換:
法線通常是存在于模型空間的,也就是說(shuō)是相對(duì)于未做任何變換的定點(diǎn)坐標(biāo)的;而計(jì)算時(shí)向量是經(jīng)過(guò)了positioned/scaled/rotated這些變換的世界坐標(biāo)中;
So far, we've only used matrices to transform coordinates. The problem is that normals are not coordinates, they are unit vectors representing directions. Rotation transformations are fine, because the rotating a unit vector results in another unit vector, but scaling or translating a normal will result in an incorrect normal. The solution is to multiply the normals by a different matrix – one that has the translation and scaling parts fixed.
之前只是對(duì)坐標(biāo)用矩陣變換,對(duì)向量做矩陣變換時(shí)旋轉(zhuǎn)沒影響但位移和縮放時(shí)就會(huì)出問(wèn)題;
Removing the translation part of a 4x4 matrix is simple: we just remove the 4th column and row, converting it to a 3x3 matrix.
mat3 normalMatrix = transpose(inverse(mat3(model)));
vec3 transformedNormal = normalize(normalMatrix * normal);
#version 150
uniform mat4 camera;
uniform mat4 model;
in vec3 vert;
in vec2 vertTexCoord;
in vec3 vertNormal;
out vec3 fragVert;
out vec2 fragTexCoord;
out vec3 fragNormal;
void main() {
// Pass some variables to the fragment shader
fragTexCoord = vertTexCoord;
fragNormal = vertNormal;
fragVert = vert;
// Apply all matrix transformations to vert
gl_Position = camera * model * vec4(vert, 1);
}
#version 150
uniform mat4 model;
uniform sampler2D tex;
uniform struct Light {
vec3 position;
vec3 intensities; //a.k.a the color of the light
} light;
in vec2 fragTexCoord;
in vec3 fragNormal;
in vec3 fragVert;
out vec4 finalColor;
void main() {
//calculate normal in world coordinates
mat3 normalMatrix = transpose(inverse(mat3(model)));
vec3 normal = normalize(normalMatrix * fragNormal);
//calculate the location of this fragment (pixel) in world coordinates
vec3 fragPosition = vec3(model * vec4(fragVert, 1));
//calculate the vector from this pixels surface to the light source
vec3 surfaceToLight = light.position - fragPosition;
//calculate the cosine of the angle of incidence
float brightness = dot(normal, surfaceToLight) / (length(surfaceToLight) * length(normal));
brightness = clamp(brightness, 0, 1);
//calculate final color of the pixel, based on:
// 1. The angle of incidence: brightness
// 2. The color/intensities of the light: light.intensities
// 3. The texture and texture coord: texture(tex, fragTexCoord)
vec4 surfaceColor = texture(tex, fragTexCoord);
finalColor = vec4(brightness * light.intensities * surfaceColor.rgb, surfaceColor.a);
}