这是我参与8月更文挑战的第15天,活动详情查看: 8月更文挑战
效果图
简单脉冲波(带锯齿的半正弦波)绘制
三角波
首先我们来看如何绘制三角波,三角波(犹如锯齿)所使用的核心算法代码如下
abs(mod(x * 0.2, 2.0) - 1.0) - 0.5;
函数示意图如下
半正弦波
接着是半正弦波(截取正弦波的一部分,看起来犹如地平线上冒出一座山峰),其所使用的核心算法代码如下
if (x < 0.0 || x > sineWidth)
return 0.0;
else
return sin(x * pi / sineWidth) * height;
函数示意图如下
实际代码中我们使用和时间关联的参数
t
,随着时间推移,这样我们的半正弦波形就可以从左到右移动至指定位置
两个波函数的结合
将以上二者结合起来的话,(两种波形相乘就能得到我们所需的新波形函数)则可以得到如下的效果
完整的代码与注释如下所示
float triangle(float x)
{
/// @note Triangle wave 三角波
return abs(mod(x * 0.2, 2.0) - 1.0) - 0.5;
}
#iUniform float height = 40.0 in {40., 250.}
float truncSine(float x)
{
/// @note Half sine wave 半正弦波
const float sineWidth = 40.0;
const float pi = 3.1415;
if (x < 0.0 || x > sineWidth)
return 0.0;
else
return sin(x * pi / sineWidth) * height;
}
/// @note 二者的结合
float rdWave(float x, float t)
{
/// @note 半正弦波随时间平移
return truncSine(x - t) * triangle(x);
}
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
float yOffset = iResolution.y * .5;
float x = floor(fragCoord.x);
float y = floor(fragCoord.y) - yOffset;
float t = mod(iTime, 10.) * 40.0;
if (y < rdWave(x, t))
fragColor = vec4(1.0, 0.0, 0.0, 1.0);
else
fragColor = vec4(0.0, 0.0, 0.0, 1.0);
}
Bonus
稍作修改我们可以得到如下类似心脏跳动脉冲的效果
修改的部分代码如下
bool center = rdWave(x, t) > y;
bool right = rdWave(x - 1.0, t) > y;
bool left = rdWave(x + 1.0, t) > y;
bool up = rdWave(x, t) > y + 1.0;
bool down = rdWave(x, t) > y - 1.0;
if (center && !(right && left && up && down))
fragColor = vec4(1.0, 0.0, 0.0, 1.0);
else
fragColor = vec4(0.0, 0.0, 0.0, 1.0);