# 生成GPU管线

``````Shader lightShader("./lightShader.vs", "./lightShader.fs");
``````

# 由程序传入GPU（管线）的变量

``````lightShader.use();
``````

``````float vertices[] = {图形顶点位置，图形顶点法向量}
``````

``````lightShader.setVec3("objectColor", 1.0f, 0.5f, 0.31f);//物体颜色
``````

``````lightShader.setMat4("projection", projection);
``````

``````glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 36);
``````

# GPU(管线)内对数据的操作

#### 1.顶点着色器

``````#version 450 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;

out vec3 FragPos;
out vec3 Normal;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

void main()
{
Normal = aNormal;
//Normal = mat3(transpose(inverse(model))) * aNormal;//用于图形变换
FragPos = vec3(model * vec4(aPos, 1.0));
gl_Position = projection * view * vec4(FragPos, 1.0);
}
``````

#### 2.片段着色器

``````#version 330 core
out vec4 FragColor;

in vec3 Normal;
in vec3 FragPos;

uniform vec3 lightPos;
uniform vec3 lightColor;
uniform vec3 objectColor;
uniform vec3 viewPos;

void main()
{
// ambient
float ambientStrength = 0.4;
vec3 ambient = ambientStrength * lightColor;

// diffuse
vec3 norm = normalize(Normal);//单位法向量
vec3 lightDir = normalize(lightPos - FragPos);//该渲染点指向光源
float diff = max(dot(norm, lightDir), 0.0);//向量点乘,角度越大数值越小.(不为负数)
vec3 diffuse = diff * lightColor;//漫反射强度与光线到该点与该平面的夹角有关,夹角越小,光照越弱.

// specular
float specularStrength = 0.5;//反光强度
vec3 viewDir = normalize(viewPos - FragPos);//绘制点指向摄像机
vec3 reflectDir = reflect(-lightDir, norm); //reflect(入射光线,法线),返回反射向量
float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32);//两向量点乘后的32次方,次方数大--集中程度高
vec3 specular = specularStrength * spec * lightColor; //反光强度*反光角度权值*光照颜色

vec3 result = (ambient + diffuse + specular) * objectColor;
FragColor = vec4(result, 1.0);
}
``````

， lightColor（光照颜色）
， objectColor（物体颜色）
， viewPos（观察值位置 、摄像机位置）
， Normal(该点法线方向)
， FragPos（该点在世界空间坐标系位置）;

##### 全局光照强度
``````// ambient
float ambientStrength = 0.4;//全局光照系数
vec3 ambient = ambientStrength * lightColor;//全局光照强度
``````
##### 漫反射光照强度
``````// diffuse
vec3 norm = normalize(Normal);//单位法向量
vec3 lightDir = normalize(lightPos - FragPos);//该渲染点指向光源
float diff = max(dot(norm, lightDir), 0.0);//向量点乘,角度越大数值越小.(不为负数)
vec3 diffuse = diff * lightColor;//漫反射强度与光线到该点与该平面的夹角有关,夹角越小,光照越弱.
``````
##### 反射光照强度
``````// specular
float specularStrength = 0.5;//反光强度系数
vec3 viewDir = normalize(viewPos - FragPos);//绘制点指向摄像机
vec3 reflectDir = reflect(-lightDir, norm); //reflect(入射光线,法线),返回反射向量
float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32);//两向量点乘后的32次方,次方数大--集中程度高
vec3 specular = specularStrength * spec * lightColor; //反光强度系数*反光角度权值*光照颜色
``````

`reflect（入射光线向量，法线）`返回反射光线向量，是GLSL内置函数。

##### 最终颜色值
`````` vec3 result = (ambient + diffuse + specular) * objectColor;
FragColor = vec4(result, 1.0);
``````

# 该管线BUG或不足

1.环境光照不能很好的替代物体间的光照影响。
2.该管线只能处理但单一光源对单一摄像机的影响。
3.最终光照强度有可能大于光源本身，不符合实际。
4.每种材质对光线的反射，漫反射强度系数不同（这将在下一节提到）。