opengl光照之镜面光逐顶点渲染与逐像素渲染
镜面光逐顶点渲染效果
文章图片
顶点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;
}
镜面光逐像素渲染效果
文章图片
可以发现 逐像素的渲染效果比逐顶点好很多,因为逐顶点渲染顶点之间的片元是插值出来的效果。
逐像素渲染顶点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 法线矩阵的计算 【opengl光照之镜面光逐顶点渲染与逐像素渲染】
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);
推荐阅读
- PMSJ寻平面设计师之现代(Hyundai)
- 太平之莲
- 闲杂“细雨”
- 七年之痒之后
- 深入理解Go之generate
- 由浅入深理解AOP
- 期刊|期刊 | 国内核心期刊之(北大核心)
- 生活随笔|好天气下的意外之喜
- 感恩之旅第75天
- python学习之|python学习之 实现QQ自动发送消息