OpenGL实现
这一篇的主要内容是利用OpenGL实现phong模型,这里为了专注于phong模型,使用最为简单的正方体作为被光照影响的物体,并分别使用点平行光光源、光源以及聚光灯光源测试。
平行光光源
平行光光源一般用于表示极远处的光源,往往可以用来表示日光、月光等光源,由于光源的距离极远,往往可认为所产生的的光是平行且光照强度相等的,即物体每一点所受光照相同,如图1所示(原谅我图画的丑…)
平行光顶点着色器
首先是平行光的顶点着色器(按照自己的OpenGL版本调整,或者直接改为330。我才不会告诉你是因为自己显卡支持最新版本故意怎么写的)
#version 460 core
layout (location = 0) in vec3 in_position;
layout (location = 1) in vec3 in_normal;
out vec3 normal;
uniform mat4 model_matrix;
uniform mat4 proj_matrix;
uniform mat3 normal_matrix;
void main(){
gl_Position = proj_matrix * model_matrix * vec4(in_position, 1.0);
normal = normalize(normal_matrix * in_normal);
}
这里为了简便起见,没有使用视变换,只使用了模型变换和投影变换,后面点光源以及聚光灯的顶点着色器都只是在此基础上做了一些微小的修改。
平行光片元着色器
然后是平行光的片元着色器
#version 460 core
in vec3 normal;
layout(location = 0) out vec4 color;
uniform vec3 light_direction;
uniform vec3 view_direction;
uniform vec3 k_diffuse;
uniform vec3 k_ambient;
uniform vec3 k_specular;
uniform float shininess; // 镜面反射系数
void main(){
vec3 light_direction = normalize(light_direction);
vec3 view_direction = normalize(view_direction);
vec3 reflect_light_direction = reflect(-light_direction, normal);
reflect_light_direction = normalize(reflect_light_direction);
vec3 light = vec3(1.0, 1.0, 1.0); // 预