基本光照一般指的是冯氏光照,冯氏光照一般由三个元素组成:环境(Ambient)、漫反射(Diffuse)和镜面(Specular)光照。
如下图所展示的。
环境光照(Ambient Lighting):即使在黑暗的情况下,世界上也仍然有一些光亮(月亮、一个来自远处的光),所以物体永远不会是完全黑暗的。我们使用环境光照来模拟这种情况,也就是无论如何永远都给物体一些颜色。
环境光照就是说一个问物体本来是什么颜色,它就会反射什么样的光。
计算方式如下:
直接用环境光向量乘以模型颜色得到的它反射了多少的光。
漫反射光照(Diffuse Lighting):模拟一个发光物对物体的方向性影响(Directional Impact)。它是冯氏光照模型最显著的组成部分。面向光源的一面比其他面会更亮。
漫反射则是说有了一个光源,照射到模型的片段上,然后光源越垂直于模型物体的片段时,该片段获得的光照也就得到的更多,以此来模拟灯光光射的效果。
计算方式如下:
灯光向量减去片段向量得到灯光方向向量,既灰色的这条向量。
然后再通过灯光方向向量点乘法向量(黄色向量),就能够得到这个夹角,
然后再用夹角乘以灯光,得到实际片段光照。
镜面光照(Specular Lighting):模拟有光泽物体上面出现的亮点。镜面光照的颜色,相比于物体的颜色更倾向于光的颜色。
镜面反射就是需要多考虑一个相机位置,其反射向量与相机方向向量的夹角越小,镜面光的作用越大。
计算方式如下:
先计算出灯光的反射向量,
然后是相机的方向向量,相机位置减去片段位置
之后是点乘计算夹角,然后乘以光照,得到当前片段的镜面光作用程度。
老样子贴代码:
先是vertexSource.txt
#version 330 core
out vec3 FragPos;//输出片段着色位置
out vec3 Normal;//输出法向量
layout(location = 3) in vec3 aPos; //读入位置参数
layout(location = 5) in vec3 normal;//读入法向量
uniform mat4 modelMat;//模型转换矩阵
uniform mat4 viewMat;//视角矩阵
uniform mat4 projMat;//投影矩阵
void main(){
gl_Position = projMat*viewMat*modelMat*vec4(aPos.x, aPos.y, aPos.z, 1.0);//计算各种变换后的模型位置
FragPos=(modelMat*vec4(aPos,1.0f)).xyz;//计算片段着色位置
Normal= (modelMat*vec4(normal,0.0f)).xyz;//计算法向量
}
接着是fragmentSource.txt
#version 330 core
out vec4 FragColor;
in vec3 FragPos;//接受片段着色位置
in vec3 Normal;//接受法向量
uniform vec3 objColor;//模型颜色
uniform vec3 lightPos;//灯光位置
uniform vec3 lightColor;//灯光颜色
uniform vec3 CameraPos;//相机位置
void main()
{
//环境光
vec3 ambientColor=lightColor*0.1f;//进行环境光的计算
//漫反射
vec3 norm=normalize(Normal);//对法向量进行归一化
vec3 lightDir=normalize(lightPos-FragPos);//计算灯光相对于片段的方向
vec3 diffuse =max(dot(norm,lightDir), 0.0f) * lightColor;//点乘计算光对当前片段的影响,两个向量的夹角越大,光就越暗,
//镜面反射
vec3 reflectVec=reflect(-lightDir,norm);//计算出反射光
vec3 CameraVec=normalize(CameraPos-FragPos);//归一化一定不能掉,计算相机方向向量
vec3 specularColor=pow(max(dot(reflectVec,CameraVec),0.0f),32)*lightColor;//计算当前片段镜面光作用程度
vec3 result=(ambientColor+diffuse+specularColor)*objColor;//计算实际的光照
FragColor = vec4(result,1.0f);
}
main.cpp中主要就是改了数据
GLfloat vertices[] = {
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
-0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
-0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
-0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f
};
跟着改了对应vertexSource的值
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0);//从vao里面在0号索引位上拿取三个值
glVertexAttribPointer(5, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(3);//启用属性0,因为默认是禁用的
glEnableVertexAttribArray(5);//启用属性0,因为默认是禁用的
然后在将几个uniform的值给投进去
glUniform3f(glGetUniformLocation(myShader->ID, "objColor"), 1.0f, 0.5f, 0.31f);
glUniform3f(glGetUniformLocation(myShader->ID, "lightColor"), 1.0f, 1.0f, 1.0f);
glUniform3f(glGetUniformLocation(myShader->ID, "lightPos"), 1.2f, 1.0f, 2.0f);
glUniform3f(glGetUniformLocation(myShader->ID, "CameraPos"), myCamera->Position.x, myCamera->Position.y, myCamera->Position.z);
然后效果如下:
注意事项:那些normalize该加的一定要加,否则这个效果啊,会很怪。
两个normalize卡了我一天。