使用GLSL实现雾化的效果
1 为什么需要在GLSL中实现雾的效果?
D3D10已经不再支持固定管线的绘制了,所有的绘制都得使用着色器语言。OpenGL虽说仍然支持固定管线,但以后难说。因为趋势如此,所以学习没有坏处。
另外,我的场景使用Shader写的,固定管线的Fog对其无效,自然得自己用着色器写雾的效果了。
2 如何进行呢?-----〉当然是上网查资料了。
网上的http://www.ozone3d.net/tutorials/glsl_fog/ 那篇文章写得还不错,但基本是照抄GLSL橙皮书9.6节的,给的Demo也无法正常运行。不过还是给我了不少帮助。
3 AMD的RenderMonkey不失为一个调Shader程序的好工具,调好后再加到项目里,节省了不少调试的时间。
以下是GLSL雾化-VS方面的代码----------------------------------------------------------------------
uniform vec4 vViewPosition; //摄像机的位置
varying float fogFactor; //雾的权重
void main(void)
{
gl_Position = ftransform();
gl_TexCoord[0] = gl_MultiTexCoord0;
const float LOG2 = 1.442695;
float fogDensity = 0.001; //这个参数代表了雾的浓度,越大雾越浓
//gl_FogFragCoord = length(vViewPosition.xyz-gl_Vertex.xyz); //计算视点与顶点的距离
gl_FogFragCoord = abs(gl_Position.z); //这样获得距离效率较高
fogFactor = exp2( -fogDensity * fogDensity * //计算雾的权重
gl_FogFragCoord * gl_FogFragCoord * LOG2 );
fogFactor = clamp(fogFactor, 0.0, 1.0); //越界处理
}
----------------------------------------------------------------------VS-End
以下是GLSL雾化-PS方面的代码----------------------------------------------------------------------
uniform sampler2D Texture0;
varying float fogFactor;
void main (void)
{
vec4 fogColor = vec4(0.0,0.4,0.6,1.0);
vec4 finalColor = texture2D(Texture0, gl_TexCoord[0].xy);
gl_FragColor = mix(fogColor, finalColor, fogFactor ); //根据雾的权重与finalColor 做混合操作
}
----------------------------------------------------------------------PS-End
4 最后效果
RenderMonkey中的效果
本人参与的海水项目中的效果(海水使用Shader着色,所以雾化也需用Shader):