現(xiàn)代OpenGL學(xué)習(xí)-06

原文地址

寫這些的目的是為了做自己的學(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種顏色如圖

顏色1

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);

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容