glsl refract导致无法解释的错误

时间:2017-04-13 15:19:33

标签: opengl glsl

我正在尝试渲染景观(由定向太阳灯点亮),部分在水下,阳光应该通过击中水来折射,我试图使用glsl refract(vec3 incidence, vec3 normal, float relativeIOR)模拟,但结果折射方向导致着色器分解,产生完全黑色的地形颜色。

我已经意识到问题是,在我的着色器中,我采用折射光方向和表面法线的点积,并且此点积返回小于或等于零的值,即使是将相对折射率设置为1,如下所示:

in vec3 surface_normal_worldspace;
in vec3 surface_location_worldspace;
uniform vec3 sunDirection_worldspace;
out vec3 color;

void main()
{
    vec3 water_normal=vec3(0,1,0);
    if (surface_location_worldspace.y<0)//if below water, use refraction
    {
         vec3 refracted_sunDirection_worldspace=refract(sunDirection_worldspace,water_normal,1.f);//logically this should result in no refraction at all, in other words refracted sun direction should be equal to sun direction, and the dot product should be equal, and not cause error
        color = vec3(clamp(dot(refracted_sunDirection_worldspace,surface_normal_worldspace),0,1));
    }
    else
    {
        color = vec3(clamp(dot(sunDirection_worldspace,surface_normal_worldspace),0,1));//in reality my shader is way more complex than this, but this is only to demonstrate the error
    }
}

我(当然)为相对折射率尝试了多个其他值,但结果仍然是这个(在这种情况下,太阳方向设置为vec3(0,1,0)):

Error

最明显的是折射角的点积小于或等于零,但我不明白为什么会这样,因为当相对折射率为1时,则折射方向应为完全等于未折射的。

奇怪的是,如果我将color = vec3(...)替换为水以上color=sunDirection_worldspace和水下color=refracted_sunDirection_worldspace,那么sunDirection_worldspace似乎与refracted_sunDirection_worldspace非常接近,我无法区分它们。< / p>

我的问题是,为什么折射方向会导致点积小于或等于零(可能会破坏我的阴影),以及如何使用折射函数,这样就不会发生? (请不要建议我避免在着色器中使用点积,这不是一个选项)

1 个答案:

答案 0 :(得分:0)

因为“海平面”你的地形是白色的,所以看起来像sunDirection_worldspace和water_normal都指向同一个方向。这是折射的问题。根据定义in the Khronos reference,当点(I,N)<1时,eta = 1将仅导致输出等于输入。 0