opengl光照之镜面光逐顶点渲染与逐像素渲染

镜面光逐顶点渲染效果

opengl光照之镜面光逐顶点渲染与逐像素渲染_第1张图片

顶点shader

attribute vec3 pos;//顶点坐标
attribute vec2 texcoord;//纹理坐标
attribute vec3 normal;//法线

uniform mat4 M;//模型矩阵
uniform mat4 P;//投影矩阵
uniform mat4 V;//摄像机观察矩阵
uniform mat4 NM;//将法线变换到世界坐标系或视口坐标系的矩阵

uniform vec3 U_LightPos;//光源位置
uniform vec3 U_EyePos;//眼睛的位置
uniform vec4 U_DiffuseLightColor;//漫反射光颜色
uniform vec4 U_DiffuseMaterial;//漫反射光的材质
uniform vec4 U_SpecularLightColor;//镜面光颜色
uniform vec4 U_SpecularMaterial;//镜面光材质

varying vec4 V_DiffuseColor;
varying vec4 V_SpecularColor;


void main()
{
	vec3 L=U_LightPos;//由物体表面指向光源的向量
	L=normalize(L);//归一化
	
	//获取转换到世界空间或者视口空间的法线向量
	vec3 n=normalize(mat3(NM)*normal);
	
	//计算漫反射光强度
	float diffuseIntensity=max(0.0,dot(L,n));
	//漫反射光照最终颜色
	V_DiffuseColor=U_DiffuseLightColor*U_DiffuseMaterial*diffuseIntensity;
	
	//镜面光产生的原因:当照射在物体上的光源产生的反射光和人眼看物体的方向一致时
	//此时,物体表面就会产生最亮的光斑,也就是镜面光
	
	//计算镜面反射反射光
	vec3 reflectDir=reflect(-L,n);
	reflectDir=normalize(reflectDir);
	//将模型上的点变化到世界空间
	vec4 worldPos=M*vec4(pos,1.0);
	
	
	//视线方向
	vec3 viewDir=U_EyePos-worldPos.xyz;
	viewDir=normalize(viewDir);
	
	//计算最终镜面光
	V_SpecularColor=U_SpecularLightColor*U_SpecularMaterial*pow(max(0.0,dot(viewDir,reflectDir)),8.0);
	gl_Position=P*V*worldPos;

}


镜面光逐顶点渲染片元shader

uniform vec4 U_AmbientLightColor;
uniform vec4 U_AmbientMaterial;

varying vec4 V_DiffuseColor;
varying vec4 V_SpecularColor;

void main()
{
	vec4 ambientColor=U_AmbientLightColor*U_AmbientMaterial;
	gl_FragColor=ambientColor+V_DiffuseColor+V_SpecularColor;
}

镜面光逐像素渲染效果

opengl光照之镜面光逐顶点渲染与逐像素渲染_第2张图片

可以发现 逐像素的渲染效果比逐顶点好很多,因为逐顶点渲染顶点之间的片元是插值出来的效果。

逐像素渲染顶点shader

attribute vec3 pos;
attribute vec2 texcoord;
attribute vec3 normal;

uniform mat4 M;
uniform mat4 P;
uniform mat4 V;
uniform mat4 NM;

varying vec3 V_Normal;
varying vec3 V_WorldPos;

void main()
{
	V_Normal=mat3(NM)*normal;
	vec4 worldPos=M*vec4(pos,1.0);
	V_WorldPos=worldPos.xyz;

	gl_Position=P*V*worldPos;
}
逐像素渲染片段shader


uniform vec3 U_LightPos;
uniform vec3 U_EyePos;
uniform vec4 U_AmbientLightColor;
uniform vec4 U_AmbientMaterial;
uniform vec4 U_DiffuseLightColor;
uniform vec4 U_DiffuseMaterial;
uniform vec4 U_SpecularLightColor;
uniform vec4 U_SpecularMaterial;

varying vec3 V_Normal;
varying vec3 V_WorldPos;

void main()
{
	//ambient
	vec4 ambientColor=U_AmbientLightColor*U_AmbientMaterial;

	//diffuse
	//L vector
	vec3 L=U_LightPos;
	L=normalize(L);
	//N vector
	vec3 n=normalize(V_Normal);

	float diffuseIntensity=max(0.0,dot(L,n));
	vec4 diffuseColor=U_DiffuseLightColor*U_DiffuseMaterial*diffuseIntensity;

	
	//specular
	//reflection
	vec3 reflectDir=reflect(-L,n);
	reflectDir=normalize(reflectDir);
	//inverse view direction : object->eye

	vec3 viewDir=U_EyePos-V_WorldPos;
	viewDir=normalize(viewDir);

	vec4 specularColor=U_SpecularLightColor*U_SpecularMaterial*pow(max(0.0,dot(viewDir,reflectDir)),8.0);

	gl_FragColor=ambientColor+diffuseColor+specularColor;
}

normalMatrix 法线矩阵的计算

	glm::mat4 modelMatrix = glm::translate(0.0f,0.0f,-3.0f);
	glm::mat4 projectionMatrix = glm::perspective(50.0f, 800.0f / 600.0f, 0.1f, 1000.0f);

	glm::mat4 normalMatrix = glm::inverseTranspose(modelMatrix);



你可能感兴趣的:(opengl_shader专题)