Shader 魔法的学习之路(4):让图形动起来


3楼猫 发布时间:2022-06-10 09:00:58 作者:mnikn Language

我们之前的教程都是静态图,但是 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 传到 sincos 中就能按照规律得到 [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;
完整代码在:点击跳转

© 2022 3楼猫 下载APP 站点地图 广告合作:asmrly666@gmail.com