我一直试图通过着色器玩具中的片段着色器生成水效果。现在我试图使用八度脊噪声多重分形来产生类似水的表面。到目前为止,这很好。我想采取的下一步是通过这个"水面"进行适当的光线折射,然而我最终会遇到一种奇怪的情况。
我设置了着色器,使用软阴影和带有棋盘图案的平面对两个球体进行射线照射,以便轻松看到失真。
这是我的着色器。 https://www.shadertoy.com/view/XddcRB
(x和y轴旋转通过,顶部,底部,左侧,右侧,横向移动) 向下看看折射表面(如果你向下移动太远,你将在表面下方,并且不会发生折射)
乍一看,这种效果看起来好像有效,但是如果你移入水中,你会看到它直到你移动到表面下方(没有发生折射),棋盘就不会出现这种情况。 t实际上服从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);
到
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);
它完全消除了折射效果。
此外,如果我尝试增加折射率,我在表面下方看不到任何东西(即使有1.1折射率)。
vs
除了这些问题之外,球体似乎从未像图案那样扭曲。
我认为我需要在水的接触点设置每条射线的原点,并从该点开始对每条射线进行角度调整(因此我认为有必要将origin =设置为water_ray,这是射线直到水面)。