iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 13
1
Modern Web

寫給工程師的 WebGL 學習心得系列 第 13

[WebGL - Day13] Shadertoy - 畫圖 (2/2) 方形、smoothstep() 函數

  • 分享至 

  • xImage
  •  

昨天介紹了畫圓與一些調整的方法
今天除了畫方形外,
也介紹 Shader 裡一個常用的函式:smoothstep()


smoothstep() 的用途是將一個值平滑漸變到另一個值,
公式圖畫起來是這樣:
smoothstep()

本文約略介紹 smoothstep() 的結果與用法,詳細數學公式較為生硬,
可參考 官方文件The Book of Shaders: smoothstep 的說明與介紹

實際將 uv.x 用 smoothstep() 做漸變時的效果:
smoothstep()

float c = smoothstep(0.4, 0.5, uv.x);
fragColor = vec4(vec3(c),1.0);

範圍從 0.4 到 0.5,漸變的值為 uv.x


將 smoothstep 套在先前畫的圓上:
smoothstep()

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec2 uv = fragCoord/iResolution.xy;
    uv -= .5;
    uv.x *= (iResolution.x / iResolution.y);
    
    float d = length(uv);
    float r = 0.3;
    float c = smoothstep(r, r-0.1, d);

    fragColor = vec4(vec3(c),1.0);
}

主要差異為這三行:

float d = length(uv);
float r = 0.3;
float c = smoothstep(r, r-0.1, d);

這個範例裡,定義了半徑是 0.3, smoothstep() 漸變的範圍是 0.3 ~ 0.2
畫出來的就是有漸變的圓了


畫方形 -1:畫帶子

與畫圓形的方法類似,也是使用 smoothstep()
有兩個比較特別的部分:

  • 自訂了一個叫做 Band 的方法,回傳運算的結果 (float)
  • Band() 回傳了 step1 * step2 的值,這個部分很有趣,
    會在明天的內容討論

主要有差異的程式碼:

float Band(float t, float start, float end, float blur)
{
    float step1 = smoothstep(start-blur, start+blur, t);
    float step2 = smoothstep(end+blur, end-blur, t);
    return step1 * step2;
}


void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec2 uv = fragCoord/iResolution.xy;
    uv -= .5;
    uv.x *= (iResolution.x / iResolution.y);
    
    float c = Band(uv.x, -.2, .2, .01);    

    fragColor = vec4(vec3(c),1.0);
}

draw Bandt


畫方形 -2:畫方形

與畫帶子類似,定義了一個叫做 Rect 的方法,執行時呼叫兩次畫帶子的方法,
回傳運算的結果 (float)

float Rect(vec2 uv, float left, float right, float bottom, float top, float blur)
{
    float band1 = Band(uv.x, left, right, blur);
    float band2 = Band(uv.y, bottom, top, blur);
    return band1 * band2;
}

float c = Rect(uv, -.2, .2, -.3, .3, .01); 

回傳了 band1 * band2 的值,這個部分與畫帶子時相同
會在明天的內容討論
draw Rect

應用

由於可以控制畫圖的參數,於是可以自己做 displacement filter 效果
displacement filter()
示意 Demo 分上下兩區對照,畫面因拖拉互動畫出白色漸層的效果範圍
並將效果再套上原圖產生 displacement filter 的效果

後面的文章會介紹手刻 displacement filter 的方法
包含原理與實作方式 (使用 PixiJS)


本篇參考自
ShaderToy Tutorials Part 1 ~ Part4
系列教學對於學習 Shader 很有幫助,
學習後也較容易延伸思考出自己想要的效果


上一篇
[WebGL - Day12] Shadertoy - 畫圖 (1/2) 圓形、變形、置中
下一篇
[WebGL - Day14] Shadertoy - 加減乘除好吃驚、用 Shader 做遮罩
系列文
寫給工程師的 WebGL 學習心得30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言