引言
在前面给出了一些纹理,渲染管线和坐标变换等,这里开始实现一些简单的渲染和光照的效果,还没有进行核对只是负责自己使用。
Lambert模型
在图形学中,已经给出了其BRDF函数,和光照方程:
while (!glfwWindowShouldClose(window))
{
processInput(window); //按键控制
glClearColor(0.1f, 0.1f, 0.1f, 1.0f); //清空区域的颜色
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清空颜色缓冲和深度缓冲
lightingShader.use();
lightingShader.setVec3("lightcolor", glm::vec3(1,1,1)); //光的强度
lightingShader.setVec3("lightposition", glm::vec3(1,10,1)); //光的位置
}
这里顶点着色器和片元着色器的代码实现:
//顶点着色器
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aUV;
layout (location = 2) in vec3 aNormal;
out vec3 normal;
out vec2 texcoord;
out vec3 FragPos;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
gl_Position = projection * view * model * vec4(aPos, 1.0);
FragPos = vec3(model * vec4(aPos, 1.0));
normal = mat3(transpose(inverse(model))) * aNormal;
texcoord = aUV;
}
//片元着色器
#version 330 core
in vec3 normal;
in vec2 texcoord;
in vec3 FragPos;
out vec4 FragColor;
uniform sampler2D ourTexture;
uniform vec3 lightPos;
uniform vec3 lightColor;
void main()
{
vec3 ambient = lightColor * 0.15; //环境光
vec3 norm = normalize(normal); //法线单位化
vec3 lightDir = normalize(lightPos - FragPos); //I指向光源
vec3 diffuse = vec3(texture(ourTexture, texcoord)); //纹理采样,teture之后是四维的,需要变成三维
float cosine = max(dot(norm, lightDir), 0.0); //计算cos
FragColor = vec4(ambient + lightColor * diffuse * cosine, 1.0);
}
需要特别注意的是,在渲染的时候可能对于顶点也进行一定的变化,所以在处理法线的时候也需要对于法线做变化,这里直接给出了变化,不做推导:
normal = mat3(transpose(inverse(model))) * aNormal;
Phong模型
还是先给出其BRDF函数,如下:
shader.setVec3("lightPos", glm::vec3(0, 3, 2));
shader.setVec3("lightColor", glm::vec3(1, 1, 1));
shader.setVec3("cameraPos", camera->cameraPos);
只需要加入高光的反射的量,只给出片元着色器:
//片元着色器
#version 330 core
in vec3 normal;
in vec2 texcoord;
in vec3 FragPos;
out vec4 FragColor;
uniform sampler2D ourTexture;
uniform vec3 lightPos;
uniform vec3 lightColor;
uniform vec3 cameraPos;
void main()
{
vec3 ambient = lightColor * 0.15;
vec3 norm = normalize(normal);
vec3 lightDir = normalize(lightPos - FragPos); //像素指向光源
vec3 rho_d = vec3(texture(ourTexture, texcoord));
float cosine = max(dot(norm, lightDir), 0.0);
float rho_s = 0.5;
vec3 viewDir = normalize(cameraPos - FragPos);
vec3 reflectDir = reflect(-lightDir, norm); //relect的传入是指向着色点
float cosine2 = pow(max(dot(viewDir, reflectDir), 0.0), 16); //高光反射项
FragColor = vec4(ambient + lightColor * (rho_d * cosine + rho_s * cosine2), 1.0);
}
Blin-Phong模型
H=normalize(I+V)
光源的衰减
一般的有,对于光源都有一定程度的衰减,距离光源的越远的物体,接受到光强越微弱,保留一下通常用如下的公式进行计算:
float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance));
模型的导入
一般采用assimp库进行导入,或者和tiny_loader都可以进行数据的导入,网上有很多的教程和使用,不做多余的解释。