我想为场景添加雾。但我不想根据片段与相机的距离向片段颜色添加雾,而是想采用更现实的方法。我想计算距离,从眼睛到碎片的矢量“穿过”一层雾。
对于雾层,我的意思是雾有一个下限(z 坐标,在本例中为向上)和一个上限。我想计算从眼睛到片段的矢量并获取雾中的部分。该部分在图中被标记为红色。
计算其实很简单。但是,我必须用简单的方法进行一些测试(如果可以的话)。
calculate line from vector and camera position;
get line intersection with lower limit;
get line intersection with higher limit;
do some logic stuff to figure out how to handle the intersections;
calculate deltaZ, based on intersections;
scale the vector (vector = deltaZ/vector.z)
fogFactor = length(vector);
这应该很容易。然而,麻烦的是我必须添加一些逻辑来弄清楚相机和片段相对于雾的位置。另外,我必须确保向量实际上与极限有交集。 (当向量 z 值为 0 时会产生麻烦) 问题是交替并不是着色器最好的朋友,至少互联网是这么告诉我的。 ;)
我的第一个问题:有没有更好的方法来解决这个问题? (我实际上想保留我的雾模型,因为这是关于解决问题的。)
第二个问题:我认为计算应该从片段着色器而不是顶点着色器完成,因为这不是可以插值的。我这样说对吗?
这是该场景的第二张图。
我没有用下限和上限来定义雾,而是用中心高度和半径来定义它。所以下限等于中心减去半径,上限等于中心加上半径。
有了这个,我想出了这个计算:(抱歉变量名不好)
// Position_worldspace is the fragment position in world space
// delta 1 and 2 are differences in the z-axis from the fragment / eye to
// the center height
float delta1 = clamp(position_worldspace.z - fog_centerZ,
-fog_height, fog_height)
float delta2 = clamp(fog_centerZ - cameraPosition_worldspace.z,
-fog_height, fog_height);
float fogFactor z = delta1 + delta2;
vec3 viewVector = position_worldspace - cameraPosition_worldspace;
float fogFactor = length(viewVector * (fogFactorZ / (viewVector ).z));
我想这不是最快的计算方法,但它确实有效。
但是! 效果并不是很漂亮,因为雾的上限和下限非常锐利。我忘记了这一点,因为当眼睛不靠近这些边界时,它看起来还不错。但我认为这个问题有一个简单的解决方案。 :)