工作生活

Godot Shader笔记:你的第一个3D Shader 第二

2019-07-01  本文已影响0人  吃烧烤的老王

原文地址:Docs » Shading » Your first shader » Your first Spatial shader: part 2

高级效果:波

shader如此强大,因为你可以使用强大的数学工具。为了展示这一点,我们将通过修改height()并引入一个新的函数wave()把我们的波浪效果再上一个档次。

wave()有一个参数,position,它和height()中的position相同。

我们将在height()多次调用wave()来模拟波的效果。

float wave(vec2 position){
 position += texture(noise, position / 10.0).x * 2.0 - 1.0;
 vec2 wv = 1.0 - abs(sin(position));
 return pow(1.0 - pow(wv.x * wv.y, 0.65), 4.0);
}

刚开始看起来有点复杂,咱们一行一行的来(译者注:真贴心,么么哒)。

position += texture(noise, position / 10.0).x * 2.0 - 1.0;

使用noise纹理对position进行偏移后,使得波是曲面的,而非相对于网格(grid)完全垂直。

vec2 wv = 1.0 - abs(sin(position));

使用sin()position定义一个波形函数(wave-like function)。正常情况下,sin()波是非常圆润的。我们使用abs()来取绝对值,使得它们能获得锋利的脊部(ridge)并且可以将他们约束在0-1之间。然后我们用1.0减去脊部值让波峰处于顶端。

return pow(1.0 - pow(wv.x * wv.y, 0.65), 4.0);

将波的x轴向分量乘以y轴向分量再平方以获得尖锐的脊部。然后用1.0减去它,使得脊部变成波峰并且再次平方,让脊部更锋利。

现在我们可以用wave()来替换height()中的对应内容了。

float height(vec2 position, float time) {
 float h = wave(position);
}

然后我们获得了下图:

image

sin形的波太过明显了。所以咱通过缩放position把它伸展开一点。

float height(vec2 position, float time) {
 float h = wave(position*0.4);
}

看起来好多了。

image

我们可以通过叠加不同频率(frequency)和振幅(amplitude)的波,使得效果更好。也就是说,我们通过缩放position改变波的宽窄(即频率),并且通过缩放输出值来波的高矮(即振幅)。

以下是一个叠加4个波让效果更好的范例。

float height(vec2 position, float time) {
 float d = wave((position + time) * 0.4, 8.0) * 0.3;
 d += wave((position - time) * 0.3, 8.0) * 0.3;
 d += wave((position + time) * 0.5, 4.0) * 0.2;
 d += wave((position - time) * 0.6, 4.0) * 0.2;
 return d;
}

注意:我们为2个波加了time为另外2个波减了time。这使得波向不同的方向运动从而产生复杂的效果。同时请注意,所有的振幅(即在每个波最后乘的那个系数)之和为1.0。这使得波的值域在1-0

使用这段代码后,你的波将会看起来更加复杂,而你所做的只不过是加了一点点数学!

image

想获取关于3D Shader更多的内容,请阅读Shading Language doc 以及Spatial Shaders doc并且请参看更多关于Shading 以及3D的高级教程。

上一篇下一篇

猜你喜欢

热点阅读