Shader 繪製基礎圖形

咱們能夠經過頂點着色器來繪製點線面圖形,並組合成其餘各類形狀,可是通常 2D 場景中,頂點着色器通常都不改,而且它通常決定的是整個畫布的大小。因此這裏探討的是經過片元着色器來繪製基礎圖形。api

把一切圖形的繪製想象是在一張佈滿格子(像素點)的紙上畫畫: 函數

1、圓

圓形的繪製須要藉助極座標系,肯定了圓心 c,半徑 r 就能獲得任意的圓形:post

當咱們在笛卡爾座標系裏想要繪製一個圓時候,你會發現很難,由於你沒有辦法將畫布中的每一個像素點跟 center 和 radius 結合:優化

因此這裏須要把笛卡爾座標系轉成極座標系,轉換公式能夠參考下面:ui

因此咱們能夠這麼改:spa

固然你會發現這個圓的邊緣有鋸齒,能夠經過 smoothstep 來優化邊緣問題:3d

假如咱們想繪製一個橢圓呢?code

橢圓能夠理解爲把圓往水平或者垂直方向進行拉伸,正好上一篇講到了座標的計算,經過乘以一個小於 1 的數字,能夠放大:cdn

封裝成函數:blog

float circle(in vec2 _st, in float _radius){
    vec2 l = _st-vec2(0.5);
    return 1.-smoothstep(_radius-(_radius*0.01),
                         _radius+(_radius*0.01),
                         dot(l,l)*4.);
}
複製代碼

2、矩形

矩形繪製能夠理解爲四邊向內縮小,獲得畫布內的矩形:

因此若是想獲得一個非正方形,只須要水平和垂直不公用一個 padding 便可。或者經過上面橢圓的方式把座標和一個係數相乘。

若是繪製平行四邊形呢?若是要繪製平行四邊形,意味着水平或者垂直的間距是傾斜的。這裏就拿水平方向的平行四邊形來講,那兩邊的黑邊要傾斜,腦補下咱們經常使用的 y = ax 線在座標系的呈現,能夠這麼改:

本來咱們只單獨使用 st.x 或 st.y,那麼它們只表明一條垂直 x 或 有軸的直線。而經過st.x + st.y引入了兩個變量,獲得了一條二元線性方程,並能產生斜邊。之因此*0.3-0.2是爲了調整傾斜角度和調整傾斜面積。

固然還有更加方便的繪製矩形的方式,兩步便可。只要把每次的單一變量變成雙變量:

封裝成函數:

float box(vec2 _st, vec2 _size, float _smoothEdges){
    _size = vec2(0.5)-_size*0.5;
    vec2 aa = vec2(_smoothEdges*0.5);
    vec2 uv = smoothstep(_size,_size+aa,_st);
    uv *= smoothstep(_size,_size+aa,vec2(1.0)-_st);
    return uv.x*uv.y;
}
複製代碼

3、直線

直線其實就是向下或者左右邊距很大,致使中間區域很小所呈現出來的樣子:

想要線多細取決於你的間距設多大。若是是斜線呢?

還有一種更簡單到寫法:

封裝出一個畫線函數:

經過改變指數,能夠創造出不同的曲線:

封裝成函數:

float plot(vec2 st, float pct){
  return  smoothstep( pct-0.02, pct, st.y) -
          smoothstep( pct, pct+0.02, st.y);
}
複製代碼

4、三角形

有了上面傾斜角度的經驗,咱們能夠繼續這麼作:

封裝了繪製多邊形的函數:

float polygon(vec2 _st, int num) {
    // Remap the space to -1. to 1.
	_st = _st *2.-1.;
    
	// Angle and radius from the current pixel
    float a = atan(_st.x, _st.y) + PI;
	float r = TWO_PI/float(num);
    
    // Shaping function that modulate the distance
	float d = cos(floor(.5+a/r)*r-a) * length(_st);

	return 1.0-smoothstep(.4,.41,d);
}
複製代碼

5、圖形組合

如今都是一個界面只能有一個圖形,假設想要把兩種圖形放在一塊兒,或者把變換過座標系的圖形和沒有變換過座標系的圖形放在一塊兒,應該怎麼作?

咱們先看看沒有變換座標系的:

先畫一個小圓圈:

咱們能夠經過改變圓心位置,並經過像素點加法來進行組合。

同理,對於變動過座標體系的,在什麼時候的時間進行重置,也能夠混合不一樣的體系的圖形在一塊兒:

那其實這樣會破壞掉原來的座標系,咱們能夠優化一下:

6、上色

顏色的混合能夠用乘法,也能夠用 mix(),咱們在以前的文章裏提過:黑色和任何顏色相乘,都是黑色。白色和任何顏色相乘,都會變成那個顏色。

因此這裏能夠這麼寫:

相關文章
相關標籤/搜索