原文地址: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);
}
然后我们获得了下图:
imagesin
形的波太过明显了。所以咱通过缩放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的高级教程。
网友评论