我们之前的教程都是静态图,但是 shader 的一大魅力就是让图形能够按照规律动起来,我们这次尝试实现一个日落的效果吧。
太阳
老规矩我们先画个圆作为太阳:
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 uv = fragCoord/iResolution.xy;
uv -= 0.5;
uv.x *= iResolution.x / iResolution.y;
float radius = 0.2;
float blur = 0.01;
vec3 suncol = vec3(1.0, 0.9, 0.3);
vec3 col = vec3(0.0);
float d = smoothstep(radius, radius - blur, length(uv));
col = mix(col, suncol, d);
// Output to screen
fragColor = vec4(col,1.0);
}
背景
然后我们加上背景,这里我们使用了 mod 函数来生成分割矩形 ,用 uv.y 对 0.2 取余能够保证值按规律落在 [0,0.2),然后再加上 step
函数针对过半的值映射到 0 和 1,结果就是分割矩形。注意背景需要在圆之前画,否则会覆盖圆。
vec3 bgcol = vec3(0.65, 0.4, 0.1);
float rect = step(mod(uv.y, 0.2), 0.1);
col = mix(col, bgcol * 1.2, rect);
col = mix(col, bgcol, 1.0 - rect);
// ...画圆的代码
移动
接下来我们要让太阳从左边向右边以圆弧形式先升起后落下,我们使用了一个内置变量 iTime
,这个变量的值是当前运行时间,会不断叠加,我们把 iTime 传到 sin
和 cos
中就能按照规律得到 [0,1] 区间的值。然后我们定义了 center
圆心,它会随着时间做圆周运动,由于圆心不再是零点了,我们就改用 distance
来计算圆。
uv.y += 0.5;
vec2 center = vec2(sin(iTime * speed) / 0.9, cos(iTime * speed) / 2.0);
float d = smoothstep(radius, radius - blur, length(distance(center, uv)));
col = mix(col, suncol, d);
补充细节
现在基本的样子有了,不过有点粗糙,我们再完善一点点细节,例如太阳移到正中央会逐渐变大,同时颜色也有相应的渐变。
float t = abs(sin(iTime*0.8));
radius -= t * 0.05;
blur += t * 0.01;
suncol -= t * 0.4;
bgcol *= cos(iTime*0.8) * 0.9;
暂无关于此日志的评论。