Glsl 水折射会产生奇数效果,不会超过1.0

Glsl 水折射会产生奇数效果,不会超过1.0,glsl,webgl,shader,raycasting,Glsl,Webgl,Shader,Raycasting,我一直试图通过shader toy中的片段着色器生成水效果。现在我正在尝试使用倍频程脊噪声多重分形来生成一个水样的表面。到目前为止,这一切都很好。我想采取的下一步是通过这个“水面”进行适当的光折射,然而我最终遇到了一个奇怪的情况 我已经将着色器设置为光线追踪两个球体,带有软阴影,以及一个带有棋盘格图案的平面,以便轻松查看扭曲 这是我的着色器。 (x轴和y轴旋转通过,顶部,底部,左侧,右侧,wasd进行横向移动) 向下看以查看折射曲面(如果向下移动太远,将位于曲面下方,并且不会发生折射) 乍一看

我一直试图通过shader toy中的片段着色器生成水效果。现在我正在尝试使用倍频程脊噪声多重分形来生成一个水样的表面。到目前为止,这一切都很好。我想采取的下一步是通过这个“水面”进行适当的光折射,然而我最终遇到了一个奇怪的情况

我已经将着色器设置为光线追踪两个球体,带有软阴影,以及一个带有棋盘格图案的平面,以便轻松查看扭曲

这是我的着色器。

(x轴和y轴旋转通过,顶部,底部,左侧,右侧,wasd进行横向移动) 向下看以查看折射曲面(如果向下移动太远,将位于曲面下方,并且不会发生折射)

乍一看,这种效果似乎有效,但如果你进入水中,你会看到,直到你移动到水面以下(没有发生折射),棋盘实际上不会遵循y轴移动来改变其透视图(也就是说,向下看和向上或向下移动时,图案保持不变)

我认为这是因为我在显示图案时没有考虑新的原点,但是,当我改变线条以决定是否显示折射时

vec3 normal_c;
float water_surface = gradientNoiseRayMarch(ray, origin, normal_c);
vec3 water_ray = origin + ray * water_surface;
float depth;
if(origin.y > water_ray.y){

    vec3 refract_ray = refract(ray, normal_c, 1.0);
    ray = normalize(refract_ray);
    //origin = water_ray;
    depth = rayMarch(normalize(refract_ray), water_ray);
}
...
vec3 surface_point = vec3(origin+ray*depth);    
float value = getCheckerPattern(surface_point.xz, 2.0);

它完全消除了折射效果

另外,如果我尝试增加折射率,我在表面下看不到任何东西(即使折射率为1.1)

vs

除了这些问题之外,球体似乎从未像图案那样扭曲

我认为我需要在水的接触点设置每条射线的原点,并使每条射线与该点成一定角度(因此我认为有必要将原点=设置为水_射线,这是直到水面的射线)

vec3 normal_c;
float water_surface = gradientNoiseRayMarch(ray, origin, normal_c);
vec3 water_ray = origin + ray * water_surface;
float depth;
if(origin.y > water_ray.y){

    vec3 refract_ray = refract(ray, normal_c, 1.0);
    ray = normalize(refract_ray);
    origin = water_ray; //CHANGED
    depth = rayMarch(normalize(refract_ray), water_ray);
}
...
vec3 surface_point = vec3(origin+ray*depth);    
float value = getCheckerPattern(surface_point.xz, 2.0);