2014-05-10 78 views
2

我想将雾添加到场景中。但是,我不想根据与相机的距离给片段颜色添加雾,而是希望采用更现实的方法。我想计算距离,从眼睛到碎片的矢量“穿过”一层雾。 enter image description here计算GLSL中的矢量交点(OpenGL)

雾层我的意思是雾的下限(在这种情况下是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时会产生问题) 问题是,变化不是着色器中最好的朋友,至少这是互联网告诉我的。 ;)

我的第一个问题:有没有更好的方法来解决这个问题? (我真的想留在我的模型雾,因为这是关于解决问题。)

第二个问题:我认为计算应该从片段着色器,而不是顶点着色器,因为这是没有什么可以被插入。我对吗?

下面是该场景的第二个图形。 second graphic

+0

我的坐标系已经搞乱了。我用z作为向上的矢量,x是屏幕上的矢量,y是平行的。我知道,我应该使用正常的坐标系,其中x和y是水平/垂直的在屏幕上... –

回答

1

问题解决了。 :)

我没有定义具有下限和上限的雾,而是用中心高度和半径来定义它。因此,下限等于中心减半径,上限是中心加半径。

有了这个,我想出了这个计算:(对不起,坏的变量名)

// 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)); 

我想这是不计算该最快的方法,但它的伎俩。

不过! 这个效应并不是真正的规律,因为雾的更高和更低的极限是锐利的。我忘了这一点,因为当眼睛不在这些边界附近时,它看起来并不坏。但我认为这个问题有一个简单的解决方案。 :)

感谢您的帮助!