这里主要讲解一下体积雾的算法和相关的知识。在许多大型游戏中都可以看到体积雾的身影,体积雾是飘动的,实现的效果也是距离摄像机越远雾的浓度也就越大。这里介绍一套数学模型相对比较简单的体积雾,可以有一个简单的认识。
作者:憨豆酒(YinDou),联系我[email protected],熟悉图形学,图像处理领域,本章的源代码可在此仓库中找到: https://github.com/douysu/person-summary 如果对您有帮助还请帮忙点一个star。如果大家发现错误以及不合理之处,还希望多多指出。
这里是片元着色器的代码:
#version 400
#extension GL_ARB_separate_shader_objects : enable
#extension GL_ARB_shading_language_420pack : enable
layout (std140,set = 0, binding = 0) uniform bufferVals { //一致块
vec4 uCamaraLocation;//摄像机位置
float startAngle;//正弦函数起始角度
} myBufferVals;
layout (binding = 1) uniform sampler2D tCaodi;//传入的草地纹理
layout (binding = 2) uniform sampler2D tXued;//传入的雪地纹理
layout (location = 0) in vec2 inTexCoor;//传入的纹理坐标
layout (location = 1) in float landHeight;//传入的当前顶点的高度(物体坐标系)
layout (location = 2) in vec4 pLocation;//当如的当前顶点位置(世界坐标系)
layout (location = 0) out vec4 outColor;//传给渲染管线的最终片元颜色值
const float slabY=60.0f;//雾平面的高度
const float QFheight=5.0f;//雾平面起伏高度
const float WAngleSpan=12*3.1415926f;//雾的总角度跨度
float tjFogCal(vec4 pLocation){//计算体积雾浓度因子的方法
float xAngle=pLocation.x/960.0f*WAngleSpan;//计算出顶点X坐标折算出的角度
float zAngle=pLocation.z/960.0f*WAngleSpan;//计算出顶点Z坐标折算出的角度
float slabYFactor=sin(xAngle+zAngle+myBufferVals.startAngle)*QFheight;//联合起始角计算出角度和的正弦值
//求从摄像机到待处理片元的射线参数方程Pc+(Pp-Pc)t与雾平面交点的t值
float t=(slabY+slabYFactor-myBufferVals.uCamaraLocation.y)/(pLocation.y-myBufferVals.uCamaraLocation.y);
//有效的t的范围应该在0~1的范围内,若不存在范围内表示待处理片元不在雾平面以下
if(t>0.0&&t<1.0){//若在有效范围内则
//求出射线与雾平面的交点坐标
float xJD=myBufferVals.uCamaraLocation.x+(pLocation.x-myBufferVals.uCamaraLocation.x)*t;
float zJD=myBufferVals.uCamaraLocation.z+(pLocation.z-myBufferVals.uCamaraLocation.z)*t;
vec3 locationJD=vec3(xJD,slabY,zJD);
float L=distance(locationJD,pLocation.xyz);//求出交点到待处理片元位置的距离
float L0=20.0;
return L0/(L+L0);//计算体积雾的雾浓度因子
}else{
return 1.0f;//若待处理片元不在雾平面以下,则此片元不受雾影响
}
}
void main() {
float height1=90;//混合纹理起始高度
float height2=180;//混合纹理结束高度
vec4 colorCaodi=textureLod(tCaodi, inTexCoor, 0.0);//采样出草地颜色
vec4 colorSand=textureLod(tXued, inTexCoor, 0.0);//采样出雪地颜色
if(landHeight
这里主要的方法就是tjFogCal方法了,该方法计算了雾的浓度因子,计算时,使用的是射线和平面的参数方程。可以查看我的另一篇博客。还有就是,雾的动态的,为了实现动态的效果,还是用了正弦函数,具体可以参考http://blog.csdn.net/modestbean/article/details/79139315 这篇博客中的内容。
如果本节对您有帮助,还希望点一个star,本人的知识有限,如果本节内容有错误和不合理之处,还请朋友们多多指出,我会虚心接受每一个建议。