iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 12
2
Modern Web

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

[WebGL - Day12] Shadertoy - 畫圖 (1/2) 圓形、變形、置中

  • 分享至 

  • xImage
  •  

上色沒什麼問題的話,那來畫圖吧!


可是
fragment shader 沒有像是 drawRect()drawCircle() 的方法

畫圓

先前提到的,用數學方式畫出想要的畫面

畫圈呢?
圓是從圓心到邊界距離固定的形狀,
也就是定義好圓心半徑後,就能畫出圓了

float d = length(uv);
vec3 col = vec3(d);

length()

在這邊用了 length() 公式:

length Vector length.
float length (gentype p)
Description
Returns the length of vector p, i.e., the square root of (p.x2 + p.y2 + ...)

從公式來推:
length(0., 0.) 結果是 0
length(0., 1.) 結果是 1
length(1., 1.) 結果是 √2,大於1,顯示為白色
length(1., 0.) 結果是 1

因此畫出來的圖是黑到白, 1/4 的...橢圓形

由於 WebGL 是由 Khronos Group 維護,
我在查找 API 時會到 khronos 的 文件查找
length()
khronos api

不是正圓

四個角落的 length() 值算出來是 0 ~ 1
但由於畫面本身不是正方形
因此畫出來的形狀是橢圓形
將橢圓形乘上邊界比,就是正圓了

uv.x *= iResolution.x /iResolution.y;
float d = length(uv);
vec3 col = vec3(d);

length circle

搬到畫面中間

相當單純,將 uv 的值各 減去 .5 即可

uv -= .5; // -.5 ~ // .5
uv.x *= iResolution.x /iResolution.y;
float d = length(uv);
vec3 col = vec3(d);

length circle fixed

需留意的是,需要先調整中心位置,然後再調整變形
如果兩行程式碼調換
就會變成形狀正確,但位置並沒有置中的情形

uv.x *= iResolution.x /iResolution.y;
uv -= .5;
float d = length(uv);
vec3 col = vec3(d);

length circle wrong

黑白的圓

用單純的判斷式即可,當 length() 的結果 大於 .3
顯示為白色,反之為黑色

uv -= .5; // -.5 ~ // .5
uv.x *= iResolution.x /iResolution.y;
float d = length(uv);
float c = d;
if(d>.3)c=1.;else c=0.;
vec3 col = vec3(c);

length


畫圖好麻煩啊,真的要會畫嗎?

用畫的很麻煩,如果要取得一樣的結果
把圖片當做素材讀入使用也是一種做法

讀圖片會有檔案大小、解析度、吃效能的問題
但可能相較容易維護


本篇參考自 Shadertoy for absolute beginners
系列教學對於學習 Shader 很有幫助,
學習後也較容易延伸思考出自己想要的效果


上一篇
[WebGL - Day11] Shadertoy - 顏色控制與使用 iTime 更新畫面
下一篇
[WebGL - Day13] Shadertoy - 畫圖 (2/2) 方形、smoothstep() 函數
系列文
寫給工程師的 WebGL 學習心得30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言