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