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

来源:互联网 发布:淘宝麦兜沙特代购真吗 编辑:程序博客网 时间:2024/06/05 18:32

镜面光逐顶点渲染效果


顶点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(){//ambientvec4 ambientColor=U_AmbientLightColor*U_AmbientMaterial;//diffuse//L vectorvec3 L=U_LightPos;L=normalize(L);//N vectorvec3 n=normalize(V_Normal);float diffuseIntensity=max(0.0,dot(L,n));vec4 diffuseColor=U_DiffuseLightColor*U_DiffuseMaterial*diffuseIntensity;//specular//reflectionvec3 reflectDir=reflect(-L,n);reflectDir=normalize(reflectDir);//inverse view direction : object->eyevec3 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<float>(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);



原创粉丝点击