opengl实现指数雾

来源:互联网 发布:mysql root无密码登录 编辑:程序博客网 时间:2024/05/01 19:41

指数雾相对于线性雾效果更逼真

可调整雾浓度参数




顶点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;//世界空间中的顶点坐标varying vec4 V_EyeSpacePos;//模型中的点在眼睛坐标系中的位置void main(){V_Normal=mat3(NM)*normal;//将法线变换到世界空间vec4 worldPos=M*vec4(pos,1.0);V_WorldPos=worldPos.xyz;V_EyeSpacePos=V*worldPos;//将物体变换到眼睛坐标系gl_Position=P*V*worldPos;}
片元shader

uniform vec4 U_LightPos;uniform vec3 U_EyePos;uniform vec4 U_LightDirection;uniform float U_Cutoff;uniform float U_DiffuseIntensity;uniform vec4 U_AmbientLightColor;uniform vec4 U_AmbientMaterial;uniform vec4 U_DiffuseLightColor;uniform vec4 U_DiffuseMaterial;uniform vec4 U_SpecularLightColor;uniform vec4 U_SpecularMaterial;uniform float U_FogStart;uniform float U_FogEnd;uniform float U_Density;uniform vec4 U_FogColor;varying vec3 V_Normal;varying vec3 V_WorldPos;varying vec4 V_EyeSpacePos;//cal fogfloat CalculateLinearFog(float distance){float fogAlpha=(distance-U_FogStart)/(U_FogEnd-U_FogStart);fogAlpha=1.0-clamp(fogAlpha,0.0,1.0);return fogAlpha;}float CalculateExpFog(float distance){float fogAlpha=exp(-(distance*U_Density));fogAlpha=clamp(fogAlpha,0.0,1.0);return fogAlpha;}void main(){float radianCutoff=U_Cutoff*3.14/180.0;float cosThta=cos(radianCutoff);vec3 spotLightDirection=normalize(U_LightDirection.xyz);//ambientvec4 ambientColor=U_AmbientLightColor*U_AmbientMaterial;//diffuse//L vectorvec3 L=vec3(0.0);float distance=0.0;float attenuation=1.0;//light attributefloat constantFactor=0.5;float linearFactor=0.3;float expFactor=0.1;if(U_LightPos.w==0.0){//direction lightL=U_LightPos.xyz;}else{//model point -> light pos//point light / spot lightL=U_LightPos.xyz-V_WorldPos;distance=length(L);attenuation=1.0/(constantFactor+linearFactor*distance+expFactor*distance*distance);}L=normalize(L);//N vectorvec3 n=normalize(V_Normal);float diffuseIntensity=0.0;if(U_LightPos.w!=0.0f&&U_Cutoff>0.0){//spotLightfloat currentCosThta=max(0.0,dot(-L,spotLightDirection));if(currentCosThta>cosThta){if(dot(L,n)>0.0){diffuseIntensity=pow(currentCosThta,U_LightDirection.w);}}}else{//point light or direction lightdiffuseIntensity=max(0.0,dot(L,n));}vec4 diffuseColor=U_DiffuseLightColor*U_DiffuseMaterial*diffuseIntensity*attenuation*U_DiffuseIntensity;//specular//inverse view direction : object->eyevec3 viewDir=U_EyePos-V_WorldPos;viewDir=normalize(viewDir);//reflectionvec3 halfVector=L+viewDir;halfVector=normalize(halfVector);float specularIntensity=0.0;if(diffuseIntensity==0.0){specularIntensity=0.0;}else{//shinessspecularIntensity=pow(max(0.0,dot(n,halfVector)),128.0);}vec4 specularColor=U_SpecularLightColor*U_SpecularMaterial*specularIntensity*attenuation;float fogAlpha=CalculateExpFog(abs(V_EyeSpacePos.z/V_EyeSpacePos.w));gl_FragColor=mix(U_FogColor,ambientColor+diffuseColor+specularColor,fogAlpha);}



原创粉丝点击